|
|
|
Docker is a container management system, that enables to execute code regardless of operating system. Read more about docker and the capabilities of containers in the [official docker documentation](https://docs.docker.com/manuals/).
|
|
|
|
|
|
|
|
[TOC]
|
|
|
|
|
|
|
|
## Dockerfile
|
|
|
|
|
|
|
|
Dockerfiles are descriptive files that contain the instructions to build containers. This repository contains two docker files for the containers it creates. Arguments for this file can be found in the [official reference](https://docs.docker.com/reference/dockerfile/)
|
|
|
|
|
|
|
|
### Database
|
|
|
|
|
|
|
|
This file is dedicated to create a container running a [Postgres database](https://www.postgresql.org). Currently, it takes the `postgres:16-alpine` image, sets the default password to `password` and exposes the default Postgres port `5432`. If you intend to make the database publicly accessible over the internet, you **need** to change password to something secure. Additionally, the Dockerfile copies the `schema.sql` file into `/docker-entrypoint-initdb.d/` upon container creation, which will execute the SQL statements in the file in postgres.
|
|
|
|
|
|
|
|
### API
|
|
|
|
The API Dockerfile uses the latest `node` image, copies `package.json` and `package-lock.json` into the container and installs the dependencies. Afterward it copies all code not excluded by `.dockerignore` into the container and runs `node .` to start the API server. By default the Dockerfile exposes the `3000` port in the container. If you intend to change this, you need to apply the same changes in `index.js`.
|
|
|
|
|
|
|
|
## docker-compose.yaml
|
|
|
|
Docker compose files contain the necessary instructions to start multiple containers and connect them to each other. They also provide the possibility to define container names, exposed ports and health checks.
|
|
|
|
|
|
|
|
### Network
|
|
|
|
|
|
|
|
The provided compose file creates a network on startup, which connects the API and database container.
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
networks:
|
|
|
|
evaluation-network:
|
|
|
|
diver: bridge
|
|
|
|
```
|
|
|
|
|
|
|
|
Providing this network for both containers enables them to communicate to each other, without being accessible from the outside. Thus they can communicate securely.
|
|
|
|
|
|
|
|
### Building
|
|
|
|
|
|
|
|
Containers are described with the `services:` key, where both services contain build information
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
services:
|
|
|
|
database:
|
|
|
|
build:
|
|
|
|
context: ./
|
|
|
|
dockerfile: Dockerfile
|
|
|
|
api:
|
|
|
|
build:
|
|
|
|
context: ./api
|
|
|
|
dockerfile: Dockerfile
|
|
|
|
```
|
|
|
|
|
|
|
|
The `context` key gets provided with the path where the resulting dockerfile lies in to enable docker compose to build the image according to the dockerfile.
|
|
|
|
|
|
|
|
### Health check
|
|
|
|
|
|
|
|
To make sure the database runs smoothly, it defines a health check, which runs `pg_isready` every 10s until it gets positive feedback. `pg_isready` is a function provided by Postgres, that returns if the database has been started completely.
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
healthcheck:
|
|
|
|
test: ["CMD", "pg_isready"]
|
|
|
|
interval: 10s
|
|
|
|
timeout: 1s
|
|
|
|
retries: 3
|
|
|
|
```
|
|
|
|
|
|
|
|
The API container then can wait with startup by depending on this healthcheck
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
depends_on:
|
|
|
|
database:
|
|
|
|
condition: service_healthy
|
|
|
|
```
|
|
|
|
|
|
|
|
### Environment
|
|
|
|
|
|
|
|
When starting the API manually, it reads in the provided `.env` file. In order for the docker container to work, it needs the same environment variables to access the database. This can be provided with the `environment` key
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
environment:
|
|
|
|
- DB_HOST=database
|
|
|
|
- DB_USER=postgres
|
|
|
|
- DB_PASS=password
|
|
|
|
- DB_DATABASE=evaluation
|
|
|
|
```
|
|
|
|
|
|
|
|
If you changed any of these values when creating the database container, you need to change them here to.
|
|
|
|
|
|
|
|
### Port
|
|
|
|
Since both containers share a network, they won't be accessible. In order to enable interaction with the API, the `ports` key needs to be configures
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
ports:
|
|
|
|
- "50000:3000"
|
|
|
|
```
|
|
|
|
|
|
|
|
If you changed the exposed port of the API in the dockerfile, you need to change the `3000` here too. Also, if you need the container to be available on another port, you can change the `50000` to any number you want. Just keep in mind, that not every port can be used, to see blocked ports, check [this list](https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers). |
|
|
\ No newline at end of file |