diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index caca7be44191f92dd447131aea370bc3aa303048..1edb017ba368305f7b913819de28cb23e8465cd7 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -36,6 +36,15 @@ build-docker:
     - .docker-matrix
     - .tag-docker-image
 
+## tag contribution branches with a more stable name than `git-${CI_COMMIT_SHORT_SHA}`
+tag contrib branch:
+  extends:
+    - .tag-docker
+    - .on-branches
+  variables:
+    # `feature/foo-bar_quux` → `feature-foo-bar-quux`
+    IMAGE_TAG: $CI_COMMIT_REF_SLUG
+
 ## dev images
 tag dev:
   extends:
diff --git a/docs/GETTING-STARTED.md b/docs/GETTING-STARTED.md
index 14e83ac6c52864c43d184ed695c0db904e3af206..68a45da11ca383756373234db12a6419176431e0 100644
--- a/docs/GETTING-STARTED.md
+++ b/docs/GETTING-STARTED.md
@@ -342,6 +342,15 @@ you need mostly 4 steps:
        # Remove `upstream` to avoid caching `CI_JOB_TOKEN`
        - "git remote remove upstream"
 
+   ## tag contribution branches with a more stable name than `git-${CI_COMMIT_SHORT_SHA}`
+   tag contrib branch:
+     extends:
+       - .tag-docker-image
+       - .on-branches
+     variables:
+       # `feature/foo-bar_quux` → `feature-foo-bar-quux`
+       IMAGE_TAG: $CI_COMMIT_REF_SLUG
+
    ## dev images
    tag dev:
      extends: