From d2a8ec9e8122b82852f9efc3097b9096a359b5e1 Mon Sep 17 00:00:00 2001 From: Igor Rybakov Date: Sat, 7 Mar 2026 00:11:11 +0200 Subject: [PATCH] CI --- .dockerignore | 8 ++++ .github/workflows/ci.yml | 80 ++++++++++++++++++++++++++++++++-------- apps/api/Dockerfile | 27 ++++++++++++++ apps/web/Dockerfile | 32 ++++++++++++++++ apps/web/next.config.js | 1 + 5 files changed, 132 insertions(+), 16 deletions(-) create mode 100644 .dockerignore create mode 100644 apps/api/Dockerfile create mode 100644 apps/web/Dockerfile diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..c0a191a --- /dev/null +++ b/.dockerignore @@ -0,0 +1,8 @@ +node_modules +.next +dist +.git +.github +*.md +.nx +.vscode diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9c48a91..ae229ec 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,9 +9,14 @@ on: permissions: actions: read contents: read + packages: write + +env: + REGISTRY: ghcr.io + IMAGE_PREFIX: ${{ github.repository }} jobs: - main: + lint-test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -19,26 +24,69 @@ jobs: filter: tree:0 fetch-depth: 0 - # This enables task distribution via Nx Cloud - # Run this command as early as possible, before dependencies are installed - # Learn more at https://nx.dev/ci/reference/nx-cloud-cli#npx-nxcloud-startcirun - # Uncomment this line to enable task distribution - # - run: npx nx start-ci-run --distribute-on="3 linux-medium-js" --stop-agents-after="e2e-ci" - - # Cache node_modules - uses: actions/setup-node@v4 with: node-version: 20 cache: 'npm' - run: npm ci - - run: npx cypress install - uses: nrwl/nx-set-shas@v4 + - run: npx nx affected -t lint test typecheck - # Prepend any command with "nx record --" to record its logs to Nx Cloud - # - run: npx nx record -- echo Hello World - # When you enable task distribution, run the e2e-ci task instead of e2e - - run: npx nx affected -t lint test build typecheck e2e - # Nx Cloud recommends fixes for failures to help you get CI green faster. Learn more: https://nx.dev/ci/features/self-healing-ci - - run: npx nx fix-ci - if: always() + build-api: + runs-on: ubuntu-latest + needs: lint-test + steps: + - uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to GitHub Container Registry + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and push API image + uses: docker/build-push-action@v6 + with: + context: . + file: apps/api/Dockerfile + push: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} + tags: | + ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/api:latest + ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/api:${{ github.sha }} + cache-from: type=gha + cache-to: type=gha,mode=max + + build-web: + runs-on: ubuntu-latest + needs: lint-test + steps: + - uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to GitHub Container Registry + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and push Web image + uses: docker/build-push-action@v6 + with: + context: . + file: apps/web/Dockerfile + push: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} + tags: | + ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/web:latest + ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/web:${{ github.sha }} + cache-from: type=gha + cache-to: type=gha,mode=max diff --git a/apps/api/Dockerfile b/apps/api/Dockerfile new file mode 100644 index 0000000..f245eef --- /dev/null +++ b/apps/api/Dockerfile @@ -0,0 +1,27 @@ +FROM node:20-alpine AS base + +FROM base AS deps +WORKDIR /app +COPY package.json package-lock.json ./ +COPY apps/api/package.json ./apps/api/ +COPY libs/shared/package.json ./libs/shared/ +RUN npm ci --omit=dev + +FROM base AS build +WORKDIR /app +COPY package.json package-lock.json ./ +COPY apps/api/package.json ./apps/api/ +COPY libs/shared/package.json ./libs/shared/ +RUN npm ci +COPY nx.json tsconfig.base.json ./ +COPY libs/ ./libs/ +COPY apps/api/ ./apps/api/ +RUN npx nx build api + +FROM base AS runner +WORKDIR /app +ENV NODE_ENV=production +COPY --from=deps /app/node_modules ./node_modules +COPY --from=build /app/apps/api/dist ./dist +EXPOSE 3000 +CMD ["node", "dist/main.js"] diff --git a/apps/web/Dockerfile b/apps/web/Dockerfile new file mode 100644 index 0000000..c5a1ae4 --- /dev/null +++ b/apps/web/Dockerfile @@ -0,0 +1,32 @@ +FROM node:20-alpine AS base + +FROM base AS deps +WORKDIR /app +COPY package.json package-lock.json ./ +COPY apps/web/package.json ./apps/web/ +COPY libs/shared/package.json ./libs/shared/ +RUN npm ci + +FROM base AS build +WORKDIR /app +COPY --from=deps /app/node_modules ./node_modules +COPY package.json package-lock.json nx.json tsconfig.base.json ./ +COPY libs/ ./libs/ +COPY apps/web/ ./apps/web/ +ENV NEXT_TELEMETRY_DISABLED=1 +RUN npx nx build web + +FROM base AS runner +WORKDIR /app +ENV NODE_ENV=production +ENV NEXT_TELEMETRY_DISABLED=1 +RUN addgroup --system --gid 1001 nodejs +RUN adduser --system --uid 1001 nextjs +COPY --from=build /app/apps/web/.next/standalone ./ +COPY --from=build /app/apps/web/.next/static ./apps/web/.next/static +COPY --from=build /app/apps/web/public ./apps/web/public +USER nextjs +EXPOSE 8888 +ENV PORT=8888 +ENV HOSTNAME="0.0.0.0" +CMD ["node", "apps/web/server.js"] diff --git a/apps/web/next.config.js b/apps/web/next.config.js index 28dc5e8..314cb51 100644 --- a/apps/web/next.config.js +++ b/apps/web/next.config.js @@ -10,6 +10,7 @@ const nextConfig = { // Use this to set Nx-specific options // See: https://nx.dev/recipes/next/next-config-setup nx: {}, + output: 'standalone', async redirects() { return [ {