diff --git a/.Rbuildignore b/.Rbuildignore
index 4862ff057517b24f544491e7a4265d20c178e630..872c75268d6f96378e088f4e0fee02e0fa57bbd3 100644
--- a/.Rbuildignore
+++ b/.Rbuildignore
@@ -8,3 +8,4 @@
 ^public$
 ^pkgdown$
 ^data-raw$
+^docker_ci\.sh$
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 694d64af407a063b5459769ec01c566a17ef8993..43401d6832e7b13b54b2112098cac53b5d4cc889 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -23,7 +23,7 @@ building:
     - mkdir -p $R_LIBS_USER $BUILD_LOGS_DIR
     - Rscript -e "remotes::install_deps(dependencies = TRUE, lib = Sys.getenv('R_LIBS_USER'))"
     # Install packages required by covr and pkgdown
-    - Rscript -e "install.packages(c('DT', 'pkgdown'), lib = Sys.getenv('R_LIBS_USER'))"
+    - Rscript -e "install.packages(c('DT', 'pkgdown', 'DiagrammeR', 'DiagrammeRsvg'), lib = Sys.getenv('R_LIBS_USER'))"
     # Use --no-environ to prevent setting the environment variable R_LIBS from Rprofile.site
     # which caused R_LIBS_USER to appear last in .libPaths(), which in turn prevented check()
     # to find the packages installed in R_LIBS_USER, leading to a installation error.
diff --git a/docker_ci.sh b/docker_ci.sh
new file mode 100755
index 0000000000000000000000000000000000000000..c1d18d340f938698928f631228a5121465ca1d17
--- /dev/null
+++ b/docker_ci.sh
@@ -0,0 +1,8 @@
+## Reproduce the CI environment with:
+docker run --rm -it \
+  -v "$(pwd)":"/opt/$(basename $(pwd))" \
+  -w "/opt/$(basename $(pwd))" \
+  -e R_LIBS_USER="/opt/$(basename $(pwd))/ci/lib" \
+  -e CHECK_DIR="/opt/$(basename $(pwd))/ci/logs" \
+  -e BUILD_LOGS_DIR="/opt/$(basename $(pwd))/ci/logs/$(basename $(pwd)).Rcheck" \
+  rocker/geospatial bash