diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 24d9a85134b4398cde9585fae4454fbb18894c40..ba27f6da08d3d2bbc3dc5a5add6d432e09b9cf13 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,4 +1,4 @@
-image: "flowdalic/debian-testing-dev:1.12"
+image: "flowdalic/debian-testing-dev:1.14"
 
 before_script:
   - |
diff --git a/docker.sh b/docker.sh
new file mode 100755
index 0000000000000000000000000000000000000000..d45d115037913cb84283741305da7decf976dc66
--- /dev/null
+++ b/docker.sh
@@ -0,0 +1,16 @@
+#!/usr/bin/env bash
+
+# The directory of this script is also EMPER's root directory.
+EMPER_ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
+
+IMAGE=$(sed --regexp-extended --quiet 's;^image: "([^"]*)"$;\1;p' "${EMPER_ROOT}/.gitlab-ci.yml")
+
+docker run \
+	   --volume="${EMPER_ROOT}:${EMPER_ROOT}" \
+	   --interactive \
+	   --tty \
+	   --env USER_ID="${UID}" \
+	   --env GROUP_ID="$(id -g ${USER})" \
+	   --security-opt=seccomp:unconfined \
+	   "${IMAGE}" \
+	   "${EMPER_ROOT}/tools/docker-prepare" "${EMPER_ROOT}" $@
diff --git a/tools/docker-prepare b/tools/docker-prepare
new file mode 100755
index 0000000000000000000000000000000000000000..ed3b4c4b619b8e2671426cefc50c5b1dff7d45b2
--- /dev/null
+++ b/tools/docker-prepare
@@ -0,0 +1,13 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+useradd -u "${USER_ID}" -o -m user
+groupmod -g "${GROUP_ID}" user
+
+OUTSIDE_EMPER_ROOT="${1}"
+shift
+
+cd "${OUTSIDE_EMPER_ROOT}"
+
+# shellcheck disable=SC2068
+exec sudo -u user $@