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
rewriteeheaders; la radice web viene daAPACHE_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_URLe, dietro un proxy,MCP_API_URLcon 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)¶
- Aspetta MySQL (30 tentativi ogni 3 secondi).
- Se manca
vendor/, eseguecomposer install --no-dev -o. - Se mancano i file locali, esegue
php init --env=Production --overwrite=n. - Fa girare Apache con
APP_UID/APP_GID(predefinito 33), necessario per i permessi delle cartelle sul NAS. - Crea
runtime,assetsestoragecon il proprietario giusto. - Solo nel worker:
php yii migrate --interactive=0,php yii vapid/generatee copia delle variabili in/etc/environmentper 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) |
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¶
- Aggiornare il codice nel repository montato.
- Se sono cambiate le dipendenze,
composer install --no-dev -onel container. - Riavviare il worker: applica le migrazioni all'avvio.
- Riavviare frontend, backend e api se è cambiata la configurazione di PHP
o Apache, e ricostruire le immagini (
docker compose up -d --build) se è cambiato ilDockerfile.