Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions .gitbook.yaml

This file was deleted.

1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@
*.log
*.pyc
.doit.db
/graph
85 changes: 85 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Agent instructions

## Repository map

| Path | Content |
| --- | --- |
| `template/` | Shared Jinja2 templates for the Dockerfiles (source) |
| `docker/<image>/<tag>/Dockerfile.jinja2` | Per-image template (source) |
| `provisioning/` | Scripts and configuration files copied into the images (source); `conf/provision.yml` says which go where |
| `docker/<image>/<tag>/Dockerfile`, `docker/<image>/<tag>/conf/` | Generated by `make provision`, never edited by hand |
| `bin/` | Old Python 2 tools behind `make provision` and the other Makefile targets |
| `ci/` | PHP generator for `.github/workflows/build.yaml` (`ci/console github:generate-ci`) |
| `tests/` | serverspec (Ruby) and container-structure-test definitions run by the CI |
| `docs/` | User documentation |

Not everything under `docker/` is built: `docker/php/7.0` to `docker/php/8.0` (and their `-alpine` variants) are dangling symlinks, and `docker/ssh` is not part of the CI workflow. The tags that are built are the `-t "webdevops/..."` lines in `.github/workflows/build.yaml`.

## Build and test

Only these commands are known to work:

- `docker run --rm -v $PWD:/app -w /app webdevops/dockerfile-build-env make provision` regenerates `docker/`. Run it after every change to `template/`, `provisioning/` or a `Dockerfile.jinja2`, and commit the result.
- `docker build -t webdevops/<image>:<tag> docker/<image>/<tag>` builds one image; its parent and `webdevops/toolbox` come from local images or Docker Hub.
- `./build-local.sh [version]` builds all PHP images of one version.

The other Makefile targets need Python 2. Apart from `provision` and `graph` inside `webdevops/dockerfile-build-env`, they do not work; `make test` fails there too (see `docs/known-issues.md`). The CI runs serverspec and container-structure-test for every image; to check a change by hand, start the image and try it as described below.

## Keep the documentation up to date

The documentation is part of every change. A pull request that changes what users of the images see also updates the documentation **in the same pull request**. Never leave it for a follow-up.

Where the documentation lives:

| File | Content |
| --- | --- |
| `README.md` | Entry point: short intro, quick start, build process, supported tags ("Debian PHP" / "Alpine PHP") |
| `docs/README.md` | Image overview, platforms and nightly updates, how the images build on each other (Mermaid diagram) |
| `docs/environment-variables.md` | Every environment variable with its default and effect; uploads and long requests |
| `docs/customization.md` | Commands, scripts at start and build time, tools for your Dockerfile, services, cron jobs and their time zone, healthcheck, configuration files and placeholders, supervisord, locales, application user and changing its UID |
| `docs/images/*.md` | One page per image family: tags, base image, services, settings, development variant. `php.md` also has Debian or Alpine, production, installing extensions, mail and Xdebug with an IDE |
| `docs/known-issues.md` | Options and tools that do not work, with affected images and workaround; migration from older images; build tools that no longer work |

### When to update it

Update the documentation whenever a change touches any of these:

- an environment variable or `php.*` / `fpm.*` setting (added, removed, renamed, new default, new effect)
- a published image or tag, for example a new or dropped PHP version
- a base image or operating system version
- a PHP extension that is added or removed
- a service, hook directory, entrypoint command or helper tool such as `docker-service`
- the build process, the CI workflow or the commands in the README

### How to update it

1. **Find the source of truth.** Check the code, not older documentation:

| Question | Where to look |
| --- | --- |
| Published images and tags | `-t "webdevops/..."` tags in `.github/workflows/build.yaml` (generated by `ci/console github:generate-ci` from `conf/console.yml` and `ci/`) |
| Base image | `FROM` line in `docker/<image>/<tag>/Dockerfile` |
| Variables and defaults | `ENV` in `template/Dockerfile/**` and `docker/**/Dockerfile.jinja2`, scripts in `provisioning/**/bin` and `provisioning/**/provision` |
| Which files end up in which image | `conf/provision.yml` |

2. **Change sources, not generated files.** `Dockerfile` and `conf/` under `docker/` are generated. Edit `Dockerfile.jinja2`, `template/` or `provisioning/` and run `make provision`.

