diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile
index d2aaebbcec16eee8739296e77f07dc4dbe04d361..2e1482aaf4b04b007857f0d0a0b0f160ac0a3686 100644
--- a/.devcontainer/Dockerfile
+++ b/.devcontainer/Dockerfile
@@ -1,4 +1,54 @@
-FROM baltig.infn.it:4567/storm2/build/ngx-voms-build:issue-17-latest
+### FROM baltig.infn.it:4567/storm2/build/ngx-voms-build:issue-17-latest
+## FROM baltig.infn.it:4567/storm2/build/base
+FROM centos:7
+
+# Allow customization of build user ID and name
+ARG BUILD_USER=build
+ARG BUILD_USER_UID=1000
+
+# Allow customization of storm user ID and name
+ARG STORM_USER=storm
+ARG STORM_USER_UID=1001
+
+# Allow customization of test user ID and name
+ARG TEST_USER=test
+ARG TEST_USER_UID=1002
+
+ENV BUILD_USER $BUILD_USER
+ENV BUILD_USER_UID $BUILD_USER_UID
+
+ENV STORM_USER $STORM_USER
+ENV STORM_USER_UID $STORM_USER_UID
+
+ENV TEST_USER $TEST_USER
+ENV TEST_USER_UID $TEST_USER_UID
+
+RUN echo "include_only=.garr.it,.cern.ch" >> /etc/yum/pluginconf.d/fastestmirror.conf && \
+      yum clean all && \
+      yum install -y hostname epel-release && \
+      yum -y update && \
+      yum -y install which wget tar sudo file && \
+      echo '%wheel ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers && \
+      adduser --uid ${BUILD_USER_UID} ${BUILD_USER} && \
+      usermod -a -G wheel ${BUILD_USER} && \
+      adduser --uid ${STORM_USER_UID} ${STORM_USER} && \
+      usermod -a -G wheel ${STORM_USER} && \
+      adduser --uid ${TEST_USER_UID} ${TEST_USER} && \
+      usermod -a -G wheel ${TEST_USER} && \
+      yum clean all && \
+      rm -rf /var/cache/yum
+
+ADD assets/setup.sh /docker/
+ADD assets/user-setup.sh /docker/
+ADD assets/build-install-openresty.sh /docker/
+ADD --chown=$BUILD_USER:$BUILD_USER assets/nginx-httpg_no_delegation.patch /home/$BUILD_USER/
+ADD --chown=$BUILD_USER:$BUILD_USER assets/build-install-ngx-voms.sh /home/$BUILD_USER/bin/
+RUN sh /docker/setup.sh
+
+USER $BUILD_USER
+
+RUN sh /docker/build-install-openresty.sh \
+    && sh /docker/user-setup.sh
 
 USER root
 
