From 046ee1856d20ff222d83f694fb8f44744ac17a12 Mon Sep 17 00:00:00 2001 From: Eric Bouchut Date: Tue, 26 May 2026 11:12:08 +0200 Subject: [PATCH 1/5] feat(mongo): Add MongoDB service and environment variables to .env - Rename the `db` service to `postgres`. - Add `mongo` service to docker-compose - Add a bridge network and a named `mongo_data` volume to Mongo data. - Add Mongo-specific environment variables to `.env.example`: --- .env.example | 43 ++++++++++++++++++--- README.md | 59 +++++++++++++++++++++++------ docker-compose.yaml | 35 ++++++++++++++--- docker/mongo/init/.gitkeep | 0 src/main/resources/application.yaml | 7 +++- 5 files changed, 122 insertions(+), 22 deletions(-) create mode 100644 docker/mongo/init/.gitkeep diff --git a/.env.example b/.env.example index 98cfe7b..84d808d 100644 --- a/.env.example +++ b/.env.example @@ -6,11 +6,11 @@ # - configure the Docker external port mapping for the postgres container # # Procedure: -# - Set a value for POSTGRES_PASSWORD, and LEARNDEV_DB_PASSWORD. +# - Set a value for POSTGRES_PASSWORD, LEARNDEV_DB_PASSWORD, MONGO_ROOT_PASSWORD # - Leave other variables unchanged because defaults are fine. # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# ~~~ Postgres Docker container port mapping ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# ~~~ External port mapping for the postgres Docker container ~~~~~~~~~~~~~~~~~~~~~ # Host port mapped to the internal Postgres container's port 5432. # Only the host side is configurable here. 5432 is fixed inside the container. @@ -22,7 +22,7 @@ POSTGRES_PORT=5433 # Exposed postgres host network interface. # Docker accepts incoming requests on this interface and routes them # to Postgres running in the Docker container. -# Default value is 0.0.0.0 (IP v4)) and :: (IP V6), +# Default value (if unset) is 0.0.0.0 (IP v4) and :: (IP V6), # meaning all network interfaces. # See: https://docs.docker.com/engine/reference/commandline/run/#publish # @@ -55,13 +55,13 @@ POSTGRES_HOST_AUTH_METHOD=scram-sha-256 POSTGRES_PASSWORD=TODO_SET_A_VALUE_HERE -# ~~~ Application database and user ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# ~~~ Postgres application database and user ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Created by docker/init/01-create-app-db-user.sh **on first** container start. # These variables are also referenced in Spring Boot's application.yaml # configuration file to configure the datasource. # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# Name of the application database. +# Name of the (Postgres) application database, # LEARNDEV_DB_NAME=learndev @@ -75,6 +75,39 @@ LEARNDEV_DB_USER=learndev LEARNDEV_DB_PASSWORD=TODO_SET_A_VALUE_HERE +# ~~~~ MongoDB ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +# Name of the MongoDB admin user +# +MONGO_ROOT_USERNAME=mongoadmin + +# Password for the MongoDB admin user +# +MONGO_ROOT_PASSWORD=TODO_SET_A_VALUE_HERE + +# Name of the MongoDB application database +# +MONGO_DB_NAME=learndev + + +# ~~~ External port mapping for the mongo Docker Compose service ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +# Exposed MongoDB host network interface. +# Docker accepts incoming requests on this interface and routes them +# to MongoDB running in the Docker container. +# Default value (**if unset**) is 0.0.0.0 (IP v4) and :: (IP V6), +# meaning all network interfaces. +# See: https://docs.docker.com/engine/reference/commandline/run/#publish +# +MONGO_HOST=127.0.0.1 + +# MongoDB port mapped to the internal Postgres container's port 27017. +# Only the host side is configurable here. 27017 is fixed inside the container. +# Use a non-standard port (e.g. 27018) to avoid clashing with a local MongoDB install. +# +MONGO_PORT=27018 + + # ~~~~ Spring Boot ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Default Spring Boot active profile: dev diff --git a/README.md b/README.md index beccd4b..757f291 100644 --- a/README.md +++ b/README.md @@ -69,25 +69,62 @@ See the [Tech Stack](#tech-stack) section. ### Installation -TODO +- Clone the `ebouchut/learn-dev` Git Repository +- Install Docker, Docker Desktop, and Docker Compose + +#### Clone the Git repository + +```shell +# +git clone git@github.com:ebouchut/learn-dev.git +# git clone https://github.com/ebouchut/learn-dev.git + +cd learn-dev +``` #### Docker Setup From the project root folder. +Install _Docker_ and _Docker Compose_: -- Install Docker - - on macOS (read [this for Windows or Linux install](https://docs.docker.com/get-started/get-docker/)): - ```shell - brew install docker docker-compose docker-desktop - ``` - - on [Windows and Linux](https://docs.docker.com/get-started/get-docker/) -- Downloads the Docker images for this application, - then runs the containers configured in the `docker-compose.yaml` configuration file: +- on macOS (read [this for Windows or Linux install](https://docs.docker.com/get-started/get-docker/)): + ```shell + brew install docker docker-compose docker-desktop + ``` +- on [Windows and Linux](https://docs.docker.com/get-started/get-docker/) + + +## Configuration + +- Edit `.env` + - [ ] Set a value for the variables `POSTGRES_PASSWORD`, `LEARNDEV_DB_PASSWORD`, `MONGO_ROOT_PASSWORD` + + +## Run the application + +- Start all the Docker containers for the application: ```shell docker compose up -d - docker compose logs ``` - A Docker init script creates the application database and user when the `learn-dev-postgres` container + +This command downloads the Docker image **for each service** +declared in the Docker Compose configuration file +(`docker-compose.yaml`), and starts a Docker container based on this image. + +- postgres +- mongo + + +### Run Postgres + +- Install the Docker images for this application, + then runs the services/containers as configured in the `docker-compose.yaml`: + ```shell + docker compose up -d postgres + docker compose ps + docker compose logs postgres + ``` + A Docker init script creates the application database and user when the `postgres` service is run for the first time. - Run the application: TODO diff --git a/docker-compose.yaml b/docker-compose.yaml index 15be136..f488a12 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,24 +1,49 @@ services: - db: + postgres: image: postgres:17 - container_name: learn-dev-postgres - # Inject database credentials and config (db name, db user, # and host port mapping) into the container. # Reads from the same .env file passed to `docker compose --env-file ...`. env_file: - .env - volumes: # Init scripts: run once on first container start (empty data dir). - ./docker/init:/docker-entrypoint-initdb.d # Named volume: preserves data across container stop/start cycles. - pgdata:/var/lib/postgresql/data - ports: # See src/main/resources/.env.example for details - "${POSTGRES_HOST}:${POSTGRES_PORT}:5432" + mongo: + image: mongo:8.0 + restart: unless-stopped + ports: + - "${MONGO_HOST}${MONGO_HOST:+:}${MONGO_PORT:-27017}:27017" + environment: + MONGO_INITDB_ROOT_USERNAME: ${MONGO_ROOT_USERNAME} + MONGO_INITDB_ROOT_PASSWORD: ${MONGO_ROOT_PASSWORD} + MONGO_INITDB_DATABASE: ${MONGO_DB_NAME:-learndev} + volumes: + - mongo_data:/data/db + - ./docker/mongo/init:/docker-entrypoint-initdb.d:ro + networks: + - learn-dev-net + healthcheck: + test: ["CMD", "mongosh", "--quiet", "--eval", "db.adminCommand('ping').ok"] + interval: 10s + timeout: 5s + retries: 5 + start_period: 20s + +networks: + learn-dev-net: + # A bridge network connects your services together + # on an isolated Virtual LAN managed by Docker. + driver: bridge + +# Named volumes used to preserve data across container stop/start cycles. volumes: pgdata: + mongo_data: diff --git a/docker/mongo/init/.gitkeep b/docker/mongo/init/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index bc4f532..e26c844 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -2,8 +2,13 @@ spring: application: name: learn-dev + data: + mongodb: + # uri: mongodb://admin:admin_password@127.0.0.1:27018/learndev?authSource=admin + uri: mongodb://${MONGO_ROOT_USER}:${MONGO_ROOT_PASSWORD}@${MONGO_HOST}${MONGO_HOST:+:}${MONGO_PORT}/${MONGO_DB_NAME}?authSource=admin + # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - # Database Connection Configuration + # Database Connection Configuration No. Done # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ datasource: # url: jdbc:postgresql://127.0.0.1:5433/learndev From 46e7a5a028bcc2e84e96660de584ad42b6129ab4 Mon Sep 17 00:00:00 2001 From: Eric Bouchut Date: Thu, 28 May 2026 09:53:31 +0200 Subject: [PATCH 2/5] docs: Update Docker Compose usage - Update sections about how to run the app and start all the services/container - Add sections about how to start / stop / remove the Postgres database --- README.md | 111 +++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 94 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 757f291..9a5ef72 100644 --- a/README.md +++ b/README.md @@ -102,31 +102,108 @@ Install _Docker_ and _Docker Compose_: ## Run the application -- Start all the Docker containers for the application: +This starts all the Docker services for the application: + ```shell docker compose up -d ``` -This command downloads the Docker image **for each service** -declared in the Docker Compose configuration file -(`docker-compose.yaml`), and starts a Docker container based on this image. +**For each service** (`postgres`, `mongo`) +declared in the *Docker Compose* configuration file +(`docker-compose.yaml`), *Docker Compose*: -- postgres -- mongo +1. downloads the Docker image (if not cached yet) from the Docker Hub registry, +2. stores the downloaded image in the local Docker image cache, +3. starts a Docker container based on this image (if it is not already running). +### Docker Terminology -### Run Postgres +I use ** Docker Compose** (a CLI tool) to describe and handle the lifecycle of services that comprise my application. -- Install the Docker images for this application, - then runs the services/containers as configured in the `docker-compose.yaml`: - ```shell - docker compose up -d postgres - docker compose ps - docker compose logs postgres - ``` - A Docker init script creates the application database and user when the `postgres` service - is run for the first time. -- Run the application: TODO +A **service** is basically a component of the application packaged as a Docker container. +It specifies the Docker image and version, configuration, and the network and Docker volume(s) if any. + +A Docker image is pre-packaged piece of software that can work as a standalone on Linux. +**Docker Hub** is a public registry that hosts and serves public Docker images. + + +### Postgres Service + +#### Run Postgres + +Running the app using `docker compose up -d` +starts **all** the application services (`postgres` and `mongo`). + +To only start the `potsgres` service: + +```shell +docker compose up -d postgres +docker compose logs postgres +``` +> [!NOTE] +> +> The above command downloads, installs the `postgres` Docker image +> specified by the `postgres` service in `docker-compose.yaml`. +> Then it runs a Docker container with this image. + +> [!NOTE] +> A Docker init script automatically **creates the database user and the application database** +> when the **`postgres`** service is run **for the first time**. + +Now, check that it is running: + +```shell +docker compose ps | grep postgres +``` + +> To recreate the database, and start from scratch you need to stop the `postgres` container +> and remove the (data) volumes. +> See the `Remove all Posgres Databases` section for details. + +#### Stop Postgres + +```shell +docker compose down postgres +``` + +#### Remove all Postgres Databases + +> [!CAUTION] +> This **destructive command** will **remove all the databases (structure and content)** +> created by Postgres running in the container. + +```shell +docker compose down -v postgres +``` + +The `v` option is the key here, it asks Docker to **remove** the **volume** of the `postgres` service. +This volume persists the postgres data outside the container, on the host **OS**. + + +### Mongo Service + +#### Start MongoDB + +```shell +docker compose up mongo +``` + +#### Stop MongoDB + +```shell +docker compose down mongo +``` + +#### Remove MongoDB and its Databases + +> [!CAUTION] +> This **destructive command** will **remove MongoDB and all its databases** +> created by MongoDB running in the container. + +```shell +docker compose down -v mongo +``` + ## Project Status From 6986f8dae57bef3613f845382f5e46a05bee1102 Mon Sep 17 00:00:00 2001 From: Eric Bouchut Date: Thu, 28 May 2026 16:23:20 +0200 Subject: [PATCH 3/5] docs: Fix sections about how to start/stop a container --- README.md | 53 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 9a5ef72..070824a 100644 --- a/README.md +++ b/README.md @@ -116,6 +116,15 @@ declared in the *Docker Compose* configuration file 2. stores the downloaded image in the local Docker image cache, 3. starts a Docker container based on this image (if it is not already running). +## Stop the Application + +This stops all the Docker services for the application: + + ```shell + docker compose down + ``` + + ### Docker Terminology I use ** Docker Compose** (a CLI tool) to describe and handle the lifecycle of services that comprise my application. @@ -129,15 +138,15 @@ A Docker image is pre-packaged piece of software that can work as a standalone o ### Postgres Service -#### Run Postgres +#### Start Postgres Running the app using `docker compose up -d` -starts **all** the application services (`postgres` and `mongo`). +starts **all** the application services, including `postgres`. -To only start the `potsgres` service: +To only start the `postgres` service: ```shell -docker compose up -d postgres +docker compose start -d postgres docker compose logs postgres ``` > [!NOTE] @@ -150,7 +159,7 @@ docker compose logs postgres > A Docker init script automatically **creates the database user and the application database** > when the **`postgres`** service is run **for the first time**. -Now, check that it is running: +Now, check that `postgres` is running: ```shell docker compose ps | grep postgres @@ -163,47 +172,55 @@ docker compose ps | grep postgres #### Stop Postgres ```shell -docker compose down postgres +docker compose stop postgres ``` #### Remove all Postgres Databases +Stops and remove the `postgres` container and its data volume. + > [!CAUTION] -> This **destructive command** will **remove all the databases (structure and content)** -> created by Postgres running in the container. +> This is a **destructive command** that will **remove all the databases +> (structure and content)** created by Postgres running in the container. ```shell -docker compose down -v postgres +docker compose stop postgres # Stop the container +docker rm postgres # Remove the container +docker volume rm pg_data # Remove the named volume ``` -The `v` option is the key here, it asks Docker to **remove** the **volume** of the `postgres` service. -This volume persists the postgres data outside the container, on the host **OS**. - ### Mongo Service #### Start MongoDB ```shell -docker compose up mongo +docker compose start mongo +``` + +Now, check that `mongo` is running: + +```shell +docker compose ps | grep mongo ``` #### Stop MongoDB ```shell -docker compose down mongo +docker compose stop mongo ``` #### Remove MongoDB and its Databases > [!CAUTION] -> This **destructive command** will **remove MongoDB and all its databases** -> created by MongoDB running in the container. +> This **destructive command** will stop and remove the container, then **remove** its data **volume** +> (all the databases created by MongoDB running in the container). ```shell -docker compose down -v mongo +docker compose stop mongo # Stop container +docker rm mongo # Remove the stopped container +docker volume rm learn-dev_mongo_data # Remove the named volume ``` - ## Project Status From fe31c91ef73c87b6c9e0537433fb5b24fd212dcc Mon Sep 17 00:00:00 2001 From: Eric Bouchut Date: Thu, 28 May 2026 16:27:28 +0200 Subject: [PATCH 4/5] chore(config): Rename environment variable - Make postgres and mongo use network net (learn-dev-net) - Rename postgres volume to pg_data (was pgdata) - Fix mongo mapping to always explicit use host:port form - Ensure mongo init DB uses LEARNDEV_MONGO_DB_NAME (renamed variable) --- .env.example | 2 +- docker-compose.yaml | 21 ++++++++++++--------- src/main/resources/application.yaml | 4 ++-- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/.env.example b/.env.example index 84d808d..d40f2b1 100644 --- a/.env.example +++ b/.env.example @@ -87,7 +87,7 @@ MONGO_ROOT_PASSWORD=TODO_SET_A_VALUE_HERE # Name of the MongoDB application database # -MONGO_DB_NAME=learndev +LEARNDEV_MONGO_DB_NAME=learndev # ~~~ External port mapping for the mongo Docker Compose service ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docker-compose.yaml b/docker-compose.yaml index f488a12..634038c 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -2,16 +2,19 @@ services: postgres: image: postgres:17 - # Inject database credentials and config (db name, db user, - # and host port mapping) into the container. - # Reads from the same .env file passed to `docker compose --env-file ...`. + # Inject into the container the database credentials and configuration variables defined in the .env file + # (database names , database user, host and port mappings) + # as environment variables. + # This is required for the docker init script in ./docker/init/. env_file: - .env + networks: + - net volumes: # Init scripts: run once on first container start (empty data dir). - ./docker/init:/docker-entrypoint-initdb.d # Named volume: preserves data across container stop/start cycles. - - pgdata:/var/lib/postgresql/data + - pg_data:/var/lib/postgresql/data ports: # See src/main/resources/.env.example for details - "${POSTGRES_HOST}:${POSTGRES_PORT}:5432" @@ -20,16 +23,16 @@ services: image: mongo:8.0 restart: unless-stopped ports: - - "${MONGO_HOST}${MONGO_HOST:+:}${MONGO_PORT:-27017}:27017" + - "${MONGO_HOST}:${MONGO_PORT}:27017" environment: MONGO_INITDB_ROOT_USERNAME: ${MONGO_ROOT_USERNAME} MONGO_INITDB_ROOT_PASSWORD: ${MONGO_ROOT_PASSWORD} - MONGO_INITDB_DATABASE: ${MONGO_DB_NAME:-learndev} + MONGO_INITDB_DATABASE: ${LEARNDEV_MONGO_DB_NAME} volumes: - mongo_data:/data/db - ./docker/mongo/init:/docker-entrypoint-initdb.d:ro networks: - - learn-dev-net + - net healthcheck: test: ["CMD", "mongosh", "--quiet", "--eval", "db.adminCommand('ping').ok"] interval: 10s @@ -38,12 +41,12 @@ services: start_period: 20s networks: - learn-dev-net: + net: # A bridge network connects your services together # on an isolated Virtual LAN managed by Docker. driver: bridge # Named volumes used to preserve data across container stop/start cycles. volumes: - pgdata: + pg_data: mongo_data: diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index e26c844..905dfb2 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -5,10 +5,10 @@ spring: data: mongodb: # uri: mongodb://admin:admin_password@127.0.0.1:27018/learndev?authSource=admin - uri: mongodb://${MONGO_ROOT_USER}:${MONGO_ROOT_PASSWORD}@${MONGO_HOST}${MONGO_HOST:+:}${MONGO_PORT}/${MONGO_DB_NAME}?authSource=admin + uri: mongodb://${MONGO_ROOT_USERNAME}:${MONGO_ROOT_PASSWORD}@${MONGO_HOST}:${MONGO_PORT}/${LEARNDEV_MONGO_DB_NAME}?authSource=admin # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - # Database Connection Configuration No. Done + # Database Connection Configuration # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ datasource: # url: jdbc:postgresql://127.0.0.1:5433/learndev From a5f290c2942182f19482593afe4500316e075fdd Mon Sep 17 00:00:00 2001 From: Eric Bouchut Date: Thu, 28 May 2026 16:31:02 +0200 Subject: [PATCH 5/5] Fix a typo in .env.example --- .env.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env.example b/.env.example index d40f2b1..61f5795 100644 --- a/.env.example +++ b/.env.example @@ -101,7 +101,7 @@ LEARNDEV_MONGO_DB_NAME=learndev # MONGO_HOST=127.0.0.1 -# MongoDB port mapped to the internal Postgres container's port 27017. +# MongoDB port mapped to the internal mongo container's port 27017. # Only the host side is configurable here. 27017 is fixed inside the container. # Use a non-standard port (e.g. 27018) to avoid clashing with a local MongoDB install. #