Post-Release Cleanups
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 454acff30a..a8260fd087 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -178,7 +178,11 @@ jobs:
 
   # Separate from everything else because slow.
   build-and-deploy-docker:
-    if: github.repository == 'mitmproxy/mitmproxy' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/dockertest')
+    if: github.repository == 'mitmproxy/mitmproxy' && (
+      github.ref == 'refs/heads/main' ||
+      github.ref == 'refs/heads/dockertest' ||
+      startsWith(github.ref, 'refs/tags/')
+      )
     environment: deploy-docker
     needs:
      - test
diff --git a/release/README.md b/release/README.md
index 1f1644550a..fbb6820d6c 100644
--- a/release/README.md
+++ b/release/README.md
@@ -40,9 +40,9 @@ These steps assume you are on the correct branch and have a git remote called `o
 
 ### Docs
 
-- `./build.sh`. If everything looks alright, continue with
+- `./build.py`. If everything looks alright, continue with
 - `./upload-stable.sh`,
-- `DOCS_ARCHIVE=true ./build.sh`, and
+- `DOCS_ARCHIVE=true ./build.py`, and
 - `./upload-archive.sh v4`. Doing this now already saves you from switching back to an old state on the next release.
 
 ### Website
diff --git a/release/cibuild.py b/release/cibuild.py
index 0bbfdff26c..0ad958dbfa 100755
--- a/release/cibuild.py
+++ b/release/cibuild.py
@@ -541,8 +541,14 @@ def upload():  # pragma: no cover
         ], cwd=docker_build_dir)
 
         if be.is_prod_release:
-            subprocess.check_call(["docker", "tag", be.docker_tag, "mitmproxy/mitmproxy:latest"])
-            subprocess.check_call(["docker", "push", "mitmproxy/mitmproxy:latest"])
+            subprocess.check_call([
+                "docker", "buildx", "build",
+                "--tag", "mitmproxy/mitmproxy:latest",
+                "--push",
+                "--platform", DOCKER_PLATFORMS,
+                "--build-arg", f"MITMPROXY_WHEEL={whl.name}",
+                "."
+            ], cwd=docker_build_dir)
 
 
 if __name__ == "__main__":  # pragma: no cover
diff --git a/release/deploy.py b/release/deploy.py
index 6e60e3f5d3..9363109dd5 100755
--- a/release/deploy.py
+++ b/release/deploy.py
@@ -1,8 +1,10 @@
 #!/usr/bin/env python3
 import os
+import re
 import subprocess
 from pathlib import Path
 from typing import Optional
+# Security: No third-party dependencies here!
 
 if __name__ == "__main__":
     ref = os.environ["GITHUB_REF"]
@@ -17,7 +19,8 @@
 
     # Upload binaries (be it release or snapshot)
     if tag:
-        upload_dir = tag
+        # remove "v" prefix from version tags.
+        upload_dir = re.sub(r"^v([\d.]+)$", r"\1", tag)
     else:
         upload_dir = f"branches/{branch}"
     subprocess.check_call([

This PR fixes the issues described in #4685.