diff --git a/.devcontainer/assets/build-install-ngx-voms.sh b/.devcontainer/assets/build-install-ngx-voms.sh
new file mode 100644
index 0000000000000000000000000000000000000000..93d7da8acbb6f95d57e1666158a6be6bf6475502
--- /dev/null
+++ b/.devcontainer/assets/build-install-ngx-voms.sh
@@ -0,0 +1,140 @@
+#!/bin/sh
+
+# Copyright 2018 Istituto Nazionale di Fisica Nucleare
+#
+# Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the
+# European Commission - subsequent versions of the EUPL (the "Licence"). You may
+# not use this work except in compliance with the Licence. You may obtain a copy
+# of the Licence at:
+#
+# https://joinup.ec.europa.eu/software/page/eupl
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the Licence is distributed on an "AS IS" basis, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# Licence for the specific language governing permissions and limitations under
+# the Licence.
+
+# This script builds in debug mode and installs openresty together with the
+# ngx_http_voms_module.
+#
+# The script requires the locations of the openresty bundle and of the
+# ngx_http_voms_module code (for example as checked-out from git). The locations
+# are expressed by the environment variables OPENRESTY_ROOT and
+# NGX_HTTP_VOMS_MODULE_ROOT respectively, if available. If they are not set,
+# they are guessed:
+# * a unique openresty bundle is looked for in ${HOME}
+# * the ngx_http_voms_module code is looked for in the working directory of the
+#   continuous integration environment first and then in ${HOME}
+#
+# The script works best (i.e. it is tested) if run within a docker container
+# started from the storm2/ngx-voms-build image.
+
+usage()
+{
+    echo "USAGE: $0 [OPTIONS] [TEXT]"
+    echo ""
+    echo "The default optimization level is -O3"
+    echo ""
+    echo "OPTIONS"
+    echo ""
+    echo "-h|--help"
+    echo "-o|--opt-log to enable the --with-debug option and the optimization level -O2"
+    echo "-d|--debug to enable the --with-debug option and the optimization level -O0"
+    echo "-c|--coverage to add the --coverage option to the --with-{ld|cc}-opt option and enable the debug options"
+    echo ""
+}
+
+#The script at the moment allows only debug builds, i.e. "-O0". This option is kept in shell variables cc2, but there is no way to set it to something else. I propose that by default it is set to -O2 (or even -O3) and is set to -O0 only if the option --debug is passed to the script. Moreover --coverage should imply --debug.
+
+
+cc1=-g
+debug=""
+cc3=""
+cc2=-O2
+ld=""
+
+while [ "$1" != "" ]; do
+  option=`echo $1 | awk -F= '{print $1}'`
+  case $option in
+    -o|--opt-log)
+      debug='--with-debug'
+      cc2=-O2
+      echo Enabled the debug option $debug and the optimization level $cc2
+      ;;
+    -d|--debug)
+      debug='--with-debug'
+      cc2=-O0
+      echo Enabled the debug option $debug and the optimization level $cc2
+      ;;
+    -c|--coverage)
+      cc3=--coverage
+      ld='--with-ld-opt=--coverage'
+      echo Enabled the coverage options $cc3 $ld
+      ;;
+    -h|--help)
+      usage
+      exit
+      ;;
+    *)
+      debug=""
+      cc3=""
+      cc2=-O2
+      ld=""
+      ;;
+  esac
+  shift
+done
+
+if [ ! -z "${cc3}" ]; then
+    if [ -z "${debug}" ]; then
+        debug="--with-debug"
+        cc2=-O0
+        echo Enabled the debug option $debug and the optimization level $cc2
+    fi
+fi
+
+if [ -f "${HOME}/openresty-env" ]; then
+    . ${HOME}/openresty-env
+fi
+
+gcc --version
+
+openresty_root=${OPENRESTY_ROOT:-$(ls -d ${HOME}/openresty-*/ 2> /dev/null)}
+
+if [ $(echo ${openresty_root} | wc -w) != 1 -o ! -d "${openresty_root}" ]; then
+    >&2 echo 'Invalid openresty environment ("'${openresty_root}'")'
+    exit 1
+fi
+
+module_root=${NGX_HTTP_VOMS_MODULE_ROOT:-${CI_PROJECT_DIR:-${HOME}/ngx_http_voms_module}}
+
+if [ ! -d "${module_root}" ]; then
+    >&2 echo 'Invalid ngx_http_voms_module environment ("'${module_root}'")'
+    exit 1
+fi
+
+RESTY_PACKAGES_PREFIX=/usr/local/openresty
+ZLIB_PREFIX=/usr
+OPENSSL_PREFIX=/usr
+PCRE_PREFIX=/usr
+
+cd ${openresty_root}
+./configure \
+	--with-cc="ccache gcc -fdiagnostics-color=always" \
+	--with-cc-opt="-DNGX_LUA_ABORT_AT_PANIC -I${ZLIB_PREFIX}/include -I${PCRE_PREFIX}/include -I${OPENSSL_PREFIX}/include" \
+        --with-ld-opt="-L${ZLIB_PREFIX}/lib -L${PCRE_PREFIX}/lib -L${OPENSSL_PREFIX}/lib -Wl,-rpath,${ZLIB_PREFIX}/lib:${PCRE_PREFIX}/lib:${OPENSSL_PREFIX}/lib" \
+        --with-luajit-xcflags="-DLUAJIT_NUMMODE=2 -DLUAJIT_ENABLE_LUA52COMPAT" \
+        ${RESTY_CONFIG_OPTIONS} \
+        ${debug} \
+        --with-cc-opt="${cc1} ${cc2} ${cc3}" \
+         ${ld} \
+        --add-module=${module_root}
+
+nginx_version=$(find build -name nginx.h | xargs awk '/define NGINX_VERSION/ {print $3}' | tr -d '"')
+cd build/nginx-${nginx_version}
+patch -p1 < ${HOME}/nginx-httpg_no_delegation.patch
+cd -
+
+make -j $(nproc)
+make install
diff --git a/.devcontainer/assets/build-install-openresty.sh b/.devcontainer/assets/build-install-openresty.sh
new file mode 100644
index 0000000000000000000000000000000000000000..0db06169771ba16600d119dcb3b2d28f86ac2e57
--- /dev/null
+++ b/.devcontainer/assets/build-install-openresty.sh
@@ -0,0 +1,62 @@
+#!/bin/sh
+set -ex
+
+# adapted from https://github.com/openresty/docker-openresty
+
+# configuring, building and installing is not strictly necessary, since
+# module development requires to rebuild nginx itself, but it's a good
+# check to see if everything is ok
+# configuring has the benefit that it builds and installs luajit, which
+# can then be reused during development (see the additions to .bashrc)
+
+# Docker Build Arguments
+RESTY_VERSION=${RESTY_VERSION:-"1.19.9.1"}
+RESTY_PREFIX=${HOME}/local/openresty
+RESTY_CONFIG_OPTIONS="\
+    --with-compat \
+    --with-http_addition_module \
+    --with-http_auth_request_module \
+    --with-http_dav_module \
+    --with-http_flv_module \
+    --with-http_gunzip_module \
+    --with-http_gzip_static_module \
+    --with-http_mp4_module \
+    --with-http_random_index_module \
+    --with-http_realip_module \
+    --with-http_secure_link_module \
+    --with-http_stub_status_module \
+    --with-http_sub_module \
+    --with-http_v2_module \
+    --without-http_rds_csv_module \
+    --without-http_rds_json_module \
+    --without-lua_rds_parser \
+    --without-mail_imap_module \
+    --without-mail_pop3_module \
+    --without-mail_smtp_module \
+    --with-pcre-jit \
+    --with-stream \
+    --with-stream_ssl_module \
+    --with-stream_ssl_preread_module \
+    --with-threads \
+    --prefix=${RESTY_PREFIX} \
+    "
+
+cd
+wget --quiet https://openresty.org/download/openresty-${RESTY_VERSION}.tar.gz
+tar zxf openresty-${RESTY_VERSION}.tar.gz
+cd openresty-${RESTY_VERSION}
+./configure \
+	--with-cc="ccache gcc -fdiagnostics-color=always" \
+	--with-cc-opt="-DNGX_LUA_ABORT_AT_PANIC" \
+	--with-luajit-xcflags="-DLUAJIT_NUMMODE=2 -DLUAJIT_ENABLE_LUA52COMPAT" \
+	${RESTY_CONFIG_OPTIONS}
+make
+make install
+
+# add the location of openresty executables to the PATH
+# save resty configuration options for future reuse during development
+
+cat << EOF > ${HOME}/openresty-env
+PATH="${RESTY_PREFIX}/luajit/bin:${RESTY_PREFIX}/nginx/sbin:${RESTY_PREFIX}/bin:\${PATH}"
+export RESTY_CONFIG_OPTIONS="${RESTY_CONFIG_OPTIONS} --with-luajit=${RESTY_PREFIX}/luajit"
+EOF
diff --git a/nginx-httpg_no_delegation.patch b/.devcontainer/assets/nginx-httpg_no_delegation.patch
similarity index 100%
rename from nginx-httpg_no_delegation.patch
rename to .devcontainer/assets/nginx-httpg_no_delegation.patch
diff --git a/.devcontainer/assets/setup.sh b/.devcontainer/assets/setup.sh
new file mode 100644
index 0000000000000000000000000000000000000000..7238be3e9f30f744a97f70c967f4070140cd1f1c
--- /dev/null
+++ b/.devcontainer/assets/setup.sh
@@ -0,0 +1,22 @@
+#!/bin/sh
+set -ex
+
+yum-config-manager --add-repo https://openresty.org/package/centos/openresty.repo
+
+yum -y install \
+    gcc-c++ \
+    GeoIP-devel \
+    gd-devel \
+    gettext \
+    ccache \
+    libxslt-devel \
+    lcov \
+    perl-ExtUtils-Embed \
+    perl-Test-Nginx \
+    perl-Digest-SHA \
+    readline-devel \
+    boost-devel \
+    voms-devel \
+    make \
+    patch \
+    less
diff --git a/.devcontainer/assets/user-setup.sh b/.devcontainer/assets/user-setup.sh
new file mode 100644
index 0000000000000000000000000000000000000000..d4716ac41cf86665f14ce700b7ad27e59a7573e5
--- /dev/null
+++ b/.devcontainer/assets/user-setup.sh
@@ -0,0 +1,18 @@
+#!/bin/sh
+set -ex
+
+cat << EOF >> ${HOME}/.bashrc
+if [ -f "\${HOME}/openresty-env" ]; then
+    . \${HOME}/openresty-env
+fi
+
+if [ -d \${HOME}/bin ]; then
+  PATH=\${HOME}/bin:\${PATH}
+fi
+
+if [ -n "\${PS1}" ]; then
+    echo
+    echo "To build and install openresty with the ngx_http_voms_module run 'build-install-ngx-voms.sh'"
+    echo
+fi
+EOF