624ca8a587056646617725d8f8611a23f68bfee9
Umlaut Press
Static site plus legacy PHP archive (preservation), served by Nginx and PHP 7.4-FPM in a single Docker container.
Architecture (refresher)
- One container: Nginx (port 80) + PHP 7.4-FPM (localhost:9000). The image is built from the root
Dockerfileand used for production. - Web root: Everything under
src/is copied into the image at/usr/share/nginx/html/. Nginx serves static files and proxies*.phpto PHP-FPM. - Static: HTML, CSS, JS, images, fonts — served by Nginx with cache rules (short cache for HTML, long for assets).
- PHP: Used for the legacy archive under
src/site_archive/(sites unchanged since ~2010). PHP runs in a compatibility-oriented mode (see below); apps that need a database (e.g. old WordPress/phpBB in the archive) will not work fully, but simple PHP pages do. - Production base:
php:7.4-fpm-alpine(Alpine, minimal). Dev container:php:7.4-fpm(Debian) so Cursor/VS Code have bash; see .devcontainer/README.md.
Request flow
- Request hits Nginx (port 80).
- Static file (e.g.
.html,.css,.js, images) → Nginx serves from/usr/share/nginx/html/with the appropriate cache headers. *.php→ Nginx passes to PHP-FPM on 127.0.0.1:9000; PHP runs the script and returns the response.
Startup (inside container)
entrypoint.sh runs when the container starts:
- Start PHP-FPM in the background (
php-fpm -D). - Start Nginx in the foreground (
nginx -g 'daemon off;') so the container stays up.
Directory layout
| Path | Purpose |
|---|---|
src/ |
Web root: static site + site_archive/ (legacy PHP). Deploy = copy this into the image. |
nginx/conf.d/ |
Nginx server config: default.conf (vhost, cache rules, PHP location). |
php/conf.d/ |
PHP overrides: 99-legacy.ini (error_reporting, short_open_tag, limits for old code). |
entrypoint.sh |
Starts PHP-FPM then Nginx. |
Dockerfile |
Production image: Alpine + Nginx + PHP 7.4-FPM, configs and src/ copied in. |
.devcontainer/ |
Dev container (Debian-based) for local testing; mounts src/ for live edits. |
.woodpecker/ |
CI (lint, etc.) and build/deploy (Docker build, push, Portainer). |
Run locally
Option A: Docker (no dev container)
docker build -t umlaut-press .
docker run -p 8080:80 umlaut-press
Then open http://localhost:8080 (and e.g. http://localhost:8080/site_archive/2004/ for the archive).
Option B: Dev container (recommended for editing)
- Open repo in Cursor/VS Code.
- Command Palette → “Dev Containers: Reopen in Container”.
- When the container is up, open http://localhost (port 80 is forwarded). Edits under
src/are reflected on refresh.
Details and troubleshooting (e.g. “bash not found” / old container reuse): .devcontainer/README.md.
Build and deploy
- Scripts (see
package.json):docker:build,docker:push(image tag:git.mifi.dev/mifi/umlaut-press:latest). - CI:
.woodpecker/ci.yml(e.g. format/lint). Build/deploy:.woodpecker/build.ymland.woodpecker/deploy.yml— on push/tag tomain, build the image, push to the registry, and trigger the Portainer stack redeploy.
PHP legacy / compatibility
- Version: PHP 7.4 (EOL) chosen so pre-2010 archive code runs without changes.
- Config:
php/conf.d/99-legacy.ini— suppresses deprecation/strict notices, enablesshort_open_tag, raises limits. Keeps the archive viewable; not for running DB-backed apps (WordPress, phpBB, etc.) unless you add a DB and config.
Quick reference
| I want to… | Do this |
|---|---|
| Test the site locally | Use the dev container (Reopen in Container) and open http://localhost. |
| Change Nginx (cache, vhost) | Edit nginx/conf.d/default.conf, rebuild image. |
| Change PHP behavior | Edit php/conf.d/99-legacy.ini, rebuild image. |
| Add or change static/PHP content | Edit or add files under src/. In dev container, just refresh the browser. |
| Build the production image | pnpm run docker:build or docker build -t umlaut-press . |
| Deploy | Push to main (Woodpecker builds and deploys) or run docker:push and update the stack yourself. |
Description
The original web venture, here for posterity since 2004, Ümlaut Press, LLC.
https://www.umlaut-press.com
Languages
PHP
84.5%
HTML
6%
JavaScript
5.9%
CSS
1.4%
Smarty
0.5%
Other
1.6%