Skip to content

Commit 95bebbb

Browse files
committed
Merge remote-tracking branch 'origin/release/3.0.0' into feature/remove-deprecated-feed-types-300
# Conflicts: # CHANGELOG.md
2 parents 2e4e5aa + 9755e41 commit 95bebbb

15 files changed

Lines changed: 441 additions & 193 deletions

.env

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,35 @@ COMPOSE_DOMAIN=display.local.itkdev.dk
55
# itkdev-docker template identifier.
66
ITKDEV_TEMPLATE=symfony-6
77

8+
# Built-in services to start (read natively by docker compose).
9+
# traefik bundled dev traefik on :80/:443 with a self-signed cert
10+
# generated by `task dev:cert`. Default for fresh clones.
11+
# Leave empty (`COMPOSE_PROFILES=`) in .env.local on itkdev hosts running
12+
# a host-level traefik on a shared `frontend` network — see opt-in below.
13+
COMPOSE_PROFILES=traefik
14+
15+
# Bundled-traefik port mapping. Override if 80/443 are taken on the host.
16+
# HTTP_PORT=80
17+
# HTTPS_PORT=443
18+
19+
# The frontend network's engine name + the matching `traefik.docker.network`
20+
# label both read from this var. Default is `<project>_frontend` (scoped
21+
# so switching modes doesn't collide with itkdev's external `frontend`).
22+
# COMPOSE_FRONTEND_NETWORK=display_frontend
23+
24+
# Itkdev devs running a host-level traefik on a shared `frontend` network:
25+
# opt out of the bundled traefik AND opt in to the shared-frontend overlay
26+
# in .env.local (Task forwards dotenv vars to subprocesses, including
27+
# `docker compose`):
28+
#
29+
# COMPOSE_PROFILES=
30+
# COMPOSE_FILE=docker-compose.yml:docker-compose.shared-frontend.yml
31+
# COMPOSE_FRONTEND_NETWORK=frontend
32+
#
33+
# Also set `TASK_DOCKER_COMPOSE=itkdev-docker-compose` in .env.local if you
34+
# want the legacy wrapper back — the Taskfile default is plain
35+
# `docker compose`.
36+
837
# In all environments, the following files are loaded if they exist,
938
# the latter taking precedence over the former:
1039
#
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
### ### Compose
2+
###
3+
### Validates the local dev compose stack — config-lint in every operational
4+
### mode, plus a smoke-test that the default-mode bundled traefik actually
5+
### serves nginx over HTTPS with the self-signed dev cert.
6+
###
7+
### Scoped to changes that can break the dev stack: compose files,
8+
### bundled traefik config, the dev-cert script, and `.env` (whose
9+
### COMPOSE_PROFILES default decides which services run).
10+
11+
on:
12+
pull_request:
13+
paths:
14+
- "docker-compose.yml"
15+
- "docker-compose.shared-frontend.yml"
16+
- "docker-compose.postgres.yml"
17+
- "traefik/**"
18+
- "scripts/dev-cert.sh"
19+
- ".env"
20+
- ".github/workflows/docker-compose.yaml"
21+
22+
name: Docker Compose
23+
24+
jobs:
25+
lint:
26+
runs-on: ubuntu-latest
27+
name: Lint compose (all modes)
28+
steps:
29+
- name: Checkout
30+
uses: actions/checkout@v6
31+
32+
- name: Default mode (traefik profile)
33+
env:
34+
COMPOSE_PROFILES: traefik
35+
run: docker compose config --quiet
36+
37+
- name: Default + dev tooling profile
38+
env:
39+
COMPOSE_PROFILES: traefik,dev
40+
run: docker compose config --quiet
41+
42+
- name: Postgres portability overlay
43+
env:
44+
COMPOSE_PROFILES: traefik
45+
COMPOSE_FILE: docker-compose.yml:docker-compose.postgres.yml
46+
run: docker compose config --quiet
47+
48+
- name: Itkdev opt-in (shared-frontend overlay, bundled traefik off)
49+
env:
50+
COMPOSE_PROFILES: ""
51+
COMPOSE_FILE: docker-compose.yml:docker-compose.shared-frontend.yml
52+
COMPOSE_FRONTEND_NETWORK: frontend
53+
run: |
54+
docker network create frontend
55+
docker compose config --quiet
56+
57+
smoke-default:
58+
runs-on: ubuntu-latest
59+
name: Smoke test (bundled traefik)
60+
env:
61+
COMPOSE_PROFILES: traefik
62+
steps:
63+
- name: Checkout
64+
uses: actions/checkout@v6
65+
66+
- name: Generate dev cert
67+
run: bash scripts/dev-cert.sh
68+
69+
# Limited service set — mariadb + phpfpm + nginx + traefik + redis.
70+
# node + playwright are intentionally excluded; they're heavy pulls
71+
# and not needed to validate the routing path.
72+
- name: Bring up core services
73+
run: docker compose up --detach --wait mariadb redis nginx traefik
74+
75+
- name: Probe nginx health via bundled traefik (HTTPS)
76+
# `--resolve` aligns URL host, TLS SNI, and HTTP Host header — all
77+
# `display.local.itkdev.dk` (matches the router rule labelled on
78+
# nginx). Mismatched SNI vs Host makes traefik v3 return 421
79+
# (misdirected request) even when `sniStrict` is off.
80+
# `-k` skips cert verification — the dev cert is self-signed.
81+
run: |
82+
status=$(curl -kfsS -o /dev/null -w '%{http_code}' \
83+
--resolve display.local.itkdev.dk:443:127.0.0.1 \
84+
https://display.local.itkdev.dk/health)
85+
echo "HTTP status: $status"
86+
test "$status" = "200"
87+
88+
- name: Dump logs on failure
89+
if: failure()
90+
run: docker compose logs --no-color
91+
92+
- name: Tear down
93+
if: always()
94+
run: docker compose down --volumes --remove-orphans
95+
96+
smoke-itkdev:
97+
runs-on: ubuntu-latest
98+
name: Smoke test (itkdev opt-in)
99+
steps:
100+
- name: Checkout
101+
uses: actions/checkout@v6
102+
103+
- name: Pre-create external frontend network
104+
run: docker network create frontend
105+
106+
# Mirror how an itkdev dev actually opts out of the bundled traefik:
107+
# an `.env.local` that overrides the committed `.env` defaults. The
108+
# dev-cert.sh script re-sources `.env` (with `.env.local` last so it
109+
# wins), so this is the only way to make the override stick.
110+
- name: Write itkdev .env.local override
111+
run: |
112+
cat > .env.local <<'EOF'
113+
COMPOSE_PROFILES=
114+
COMPOSE_FILE=docker-compose.yml:docker-compose.shared-frontend.yml
115+
COMPOSE_FRONTEND_NETWORK=frontend
116+
EOF
117+
118+
- name: Dev cert script no-ops when bundled traefik is off
119+
run: |
120+
out=$(bash scripts/dev-cert.sh)
121+
echo "$out"
122+
echo "$out" | grep -q "skipping dev cert"
123+
test ! -f traefik/ssl/dev.crt
124+
125+
- name: Bring up core services (no bundled traefik)
126+
run: docker compose up --detach --wait mariadb redis nginx
127+
128+
- name: Dump logs on failure
129+
if: failure()
130+
run: docker compose logs --no-color
131+
132+
- name: Tear down
133+
if: always()
134+
run: docker compose down --volumes --remove-orphans

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ All notable changes to this project will be documented in this file.
1212
Run the new `app:feed:remove-deprecated-feed-sources` command to review and `--force`-remove the
1313
inert feed sources together with their feeds and slides; `app:update` prints a notice when any exist.
1414
Migrate event database feeds to `EventDatabaseApiV2FeedType`. See `UPGRADE.md`.
15+
- Decoupled the dev compose stack from `itkdev-docker`: dropped the wrapper overlays in
16+
favour of a self-contained stack with bundled traefik (opt-in via `COMPOSE_PROFILES=traefik`)
17+
and a `docker-compose.shared-frontend.yml` overlay for devs keeping a host-level traefik.
1518
- Added project-shared Claude Code configuration (hooks, skills, subagents, MCP servers, plugins) under `.claude/`
1619
for consistent AI-assisted workflows on this codebase. Requires `npm install -g intelephense` once per developer
1720
to activate the PHP language server (the `playwright` and `context7` plugins need no prerequisites).

README.md

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -170,11 +170,44 @@ The fixtures have an editor user: <editor@example.com> with the password: "apass
170170

171171
The fixtures have the image-text template, and two screen layouts: "full screen" and "two boxes".
172172

173+
### Reverse proxy & local HTTPS
174+
175+
A fresh clone bundles its own traefik (compose profile `traefik`, enabled by default via
176+
`COMPOSE_PROFILES` in `.env`) that terminates TLS on `:80`/`:443` with a self-signed dev cert.
177+
`task site-install` runs `task dev:cert` for you on first install; re-run it manually with `FORCE=1`
178+
to regenerate (e.g. after changing `COMPOSE_DOMAIN`). The cert covers `COMPOSE_DOMAIN` plus
179+
the `node-` variant and `localhost`. Browsers warn the first time — accept the cert once.
180+
181+
If 80/443 are taken on the host, override via `.env.local`:
182+
183+
```text
184+
HTTP_PORT=8080
185+
HTTPS_PORT=8443
186+
```
187+
188+
### Itkdev developers: host-level traefik opt-in
189+
190+
Itkdev hosts already run a shared traefik on an external `frontend` network. Disable the bundled
191+
traefik and switch to the shared-frontend overlay in `.env.local`:
192+
193+
```text
194+
COMPOSE_PROFILES=
195+
COMPOSE_FILE=docker-compose.yml:docker-compose.shared-frontend.yml
196+
COMPOSE_FRONTEND_NETWORK=frontend
197+
# Optional — restores the legacy wrapper:
198+
TASK_DOCKER_COMPOSE=itkdev-docker-compose
199+
```
200+
201+
Switching modes is safe: the default network is `<project>_frontend`, scoped so it never collides
202+
with itkdev's shared `frontend` (override via `COMPOSE_FRONTEND_NETWORK`).
203+
204+
See `docker-compose.shared-frontend.yml` for the pre-existing-network requirement.
205+
173206
### Frontend dev server
174207

175208
The Vite dev server runs automatically inside the `node` container — it is started by `docker compose up` (and
176209
therefore by `task compose-up` and `task site-install`) via the `command: npm run dev` entry in
177-
`docker-compose.override.yml`. There is no separate command to run.
210+
`docker-compose.yml`. There is no separate command to run.
178211

179212
HMR is served from `node-display.local.itkdev.dk` over WSS on port 443 (host configurable via `COMPOSE_DOMAIN` in
180213
`.env`; see `vite.config.js`).
@@ -416,7 +449,7 @@ To test the React apps we use playwright.
416449

417450
It is important that the versions of the playwright container and the library imported in package.json align.
418451

419-
See the `docker-compose.override.yml` playwright entry and the version imported in package.json.
452+
See the `docker-compose.yml` playwright entry and the version imported in package.json.
420453

421454
#### Testing on the built files
422455

@@ -658,7 +691,7 @@ rather than the friendly Symfony validator message. Keep them ordered as: **PHP-
658691
| Layer | Knob | Where it lives |
659692
|---|---|---|
660693
| App (Symfony validator + Admin UI) | `MEDIA_MAX_UPLOAD_SIZE_MB` (megabytes, integer) | `.env` (committed default `200`) — override in `.env.local` for development or in the deployment environment for production |
661-
| Nginx request body | `NGINX_MAX_BODY_SIZE` (nginx size string, e.g. `200m`) | `docker-compose.yml` and `docker-compose.server.yml`; image default is `200m` (set in `infrastructure/nginx/Dockerfile`) |
694+
| Nginx request body | `NGINX_MAX_BODY_SIZE` (nginx size string, e.g. `200m`) | `docker-compose.yml`; image default is `200m` (set in `infrastructure/nginx/Dockerfile`) |
662695
| PHP-FPM upload + post body | `PHP_UPLOAD_MAX_FILESIZE`, `PHP_POST_MAX_SIZE` (PHP size strings, e.g. `200M`) | Operator-managed env vars on the php-fpm container (supported by the `itkdev/php8.4-fpm` base image). Not set in this repo by default — base image defaults apply unless overridden |
663696

664697
The app reads `MEDIA_MAX_UPLOAD_SIZE_MB` per-request, so a deploy / php-fpm worker reload is enough to pick up

Taskfile.yml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@ dotenv: [".env.local", ".env"]
66
vars:
77
# https://taskfile.dev/reference/templating/
88
BASE_URL: "{{.TASK_BASE_URL | default .COMPOSE_SERVER_DOMAIN | default .COMPOSE_DOMAIN }}"
9-
DOCKER_COMPOSE: '{{ .TASK_DOCKER_COMPOSE | default "itkdev-docker-compose" }}'
9+
# Plain `docker compose` by default — works on any host with Docker
10+
# Compose v2 installed, no itkdev wrapper required. Itkdev hosts that
11+
# want the legacy `itkdev-docker-compose` wrapper can opt in via
12+
# `TASK_DOCKER_COMPOSE=itkdev-docker-compose` in `.env.local`.
13+
DOCKER_COMPOSE: '{{ .TASK_DOCKER_COMPOSE | default "docker compose" }}'
1014

1115
tasks:
1216
default:
@@ -49,6 +53,15 @@ tasks:
4953
- task site-open
5054
silent: true
5155

56+
dev:cert:
57+
desc: |
58+
Generate a self-signed cert for the bundled dev traefik
59+
(traefik/ssl/dev.{crt,key}). Idempotent — no-op if dev.crt exists;
60+
set FORCE=1 to overwrite. Has no effect when COMPOSE_PROFILES
61+
doesn't include `traefik` (itkdev devs using a host-level traefik).
62+
cmds:
63+
- sh scripts/dev-cert.sh
64+
5265
site-open:
5366
desc: "Opens admin, docs and client."
5467
cmds:
@@ -92,6 +105,7 @@ tasks:
92105
compose-up:
93106
desc: "Runs docker compose up."
94107
cmds:
108+
- task dev:cert
95109
- task compose -- up --detach --remove-orphans
96110
silent: true
97111

docker-compose.dev.yml

Lines changed: 0 additions & 27 deletions
This file was deleted.

docker-compose.override.yml

Lines changed: 0 additions & 73 deletions
This file was deleted.

docker-compose.redirect.yml

Lines changed: 0 additions & 15 deletions
This file was deleted.

0 commit comments

Comments
 (0)