deploy: build production containers and send to ghcr

Pedro Lucas Porcellis porcellis@eletrotupi.com 5 days ago 2413af1abc6efc9954e73e8d3acfc14be7720858
Parents: 28732da
2 file(s) changed
  • .github/workflows/deploy.yml +55 -0
  • api/Dockerfile.production +36 -0
.github/workflows/deploy.yml
@@ -0,0 +1,55 @@
1 + name: Deploy
2 +
3 + on:
4 + push:
5 + branches:
6 + - master # goes for production now, will become staging later on
7 + - production
8 +
9 + env:
10 + REGISTRY: ghcr.io
11 + IMAGE_NAME: ${{ github.repository }}
12 +
13 + jobs:
14 + build-and-push:
15 + name: Build & push image
16 + runs-on: ubuntu-latest
17 + permissions:
18 + contents: read
19 + packages: write
20 +
21 + outputs:
22 + image_tag: ${{ steps.meta.outputs.version }}
23 +
24 + steps:
25 + - name: Checkout
26 + uses: actions/checkout@v4
27 +
28 + - name: Log in to GHCR
29 + uses: docker/login-action@v3
30 + with:
31 + registry: ${{ env.REGISTRY }}
32 + username: ${{ github.actor }}
33 + password: ${{ secrets.GHCR_TOKEN }}
34 +
35 + - name: Docker metadata
36 + id: meta
37 + uses: docker/metadata-action@v5
38 + with:
39 + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
40 + tags: |
41 + # main branch => tag "latest"
42 + type=raw,value=latest,enable=${{ github.ref == 'refs/heads/master' }}
43 + # production branch => tag "production"
44 + # type=raw,value=production,enable=${{ github.ref == 'refs/heads/production' }}
45 + # always tag with short SHA for traceability
46 + type=sha,prefix=,format=short
47 +
48 + - name: Build and push
49 + uses: docker/build-push-action@v5
50 + with:
51 + context: ./api
52 + file: ./api/Dockerfile.production
53 + push: true
54 + tags: ${{ steps.meta.outputs.tags }}
55 + labels: ${{ steps.meta.outputs.labels }}
api/Dockerfile.production
@@ -0,0 +1,36 @@
1 + FROM node:24-alpine3.23 AS deps
2 +
3 + RUN apk add --no-cache build-base yaml-dev
4 +
5 + ARG UID=1000
6 + ARG GID=1000
7 +
8 + USER ${UID}:${GID}
9 + WORKDIR /app
10 +
11 + COPY --chown=${UID}:${GID} package*.json ./
12 + RUN npm ci --frozen-lockfile --omit=dev
13 +
14 + COPY --chown=${UID}:${GID} prisma ./prisma/
15 + RUN npx prisma generate
16 +
17 + # For runtime then:
18 + FROM node:24-alpine3.23
19 +
20 + RUN apk add --no-cache bash postgresql17-client valkey-cli
21 +
22 + ARG UID=1000
23 + ARG GID=1000
24 +
25 + USER ${UID}:${GID}
26 + WORKDIR /app
27 +
28 + COPY --from=deps --chown=${UID}:${GID} /app/node_modules ./node_modules
29 + COPY --from=deps --chown=${UID}:${GID} /app/node_modules/.prisma ./node_modules/.prisma
30 +
31 + COPY --chown=${UID}:${GID} . .
32 +
33 + EXPOSE 3000
34 +
35 + # migrate then start — migrations are idempotent
36 + CMD ["sh", "-c", "npx prisma migrate deploy && npm run start"]