3. **Verify every statement in a running container.** Build the image (or use the image the CI built) and try the option. Do not rely on reading the scripts alone. Examples:
- PHP settings: `php -r 'echo ini_get("memory_limit");'`, or `php-fpm -i` for values the CLI overrides
- PHP-FPM settings: `php-fpm -tt`
- Web server settings: an HTTP request against the container, or the rendered configuration under `/opt/docker/etc/nginx` or `/opt/docker/etc/httpd`
- Service options: the command line of the running process
- Hooks: a script that writes a marker file, then check the marker

Check every image a statement names, not just one representative: images differ in what they inherit (for example `cli` only works where `APPLICATION_USER` is set). Check both the Debian and the Alpine variant whenever their implementation differs (separate files under `provisioning/*/alpine`, apk vs. apt, `httpd` vs. `apache2`, `crond` vs. `cron`). Test examples with the exact command you document, and make sure a check cannot pass on an error message.

4. **Document only what works.** Never describe an option that has no effect as working. Fix it, or leave it out and list it in `docs/known-issues.md`. If it works only in some images, say exactly which. Anything `docs/known-issues.md` lists as not working must never appear as working anywhere else. An `ENV` line in a Dockerfile is no proof that a variable works: `FTP_PATH` is declared, but no script reads it. When you fix a known issue, remove its entry in the same pull request.

5. **Keep lists in sync.** The tag lists in `README.md` and in `docs/images/*.md` must match the tags pushed by `.github/workflows/build.yaml`. `webdevops/php-official` is not listed in the README; it is built from the same Dockerfiles as `webdevops/php`. The defaults in `docs/environment-variables.md` must match what a container reports.

6. **Follow the style.**
- English, GitHub Markdown, relative links, diagrams as Mermaid. No documentation tooling.
- Usage examples use `docker compose`, not `docker run`.
- Change the README only where needed; keep its structure and wording.

7. **Say how you verified it.** In the pull request description, list each documented change and the check that confirmed it.
10 changes: 1 addition & 9 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
ARGS = $(filter-out $@,$(MAKECMDGOALS))
MAKEFLAGS += --silent
.PHONY: test documentation provision
.PHONY: test provision

DOCKER_REPOSITORY=`cat DOCKER_REPOSITORY`
DOCKER_TAG_LATEST=`cat DOCKER_TAG_LATEST`
Expand Down Expand Up @@ -58,11 +58,3 @@ graph:
graph-full:
python2 ./bin/console generate:graph --all\
--filename docker-image-full-layout.gv

documentation:
docker run -t -i --rm -p 8000 \
-v "$$(pwd)/documentation/docs/:/opt/docs" \
-e "VIRTUAL_HOST=documentation.docker" \
-e "VIRTUAL_PORT=8000" \
webdevops/sphinx sphinx-autobuild \
--poll -H 0.0.0.0 /opt/docs html
67 changes: 51 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,31 @@ We add additional stuff like:
* run multiple services (like php-fpm and nginx) with supervisord

[![GitHub issues](https://img.shields.io/github/issues/webdevops/Dockerfile.svg)](https://github.com/webdevops/Dockerfile/issues)[![GitHub forks](https://img.shields.io/github/forks/webdevops/Dockerfile.svg)](https://github.com/webdevops/Dockerfile/network)[![GitHub stars](https://img.shields.io/github/stars/webdevops/Dockerfile.svg)](https://github.com/webdevops/Dockerfile/stargazers)[![GitHub license](https://img.shields.io/github/license/webdevops/Dockerfile.svg)](https://github.com/webdevops/Dockerfile/blob/master/LICENSE)
[![pipeline status](https://gitlab.com/webdevops/dockerfile/badges/master/pipeline.svg)](https://gitlab.com/webdevops/dockerfile/commits/master)


[![build](https://github.com/webdevops/Dockerfile/actions/workflows/build.yaml/badge.svg)](https://github.com/webdevops/Dockerfile/actions/workflows/build.yaml)

## Quick start

Save this as `compose.yaml` in your project (with the entry point in `public/index.php`) and run `docker compose up -d`:

```yaml
services:
app:
image: webdevops/php-nginx:8.5
ports:
- "8080:80"
volumes:
- ./:/app
environment:
WEB_DOCUMENT_ROOT: /app/public
```

Automated build and test running on [Gitlab CI](https://gitlab.com/webdevops/dockerfile/) \(GitLab.com CI custom Google Cloud runner\) sponsored by [Onedrop GmbH & Co. KG](https://1drop.de).
The application is then available at http://localhost:8080. All images, settings and hooks are described in the [documentation](docs/README.md).

[![Docker layout](documentation/gitbook/.gitbook/assets/docker-image-layout.gv.png)](https://github.com/webdevops/Dockerfile/tree/511a870fa90fe53da5c63a95b4254f6980e6d3d2/documentation/docs/resources/images/docker-image-layout.gv.png)
The images run on `linux/amd64` and `linux/arm64` and are rebuilt every night, so a tag such as `8.5` gets new images daily. To pin an image, see [Platforms and updates](docs/README.md#platforms-and-updates).

## Communication and support

Or write an issue in our [GitHub repository](https://github.com/webdevops/Dockerfile/issues).
Found a bug or have a question? Write an issue in our [GitHub repository](https://github.com/webdevops/Dockerfile/issues). Problems we already know about are listed in [Known issues](docs/known-issues.md).

Or join our discord https://discord.gg/BpBZtXAgJz

Expand All @@ -37,21 +51,41 @@ docker run --rm -ti -v $PWD:/app -w /app webdevops/dockerfile-build-env make pro
It will use the Jinja2 templates inside of the `template` directory and the
config files from the `provisioning` directory.

**The files in the `docker` directory are never modified manually**
**The generated files in the `docker` directory (`Dockerfile` and `conf/`) are never modified manually.**
Edit the `Dockerfile.jinja2` templates next to them, the shared templates in `template` or the files in `provisioning` instead.
`make provision` copies the `provisioning` files into the `conf/` directories as configured in `conf/provision.yml`.

*This will be replaced with PHP twig templates in the future to streamline everything.*

### Building in CI

We generate a multi stage Gitlab-CI configuration using PHP:
We generate the GitHub Actions workflow (`.github/workflows/build.yaml`) using PHP:

```
docker run --rm -ti -v $PWD:/app -w /app/ci webdevops/php:8.4-alpine composer install
docker run --rm -ti -v $PWD:/app -w /app webdevops/php:8.4-alpine ci/console github:generate
docker run --rm -ti -v $PWD:/app -w /app webdevops/php:8.4-alpine ci/console github:generate-ci
```

GitHub Actions builds every image independently and runs the serverspec and structure tests
defined for it before pushing it to Docker Hub. The CI also uses `ghcr.io/webdevops/`, but only
internally; pull the images from Docker Hub.

### Building and testing locally

Build a single image from its directory. Its parent image (the `FROM` line) and `webdevops/toolbox` are taken from your local images or pulled from Docker Hub:

```
docker build -t webdevops/php-nginx:8.5 docker/php-nginx/8.5
```

Gitlab CI builds every image independent and runs serverspec and structure tests on every
image before pushing them to the registry.
Build all PHP images of one version (default `8.5`), in the order they depend on each other:

```
./build-local.sh 8.4
```

Then try an image with the quick start above. `make test` and the other Makefile targets that call `bin/console` need Python 2;
only `make provision` and `make graph` still work, inside `webdevops/dockerfile-build-env`. See [Known issues](docs/known-issues.md#build-tools).

### PHP extension builds

Expand All @@ -75,14 +109,15 @@ tests retain their existing image matrix.

## Documentation

As in many projects the documentation is kind of up to date 😅.

* [Old version of the documentation is available on readthedocs](https://dockerfile.readthedocs.io/)
* [New version is currently being written on gitbook](https://webdevops.gitbook.io/dockerfile)
* [Overview of all images](docs/README.md)
* [Environment variables](docs/environment-variables.md)
* [Customization: commands, hooks, services](docs/customization.md)
* PHP images: [Debian or Alpine](docs/images/php.md#debian-or-alpine), [production](docs/images/php.md#production), [Xdebug with an IDE](docs/images/php.md#xdebug-with-an-ide), [mail](docs/images/php.md#mail)
* [Known issues](docs/known-issues.md)

### Debian PHP

The following images which are currently supported are based on `php:{VER}-fpm-buster`.
The following images which are currently supported are based on `php:{VER}-fpm-bookworm`.

* `webdevops/php:8.2`
* `webdevops/php:8.3`
Expand Down
2 changes: 1 addition & 1 deletion conf/console.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
dockerPath: 'docker'
templatePath: 'template'
provisionPath: 'provisioning'
imagePath: 'documentation/docs/resources/images/'
imagePath: 'graph/'
baselayoutPath: 'baselayout'
testinfraPath: 'tests/testinfra'
serverspecPath: 'tests/serverspec'
Expand Down
50 changes: 0 additions & 50 deletions docker/apache/README.md

This file was deleted.

Loading
Loading