--- name: docker-bundle-deployment description: Work on the Nyone docker-bundle deployment bundle under docker-bundle/. Use when modifying Docker Compose, Apache, MediaMTX, PostgreSQL, Redis, Laravel queue/scheduler/viewer-sync services, deploy.sh, deployment README files, or runtime environment defaults for this self-contained Docker deployment. --- # Nyone docker-bundle Deployment ## Core Rules - Keep deployment changes inside `docker-bundle/` unless the user explicitly requests application code changes. - Treat `docker-bundle/.env` and `docker-bundle/runtime/` as server-local generated state; do not commit or depend on them. - Do not make this bundle depend on the cloned app repository's `.env` or `deploy/mediamtx.yml`. - Keep MediaMTX config Docker-owned at `docker/mediamtx/mediamtx.yml.template`. - Keep `APP_DOMAIN` and `HLS_DOMAIN` separate because the app and HLS are served by different host-level Nginx virtual hosts. - Do not run `scripts/deploy.sh`, `docker compose up`, or image builds unless the user confirms this is a deployment server. ## Architecture - `scripts/deploy.sh` is the entrypoint for server deployment. - `scripts/backup.sh` creates restore-ready zip backups for the docker-bundle deployment. - `docker-compose.yml` defines `app`, `db`, `redis`, `mediamtx`, `queue`, `scheduler`, `viewer-sync`, and one-shot `migrate`. - `docker/app/Dockerfile` builds the Laravel Apache image from `runtime/source`. - `docker/app/entrypoint.sh` selects behavior by `CONTAINER_ROLE`. - `docker/app/apache/nyone.conf.template` serves Laravel on `APP_DOMAIN`. - Host Nginx should proxy `HLS_DOMAIN` directly to the locally published MediaMTX HLS port. - `docker/mediamtx/entrypoint.sh` renders the MediaMTX template at container start. ## Port Defaults - Apache published HTTP: `80`. - MediaMTX RTMP: `1935`. - MediaMTX HLS local publish/internal: `8888`. - MediaMTX API internal: `9997`. - PostgreSQL internal: `5432`. - Redis internal: `6379`. Publish Apache HTTP and RTMP by default, and bind MediaMTX HLS to `127.0.0.1:8888` for host Nginx. Keep the MediaMTX API private on the Docker network. ## Editing Guidance - When adding an environment option, update `.env.example`, `docker-compose.yml`, and any entrypoint/template that consumes it. - When changing MediaMTX ports, update Compose environment, published ports, entrypoint defaults, and the template together. - When changing Laravel runtime behavior, update the shared `x-app-environment` block unless the value belongs to one role only. - When changing queue behavior, prefer env-driven options on the `queue` service and `docker/app/entrypoint.sh`. - Do not run the long-lived Docker `viewer-sync` service with `--isolated`; a stale cache lock can make the command exit cleanly and trigger an endless container restart loop. - Keep `npm run build` after PHP setup and Composer install in `docker/app/Dockerfile`; the Wayfinder Vite plugin invokes `php artisan wayfinder:generate` during the build. The asset stage must also provide safe build-time Laravel env values, create Laravel writable directories such as `storage/framework/views`, and run `php artisan wayfinder:generate --with-form --no-interaction` before `npm run build` so failures are visible in Docker logs. - Do not call `php artisan storage:link --force` as `www-data` during container startup; `public/storage` lives in the root-owned image filesystem. Create the symlink as root in the entrypoint if it is missing. - Keep deploy script behavior idempotent: repeat runs should update the Git checkout, rebuild, migrate, and restart services without deleting volumes. - Keep backup behavior restore-ready: include deployment files, `.env`, source checkout when present, PostgreSQL dump, app storage volume, Redis volume, checksums, restore notes, and a restore helper in one zip. - Keep generated secrets in `.env`; do not bake secrets into images or templates. ## Nginx TLS Proxy Guidance - Document Nginx as a host-level TLS reverse proxy in `README.md`; do not add Nginx as another Compose service unless the user asks. - Keep Docker Apache as the upstream for the app hostname only. Nginx should proxy HLS directly to the locally published MediaMTX HLS port. - Recommend `APP_HTTP_PORT=127.0.0.1:8080` when Nginx owns host ports `80` and `443`. - Recommend `HLS_HTTP_PORT=127.0.0.1:8888` so HLS is reachable by host Nginx but not publicly exposed as a raw port. - Include `X-Forwarded-Proto https`, `X-Forwarded-Port 443`, `X-Forwarded-Host`, `X-Real-IP`, and `X-Forwarded-For` in proxy examples. - Let host Nginx own public HLS CORS headers. Keep `hlsAllowOrigins: []` in the MediaMTX template so proxied HLS responses do not contain duplicate `Access-Control-Allow-Origin` values. - Keep HLS proxy examples buffering off and cache headers set to no-store. - Keep RTMP outside the HTTP proxy guidance unless explicitly using Nginx stream proxying; the default is direct TCP `1935` to MediaMTX through Docker. ## Static Verification Use static checks when not on a deployment server: ```bash git diff --check rg "1993[5]|1998[8]|80[8]0|25[2]5|nyone[.]net|nyone-hls[.]net|change-this-secre[t]" docker-bundle -n bash -n docker-bundle/scripts/backup.sh ``` If Docker is available and the user allows non-deploy validation, validate only the Compose config: ```bash docker compose --env-file docker-bundle/.env.example -f docker-bundle/docker-compose.yml config ``` Do not start containers during local verification unless the user explicitly asks for runtime testing.