From 3cbe2ab8b1dc514a82310a2f9bc267a4ae1be1e6 Mon Sep 17 00:00:00 2001 From: Mrugesh Mohapatra <1884376+raisedadead@users.noreply.github.com> Date: Tue, 7 Oct 2025 10:49:41 +0530 Subject: [PATCH] fix(tools): consolidate docker compose setup (#62525) --- .github/workflows/e2e-playwright.yml | 2 +- .github/workflows/e2e-third-party.yml | 2 +- .gitpod.yml | 3 +- api/README.md | 46 -------------------- api/src/plugins/mail-providers/nodemailer.ts | 4 +- api/src/utils/env.ts | 7 ++- docker-compose.yml | 39 ----------------- docker/api/docker-compose.yml | 14 ------ docker/docker-compose.e2e.yml | 19 ++++++++ {api/tools => docker}/docker-compose.yml | 7 +++ e2e/utils/mailhog.ts | 7 ++- 11 files changed, 43 insertions(+), 107 deletions(-) delete mode 100644 api/README.md delete mode 100644 docker-compose.yml delete mode 100644 docker/api/docker-compose.yml create mode 100644 docker/docker-compose.e2e.yml rename {api/tools => docker}/docker-compose.yml (86%) diff --git a/.github/workflows/e2e-playwright.yml b/.github/workflows/e2e-playwright.yml index e759fa26b9e..9aa1ec36ec1 100644 --- a/.github/workflows/e2e-playwright.yml +++ b/.github/workflows/e2e-playwright.yml @@ -160,7 +160,7 @@ jobs: - name: Start apps run: | - docker compose up -d + docker compose -f docker/docker-compose.yml -f docker/docker-compose.e2e.yml up -d pnpm run serve:client-ci & sleep 10 diff --git a/.github/workflows/e2e-third-party.yml b/.github/workflows/e2e-third-party.yml index 7a4a33be269..97c2bd8401f 100644 --- a/.github/workflows/e2e-third-party.yml +++ b/.github/workflows/e2e-third-party.yml @@ -152,7 +152,7 @@ jobs: - name: Start apps run: | - docker compose up -d + docker compose -f docker/docker-compose.yml -f docker/docker-compose.e2e.yml up -d pnpm run serve:client-ci & sleep 10 diff --git a/.gitpod.yml b/.gitpod.yml index 8bc673b170a..bf61e9b5259 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -42,8 +42,7 @@ tasks: - name: db # starting mongod in background, so it doesn't block prebuilds before: > - cd api/tools && - docker compose up -d + docker compose -f docker/docker-compose.yml up -d - name: server before: export COOKIE_DOMAIN=.gitpod.io && export HOME_LOCATION=$(gp url 8000) && export API_LOCATION=$(gp url 3000) diff --git a/api/README.md b/api/README.md deleted file mode 100644 index c0e31d88c90..00000000000 --- a/api/README.md +++ /dev/null @@ -1,46 +0,0 @@ -# Working on the new api - -## Connecting to local database - -The api uses the ORM Prisma and it needs the MongoDB instance to be a replica set. - -### Atlas - -If you use MongoDB Atlas, the set is managed for you. - -### Local - -The simplest way to run a replica set locally is to use the docker-compose file -in /tools. - -```bash -cd tools -docker compose up -d -``` - -The new db will be empty, so you can run the seed script to populate it. - -```bash -cd ../.. # back to the root of the repo -pnpm seed -``` - -### Troubleshooting - -If you have any issues connecting to the database (e.g. MongoServerError: not primary), try removing the volume and recreating the containers. - -```bash -cd tools -docker compose down -v -docker compose up -d -``` - -## Login in development/testing - -During development and testing, the api exposes the endpoint GET auth/dev-callback. Calling this will log you in as the user with the email `foo@bar.com` by setting the session cookie for that user. - -## Generating Exams - -```bash -pnpm run exam-env:generate -``` diff --git a/api/src/plugins/mail-providers/nodemailer.ts b/api/src/plugins/mail-providers/nodemailer.ts index 7adf31b04f3..66009bde278 100644 --- a/api/src/plugins/mail-providers/nodemailer.ts +++ b/api/src/plugins/mail-providers/nodemailer.ts @@ -1,7 +1,7 @@ import nodemailer, { Transporter } from 'nodemailer'; import { MailProvider, SendEmailArgs } from '../mailer.js'; -import { MAILHOG_HOST } from '../../utils/env.js'; +import { MAILPIT_HOST } from '../../utils/env.js'; /** * NodemailerProvider is a wrapper around nodemailer that provides a clean @@ -16,7 +16,7 @@ export class NodemailerProvider implements MailProvider { */ constructor() { this.transporter = nodemailer.createTransport({ - host: MAILHOG_HOST, + host: MAILPIT_HOST, secure: false, port: 1025, auth: { diff --git a/api/src/utils/env.ts b/api/src/utils/env.ts index 0876dc13329..f03ccb46d19 100644 --- a/api/src/utils/env.ts +++ b/api/src/utils/env.ts @@ -159,7 +159,12 @@ if (process.env.FREECODECAMP_NODE_ENV !== 'development') { export const HOME_LOCATION = process.env.HOME_LOCATION; // Mailpit is used in development and test environments, hence the localhost // default. -export const MAILHOG_HOST = process.env.MAILHOG_HOST ?? 'localhost'; +// TODO: Remove MAILHOG_HOST in a few months +// We renamed MailHog to MailPit, but kept the same port and API +// This is to keep backward compatibility with existing setups +// that might still use MAILHOG_HOST environment variable +export const MAILPIT_HOST = + process.env.MAILPIT_HOST ?? process.env.MAILHOG_HOST ?? 'localhost'; export const MONGOHQ_URL = process.env.NODE_ENV === 'test' ? createTestConnectionURL( diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index 402f38e46f9..00000000000 --- a/docker-compose.yml +++ /dev/null @@ -1,39 +0,0 @@ -services: - mongo: - image: mongo - ports: - - '27017:27017' - command: mongod --replSet rs0 - setup: - image: mongo - depends_on: - - mongo - restart: on-failure - entrypoint: [ - 'bash', - '-c', - # This will try to initiate the replica set, until it succeeds twice (i.e. until the replica set is already initialized) - 'mongosh --host mongo:27017 --eval ''try {rs.initiate();} catch (err) { if(err.codeName !== "AlreadyInitialized") throw err };''' - ] - mailpit: - restart: unless-stopped - image: axllent/mailpit - ports: - - '1025:1025' - - '8025:8025' - api: - restart: unless-stopped - depends_on: - - mongo - - mailpit - image: fcc-api - env_file: - - .env - environment: - # The api cannot connect to mongodb or mailpit via localhost from inside the - # container, so we have to override these variables. - - MONGOHQ_URL=mongodb://mongo:27017/freecodecamp?directConnection=true - - MAILHOG_HOST=mailpit - - HOST=0.0.0.0 - ports: - - '3000:3000' diff --git a/docker/api/docker-compose.yml b/docker/api/docker-compose.yml deleted file mode 100644 index fd4e927a44a..00000000000 --- a/docker/api/docker-compose.yml +++ /dev/null @@ -1,14 +0,0 @@ -services: - api: - restart: unless-stopped - image: fcc-api - env_file: - - ../../.env - ports: - - '3000:3000' - logging: - driver: 'local' - options: - max-size: '10m' - max-file: '3' - compress: 'true' diff --git a/docker/docker-compose.e2e.yml b/docker/docker-compose.e2e.yml new file mode 100644 index 00000000000..0da4ecce0b3 --- /dev/null +++ b/docker/docker-compose.e2e.yml @@ -0,0 +1,19 @@ +# Docker Compose override for E2E testing +# Usage: docker compose -f docker/docker-compose.yml -f docker/docker-compose.e2e.yml up -d +services: + api: + restart: unless-stopped + depends_on: + - db + - mailpit + image: fcc-api + env_file: + - ../.env + environment: + # The api cannot connect to mongodb or mailpit via localhost from inside the + # container, so we have to override these variables. + - MONGOHQ_URL=mongodb://db:27017/freecodecamp?directConnection=true + - MAILHOG_HOST=mailpit + - HOST=0.0.0.0 + ports: + - '3000:3000' diff --git a/api/tools/docker-compose.yml b/docker/docker-compose.yml similarity index 86% rename from api/tools/docker-compose.yml rename to docker/docker-compose.yml index 070fcccc3a7..c7b1b731681 100644 --- a/api/tools/docker-compose.yml +++ b/docker/docker-compose.yml @@ -29,6 +29,13 @@ services: } ' + mailpit: + restart: unless-stopped + image: axllent/mailpit + ports: + - '1025:1025' + - '8025:8025' + volumes: db-data: driver: local diff --git a/e2e/utils/mailhog.ts b/e2e/utils/mailhog.ts index 9c3d0f0a042..513b21970bc 100644 --- a/e2e/utils/mailhog.ts +++ b/e2e/utils/mailhog.ts @@ -11,7 +11,12 @@ type AllEmails = { count: number; }; -const host = process.env.MAILHOG_HOST || 'localhost'; +// TODO: Remove MAILHOG_HOST in a few months +// We renamed MailHog to MailPit, but kept the same port and API +// This is to keep backward compatibility with existing setups +// that might still use MAILHOG_HOST environment variable +const host = + process.env.MAILPIT_HOST || process.env.MAILHOG_HOST || 'localhost'; export const getAllEmails = async (): Promise => { const res = await fetch(`http://${host}:8025/api/v1/messages`);