Vai al contenuto

Deploy con Docker

In produzione GesTask gira in container Docker su un NAS. MySQL non è nei container: sta sull'host.

Immagine

docker/Dockerfile parte da php:8.4-apache-bookworm. Non usa l'immagine ufficiale di Yii perché il NAS è armv7, e resta su bookworm per evitare gli errori di seccomp di trixie.

  • Estensioni: intl, pdo_mysql, gd, zip, bcmath, gmp, opcache, più composer.
  • PHP: fuso UTC, 128 MB di memoria, upload e POST fino a 512 MB, opcache.
  • Apache con rewrite e headers; la radice web viene da APACHE_DOCUMENT_ROOT.
Stage Radice web Note
frontend /app/frontend/web
backend /app/backend/web
api /app/api/web il .htaccess inoltra l'header Authorization
worker — cron e supervisord per crontab e coda

docker/Dockerfile_v1 è la versione precedente, basata sull'immagine Yii.

Servizi (docker-compose.yml)

Servizio Porta Note
frontend ${FRONTEND_PORT:-20080}
backend ${BACKEND_PORT:-21080}
api ${API_PORT:-22080} API v1; Swagger UI su /docs/
wiki ${WIKI_PORT:-23080} nginx:alpine che serve ./wiki in sola lettura
worker — migrazioni, cron, queue/listen
redis interna redis:7-alpine, volume redisdata
caddy 80, 443 HTTPS con Let's Encrypt per frontend, backend, api e wiki (host nel .env, vedi Caddyfile)

I servizi PHP montano il repository in /app, leggono .env, hanno DOCKER_ENV=1 e raggiungono MySQL sull'host come host.docker.internal.

Indirizzi

In XAMPP tutto il repository è sotto la radice web e ogni applicazione si apre dalla sua cartella. In Docker ogni applicazione ha un container con la radice sulla propria cartella web, e si raggiunge dalla sua porta:

Applicazione XAMPP Docker
Frontend …/gestask/frontend/web http://<host>:20080
Pannello …/gestask/backend/web http://<host>:21080
API …/gestask/api/web/v1/… http://<host>:22080/v1/…
Server MCP …/gestask/api/web/mcp http://<host>:22080/mcp
Server MCP di amministrazione …/gestask/api/web/mcp/admin http://<host>:22080/mcp/admin
Swagger UI …/gestask/api/web/docs/ http://<host>:22080/docs/
Wiki …/gestask/wiki/ http://<host>:23080

Con un reverse proxy davanti (un dominio con più percorsi o sottodomini) cambiano solo le regole del proxy; APP_URL e BACKEND_URL vanno impostati sugli indirizzi pubblici, perché li usano le email e i collegamenti fra frontend e pannello.

La wiki si serve così com'è nel repository: dopo mkdocs build basta aggiornare il codice, senza riavviare il container.

Connettore MCP

Perché claude.ai, l'app e Claude Desktop si colleghino servono:

  • l'API su un indirizzo HTTPS pubblico, raggiungibile dai server di Anthropic;
  • l'API alla radice del suo host (o un proxy che inoltri /.well-known/oauth-* all'app api): i client cercano lì i metadati OAuth;
  • MCP_FRONTEND_URL e, dietro un proxy, MCP_API_URL con gli indirizzi pubblici.

In XAMPP, con l'app in sottocartella, la scoperta OAuth non funziona: Claude Code si collega con il token personale (vedi Connettore MCP). Fuori da Docker le variabili si impostano con SetEnv nella configurazione di Apache, perché PHP non legge .env.

Avvio del container (docker/entrypoint.sh)

  1. Aspetta MySQL (30 tentativi ogni 3 secondi).
  2. Se manca vendor/, esegue composer install --no-dev -o.
  3. Se mancano i file locali, esegue php init --env=Production --overwrite=n.
  4. Fa girare Apache con APP_UID/APP_GID (predefinito 33), necessario per i permessi delle cartelle sul NAS.
  5. Crea runtime, assets e storage con il proprietario giusto.
  6. Solo nel worker: php yii migrate --interactive=0, php yii vapid/generate e copia delle variabili in /etc/environment per il cron.

Variabili d'ambiente

Lette da common/config/docker.php:

Gruppo Variabili
Database DB_HOST, DB_PORT, DB_NAME, DB_USER, DB_PASSWORD
Redis REDIS_HOST, REDIS_PORT
SMTP SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASSWORD, SMTP_ENCRYPTION (ssl usa smtps, altrimenti smtp)
Email SENDER_EMAIL, SENDER_NAME, SUPPORT_EMAIL, ADMIN_EMAIL
Indirizzi APP_URL (frontend), BACKEND_URL
Push VAPID_SUBJECT, VAPID_PUBLIC_KEY, VAPID_PRIVATE_KEY
Canali NTFY_BASE_URL, TELEGRAM_BOT_TOKEN
Verifica in due passaggi TOTP_ENC_KEY (vuota = funzione spenta; una volta scelta non va più cambiata)
Connettore MCP MCP_FRONTEND_URL (indirizzo pubblico del frontend, obbligatorio per OAuth), MCP_API_URL (indirizzo pubblico dell'API, vuoto = quello della richiesta); lette da common/config/params.php

Altre: DOCKER_ENV (attiva docker.php), APP_UID, APP_GID, FRONTEND_PORT, BACKEND_PORT, API_PORT, WIKI_PORT, e YII_ENV per l'API (predefinito prod; con dev gli errori mostrano i dettagli).

.env.example le elenca tutte, tranne YII_ENV, con un valore d'esempio.

La configurazione delle email in produzione e i problemi più comuni sono in notes/configurazione-email-produzione.md.

Aggiornare un'installazione

  1. Aggiornare il codice nel repository montato.
  2. Se sono cambiate le dipendenze, composer install --no-dev -o nel container.
  3. Riavviare il worker: applica le migrazioni all'avvio.
  4. Riavviare frontend, backend e api se è cambiata la configurazione di PHP o Apache, e ricostruire le immagini (docker compose up -d --build) se è cambiato il Dockerfile.