changed to php base

This commit is contained in:
2026-07-20 20:30:03 -07:00
parent 76fd1ca3ed
commit 0831331fe3
4 changed files with 33 additions and 42 deletions
+24 -33
View File
@@ -1,42 +1,33 @@
# Arch Linux + Apache + PHP image for running novaconium in production. # Official PHP + Apache image for running novaconium in production.
# See /admin/docs/docker for the bind-mounted paths, docker-entrypoint.sh's # See /admin/docs/docker for the bind-mounted paths, docker-entrypoint.sh's
# seeding/permissions behavior, and optional MySQL wiring. # seeding/permissions behavior, and optional MySQL wiring.
FROM archlinux:base
# Arch's repos are rolling-release with no version-pinned packages, so # Build: docker build --no-cache -t novaconium:latest .
# `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 php-sqlite \ # Fixed: full official image tag (was missing "php:")
&& pacman -Scc --noconfirm FROM php:8.5.8-apache-trixie
# php-apache on Arch is built against mpm_prefork, not httpd's default # Pin to a specific tag (not a floating "php:apache") so a rebuild months
# mpm_event — swap MPMs, enable mod_rewrite, point DocumentRoot at # from now installs the same PHP/Apache/Debian base instead of whatever
# public/, and wire in mod_php. # happens to be current that day. Bump the tag above deliberately (e.g. to
RUN sed -i \ # pick up a PHP security release), not as a side effect of an unrelated
-e 's/^LoadModule mpm_event_module/#LoadModule mpm_event_module/' \ # rebuild.
-e 's/^#LoadModule mpm_prefork_module/LoadModule mpm_prefork_module/' \
-e '/^#LoadModule rewrite_module/s/^#//' \ RUN apt-get update \
-e 's#DocumentRoot "/srv/http"#DocumentRoot "/var/www/html/public"#' \ && apt-get install -y --no-install-recommends libsqlite3-dev \
-e 's#<Directory "/srv/http">#<Directory "/var/www/html/public">#' \ && rm -rf /var/lib/apt/lists/* \
-e 's/^\( *\)AllowOverride None$/\1AllowOverride All/' \ && docker-php-ext-install pdo_sqlite pdo_mysql \
/etc/httpd/conf/httpd.conf \ && a2enmod rewrite
&& printf '\nLoadModule php_module modules/libphp.so\nAddHandler php-script .php\nDirectoryIndex index.php index.html\nServerName localhost\n' \
>> /etc/httpd/conf/httpd.conf \ # Point DocumentRoot at public/ and allow .htaccess overrides there.
&& sed -i \ RUN sed -ri -e 's#/var/www/html#/var/www/html/public#g' \
-e 's/^;extension=pdo_sqlite/extension=pdo_sqlite/' \ /etc/apache2/sites-available/*.conf \
-e 's/^;extension=pdo_mysql/extension=pdo_mysql/' \ && sed -ri -e '/<Directory \/var\/www\/>/,/<\/Directory>/ s/AllowOverride None/AllowOverride All/' \
/etc/php/php.ini /etc/apache2/apache2.conf
WORKDIR /var/www/html WORKDIR /var/www/html
# Copy application files
COPY novaconium/ ./novaconium/ COPY novaconium/ ./novaconium/
COPY public/ ./public/ COPY public/ ./public/
COPY App/ ./App/ COPY App/ ./App/
@@ -53,7 +44,7 @@ RUN cp -a App/ /opt/novaconium-app-default/
# container with no bind mounts configured at all. # container with no bind mounts configured at all.
RUN mkdir -p public/cache public/uploads data \ RUN mkdir -p public/cache public/uploads data \
&& touch novaconium/contact-log.txt \ && touch novaconium/contact-log.txt \
&& chown -R http:http public/cache public/uploads data App novaconium/contact-log.txt && chown -R www-data:www-data public/cache public/uploads data App novaconium/contact-log.txt
COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
RUN chmod +x /usr/local/bin/docker-entrypoint.sh RUN chmod +x /usr/local/bin/docker-entrypoint.sh
@@ -61,4 +52,4 @@ RUN chmod +x /usr/local/bin/docker-entrypoint.sh
EXPOSE 80 EXPOSE 80
ENTRYPOINT ["docker-entrypoint.sh"] ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["httpd", "-D", "FOREGROUND"] CMD ["apache2-foreground"]
+1 -1
View File
@@ -1,6 +1,6 @@
services: services:
web: web:
image: novaconium-beta image: novaconium:latest
ports: ports:
- "8080:80" - "8080:80"
volumes: volumes:
+1 -1
View File
@@ -24,6 +24,6 @@ if [ -z "$(ls -A /var/www/html/App 2>/dev/null)" ]; then
cp -a /opt/novaconium-app-default/. /var/www/html/App/ cp -a /opt/novaconium-app-default/. /var/www/html/App/
fi fi
chown -R http:http /var/www/html/public/cache /var/www/html/public/uploads /var/www/html/App /var/www/html/data chown -R www-data:www-data /var/www/html/public/cache /var/www/html/public/uploads /var/www/html/App /var/www/html/data
exec "$@" exec "$@"
@@ -9,7 +9,7 @@
{% block docs_content %} {% block docs_content %}
<h1>Docker</h1> <h1>Docker</h1>
<p>The root <code>Dockerfile</code> builds an Apache + PHP image on an <a href="https://archlinux.org/">Arch Linux</a> base, with <code>mod_rewrite</code>, <code>AllowOverride All</code>, and <code>pdo_sqlite</code>/<code>pdo_mysql</code> already enabled — nothing else in <a href="/admin/docs/getting-started">Getting started</a>'s "Deploy on Apache" section needs configuring by hand.</p> <p>The root <code>Dockerfile</code> builds on the official <a href="https://hub.docker.com/_/php"><code>php:8.3-apache</code></a> image, with <code>mod_rewrite</code>, <code>AllowOverride All</code>, and <code>pdo_sqlite</code>/<code>pdo_mysql</code> already enabled — nothing else in <a href="/admin/docs/getting-started">Getting started</a>'s "Deploy on Apache" section needs configuring by hand.</p>
<pre><code>docker compose up --build</code></pre> <pre><code>docker compose up --build</code></pre>
@@ -30,24 +30,24 @@
<ul> <ul>
<li><strong>Empty <code>App/</code> on first run.</strong> The Dockerfile stashes a pristine copy of the baked-in <code>App/</code> at <code>/opt/novaconium-app-default</code> at build time. If the bind-mounted <code>/var/www/html/App</code> is empty when the container starts, the entrypoint copies that pristine copy in — so a first <code>docker compose up</code> against a fresh, empty <code>${VOL_PATH}/novaconium/App</code> on the host produces a working site instead of a blank one. It only seeds when the directory is empty, so it never clobbers content you've already put there.</li> <li><strong>Empty <code>App/</code> on first run.</strong> The Dockerfile stashes a pristine copy of the baked-in <code>App/</code> at <code>/opt/novaconium-app-default</code> at build time. If the bind-mounted <code>/var/www/html/App</code> is empty when the container starts, the entrypoint copies that pristine copy in — so a first <code>docker compose up</code> against a fresh, empty <code>${VOL_PATH}/novaconium/App</code> on the host produces a working site instead of a blank one. It only seeds when the directory is empty, so it never clobbers content you've already put there.</li>
<li><strong>Permissions.</strong> A bind mount keeps the host directory's ownership, not the image's — the build-time <code>chown -R http:http</code> in the Dockerfile only applies to the image layer, not to whatever gets mounted over it. The entrypoint re-runs <code>chown -R http:http</code> on all four mounted paths on every container start, so Apache's worker user (<code>http</code> on Arch) can always write to them regardless of the host-side UID/GID — no manual <code>chmod</code> on the host required.</li> <li><strong>Permissions.</strong> A bind mount keeps the host directory's ownership, not the image's — the build-time <code>chown -R www-data:www-data</code> in the Dockerfile only applies to the image layer, not to whatever gets mounted over it. The entrypoint re-runs <code>chown -R www-data:www-data</code> on all four mounted paths on every container start, so Apache's worker user (<code>www-data</code>, the Debian default) can always write to them regardless of the host-side UID/GID — no manual <code>chmod</code> on the host required.</li>
</ul> </ul>
<h2>MySQL</h2> <h2>MySQL</h2>
<p><code>Lib\Db</code> supports MySQL alongside or instead of SQLite (see <a href="/admin/docs/database">Database</a>). <code>docker-compose.yml</code> has a commented-out <code>db</code> service and <code>mysql-data</code> volume — uncomment both, add a <code>db_connections</code> entry with <code>driver: mysql</code> and matching credentials in <code>App/config.php</code>, and the app container can reach it at hostname <code>db</code>.</p> <p><code>Lib\Db</code> supports MySQL alongside or instead of SQLite (see <a href="/admin/docs/database">Database</a>). <code>docker-compose.yml</code> has a commented-out <code>db</code> service and <code>mysql-data</code> volume — uncomment both, add a <code>db_connections</code> entry with <code>driver: mysql</code> and matching credentials in <code>App/config.php</code>, and the app container can reach it at hostname <code>db</code>.</p>
<h2>Pinned package versions</h2> <h2>Pinned base image</h2>
<p>Arch's repos are rolling-release, so the Dockerfile doesn't install <code>apache</code>/<code>php</code>/<code>sqlite</code> from the live mirror — it points <code>pacman</code> at a dated <a href="https://archive.archlinux.org/">Arch Linux Archive</a> snapshot via the <code>ARCH_SNAPSHOT</code> build arg (a <code>YYYY/MM/DD</code> path), so a rebuild next month installs the exact same versions as today instead of whatever's newest that day. To move to a newer snapshot deliberately (e.g. to pick up a PHP security release):</p> <p>The Dockerfile pins an exact tag (<code>php:8.3-apache</code>), not a floating <code>php:apache</code>, so a rebuild months from now installs the same PHP/Apache/Debian base instead of whatever the tag happens to point at that day. Bump the tag in the <code>FROM</code> line deliberately (e.g. to pick up a PHP security release), then rebuild:</p>
<pre><code>docker build --build-arg ARCH_SNAPSHOT=2026/08/01 --no-cache -t novaconium-beta .</code></pre> <pre><code>docker build --no-cache -t novaconium-beta .</code></pre>
<p><code>--no-cache</code> is worth using any time you change the Dockerfile itself (not just <code>App/</code> content) — Docker otherwise reuses a cached layer for an unchanged-looking <code>RUN</code> step, and <code>docker-compose.yml</code> here uses <code>image:</code> rather than <code>build:</code>, so <code>docker compose up</code> alone never rebuilds at all; you have to <code>docker build</code> (and re-tag, if needed) yourself first.</p> <p><code>--no-cache</code> is worth using any time you change the Dockerfile itself (not just <code>App/</code> content) — Docker otherwise reuses a cached layer for an unchanged-looking <code>RUN</code> step, and <code>docker-compose.yml</code> here uses <code>image:</code> rather than <code>build:</code>, so <code>docker compose up</code> alone never rebuilds at all; you have to <code>docker build</code> (and re-tag, if needed) yourself first.</p>
<h2>Arch-specific notes</h2> <h2>What the image adds on top of <code>php:8.3-apache</code></h2>
<p>Arch's <code>php-apache</code> package is built against <code>mpm_prefork</code>, not <code>httpd</code>'s default <code>mpm_event</code> — the Dockerfile swaps MPMs as part of the build. The Apache/PHP worker user on Arch is <code>http</code>, not Debian's <code>www-data</code>; both the build-time <code>chown</code> and <code>docker-entrypoint.sh</code>'s startup <code>chown</code> (see above) target <code>http:http</code> for this reason.</p> <p>The base image ships Apache with <code>mod_rewrite</code> disabled and <code>AllowOverride None</code>, no <code>pdo_sqlite</code>/<code>pdo_mysql</code>, and a <code>/var/www/html</code> document root. The Dockerfile runs <code>a2enmod rewrite</code>, <code>docker-php-ext-install pdo_sqlite pdo_mysql</code> (after installing <code>libsqlite3-dev</code>, needed to build <code>pdo_sqlite</code>), and rewrites both the vhost and <code>apache2.conf</code> to point the document root at <code>public/</code> and set <code>AllowOverride All</code> there.</p>
<p>This is a separate Dockerfile from the one-off Dart Sass build tool described in <a href="/admin/docs/styling">Styling</a> — that one lives at <code>Dockerfile.sass</code>, a Debian-based image whose only job is running the <code>sass</code> CLI, not serving the app.</p> <p>This is a separate Dockerfile from the one-off Dart Sass build tool described in <a href="/admin/docs/styling">Styling</a> — that one lives at <code>Dockerfile.sass</code>, a Debian-based image whose only job is running the <code>sass</code> CLI, not serving the app.</p>
{% endblock %} {% endblock %}