# Arch Linux + Apache + PHP image for running novaconium in production. # See /admin/docs/docker for the bind-mounted paths, docker-entrypoint.sh's # seeding/permissions behavior, and optional MySQL wiring. FROM archlinux:base # Arch's repos are rolling-release with no version-pinned packages, so # `pacman -S apache=X.Y` isn't reliably available — point pacman at a dated # Arch Linux Archive (https://archive.archlinux.org) snapshot instead of the # live mirror so a rebuild months from now installs the same Apache/PHP/ # SQLite versions instead of whatever happens to be current that day. Bump # ARCH_SNAPSHOT deliberately (e.g. to pick up a PHP security release), not # as a side effect of an unrelated rebuild. ARG ARCH_SNAPSHOT=2026/07/01 RUN echo "Server=https://archive.archlinux.org/repos/${ARCH_SNAPSHOT}/\$repo/os/\$arch" \ > /etc/pacman.d/mirrorlist RUN pacman -Syyu --noconfirm --needed apache php php-apache sqlite \ && pacman -Scc --noconfirm # php-apache on Arch is built against mpm_prefork, not httpd's default # mpm_event — swap MPMs, enable mod_rewrite, point DocumentRoot at # public/, and wire in mod_php. RUN sed -i \ -e 's/^LoadModule mpm_event_module/#LoadModule mpm_event_module/' \ -e 's/^#LoadModule mpm_prefork_module/LoadModule mpm_prefork_module/' \ -e '/^#LoadModule rewrite_module/s/^#//' \ -e 's#DocumentRoot "/srv/http"#DocumentRoot "/var/www/html/public"#' \ -e 's###' \ -e 's/^\( *\)AllowOverride None$/\1AllowOverride All/' \ /etc/httpd/conf/httpd.conf \ && printf '\nLoadModule php_module modules/libphp.so\nAddHandler php-script .php\nDirectoryIndex index.php index.html\nServerName localhost\n' \ >> /etc/httpd/conf/httpd.conf \ && sed -i \ -e 's/^;extension=pdo_sqlite/extension=pdo_sqlite/' \ -e 's/^;extension=pdo_mysql/extension=pdo_mysql/' \ /etc/php/php.ini WORKDIR /var/www/html COPY novaconium/ ./novaconium/ COPY public/ ./public/ COPY App/ ./App/ # Pristine copy of the starter App/, kept outside /var/www/html so # docker-entrypoint.sh can reseed a bind-mounted (but empty/missing) App/ on # first start — see docker-entrypoint.sh and /admin/docs/docker. RUN cp -a App/ /opt/novaconium-app-default/ # Runtime-writable paths — cache/uploads/App/data are bind-mounted from the # host by docker-compose.yml, so docker-entrypoint.sh re-chowns them at # every container start (a build-time chown only survives on the image # layer, not on a host bind mount). This chown still covers a fresh # container with no bind mounts configured at all. RUN mkdir -p public/cache public/uploads data \ && touch novaconium/contact-log.txt \ && chown -R http:http public/cache public/uploads data App novaconium/contact-log.txt COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh RUN chmod +x /usr/local/bin/docker-entrypoint.sh EXPOSE 80 ENTRYPOINT ["docker-entrypoint.sh"] CMD ["httpd", "-D", "FOREGROUND"]