01FROM node:22-alpine AS build02WORKDIR /app03COPY package*.json ./04RUN npm ci --ignore-scripts05COPY . .06RUN npm run build07FROM node:22-alpine08WORKDIR /app09COPY --from=build /app/dist ./dist10USER node11CMD ["node", "dist/server.js"]
01services:02 app:03 image: ghcr.io/acme/app:${APP_SHA}04 env_file: .env05 depends_on:06 db:07 condition: service_healthy08 restart: unless-stopped09 db:10 image: postgres:17-alpine11 healthcheck:12 test: ["CMD-SHELL", "pg_isready -U app"]13 volumes:14 - db-data:/var/lib/postgresql/data15volumes:16 db-data: {}
01name: deploy02on: { push: { branches: [main] } }03jobs:04 release:05 runs-on: ubuntu-latest06 steps:07 - uses: actions/checkout@v408 - run: npm ci && npm test09 - run: docker build -t app:${{ github.sha }} .10 - name: Deploy immutable image11 run: ./ops/deploy.sh ${{ github.sha }}12 - name: Verify release13 run: curl --fail --retry 6 $HEALTH_URL