diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..2ae88ec --- /dev/null +++ b/.dockerignore @@ -0,0 +1,7 @@ +node_modules +.git +build +tmp +coverage +.env +.env.test diff --git a/.env.production.example b/.env.production.example new file mode 100644 index 0000000..2acfcc1 --- /dev/null +++ b/.env.production.example @@ -0,0 +1,9 @@ +# App +APP_KEY=change-me-to-a-random-string +APP_URL=https://pc-builder.example.com + +# Database +DB_ROOT_PASSWORD=change-me-root-password +DB_USER=pcbuilder +DB_PASSWORD=change-me-db-password +DB_DATABASE=pc_builderv2 diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml index 53d807f..9103887 100644 --- a/.gitea/workflows/build.yml +++ b/.gitea/workflows/build.yml @@ -28,7 +28,7 @@ jobs: if: github.event_name == 'push' && github.ref == 'refs/heads/main' steps: - name: Checkout repository - uses: actions/checkout@v4 + run: git clone --depth=1 http://x-access-token:${{ github.token }}@192.168.1.39:3000/${{ github.repository }}.git . - name: Login to Gitea Container Registry run: | diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..56e68be --- /dev/null +++ b/Dockerfile @@ -0,0 +1,18 @@ +FROM node:24-alpine AS base +RUN apk add --no-cache ffmpeg + +FROM base AS build +WORKDIR /app +COPY package*.json ./ +RUN npm ci +COPY . . +RUN npm run build + +FROM base AS production +WORKDIR /app +COPY package*.json ./ +RUN npm ci --omit=dev +COPY --from=build /app/build ./ +RUN mkdir -p uploads +EXPOSE 3333 +CMD ["node", "bin/server.js"] diff --git a/deploy/Dockerfile b/deploy/Dockerfile new file mode 100644 index 0000000..b50114c --- /dev/null +++ b/deploy/Dockerfile @@ -0,0 +1,8 @@ +FROM alpine:3.19 + +RUN apk add --no-cache docker-cli netcat-openbsd + +COPY deploy-webhook.sh /usr/local/bin/deploy-webhook.sh +RUN chmod +x /usr/local/bin/deploy-webhook.sh + +ENTRYPOINT ["/usr/local/bin/deploy-webhook.sh"] diff --git a/deploy/deploy-webhook.sh b/deploy/deploy-webhook.sh new file mode 100644 index 0000000..4455158 --- /dev/null +++ b/deploy/deploy-webhook.sh @@ -0,0 +1,27 @@ +#!/bin/sh +set -e + +COMPOSE_DIR="${COMPOSE_DIR:-/app}" +WEBHOOK_PORT="${WEBHOOK_PORT:-9000}" + +cd "$COMPOSE_DIR" + +deploy() { + echo "[$(date)] Deploy triggered..." + docker compose pull + docker compose up -d --remove-orphans + echo "[$(date)] Deploy complete." +} + +echo "=== PC Builder Deploy Webhook ===" +echo "Compose dir: $COMPOSE_DIR" +echo "Listening on port $WEBHOOK_PORT..." + +while true; do + # Netcat reads the HTTP request, we filter for POST /deploy + REQ=$(nc -l -p "$WEBHOOK_PORT" -q 1 2>/dev/null || true) + + if echo "$REQ" | grep -q "^POST /deploy"; then + deploy & + fi +done diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml new file mode 100644 index 0000000..c819668 --- /dev/null +++ b/docker-compose.prod.yml @@ -0,0 +1,69 @@ +services: + pc-builder: + image: 192.168.1.39:3000/username/pc-builder:latest + container_name: pc-builder + restart: unless-stopped + ports: + - '3333:3333' + environment: + - TZ=Europe/Paris + - PORT=3333 + - HOST=0.0.0.0 + - NODE_ENV=production + - APP_KEY=${APP_KEY} + - APP_URL=${APP_URL} + - SESSION_DRIVER=cookie + - DB_CONNECTION=mysql + - DB_HOST=mysql + - DB_PORT=3306 + - DB_USER=${DB_USER:-pcbuilder} + - DB_PASSWORD=${DB_PASSWORD} + - DB_DATABASE=${DB_DATABASE:-pc_builderv2} + volumes: + - uploads:/app/uploads + depends_on: + mysql: + condition: service_healthy + networks: + - pc-builder + + mysql: + image: mysql/mysql-server:8.0.32 + container_name: pc-builder-mysql + restart: unless-stopped + environment: + MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD} + MYSQL_DATABASE: ${DB_DATABASE:-pc_builderv2} + MYSQL_USER: ${DB_USER:-pcbuilder} + MYSQL_PASSWORD: ${DB_PASSWORD} + volumes: + - mysql_data:/var/lib/mysql + healthcheck: + test: ['CMD', 'mysqladmin', 'ping', '-p${DB_ROOT_PASSWORD}'] + retries: 10 + timeout: 5s + networks: + - pc-builder + + deployer: + build: ./deploy + container_name: pc-builder-deployer + restart: unless-stopped + ports: + - '9000:9000' + environment: + - COMPOSE_DIR=/app + - WEBHOOK_PORT=9000 + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - .:/app:ro + networks: + - pc-builder + +volumes: + mysql_data: + uploads: + +networks: + pc-builder: + driver: bridge