Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 38 additions & 5 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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
#
Expand Down Expand Up @@ -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

Expand All @@ -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
#
LEARNDEV_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 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.
#
MONGO_PORT=27018


# ~~~~ Spring Boot ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

# Default Spring Boot active profile: dev
Expand Down
157 changes: 144 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,27 +69,158 @@ 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_:

- 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

This starts all the Docker services for the application:

- 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:
```shell
docker compose up -d
docker compose logs
```
A Docker init script creates the application database and user when the `learn-dev-postgres` container
is run for the first time.
- Run the application: TODO

**For each service** (`postgres`, `mongo`)
declared in the *Docker Compose* configuration file
(`docker-compose.yaml`), *Docker Compose*:

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).

## 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.

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

#### Start Postgres

Running the app using `docker compose up -d`
starts **all** the application services, including `postgres`.

To only start the `postgres` service:

```shell
docker compose start -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 `postgres` 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 stop postgres
```

#### Remove all Postgres Databases

Stops and remove the `postgres` container and its data volume.

> [!CAUTION]
> This is a **destructive command** that will **remove all the databases
> (structure and content)** created by Postgres running in the container.

```shell
docker compose stop postgres # Stop the container
docker rm postgres # Remove the container
docker volume rm pg_data # Remove the named volume
```


### Mongo Service

#### Start MongoDB

```shell
docker compose start mongo
```

Now, check that `mongo` is running:

```shell
docker compose ps | grep mongo
```

#### Stop MongoDB

```shell
docker compose stop mongo
```

#### Remove MongoDB and its Databases

> [!CAUTION]
> 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 stop mongo # Stop container
docker rm mongo # Remove the stopped container
docker volume rm learn-dev_mongo_data # Remove the named volume
```
Comment thread
ebouchut marked this conversation as resolved.


## Project Status
Expand Down
48 changes: 38 additions & 10 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -1,24 +1,52 @@
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 ...`.
# 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"

Comment thread
ebouchut marked this conversation as resolved.
mongo:
image: mongo:8.0
restart: unless-stopped
ports:
- "${MONGO_HOST}:${MONGO_PORT}:27017"
environment:
MONGO_INITDB_ROOT_USERNAME: ${MONGO_ROOT_USERNAME}
MONGO_INITDB_ROOT_PASSWORD: ${MONGO_ROOT_PASSWORD}
MONGO_INITDB_DATABASE: ${LEARNDEV_MONGO_DB_NAME}
volumes:
- mongo_data:/data/db
- ./docker/mongo/init:/docker-entrypoint-initdb.d:ro
networks:
- net
healthcheck:
test: ["CMD", "mongosh", "--quiet", "--eval", "db.adminCommand('ping').ok"]
interval: 10s
timeout: 5s
retries: 5
start_period: 20s

networks:
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:
Empty file added docker/mongo/init/.gitkeep
Empty file.
5 changes: 5 additions & 0 deletions src/main/resources/application.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ spring:
application:
name: learn-dev

data:
mongodb:
# uri: mongodb://admin:admin_password@127.0.0.1:27018/learndev?authSource=admin
uri: mongodb://${MONGO_ROOT_USERNAME}:${MONGO_ROOT_PASSWORD}@${MONGO_HOST}:${MONGO_PORT}/${LEARNDEV_MONGO_DB_NAME}?authSource=admin

Comment thread
ebouchut marked this conversation as resolved.
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Database Connection Configuration
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Comment thread
ebouchut marked this conversation as resolved.
Expand Down
Loading