From 45253ba7056edd7f76d9fea767c413f0a8400c1c Mon Sep 17 00:00:00 2001 From: syoul Date: Fri, 13 Mar 2026 18:15:12 +0100 Subject: [PATCH] Migrate CI to single-step DinD with Fabio/Consul Replace 5-step pipeline (build/test/push/push/deploy) with single docker:dind step that builds and deploys in-place via Docker socket. - .woodpecker.yml: single-step DinD, 1 secret (SECRET_KEY) - docker-compose.fabio.yml: overlay with SERVICE_* labels for Registrator - docker-compose.yml: add ports without host bind (Fabio/Traefik routing) - docker-compose.dev.yml: named volumes with bind driver - Dockerfiles: install curl, HEALTHCHECK via curl /api/health - Makefile: docker-fabio, consul-services, fabio-routes targets Co-Authored-By: Claude Opus 4.6 --- .woodpecker.yml | 71 +++++++-------------------------- Makefile | 16 +++++++- docker/backend.Dockerfile | 5 ++- docker/docker-compose.dev.yml | 20 ++++++++-- docker/docker-compose.fabio.yml | 14 +++++++ docker/docker-compose.yml | 4 ++ docker/frontend.Dockerfile | 3 ++ 7 files changed, 71 insertions(+), 62 deletions(-) create mode 100644 docker/docker-compose.fabio.yml diff --git a/.woodpecker.yml b/.woodpecker.yml index 76d536a..5a4a636 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -3,61 +3,20 @@ when: event: push steps: - build-frontend: - image: node:20-slim + - name: build + image: docker:dind + environment: + COMPOSE_PROJECT_NAME: ${CI_REPO_OWNER,,}-${CI_REPO_NAME,,}-${CI_COMMIT_BRANCH//\//-} + DOMAIN: sejeteralo.org + LETSENCRYPT_HOST: sejeteralo.org + SERVICE_8000_TAGS: urlprefix-sejeteralo.org:443/api + SERVICE_3000_TAGS: urlprefix-sejeteralo.org:443/* + SECRET_KEY: + from_secret: SECRET_KEY commands: - - cd frontend && npm ci && npm run build - - build-backend: - image: python:3.11-slim - commands: - - pip install -r backend/requirements.txt - - cd backend && python -m pytest tests/ -v --tb=short || true - - docker-backend: - image: woodpeckerci/plugin-docker-buildx - settings: - repo: - from_secret: registry_repo_backend - registry: - from_secret: registry_host - username: - from_secret: registry_user - password: - from_secret: registry_password - dockerfile: docker/backend.Dockerfile - target: production - tags: latest + - docker compose -f docker/docker-compose.yml -f docker/docker-compose.fabio.yml up --build -d + volumes: + - ${DOCKER_SOCKET_LOCATION:-/var/run/docker.sock}:/var/run/docker.sock when: - status: success - - docker-frontend: - image: woodpeckerci/plugin-docker-buildx - settings: - repo: - from_secret: registry_repo_frontend - registry: - from_secret: registry_host - username: - from_secret: registry_user - password: - from_secret: registry_password - dockerfile: docker/frontend.Dockerfile - target: production - tags: latest - when: - status: success - - deploy: - image: appleboy/drone-ssh - settings: - host: - from_secret: deploy_host - username: - from_secret: deploy_user - key: - from_secret: deploy_key - script: - - cd /opt/sejeteralo && docker compose -f docker/docker-compose.yml pull && docker compose -f docker/docker-compose.yml up -d - when: - status: success + - branch: main + event: push diff --git a/Makefile b/Makefile index fb4f9fd..1fcd804 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: install dev dev-backend dev-frontend test seed docker-up docker-down docker-dev +.PHONY: install dev dev-backend dev-frontend test seed docker-up docker-down docker-dev docker-fabio docker-fabio-down consul-services fabio-routes # ── Development (local) ── @@ -32,3 +32,17 @@ docker-down: docker-dev: docker compose -f docker/docker-compose.yml -f docker/docker-compose.dev.yml up --build + +# ── Docker (Fabio/Consul) ── + +docker-fabio: + docker compose -f docker/docker-compose.yml -f docker/docker-compose.fabio.yml up --build -d + +docker-fabio-down: + docker compose -f docker/docker-compose.yml -f docker/docker-compose.fabio.yml down + +consul-services: + @curl -s http://localhost:8500/v1/catalog/services | python3 -m json.tool + +fabio-routes: + @curl -s http://localhost:9998/routes diff --git a/docker/backend.Dockerfile b/docker/backend.Dockerfile index 9554f42..d1ed666 100644 --- a/docker/backend.Dockerfile +++ b/docker/backend.Dockerfile @@ -17,13 +17,16 @@ FROM base AS production ENV PYTHONUNBUFFERED=1 +RUN apt-get update && apt-get install -y --no-install-recommends curl \ + && rm -rf /var/lib/apt/lists/* + COPY --from=build /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages COPY --from=build /usr/local/bin/uvicorn /usr/local/bin/uvicorn COPY --from=build /usr/local/bin/alembic /usr/local/bin/alembic COPY --from=build /app /app HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \ - CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/docs')" || exit 1 + CMD curl -f http://localhost:8000/api/health || exit 1 EXPOSE 8000 CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"] diff --git a/docker/docker-compose.dev.yml b/docker/docker-compose.dev.yml index 4c790cf..a24401f 100644 --- a/docker/docker-compose.dev.yml +++ b/docker/docker-compose.dev.yml @@ -10,8 +10,7 @@ services: ports: !override - "8000:8000" volumes: - - ../backend:/app - labels: [] + - backend-sources:/app frontend: build: @@ -22,5 +21,18 @@ services: - "3000:3000" - "24678:24678" volumes: - - ../frontend:/app - labels: [] + - frontend-sources:/app + +volumes: + backend-sources: + driver: local + driver_opts: + type: none + o: bind + device: ../backend + frontend-sources: + driver: local + driver_opts: + type: none + o: bind + device: ../frontend diff --git a/docker/docker-compose.fabio.yml b/docker/docker-compose.fabio.yml new file mode 100644 index 0000000..77f8829 --- /dev/null +++ b/docker/docker-compose.fabio.yml @@ -0,0 +1,14 @@ +# Overlay Fabio — combine avec : docker compose -f docker-compose.yml -f docker-compose.fabio.yml + +services: + backend: + labels: + - SERVICE_8000_CHECK_HTTP=${SERVICE_8000_CHECK_HTTP:-/api/health} + - SERVICE_8000_NAME=${SERVICE_8000_NAME:-${COMPOSE_PROJECT_NAME:-sejeteralo}-backend-8000} + - SERVICE_8000_TAGS=${SERVICE_8000_TAGS:-urlprefix-sejeteralo.org:443/api} + + frontend: + labels: + - SERVICE_3000_CHECK_HTTP=${SERVICE_3000_CHECK_HTTP:-/} + - SERVICE_3000_NAME=${SERVICE_3000_NAME:-${COMPOSE_PROJECT_NAME:-sejeteralo}-frontend-3000} + - SERVICE_3000_TAGS=${SERVICE_3000_TAGS:-urlprefix-sejeteralo.org:443/*} diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 9429420..a811f2e 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -11,6 +11,8 @@ services: SECRET_KEY: ${SECRET_KEY} DEBUG: "false" CORS_ORIGINS: '["https://${DOMAIN:-sejeteralo.org}"]' + ports: + - 8000 volumes: - backend-data:/app restart: always @@ -29,6 +31,8 @@ services: environment: NODE_ENV: production NUXT_PUBLIC_API_BASE: http://backend:8000/api/v1 + ports: + - 3000 depends_on: - backend restart: always diff --git a/docker/frontend.Dockerfile b/docker/frontend.Dockerfile index 3cf7233..bf2e76f 100644 --- a/docker/frontend.Dockerfile +++ b/docker/frontend.Dockerfile @@ -21,6 +21,9 @@ FROM base AS production ENV PORT=3000 ENV NODE_ENV=production +RUN apt-get update && apt-get install -y --no-install-recommends curl \ + && rm -rf /var/lib/apt/lists/* + COPY --from=build /src/.output /src/.output HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \