diff --git a/.github/workflows/climatemappedafrica-deploy-dev.yml b/.github/workflows/climatemappedafrica-deploy-dev.yml index 804cbaede..4c9d24776 100644 --- a/.github/workflows/climatemappedafrica-deploy-dev.yml +++ b/.github/workflows/climatemappedafrica-deploy-dev.yml @@ -33,6 +33,10 @@ jobs: with: fetch-depth: 0 + # Add support for more platforms with QEMU (optional) + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 @@ -54,10 +58,13 @@ jobs: uses: docker/build-push-action@v3 with: build-args: | - HURUMAP_API_URL=${{ secrets.HURUMAP_HURUMAP_API_URL }} + HURUMAP_API_URL=${{ secrets.CLIMATEMAPPEDAFRICA_HURUMAP_API_URL }} + MONGO_URL=${{ secrets.CLIMATEMAPPEDAFRICA_MONGO_URL }} + PAYLOAD_SECRET=${{ secrets.CLIMATEMAPPEDAFRICA_PAYLOAD_SECRET }} cache-from: type=local,src=/tmp/.buildx-cache cache-to: type=local,dest=/tmp/.buildx-cache-new context: . + platforms: linux/amd64,linux/arm64 target: climatemappedafrica-runner push: true tags: "${{ env.IMAGE_NAME }}:${{ github.sha }}" diff --git a/Dockerfile b/Dockerfile index f8b072f99..4fe65a578 100644 --- a/Dockerfile +++ b/Dockerfile @@ -235,7 +235,7 @@ CMD ["node", "dist/server.js"] # ============================================================================ # -# climatemappedafrica-desp: image with all climatemappedafrica dependencies +# climatemappedafrica-deps: image with all climatemappedafrica dependencies # ------------------------------------------------------------------------- FROM base-deps AS climatemappedafrica-deps @@ -243,6 +243,7 @@ FROM base-deps AS climatemappedafrica-deps COPY packages/hurumap-core/package.json ./packages/hurumap-core/package.json COPY packages/hurumap-next/package.json ./packages/hurumap-next/package.json COPY apps/climatemappedafrica/package.json ./apps/climatemappedafrica/package.json +COPY packages/commons-ui-payload/package.json ./packages/commons-ui-payload/package.json # Use virtual store: https://pnpm.io/cli/fetch#usage-scenario RUN pnpm --filter "./apps/climatemappedafrica" install --offline --frozen-lockfile @@ -264,6 +265,9 @@ ARG NEXT_TELEMETRY_DISABLED \ NEXT_PUBLIC_IMAGE_DOMAINS="cms.dev.codeforafrica.org,hurumap-v2.s3.amazonaws.com" \ NEXT_PUBLIC_IMAGE_SCALE_FACTOR=2 \ NEXT_PUBLIC_GOOGLE_ANALYTICS \ + # Payload (runtime) + MONGO_URL \ + PAYLOAD_SECRET \ # Sentry (build time) SENTRY_AUTH_TOKEN \ SENTRY_ENVIRONMENT \ @@ -279,7 +283,15 @@ COPY --from=climatemappedafrica-deps /workspace/apps/climatemappedafrica/node_mo COPY apps/climatemappedafrica ./apps/climatemappedafrica -RUN pnpm --filter "./apps/climatemappedafrica" build +# When building Next.js app, Next.js needs to connect to local Payload +ENV PAYLOAD_PUBLIC_APP_URL=http://localhost:3000 +ENV NEXT_PUBLIC_SEO_DISABLED=${NEXT_PUBLIC_SEO_DISABLED} +RUN --mount=type=secret,id=sentry_auth_token,env=SENTRY_AUTH_TOKEN \ + pnpm --filter "./apps/climatemappedafrica" build-next + +# When building Payload app, Payload needs to have final app URL +ENV PAYLOAD_PUBLIC_APP_URL=${NEXT_PUBLIC_APP_URL} +RUN pnpm --filter "./apps/climatemappedafrica" build-payload # # climatemappedafrica-runner: final deployable image @@ -287,15 +299,16 @@ RUN pnpm --filter "./apps/climatemappedafrica" build FROM base-runner AS climatemappedafrica-runner -ARG NEXT_PUBLIC_IMAGE_DOMAINS \ - NEXT_PUBLIC_IMAGE_SCALE_FACTOR \ - NEXT_PUBLIC_OPENAFRICA_DOMAINS \ - NEXT_PUBLIC_SOURCEAFRICA_DOMAINS +ARG PAYLOAD_CONFIG_PATH="dist/payload.config.js" \ + PAYLOAD_PUBLIC_APP_URL -ENV NEXT_PUBLIC_IMAGE_DOMAINS=${NEXT_PUBLIC_IMAGE_DOMAINS} \ - NEXT_PUBLIC_IMAGE_SCALE_FACTOR=${NEXT_PUBLIC_IMAGE_SCALE_FACTOR} \ - NEXT_PUBLIC_OPENAFRICA_DOMAINS=${NEXT_PUBLIC_OPENAFRICA_DOMAINS} \ - NEXT_PUBLIC_SOURCEAFRICA_DOMAINS=${NEXT_PUBLIC_SOURCEAFRICA_DOMAINS} +# DO NOT initialise ENV vars using ARG for secrets!!!! +# These include: +# i. Mongo DB URL +# ii. Payload Secret +# ENV are persisted in the image & may lead to security issues +ENV PAYLOAD_PUBLIC_APP_URL=${PAYLOAD_PUBLIC_APP_URL} \ + PAYLOAD_CONFIG_PATH=${PAYLOAD_CONFIG_PATH} RUN set -ex \ # Create nextjs cache dir w/ correct permissions @@ -306,21 +319,29 @@ RUN set -ex \ # symlink some dependencies COPY --from=climatemappedafrica-builder --chown=nextjs:nodejs /workspace/node_modules ./node_modules +# Since we can't use output: "standalone", copy all app's dependencies +COPY --from=climatemappedafrica-builder --chown=nextjs:nodejs /workspace/apps/climatemappedafrica/node_modules ./apps/climatemappedafrica/node_modules +COPY --from=climatemappedafrica-builder --chown=nextjs:nodejs /workspace/apps/climatemappedafrica/next.config.js ./apps/climatemappedafrica/next.config.js +COPY --from=climatemappedafrica-builder --chown=nextjs:nodejs /workspace/apps/climatemappedafrica/.env ./apps/climatemappedafrica/.env # Next.js # Public assets COPY --from=climatemappedafrica-builder --chown=nextjs:nodejs /workspace/apps/climatemappedafrica/public ./apps/climatemappedafrica/public -# Automatically leverage output traces to reduce image size -# https://nextjs.org/docs/advanced-features/output-file-tracing -COPY --from=climatemappedafrica-builder --chown=nextjs:nodejs /workspace/apps/climatemappedafrica/.next/standalone ./apps/climatemappedafrica -COPY --from=climatemappedafrica-builder --chown=nextjs:nodejs /workspace/apps/climatemappedafrica/.next/static ./apps/climatemappedafrica/.next/static +# Since we can't use output: "standalone", copy the whole app's .next folder +# TODO(kilemensi): Figure out which files in .next folder are not needed +COPY --from=climatemappedafrica-builder --chown=nextjs:nodejs /workspace/apps/climatemappedafrica/.next ./apps/climatemappedafrica/.next -USER nextjs +# Payload +COPY --from=climatemappedafrica-builder /workspace/apps/climatemappedafrica/dist ./apps/climatemappedafrica/dist +COPY --from=climatemappedafrica-builder /workspace/apps/climatemappedafrica/build ./apps/climatemappedafrica/build -# server.js is created by next build from the standalone output -# https://nextjs.org/docs/pages/api-reference/next-config-js/output -CMD ["node", "apps/climatemappedafrica/server.js"] +# Since we can't use output: "standalone", switch to specific app's folder +WORKDIR /workspace/apps/climatemappedafrica + +USER nextjs +# Custom server to run Payload and Next.js in the same app +CMD ["node", "dist/server.js"] # ============================================================================ # CivicSignal Blog diff --git a/apps/climatemappedafrica/payload.config.ts b/apps/climatemappedafrica/payload.config.ts index 9f7505efe..6d65eb688 100644 --- a/apps/climatemappedafrica/payload.config.ts +++ b/apps/climatemappedafrica/payload.config.ts @@ -16,7 +16,7 @@ import Members from "./src/payload/collections/Members"; import Pages from "./src/payload/collections/Pages"; import Users from "./src/payload/collections/Users"; -import Site from "./src/payload/globals/Site"; +import Site from "./src/payload/globals/site"; const projectDir = process.cwd(); loadEnvConfig(projectDir); diff --git a/docker-compose.yml b/docker-compose.yml index 4f0f5ec5d..6c4d40382 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -83,12 +83,22 @@ services: target: climatemappedafrica-runner args: - HURUMAP_API_URL + - MONGO_URL=mongodb://${MONGO_INITDB_ROOT_USERNAME:-root}:${MONGO_INITDB_ROOT_PASSWORD:-rootpassword}@host.docker.internal:${MONGODB_PORT:-27017}/climatemappedafrica?authSource=admin&directConnection=true + - PAYLOAD_SECRET + - SENTRY_ENVIRONMENT + - SENTRY_ORG + - SENTRY_PROJECT environment: HURUMAP_API_URL: ${HURUMAP_API_URL} S3_UPLOAD_KEY: ${S3_UPLOAD_KEY} S3_UPLOAD_SECRET: ${S3_UPLOAD_SECRET} S3_UPLOAD_BUCKET: ${S3_UPLOAD_BUCKET} S3_UPLOAD_REGION: ${S3_UPLOAD_REGION} + MONGO_URL: mongodb://${MONGO_INITDB_ROOT_USERNAME:-root}:${MONGO_INITDB_ROOT_PASSWORD:-rootpassword}@host.docker.internal:${MONGODB_PORT:-27017}/climatemappedafrica?authSource=admin&directConnection=true + PAYLOAD_SECRET: ${PAYLOAD_SECRET} + SENTRY_ORG: ${SENTRY_ORG} + SENTRY_ENVIRONMENT: ${SENTRY_ENVIRONMENT} + SENTRY_PROJECT: ${SENTRY_PROJECT} ports: - 3000:3000