diff --git a/.gitignore b/.gitignore
index cb540b07dce57e8cc81f6ea136d55e5157f8f980..bde8ebf2a157ff6d6e90884e8e9f66adde5f172d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,7 +18,7 @@ import/solrmarc.log*
 /auth.json
 /core
 /lessphp_*.list
-/data/docker
+/data
 /docker-compose.override.yml
 /docker-env.override.yml
 /.env
diff --git a/devops/composer/modules.php b/devops/composer/modules.php
index 2d2f99618c3e7a5dd30b9ec5a186cac51d21530c..55f89bb5d3115df97df277f3f4076ef036c20b9a 100644
--- a/devops/composer/modules.php
+++ b/devops/composer/modules.php
@@ -22,13 +22,15 @@
 namespace ComposerEventHandlers;
 
 use Composer\Script\Event;
+use Symfony\Component\Filesystem\Filesystem;
 
 class Modules
 {
-    private const PATH = __DIR__ . '/../../data/cache/modules.php';
+    private const PATH = __DIR__ . '/../../data/modules.php';
 
     public static function dump(Event $event)
     {
+        (new Filesystem())->mkdir(dirname(self::PATH));
         /** @noinspection PhpUndefinedMethodInspection */
         $extra = $event->getComposer()->getPackage()->getExtra();
         $modules = var_export($extra['vufind']['modules'] ?? [], true);
diff --git a/devops/docker/autoconfig/entrypoint.sh b/devops/docker/autoconfig/entrypoint.sh
index c2734b0e17e8969eea12e0b609c4ae6efa5a040d..dd457ef03bb0fdd77ae0d62da5f52dd81bccf683 100755
--- a/devops/docker/autoconfig/entrypoint.sh
+++ b/devops/docker/autoconfig/entrypoint.sh
@@ -21,8 +21,9 @@ until ! (ping -c1 env >/dev/null 2>&1) && [ -f ./data/docker/env/autoconfig ]; d
 set -a; . ./data/docker/env/autoconfig; set +a
 
 if [ "$(whoami)" = "node" ]; then
+  echo "$VUFIND_DEFAULTS" > "./data/docker/autoconfig/$VUFIND_SITE.json"
   [ -d "$HOME" ] || PREFIX=$HOME npm install -g @ubleipzig/autoconfig@2.3.2
-  exec "$HOME/bin/autoconfig" "$@"
+  exec "$HOME/bin/autoconfig" -c ./data/docker/autoconfig "$@"
   exit
 fi
 
diff --git a/devops/docker/composer/entrypoint.sh b/devops/docker/composer/entrypoint.sh
index dd445c103f4ca45f63c32451309a7ddbf9bb7762..2be4334579feb7885945cc8e1628595584fd55f3 100755
--- a/devops/docker/composer/entrypoint.sh
+++ b/devops/docker/composer/entrypoint.sh
@@ -18,7 +18,7 @@
 # @license https://opensource.org/licenses/GPL-3.0 GNU GPLv3
 
 if [ "$(whoami)" = "php" ]; then
-  mkdir -p "$HOME"
+  mkdir -p "$COMPOSER_HOME"
   exec /docker-entrypoint.sh "$@"
   exit
 fi
@@ -27,5 +27,6 @@ until ! (ping -c1 env >/dev/null 2>&1) && [ -f ./data/docker/env/composer ]; do
 set -a; . ./data/docker/env/composer; set +a
 
 : "${UIDGID:=$(stat -c '%u' .):$(stat -c '%g' .)}"
-echo "php:x:$UIDGID:php::/bin/sh" >> /etc/passwd
+echo "php:x:$UIDGID:php:$(pwd):/bin/sh" >> /etc/passwd
+chown "$UIDGID" "$(command -v composer)"
 su -p -c "exec $0 $*" php
\ No newline at end of file
diff --git a/devops/docker/env/entrypoint.sh b/devops/docker/env/entrypoint.sh
index a78b9a236df0f40af50d409b8fede851b63fcf03..d623d231f24177d753340bc6d484c817144d338c 100755
--- a/devops/docker/env/entrypoint.sh
+++ b/devops/docker/env/entrypoint.sh
@@ -20,18 +20,21 @@
 # Taken from http://www.etalabs.net/sh_tricks.html
 quote () { printf %s\\n "$1" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/'/" ; }
 
-: "${UIDGID:=$(stat -c '%u' .):$(stat -c '%g' .)}"
+if ! [ "$(whoami)" = "dev" ]; then
+  : "${UIDGID:=$(stat -c '%u' .):$(stat -c '%g' .)}"
+  echo "dev:x:$UIDGID:dev:$(pwd):/bin/sh" >> /etc/passwd
+  su -p -c "exec $0 $*" dev
+  exit
+fi
 
-DIR=data/docker/env; [ -d "$DIR" ] && rm -rf $DIR
-mkdir -p "$DIR"; chown "$UIDGID" $DIR/.. $DIR
+mkdir -p "${DIR=data/docker/env}"
 
 # shellcheck disable=SC2046
 JSON=$(spruce merge $(find docker-env.*.yml) | spruce json)
 for KEY in $(echo "$JSON" | jq -r 'keys | join(" ")'); do
-  FILE="$DIR/$KEY"; [ -f "$FILE" ] && rm "$FILE"
+  FILE="$DIR/$KEY"; [ -f "$FILE" ] && rm "$FILE"; touch "$FILE"
   for VAR in $(echo "$JSON" | jq -r ".\"$KEY\" | keys | join(\" \")"); do
     VAL=$(echo "$JSON" | jq -r ".\"$KEY\".\"$VAR\"")
     echo "$VAR=$(quote "$VAL")" >> "$FILE"
   done
-  chown "$UIDGID" $FILE
 done
\ No newline at end of file
diff --git a/devops/docker/grunt/entrypoint.sh b/devops/docker/grunt/entrypoint.sh
index 06189b8b841d115fc1926a84b992f248d2c82538..b2ca391b650a42c36fbf0e3417bd28e143843a99 100755
--- a/devops/docker/grunt/entrypoint.sh
+++ b/devops/docker/grunt/entrypoint.sh
@@ -42,4 +42,4 @@ trap term_grunt TERM
 : "${UIDGID:=$(stat -c '%u' .):$(stat -c '%g' .)}"
 sed -i "s/$(id -u node):$(id -g node)/$UIDGID/" /etc/passwd
 su -p -c "exec $0 $*" node &
-while true; do :; done
\ No newline at end of file
+while true; do sleep 1; done
\ No newline at end of file
diff --git a/devops/docker/mail/entrypoint.sh b/devops/docker/mail/entrypoint.sh
index c2fb39bfc2e70857a3eb641e224e476294a8878e..b067d64c077f27b8f1fd193d3c20b97ecc904819 100755
--- a/devops/docker/mail/entrypoint.sh
+++ b/devops/docker/mail/entrypoint.sh
@@ -22,4 +22,4 @@ set -a; . ./data/docker/env/mail; set +a
 
 trap 'supervisorctl stop dovecot && supervisorctl stop postfix && exit 0' TERM
 /docker/init "$@" &
-while true; do :; done
\ No newline at end of file
+while true; do sleep 1; done
\ No newline at end of file
diff --git a/devops/docker/php/Dockerfile b/devops/docker/php/Dockerfile
index cb900d0d3693de568ca0be85e90fe8b614d937b1..754f1aef14c89091b4c907e3c2e6883a0fbc434f 100644
--- a/devops/docker/php/Dockerfile
+++ b/devops/docker/php/Dockerfile
@@ -17,12 +17,14 @@
 # @license https://opensource.org/licenses/GPL-3.0 GNU GPLv3
 
 FROM php:7.2.11-fpm-alpine3.8
-RUN apk add --no-cache $PHPIZE_DEPS freetype-dev libxml2-dev icu-dev \
+RUN apk add --no-cache $PHPIZE_DEPS freetype-dev libxml2-dev icu-dev libxslt-dev \
     && pecl install xdebug \
     && docker-php-ext-enable xdebug \
     && docker-php-ext-install mysqli \
     && docker-php-ext-install pdo_mysql \
     && docker-php-ext-install gd \
     && docker-php-ext-install soap \
-    && docker-php-ext-install intl
+    && docker-php-ext-install intl \
+    && docker-php-ext-install dom \
+    && docker-php-ext-install xsl
 COPY php.ini /usr/local/etc/php/conf.d/php.ini
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
index 7096c7eed6425832d005df8b281ff08f271ec5fd..1e244e2e990973150e01e4285d8a08590ca324d8 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -32,16 +32,13 @@ services:
     command: ["php-fpm"]
 
   httpd:
-    image: ubleipzig/vufind-httpd:2.4-2
+    image: ubleipzig/vufind-httpd:2.4-5
     ports:
       - 127.0.0.1:${HTTPD_PORT:-11100}:80
     volumes:
       - ./:/usr/local/vufind:ro
-      - ./data/cache:/var/cache/vufind:ro
     depends_on:
-      - env
       - php
-    command: ["httpd", "-D", "FOREGROUND", "-c", "ProxyTimeout 3600"]
 
   db:
     image: mariadb:10.3.17
diff --git a/docker-env.0.finc.yml b/docker-env.0.finc.yml
index b6df023b7b73792ee6ed830d6caa8d063d5a80fb..d3766a42100edd5c832883b6ff46721d96ba548e 100644
--- a/docker-env.0.finc.yml
+++ b/docker-env.0.finc.yml
@@ -1,3 +1,4 @@
+
 # Copyright (C) 2020  Leipzig University Library
 #
 # This program is free software: you can redistribute it and/or modify
@@ -38,11 +39,21 @@ autoconfig:
   VUFIND_INSTANCE: dev
   VUFIND_DB_CLIENT: '%'
   VUFIND_DB_ADMIN_PASSWORD: root
-  VF_config_ini__Authentication__hash_passwords: true
-  VF_config_ini__Authentication__encrypt_ils_password: true
-  VF_config_ini__Database__database: mysql://vufind:vufind@db/vufind
-  VF_config_ini__Index__url: https://index.ub.uni-leipzig.de/kxp
-  VF_config_ini__Mail__host: mail
-  VF_config_ini__Mail__port: 25
-  VF_config_ini__Mail__username: dev
-  VF_config_ini__Mail__pasword: dev
+  VUFIND_DEFAULTS:
+    config.ini:
+      Authentication:
+        hash_passwords: true
+        encrypt_ils_password: true
+      Database:
+        database: mysql://vufind:vufind@db/vufind
+      Index:
+        url: https://index.ub.uni-leipzig.de/solr
+      Mail:
+        host: mail
+        port: 25
+        username: dev
+        password: dev
+    searches.ini:
+      IndexShards: {}
+
+mail: {}
\ No newline at end of file