diff --git a/.github/workflows/dockerimages.yml b/.github/workflows/dockerimages.yml
index bb7282fdbb0f677ca5ffd0019bbdf3d32bfac287..97f0e8ab48dd4879278dcbf98f60288749a71f98 100644
--- a/.github/workflows/dockerimages.yml
+++ b/.github/workflows/dockerimages.yml
@@ -1,23 +1,37 @@
 name: Docker Images CI
 
-on: [pull_request]
+on:
+  push:
+    branches:
+      - master
+
+  pull_request:
 
 env:
   PLATFORM: linux/amd64
+  # TODO: Replace with renovate/renovate
+  DOCKER_REPO: renovate/cache-test
 
 jobs:
   build:
     name: Build image
     runs-on: ubuntu-latest
 
+    timeout-minutes: 20
+
     strategy:
       matrix:
-        file: [Dockerfile, Dockerfile.slim]
+        tag: [latest, slim]
+
+    env:
+      DOCKER_FILE: Dockerfile.${{ matrix.tag }}
+      DOCKER_TAG: ${{ matrix.tag }}
 
     steps:
-      - uses: actions/checkout@v2
-        with:
-          fetch-depth: 1
+      - name: Overwrite env for latest tag
+        if: matrix.tag == 'latest'
+        run: |
+          echo "::set-env name=DOCKER_FILE::Dockerfile"
 
       - name: Set up Docker Buildx
         id: buildx
@@ -25,16 +39,34 @@ jobs:
         with:
           version: v0.3.1
 
+      - uses: actions/checkout@v2
+
       - name: Build the Docker image
         run: |
           docker buildx build \
             --platform ${PLATFORM} \
-            --output "type=docker" \
-            --tag renovate \
-            --file ./${{ matrix.file }} .
+            --output=type=docker \
+            --cache-from=${DOCKER_REPO}:cache-${DOCKER_TAG} \
+            --tag=renovate \
+            --file=./${DOCKER_FILE} .
+
+      - name: Test the Docker image
+        run: |
+          docker run --rm -t renovate --version
 
       - name: Image history
         run: docker history renovate
-
       - name: Image size
         run: docker image ls | grep renovate
+
+      - name: Push the Docker image
+        if: github.event_name == 'push' && github.ref == 'refs/heads/master'
+        run: |
+          echo "${{ secrets.DOCKER_RENOVATERELEASE_TOKEN }}" | docker login -u renovaterelease --password-stdin
+          docker buildx build \
+            --platform ${PLATFORM} \
+            --output=type=registry \
+            --cache-from=${DOCKER_REPO}:cache-${DOCKER_TAG} \
+            --cache-to=${DOCKER_REPO}:cache-${DOCKER_TAG} \
+            --tag=${DOCKER_REPO}:test-${DOCKER_TAG} \
+            --file=./${DOCKER_FILE} .
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 0000000000000000000000000000000000000000..194dc18e9c19b6bd1d4b5b9a10b16f22b3379359
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,99 @@
+name: Release CI
+
+on:
+  push:
+    tags:
+      - '[0-9]+.[0-9]+.[0-9]+'
+
+env:
+  PLATFORM: linux/amd64
+  # TODO: Replace with renovate/renovate
+  DOCKER_REPO: renovate/cache-test
+
+jobs:
+  docker-release:
+    runs-on: ubuntu-latest
+
+    timeout-minutes: 30
+
+    strategy:
+      matrix:
+        tag: [latest, slim]
+
+    env:
+      DOCKER_FILE: Dockerfile.${{ matrix.tag }}
+      DOCKER_TAG: ${{ matrix.tag }}
+
+    steps:
+      - name: Overwrite env for latest tag
+        if: matrix.tag == 'latest'
+        run: |
+          echo "::set-env name=DOCKER_FILE::Dockerfile"
+
+      - name: Set up Docker Buildx
+        id: buildx
+        uses: crazy-max/ghaction-docker-buildx@v1
+        with:
+          version: v0.3.1
+
+      - uses: actions/checkout@v2
+
+      - name: Build the Docker image
+        run: |
+          docker buildx build \
+            --platform ${PLATFORM} \
+            --output=type=docker \
+            --cache-from=${DOCKER_REPO}:cache-${DOCKER_TAG} \
+            --tag=renovate \
+            --file=./${DOCKER_FILE} .
+
+      - name: Test the Docker image
+        run: |
+          docker run --rm -t renovate --version
+
+      - name: Image history
+        run: docker history renovate
+      - name: Image size
+        run: docker image ls | grep renovate
+
+      - name: Generate tags
+        run: |
+          # Strip git ref prefix from version
+          VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,')
+
+
+          # Tag base
+          tags="${DOCKER_REPO}:${DOCKER_TAG}"
+          echo "Tagging ${DOCKER_REPO}:${DOCKER_TAG}"
+
+          SEMVER_REGEX="^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)?$"
+
+          if ! [[ "$VERSION" =~ $SEMVER_REGEX ]]; then
+            echo Not a semver tag - skipping
+            exit 1
+          fi
+
+          major=${BASH_REMATCH[1]}
+          minor=${BASH_REMATCH[2]}
+          patch=${BASH_REMATCH[3]}
+          slim=${DOCKER_TAG#latest}
+          slim=${slim:+-}${slim}
+
+
+          # Tag for versions additional
+          for tag in {"${major}${slim}","${major}.${minor}${slim}","${major}.${minor}.${patch}${slim}"}; do
+            echo "Tagging ${DOCKER_REPO}:${tag}"
+            tags+=",${DOCKER_REPO}:${tag}"
+          done
+
+          echo "::set-env name=TAGS::${tags}"
+
+      - name: Push the Docker image
+        run: |
+          echo "${{ secrets.DOCKER_RENOVATERELEASE_TOKEN }}" | docker login -u renovaterelease --password-stdin
+          docker buildx build \
+            --platform ${PLATFORM} \
+            --output=type=registry \
+            --cache-from=${DOCKER_REPO}:cache-${DOCKER_TAG} \
+            --tag=${TAGS} \
+            --file=./${DOCKER_FILE} .