diff --git a/.github/workflows/cd.yaml b/.github/workflows/cd.yaml deleted file mode 100644 index 3465264..0000000 --- a/.github/workflows/cd.yaml +++ /dev/null @@ -1,69 +0,0 @@ -name: Deploy Template Application - -on: - push: - branches: - - main - -concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: true - -jobs: - deploy: - runs-on: self-hosted - steps: - - name: Checkout repository - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: '24' - - - name: Install pnpm - run: | - npm install -g pnpm@latest - pnpm --version - - - name: Deploy to c4g.dev server - run: | - touch .env - echo 'DATABASE_PW=${{ secrets.DATABASE_PW }}' >> .env - echo 'DATABASE_USER=${{ secrets.DATABASE_USER }}' >> .env - echo 'DATABASE_NAME=${{ secrets.DATABASE_NAME }}' >> .env - echo 'DATABASE_HOST=${{ secrets.DATABASE_HOST }}' >> .env - echo 'DATABASE_PORT=${{ secrets.DATABASE_PROD_PORT }}' >> .env - echo 'DATABASE_URL=${{ secrets.DATABASE_PROD_URL }}' >> .env - echo 'AUTH_SECRET=${{ secrets.AUTH_SECRET }}' >> .env - echo 'AUTH_GOOGLE_ID=${{ secrets.AUTH_GOOGLE_ID }}' >> .env - echo 'AUTH_GOOGLE_SECRET=${{ secrets.AUTH_GOOGLE_SECRET }}' >> .env - echo 'RESEND_API_KEY=${{ secrets.RESEND_API_KEY }}' >> .env - echo 'NEXT_PUBLIC_VAPID_PUBLIC_KEY=${{ secrets.NEXT_PUBLIC_VAPID_PUBLIC_KEY }}' >> .env - echo 'VAPID_PRIVATE_KEY=${{ secrets.VAPID_PRIVATE_KEY }}' >> .env - echo 'NEXTAUTH_URL=https://template.c4g.dev' >> .env - echo 'AUTH_TRUST_HOST=true' >> .env - - # Build and start Docker containers (will replace running ones) - docker compose --profile production up --build -d --remove-orphans - - # Wait for services to be healthy - echo "Waiting for services to start..." - for i in {1..60}; do - if docker compose ps | grep -q "template-app.*healthy"; then - echo "Services are running successfully!" - break - fi - if [ $i -eq 60 ]; then - echo "Services failed to start" - docker compose logs - exit 1 - fi - echo "Waiting... (attempt $i/60)" - sleep 2 - done - - # Clean up old images from this project only - docker image prune -f --filter label=com.docker.compose.project=template diff --git a/Dockerfile b/Dockerfile index b6eb980..a073463 100644 --- a/Dockerfile +++ b/Dockerfile @@ -56,14 +56,23 @@ RUN adduser --system --uid 1001 nextjs # Install wget for healthcheck RUN apk add --no-cache wget -# Copy necessary files from builder -COPY --from=builder /app/public ./public -COPY --from=builder /app/.next/standalone ./ -COPY --from=builder /app/.next/static ./.next/static -COPY --from=builder /app/prisma ./prisma - -# Set correct permissions -RUN chown -R nextjs:nodejs /app +# Copy necessary files from builder with correct ownership +COPY --from=builder --chown=nextjs:nodejs /app/public ./public +COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ +COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static +COPY --from=builder --chown=nextjs:nodejs /app/prisma ./prisma +COPY --from=builder --chown=nextjs:nodejs /app/prisma.config.ts ./prisma.config.ts +COPY --from=builder --chown=nextjs:nodejs /app/package.json ./package.json +COPY --from=builder --chown=nextjs:nodejs /app/pnpm-lock.yaml ./pnpm-lock.yaml + +# Copy node_modules with Prisma from builder with correct ownership +COPY --from=builder --chown=nextjs:nodejs /app/node_modules/.bin/prisma ./node_modules/.bin/prisma +COPY --from=builder --chown=nextjs:nodejs /app/node_modules/.bin/tsx ./node_modules/.bin/tsx +COPY --from=builder --chown=nextjs:nodejs /app/node_modules/.pnpm ./node_modules/.pnpm +COPY --from=builder --chown=nextjs:nodejs /app/node_modules/prisma ./node_modules/prisma +COPY --from=builder --chown=nextjs:nodejs /app/node_modules/@prisma ./node_modules/@prisma +COPY --from=builder --chown=nextjs:nodejs /app/node_modules/dotenv ./node_modules/dotenv +COPY --from=builder --chown=nextjs:nodejs /app/node_modules/tsx ./node_modules/tsx USER nextjs diff --git a/docker-compose.yml b/docker-compose.yml index 4981cc8..13770bb 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -10,7 +10,7 @@ services: volumes: - template-db-data:/var/lib/postgresql/data healthcheck: - test: ["CMD-SHELL", "pg_isready -U ${DATABASE_USER}"] + test: ["CMD-SHELL", "pg_isready -U ${DATABASE_USER} -d ${DATABASE_NAME}"] interval: 5s timeout: 5s retries: 5 @@ -40,9 +40,16 @@ services: - VAPID_PRIVATE_KEY=${VAPID_PRIVATE_KEY} - NEXTAUTH_URL=${NEXTAUTH_URL:-http://localhost:3000} - AUTH_TRUST_HOST=${AUTH_TRUST_HOST:-true} + command: > + sh -c " + echo 'Running database migrations...' && + ./node_modules/.bin/prisma migrate deploy && + echo 'Migrations completed, starting application...' && + node server.js + " depends_on: - template-migrate: - condition: service_completed_successfully + template-db: + condition: service_healthy healthcheck: test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:3000/api/health || exit 1"] interval: 10s @@ -52,35 +59,5 @@ services: profiles: - production - # Database migration container (production only) - template-migrate: - build: - context: . - dockerfile: Dockerfile - target: builder - environment: - - DATABASE_URL=postgresql://${DATABASE_USER}:${DATABASE_PW}@template-db:5432/${DATABASE_NAME} - - DATABASE_PW=${DATABASE_PW} - - DATABASE_USER=${DATABASE_USER} - - DATABASE_NAME=${DATABASE_NAME} - - DATABASE_HOST=template-db - - DATABASE_PORT=5432 - command: > - sh -c " - apk add --no-cache netcat-openbsd && - echo 'Waiting for database to be ready...' && - while ! nc -z template-db 5432; do - sleep 1 - done && - echo 'Database is ready, running migrations...' && - pnpm exec prisma migrate deploy && - echo 'Migrations completed successfully!' - " - depends_on: - template-db: - condition: service_healthy - profiles: - - production - volumes: template-db-data: \ No newline at end of file