From 5558db6d56ec7f4812ab24a4568403d81cfb8eae Mon Sep 17 00:00:00 2001 From: Josep Piguillem Date: Sun, 23 Aug 2026 00:09:00 +0200 Subject: [PATCH] Rename the app service to landing-app to avoid a Dokploy network collision MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Compose aliases a service to its own name on every network it joins, including the shared external dokploy-network. A service named plain "app" collided with another project's equally generic "app" on that same network, so its containers started resolving "app" to this one instead — breaking oauth-iam's PHP-FPM upstream whenever both stacks were up together. Co-Authored-By: Claude Sonnet 5 --- .env.production.example | 2 +- README.md | 8 ++++---- docker-compose.yml | 29 ++++++++++++++++++++--------- 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/.env.production.example b/.env.production.example index 6e35307..44b7908 100644 --- a/.env.production.example +++ b/.env.production.example @@ -4,7 +4,7 @@ # cp .env.production.example .env.production # # fill in at least DB_PASSWORD below — docker-compose.yml refuses to # # interpolate at all without it, even for the next command -# docker compose --env-file .env.production run --rm --no-deps app php artisan key:generate --show +# docker compose --env-file .env.production run --rm --no-deps landing-app php artisan key:generate --show # # Everything the containers need is here; docker-compose.yml sets the database, # cache, session and queue drivers itself so they cannot drift. diff --git a/README.md b/README.md index 910c85e..f3e3990 100644 --- a/README.md +++ b/README.md @@ -1458,7 +1458,7 @@ párrafo aparte sin relación programática con él. ## Estructura ``` -docker-compose.yml stack de producción (app, worker, scheduler, postgres) +docker-compose.yml stack de producción (landing-app, worker, scheduler, postgres) docker-compose.test.yml la suite contra Postgres, desechable Dockerfile imagen única para los tres contenedores PHP docker/ Caddyfile, php.ini y entrypoint @@ -1504,11 +1504,11 @@ cp .env.production.example .env.production # comando siguiente, que solo interpola el fichero entero antes de ejecutar # nada. APP_KEY puede quedarse vacío por ahora, se rellena con este paso: -docker compose --env-file .env.production run --rm --no-deps app php artisan key:generate --show # pégalo en APP_KEY +docker compose --env-file .env.production run --rm --no-deps landing-app php artisan key:generate --show # pégalo en APP_KEY docker compose --env-file .env.production up -d --build # el primer administrador, igual que en local -docker compose exec app php artisan user:role tu@email.com super_admin +docker compose exec landing-app php artisan user:role tu@email.com super_admin ``` Todas las variables de `docker-compose.yml` llegan por interpolación `${VAR}`, @@ -1521,7 +1521,7 @@ servidor. | Contenedor | Qué hace | |---|---| -| `app` | FrankenPHP sirviendo el panel y la API | +| `landing-app` | FrankenPHP sirviendo el panel y la API | | `worker` | procesa imágenes y manda los avisos del buzón | | `scheduler` | cierra convocatorias, barre imágenes pendientes, sincroniza repos | | `postgres` | la base de datos | diff --git a/docker-compose.yml b/docker-compose.yml index 1908cfc..e6aca2c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -17,19 +17,30 @@ # cannot run without it: `docker/entrypoint.sh` checks it instead, with a # message that says how to generate one. Requiring it at this level would also # break generating it in the first place — `docker compose run --rm --no-deps -# app php artisan key:generate --show` has to work before `APP_KEY` exists. +# landing-app php artisan key:generate --show` has to work before `APP_KEY` +# exists. # -# `app` is not published on a host port: it only joins the external -# `dokploy-network` so Dokploy's Traefik can reach it, and TLS is terminated -# there before anything reaches this container — same reason +# The web service is named `landing-app`, not `app`: Compose aliases a +# service to its own name on every network it joins, `dokploy-network` +# included, and that network is shared with whatever else Dokploy runs on the +# same host. A service called plain `app` collides with the equally common +# `app` another compose project puts on the same network — its containers +# start resolving `app` to *this* one, on a port nothing here is listening on. +# That is exactly what broke `oauth-iam`'s PHP-FPM upstream the moment both +# stacks were up together, and it stops happening the moment the name isn't +# generic enough to collide. +# +# `landing-app` is not published on a host port either: it only joins the +# external `dokploy-network` so Dokploy's Traefik can reach it, and TLS is +# terminated there before anything reaches this container — same reason # `docker/Caddyfile` trusts `X-Forwarded-*` only from private ranges. The # domain itself is configured through Dokploy's own "Domains" tab, which # injects its own Traefik labels — don't also add them here, Traefik ends up # with two routers for the same Host() and picks one unpredictably. # # A manual deploy without Dokploy needs its own reverse proxy joined to that -# network (with its own labels/config), or `app` added back to `default` with -# a published port. +# network (with its own labels/config), or `landing-app` added back to +# `default` with a published port. # # The web container is the only one that migrates, so a deploy runs them once # rather than once per replica. @@ -121,7 +132,7 @@ x-app-env: &app-env MAIL_FROM_NAME: ${MAIL_FROM_NAME:-Pireon Admin} services: - app: + landing-app: <<: *app environment: <<: *app-env @@ -159,7 +170,7 @@ services: depends_on: postgres: condition: service_healthy - app: + landing-app: condition: service_healthy healthcheck: test: ["CMD", "php", "artisan", "queue:monitor", "default"] @@ -195,7 +206,7 @@ services: depends_on: postgres: condition: service_healthy - app: + landing-app: condition: service_healthy stop_grace_period: 30s