Deploy app
Procedura centralizzata per pubblicare e aggiornare app dietro Traefik
Obiettivo
Pubblicare una nuova applicazione Docker dietro Traefik senza esporre porte interne direttamente su internet.
Dal 2026-06-24 i deploy delle app containerizzate devono passare dal
control plane Rust obelica, non da comandi docker compose up -d --build
lanciati a mano.
Il sistema centralizzato:
- legge i target da
/opt/obelica/infra/config/deploy-apps.tsv; - verifica che il repo sia pulito;
- esegue
git fetche solo fast-forward; - separa build e start:
docker compose buildpoidocker compose up -d --no-build; - applica timeout per fetch/build/start;
- verifica i container attesi;
- esegue smoke test HTTP/HTTPS con retry;
- fallisce in modo esplicito se un passaggio non torna.
Comandi
Lista target configurati:
cd /opt/obelica
/opt/obelica/infra/bin/obelica deploy listDeploy singola app:
cd /opt/obelica
/opt/obelica/infra/bin/obelica app deploy tulpa-studioDeploy docs:
cd /opt/obelica
/opt/obelica/infra/bin/obelica deploy docsDeploy completo di tutti i target configurati:
cd /opt/obelica
/opt/obelica/infra/bin/obelica deploy allNota: il binario globale /usr/local/bin/obelica puo' essere una copia piu'
vecchia se non e' stato promosso con sudo. In caso di dubbio usare sempre
/opt/obelica/infra/bin/obelica.
Config deploy centralizzata
File:
/opt/obelica/infra/config/deploy-apps.tsvFormato colonne:
name strategy repo compose branch containers smoke_url expected_codes build_timeout_secs up_timeout_secs [migration_env_file migration_command migration_timeout_secs]Esempio:
tulpa-studio next-docker repos/tulpa-studio repos/tulpa-studio main tulpa-studio https://tulpa-studio.vps.obelica.com/ 200,301,302,307,308 1800 180Strategie attuali:
| Strategia | Uso |
|---|---|
next-docker | app Next.js con Dockerfile standalone |
astro-static-docker | app Astro statica servita da nginx |
vite-static-docker | app Vite statica servita da nginx |
static-docker | statico puro servito da nginx |
monorepo-next-docker | monorepo Next con piu' container, es. Wash Dog |
Per ora la strategia guida metadata, timeout e lettura operativa. Tutti i target attuali usano Docker Compose come backend di deploy.
Migration opzionali
Dal 2026-07-04 obelica app deploy supporta tre colonne opzionali in
deploy-apps.tsv:
| Colonna | Significato |
|---|---|
migration_env_file | file env relativo a /opt/obelica o path assoluto, usato per caricare almeno DATABASE_URL |
migration_command | comando eseguito nella root del repo dopo docker compose build e prima di docker compose up -d --no-build |
migration_timeout_secs | timeout dello step migration, default 300 secondi |
Lo step e' intenzionalmente tra build e start: se la build fallisce il DB non viene toccato; se la migration fallisce i container correnti restano in piedi e il deploy si ferma.
wash-dog-ferrara usa questo meccanismo per Drizzle:
migration_env_file: secrets/apps/wash-dog-ferrara-admin.env
migration_command: docker run --rm -e DATABASE_URL -e PGSSLMODE=no-verify -v "$PWD":/src:ro -w /work node:22-alpine sh -lc 'apk add --no-cache git >/dev/null && cp -a /src/. /work && npm install -g pnpm@9.15.0 >/dev/null && pnpm install --frozen-lockfile && pnpm --filter @obelica/database db:migrate'
migration_timeout_secs: 900Nota: il container migration monta il repo in sola lettura e copia i sorgenti in
/work, quindi non sporca la working tree del repo di produzione.
Target verificati
Il 2026-06-24 e' stato eseguito obelica deploy all con successo su 14
target:
| Target | Strategia | Esito |
|---|---|---|
obelica-docs | next-docker | build, restart, smoke 200 |
alessandro-zucchini | next-docker | fast-forward, build, restart, smoke 200 |
caffe-del-corso | astro-static-docker | build, restart, smoke 200 |
centro-donna-giustizia | next-docker | build, restart, smoke 200 |
macelleria | next-docker | build Chromium-heavy, restart, smoke 200 |
officina-longhi | vite-static-docker | build, restart, smoke 200 |
ottica-style | static-docker | build, restart, smoke 200 |
romauto | next-docker | build, restart, smoke 200 |
sazzini | astro-static-docker | build, restart, smoke 200 |
sonja-trekking | next-docker | fast-forward Spaces, build, restart, smoke 200 |
tulpa-studio | next-docker | build asset-heavy, restart, smoke 200 |
wash-dog-ferrara | monorepo-next-docker | admin/staff build, both containers running, smoke admin 200 |
zannoni | astro-static-docker | image-heavy build, restart, smoke 200 |
Il 2026-07-04 wash-dog-ferrara e' stato verificato anche con migration
esplicita nel deploy: build cached, @obelica/database db:migrate riuscito
contro DigitalOcean Managed Postgres, compose up, container running e smoke
admin 200 al secondo tentativo.
Layout
/opt/obelica/repos/<repo-name>
/opt/obelica/apps/<app-name>
/opt/obelica/secrets/apps/<app-name>.envFile minimi runtime:
docker-compose.yml
.envFile minimi build:
Dockerfile
.dockerignoreRequisiti Compose
Il servizio pubblico deve:
- usare
restart: unless-stopped; - limitare i log Docker con driver
json-file,max-size=10m,max-file=3; - non pubblicare porte host con
ports, salvo eccezioni approvate; - collegarsi alla rete esterna
proxy; - avere
traefik.enable=true; - avere host rule esplicita;
- usare entrypoint
websecure; - usare resolver
letsencrypt; - dichiarare la porta interna del servizio.
Esempio:
labels:
- "traefik.enable=true"
- "traefik.http.routers.nome.rule=Host(`${APP_DOMAIN}`)"
- "traefik.http.routers.nome.entrypoints=websecure"
- "traefik.http.routers.nome.tls.certresolver=letsencrypt"
- "traefik.http.services.nome.loadbalancer.server.port=3000"
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
networks:
proxy:
external: trueProcedura nuova app
- Creare scheda tecnica app.
- Creare o verificare record DNS verso
129.212.141.97. - Preparare Dockerfile,
.dockerignore, compose e.env. - Mettere secret in
/opt/obelica/secrets/apps/<app-name>.env. - Aggiungere il target a
/opt/obelica/infra/config/deploy-apps.tsv. - Eseguire backup se il cambio tocca servizi esistenti.
obelica backup- Avviare con il framework centralizzato.
cd /opt/obelica
/opt/obelica/infra/bin/obelica app deploy <app-name>- Verificare.
docker ps
curl -I https://dominio.example
obelica doctor
obelica smoke staging- Aggiornare docs.
Regole
- Non committare segreti.
- Non aprire porte applicative pubbliche senza Traefik.
- Per servizi stateful, documentare path dati e restore prima del go-live.
- Ogni app deve avere rollback plan.
- Ogni app deve avere
.dockerignoreper escludere.git,.env,node_modules,.next, cache locali, log e output di test. - I Dockerfile npm/pnpm devono usare cache mount BuildKit per installare dipendenze.
- Dopo deploy o rebuild pubblico, eseguire
obelica smoke staging. - Non usare
docker compose up -d --buildcome procedura normale: la build e lo start devono restare separati per evitare blocchi non diagnosticabili. - Se un target richiede piu' container, indicare tutti i nomi nella colonna
containersseparati da virgola. - Se uno smoke URL richiede warm-up, lasciare che sia il framework a ritentare.
Debiti emersi dal deploy all 2026-06-24
- Molte app hanno vulnerabilita' npm moderate/high; alcune hanno critical.
macelleriainstalla Chromium nella build e produce immagini grandi.tulpa-studioha build context da ~1.14 GB per asset locali.zannonispende diversi minuti in ottimizzazione immagini Astro.- Alcuni progetti Next 16 usano ancora convenzione
middleware, deprecata in favore diproxy. wash-dog-ferraramostra warning Turbopack/NFT su tracing dinamico nella route cron recurring.
Esempio Dockerfile npm
# syntax=docker/dockerfile:1
FROM node:22-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN --mount=type=cache,target=/root/.npm npm ci --ignore-scripts
COPY . .
RUN npm run build