diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 57afb5f39c1a0585de845b46c1b53dec4aac7b46..d8ead1a2314ce8b0344c3ece3140075af9c4a183 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -61,3 +61,19 @@ deploy-staging:
     - launch_job_template deploy-csentry-staging
   only:
     - master
+
+pages:
+  <<: *runner_tags
+  stage: deploy
+  image: "$CONTAINER_RELEASE_IMAGE"
+  before_script: []
+  script:
+    - sphinx-build -M html docs docs/_build
+    - mv docs/_build/html public
+  artifacts:
+    paths:
+      - public
+  # CI_COMMIT_TAG is used in docs/conf.py
+  # Don't forget to update if not only deploying docs for tags
+  only:
+    - tags
diff --git a/docs/conf.py b/docs/conf.py
index 63d04c093b7f52fafcd99d6d65c4ca88d6b518c0..3f9bb765c83eb0d7f366e027ffc78aa13fed8b50 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -62,7 +62,12 @@ author = 'Benjamin Bertrand'
 # built documents.
 #
 # The short X.Y version.
-version = os.popen('git describe').read().strip()
+try:
+    # CI_COMMIT_TAG is defined by GitLab Runner when building tags
+    version = os.environ['CI_COMMIT_TAG']
+except KeyError:
+    # dev mode
+    version = os.popen('git describe').read().strip()
 # The full version, including alpha/beta/rc tags.
 release = version