initial commit

This commit is contained in:
BeauTroll
2026-01-19 08:52:38 +01:00
commit 46907ca153
193 changed files with 35051 additions and 0 deletions

View File

@@ -0,0 +1,215 @@
# 14. Deployment Architecture
## Docker Configuration
```dockerfile
# docker/Dockerfile
# Build stage
FROM node:20-alpine AS builder
WORKDIR /app
# Install pnpm
RUN corepack enable && corepack prepare pnpm@latest --activate
# Copy package files
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile
# Copy source and build
COPY . .
RUN pnpm prisma generate
RUN pnpm build
# Production stage
FROM node:20-alpine AS runner
WORKDIR /app
# Install pnpm
RUN corepack enable && corepack prepare pnpm@latest --activate
# Create non-root user
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 app
# Copy built application
COPY --from=builder --chown=app:nodejs /app/.output ./.output
COPY --from=builder --chown=app:nodejs /app/node_modules ./node_modules
COPY --from=builder --chown=app:nodejs /app/package.json ./package.json
COPY --from=builder --chown=app:nodejs /app/prisma ./prisma
USER app
EXPOSE 3000
ENV NODE_ENV=production
ENV PORT=3000
CMD ["node", ".output/server/index.mjs"]
```
## Docker Compose (Production)
```yaml
# docker/docker-compose.yml
services:
app:
build:
context: ..
dockerfile: docker/Dockerfile
restart: unless-stopped
environment:
- DATABASE_URL=postgresql://postgres:${DB_PASSWORD}@postgres:5432/dofus_manager
- SESSION_SECRET=${SESSION_SECRET}
- NODE_ENV=production
depends_on:
postgres:
condition: service_healthy
networks:
- internal
- traefik
labels:
- "traefik.enable=true"
- "traefik.http.routers.dofus.rule=Host(`dofus.example.com`)"
- "traefik.http.routers.dofus.entrypoints=websecure"
- "traefik.http.routers.dofus.tls.certresolver=letsencrypt"
- "traefik.http.services.dofus.loadbalancer.server.port=3000"
postgres:
image: postgres:16-alpine
restart: unless-stopped
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=${DB_PASSWORD}
- POSTGRES_DB=dofus_manager
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 5
networks:
- internal
traefik:
image: traefik:v3.0
restart: unless-stopped
command:
- "--api.dashboard=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--entrypoints.web.http.redirections.entrypoint.to=websecure"
- "--certificatesresolvers.letsencrypt.acme.httpchallenge=true"
- "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
- "--certificatesresolvers.letsencrypt.acme.email=${ACME_EMAIL}"
- "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- letsencrypt:/letsencrypt
networks:
- traefik
volumes:
postgres_data:
letsencrypt:
networks:
internal:
traefik:
external: true
```
## GitLab CI/CD Pipeline
```yaml
# .gitlab-ci.yml
stages:
- test
- build
- deploy
variables:
DOCKER_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
# Test stage
test:
stage: test
image: node:20-alpine
before_script:
- corepack enable
- pnpm install --frozen-lockfile
script:
- pnpm lint
- pnpm typecheck
- pnpm test
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- node_modules/
# Build stage
build:
stage: build
image: docker:24
services:
- docker:24-dind
before_script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
script:
- docker build -t $DOCKER_IMAGE -f docker/Dockerfile .
- docker push $DOCKER_IMAGE
- docker tag $DOCKER_IMAGE $CI_REGISTRY_IMAGE:latest
- docker push $CI_REGISTRY_IMAGE:latest
only:
- main
- develop
# Deploy staging
deploy_staging:
stage: deploy
image: alpine:latest
before_script:
- apk add --no-cache openssh-client
- eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY" | ssh-add -
- mkdir -p ~/.ssh
- echo "$SSH_KNOWN_HOSTS" >> ~/.ssh/known_hosts
script:
- ssh $STAGING_USER@$STAGING_HOST "cd /opt/dofus-manager && docker compose pull && docker compose up -d"
environment:
name: staging
url: https://staging.dofus.example.com
only:
- develop
# Deploy production
deploy_production:
stage: deploy
image: alpine:latest
before_script:
- apk add --no-cache openssh-client
- eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY" | ssh-add -
- mkdir -p ~/.ssh
- echo "$SSH_KNOWN_HOSTS" >> ~/.ssh/known_hosts
script:
- ssh $PROD_USER@$PROD_HOST "cd /opt/dofus-manager && docker compose pull && docker compose up -d && docker compose exec app pnpm prisma migrate deploy"
environment:
name: production
url: https://dofus.example.com
only:
- main
when: manual
```
---