v3 : déploiement (image unique, produit à la racine, maquette en sous-domaine) et documentation du chantier

- docker/app.Dockerfile : une image Rust + Svelte, la construction rejoue toute
  la boucle (fmt, clippy -D warnings, tests, svelte-check, vitest) ; utilisateur
  non-root, volume /data. docker/app-compose.yml pour sonic (fabio).
- .woodpecker/app.yml : produit sur decision.librodrome.org, attend la maquette,
  écarte tout conteneur qui revendique encore la racine, healthcheck du commit.
- .woodpecker/maquette.yml (ex .woodpecker.yml) : la maquette v2 telle quelle,
  sur maquette.decision.librodrome.org, mêmes volumes.
- .env.example de la maquette rangé dans maquette/ ; celui de la v3 à la racine.
- Docs : README, CONTRIBUTING (travail à deux), CLAUDE.md v3, HANDOFF,
  docs/chantiers (feuille de route, fiche, contrôles, onboarding de Chiara,
  demande à poka), docs/adr 0001–0006.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Yvv
2026-10-21 03:50:44 +02:00
co-authored by Claude Opus 5.5
parent c2669a3d0b
commit 1f9c241b41
24 changed files with 1187 additions and 281 deletions
+37
View File
@@ -0,0 +1,37 @@
# libreDecision v3 on sonic — decision.librodrome.org.
# Runtime data lives in the named volume `data` (SQLite, the server's clone of
# the texts repository, its deploy key): never `down -v`, never recreated.
# Settings that are not secret are here; secrets, if any, in /opt/libredecision-app/secrets.env.
name: lpk-libredecision-app
services:
app:
image: libredecision-app:latest
container_name: lpk-libredecision-app
restart: always
env_file:
- path: /opt/libredecision-app/secrets.env
required: false
environment:
LD_PUBLIC_URL: https://${APP_DOMAIN:-decision.librodrome.org}
LD_ADMIN_G1_IDS: ${LD_ADMIN_G1_IDS:-idty:8352}
LD_BOOTSTRAP_ADMIN: "1"
LD_PUBLISH_REMOTE: ${LD_PUBLISH_REMOTE:-git@git.duniter.org:Yvv/libredecision-textes.git}
LD_PUBLISH_BRANCH: main
RUST_LOG: info,sqlx=warn,tower_http=warn
volumes:
- data:/data
labels:
# Registrator → Consul → Fabio.
- SERVICE_8002_NAME=lpk-libredecision-app-8002
- SERVICE_8002_TAGS=urlprefix-${APP_DOMAIN:-decision.librodrome.org}/*
- SERVICE_8002_CHECK_TCP=true
networks:
- sonic
volumes:
data:
networks:
sonic:
external: true
+56
View File
@@ -0,0 +1,56 @@
# syntax=docker/dockerfile:1
# libreDecision v3 — one image: the Rust server serves the API and the compiled
# Svelte interface. Every gate of the loop runs inside the build: a red check
# means no image.
# --- Interface -----------------------------------------------------------------
FROM node:22-bookworm-slim AS web
WORKDIR /src/web
COPY web/package.json web/package-lock.json ./
RUN npm ci --no-audit --no-fund
COPY web/ ./
ARG LD_BUILD=dev
ENV LD_BUILD=${LD_BUILD}
RUN npx svelte-kit sync \
&& npx svelte-check --tsconfig ./tsconfig.json --fail-on-warnings \
&& npx vitest run \
&& npx vite build
# --- Server --------------------------------------------------------------------
FROM rust:1.99-slim-bookworm AS server
RUN apt-get update && apt-get install -y --no-install-recommends git ca-certificates && rm -rf /var/lib/apt/lists/*
WORKDIR /src
COPY rust-toolchain.toml ./
RUN rustup show active-toolchain || rustup toolchain install
COPY Cargo.toml Cargo.lock rustfmt.toml ./
COPY crates crates
COPY seeds seeds
RUN --mount=type=cache,target=/usr/local/cargo/registry \
--mount=type=cache,target=/src/target \
cargo fmt --all --check \
&& cargo clippy --workspace --all-targets --locked -- -D warnings \
&& cargo test --workspace --locked \
&& cargo build --release --locked -p ld-server \
&& cp target/release/ld-server /usr/local/bin/ld-server
# --- Runtime -------------------------------------------------------------------
FROM debian:bookworm-slim AS production
RUN apt-get update \
&& apt-get install -y --no-install-recommends ca-certificates git openssh-client tini \
&& rm -rf /var/lib/apt/lists/* \
&& useradd --system --uid 10001 --create-home --home-dir /home/app app \
&& mkdir -p /data && chown app:app /data
COPY --from=server /usr/local/bin/ld-server /usr/local/bin/ld-server
COPY --from=web /src/web/build /app/web
COPY seeds /app/seeds
ARG LD_BUILD=dev
ENV LD_BUILD=${LD_BUILD} \
LD_BIND=0.0.0.0:8002 \
LD_DATA_DIR=/data \
LD_WEB_DIR=/app/web \
LD_SEED_DIR=/app/seeds
USER app
EXPOSE 8002
VOLUME /data
ENTRYPOINT ["tini", "--"]
CMD ["ld-server"]