Alternative: Docker Compose Setup
Getting Started with Docker Compose
Install Docker Desktop or Docker Engine and Docker CLI with the Docker Compose Plugin (
docker compose
command).We DON’T support the usage of the Compose standalone binary (
docker-compose
command) as its installation method is no longer supported by Docker.We recommend the latest version of Docker Desktop or Docker Engine and Docker CLI with Docker Compose Plugin. The minimum version for Docker Compose is 1.27.0+ as of this version the latest Compose file format is supported.
Hint
Make sure that Docker Desktop has enough memory (~ 6GB). To adapt it, go to
Settings -> Resources
.Check that all local network ports used by Docker Compose are free (e.g. you haven’t started a local MySQL server when you would like to start a Docker Compose instance of MySQL).
Run
docker compose pull && docker compose up
in the directorydocker/
Open the Artemis instance in your browser at https://localhost
Run
docker compose down
in the directorydocker/
to stop and remove the docker containers
Tip
docker compose pull
command is just necessary the first time as an extra step;
otherwise, Artemis will be built from source as you don’t already have an Artemis Image locally.Other Docker Compose Setups
The easiest way to configure a local deployment via Docker is a deployment with a docker compose file.
In the directory docker/
you can find the following docker compose files for different setups:
artemis-dev-mysql.yml
: Artemis-Dev-MySQL Setup containing the development build of Artemis and a MySQL DBartemis-dev-postgres.yml
: Artemis-Dev-Postgres Setup containing the development build of Artemis and a PostgreSQL DBartemis-prod-mysql.yml
: Artemis-Prod-MySQL Setup containing the production build of Artemis and a MySQL DBartemis-prod-postgres.yml
: Artemis-Prod-Postgres Setup containing the production build of Artemis and a PostgreSQL DBgitlab-gitlabci.yml
: GitLab-GitLabCI Setup containing a GitLab and GitLabCI instancegitlab-jenkins.yml
: GitLab-Jenkins Setup containing a GitLab and Jenkins instance (see Gitlab Server Quickstart Guide for the configuration of this setup)monitoring.yml
: Prometheus-Grafana Setup containing a Prometheus and Grafana instancemysql.yml
: MySQL Setup containing a MySQL DB instancenginx.yml
: Nginx Setup containing a preconfigured Nginx instancepostgres.yml
: Postgres Setup containing a PostgreSQL DB instance
Three example commands to run such setups:
docker compose -f docker/mysql.yml -f docker/gitlab-jenkins.yml up
docker compose -f docker/artemis-dev-postgres.yml up
Tip
There is also a single docker-compose.yml
in the directory docker/
which mirrors the setup of artemis-prod-mysql.yml
.
This should provide a quick way, without manual changes necessary, for new contributors to start up an Artemis instance.
If the documentation just mentions to run docker compose
without a -f <file.yml>
argument, it’s
assumed you are running the command from the docker/
directory.
For each service being used in these docker compose files, a base service (containing similar settings) is defined in the following files:
artemis.yml
: Artemis Servicemysql.yml
: MySQL DB Servicenginx.yml
: Nginx Servicepostgres.yml
: PostgreSQL DB Servicegitlab.yml
: GitLab Servicejenkins.yml
: Jenkins Service
For testing mails or SAML logins, you can append the following services to any setup with an Artemis container:
mailhog.yml
: Mailhog Service (email testing tool)saml-test.yml
: Saml-Test Service (SAML Test Identity Provider for testing SAML features)
An example command to run such an extended setup:
docker compose -f docker/artemis-dev-mysql.yml -f docker/mailhog.yml up
Warning
If you want to run multiple docker compose setups in parallel on one host, you might have to modify volume, container, and network names!
Folder structure
docker/
.docker/<base service or setup name>/
).Artemis Base Service
Everything related to the Docker Image of Artemis (built by the Dockerfile) can be found in the Server Setup section. All Artemis-related settings changed in Docker Compose files are described here.
artemis.yml
base service (e.g. in the artemis-prod-mysql.yml
setup) defaults to the latest
Artemis Docker Image tag in your local docker registry.docker compose build artemis-app
before starting Artemis.image:
value to the desired image
for the artemis-app
service and run docker compose pull artemis-app
.Debugging with Docker
See the Debugging with Docker section for detailed information.
In all development docker compose setups like artemis-dev-mysql.yml
Java Remote Debugging is enabled by default.
Service, Container and Volume names
Service names for the usage within docker compose are kept short, like mysql
, to make it easier
to use them in a CLI.
Container and volume names are prepended with artemis-
in order to not interfere with other container or volume
names on your system.
Get a shell into the containers
Tip
To keep the documentation short, we will use the standard form of docker compose COMMAND
from this point on.
You can use the following commands also with the -f docker/<setup to be launched>.yml
argument pointing
to a specific setup.
app container:
docker compose exec artemis-app bash
or if the container is not yet running:docker compose run --rm artemis-app bash
mysql container:
docker compose exec mysql bash
or directly into MySQLdocker compose exec mysql mysql
Analog for other services.
Other useful commands
Start a setup in the background:
docker compose up -d
Stop and remove containers of a setup:
docker compose down
Stop, remove containers and volumes:
docker compose down -v
Remove Artemis-related volumes/state:
docker volume rm artemis-data artemis-mysql-data
This is helpful in setups where you just want to delete the state of Artemis but not of Jenkins and GitLab for instance.
Stop a service:
docker compose stop <name of the service>
(restart viadocker compose start <name of the service>
)Restart a service:
docker compose restart <name of the service>
Remove all local Docker containers:
docker container rm $(docker ps -a -q)
Remove all local Artemis Docker images:
docker rmi $(docker images --filter=reference="ghcr.io/ls1intum/artemis:*" -q)
Using Traefik as a reverse proxy
If you want to use Traefik as a reverse proxy for your Artemis instance, you can configure your setup using a single traefik.toml
file and a docker-compose.yml
file.
The traefik.toml
file should be located in the same directory as the docker-compose.yml
file.
You should also ensure that an acme.json
file exists within your directory.
The acme.json
file is used to store the certificates generated by Traefik.
Thus, the permissions of the acme.json
file should be set to 600 for root.
The traefik.toml
file should be configured as follows:
[global]
checkNewVersion = true
sendAnonymousUsage = false
[log]
level = "INFO"
[api]
dashboard = true
insecure = false
[entryPoints]
[entryPoints.web]
address = ":80"
[entryPoints.websecure]
address = ":443"
[certificatesResolvers.customresolver.acme]
email = "your-mail-address-here"
storage = "/etc/traefik/acme/acme.json"
[certificatesResolvers.customresolver.acme.httpChallenge]
# used during the challenge
entryPoint = "web"
[entryPoints.web.http.redirections.entrypoint]
to = "websecure"
scheme = "https"
[acme]
onHostRule = true
[providers.docker]
endpoint = "unix:///var/run/docker.sock"
exposedByDefault = false
network = "artemis-net" # name of the network in the docker-compose.yml file
[accessLog]
[accesslog.fields.names]
StartUTC = "drop"
The docker-compose.yml
file could look like this for an Artemis, Jenkins and MySQL setup with Traefik as a reverse proxy:
services:
traefik:
image: traefik
container_name: "traefik"
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- "./traefik.toml:/etc/traefik/traefik.toml:ro"
- "./acme.json:/etc/traefik/acme/acme.json"
- "/var/run/docker.sock:/var/run/docker.sock:ro"
networks:
- artemis-net
environment:
- TZ=Europe/Berlin
labels:
- "traefik.enable=true"
- "traefik.http.routers.api.entrypoints=websecure"
- "traefik.http.routers.api.tls=true"
# Manage Access to the Traefik Dashboard. Replace <<USERNAME>> and <<PASSWORD_HASH>> with your credentials.
# The dashboard will be available at https://<<ARTEMIS_HOST_NAME>>/dashboard/
# Artemis will be available at another domain: https://<<ARTEMIS_SERVER_NAME>>/
# If you don't want to use the dashboard, you can remove the following lines and disable the dashboard in the traefik.toml file.
- "traefik.http.routers.api.rule=Host(`${ARTEMIS_HOST_NAME}`) && (PathPrefix(`/api/`) || PathPrefix(`/dashboard/`)) || Path(`/dashboard`) || Path(`/api`)"
- "traefik.http.middlewares.api-redirect.redirectregex.regex=^https?://([^/]+)(/[^/]+)$"
- "traefik.http.middlewares.api-redirect.redirectregex.replacement=https://$$1$$2/"
- "traefik.http.routers.api.service=api@internal"
- "traefik.http.routers.api.middlewares=api-redirect,api-auth"
- "traefik.http.middlewares.api-auth.basicauth.users=<<USERNAME>>:<<PASSWORD_HASH>>"
jenkins:
image: jenkins/jenkins:lts
container_name: "jenkins"
restart: unless-stopped
user: root
volumes:
- ./data/jenkins/home:/var/jenkins_home
- /var/run/docker.sock:/var/run/docker.sock
- /usr/bin/docker:/usr/bin/docker:ro
- /usr/bin/com.docker.cli:/usr/bin/com.docker.cli:ro
ports:
- "50000:50000"
networks:
- artemis-net
labels:
- "traefik.enable=true"
- "traefik.http.routers.jenkins.rule=Host(`${JENKINS_SERVER_NAME}`)"
- "traefik.http.routers.jenkins.entrypoints=websecure"
- "traefik.http.routers.jenkins.tls=true"
- "traefik.http.routers.jenkins.tls.certresolver=customresolver"
- "traefik.http.services.jenkins.loadbalancer.server.port=8080"
artemis:
image: ghcr.io/ls1intum/artemis:${ARTEMIS_VERSION}
container_name: "artemis"
restart: unless-stopped
depends_on:
artemis-db:
condition: service_started
jenkins:
condition: service_started
volumes:
- ./data/artemis-be/config:/opt/artemis/config
- ./data/artemis-be/data:/opt/artemis/data
- ./branding:/opt/artemis/public/content:ro
ports:
- "22:22"
environment:
- spring.profiles.active=${PROFILES}
- SPRING_DATASOURCE_URL=jdbc:mysql://artemis-db:3306/Artemis?createDatabaseIfNotExist=true&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=utf8&useSSL=false&useLegacyDatetimeCode=false&serverTimezone=UTC
networks:
- artemis-net
labels:
- "traefik.enable=true"
- "traefik.http.routers.artemis.rule=Host(`${ARTEMIS_SERVER_NAME}`)"
- "traefik.http.routers.artemis.entrypoints=websecure"
- "traefik.http.routers.artemis.tls=true"
- "traefik.http.routers.artemis.tls.certresolver=customresolver"
- "traefik.http.services.artemis.loadbalancer.server.port=8080"
artemis-db:
image: mysql:9
container_name: "mysql"
restart: unless-stopped
volumes:
- ./data/artemis-db:/var/lib/mysql
environment:
- MYSQL_ALLOW_EMPTY_PASSWORD=yes
- MYSQL_DATABASE=Artemis
command: mysqld --lower_case_table_names=1 --skip-ssl --character_set_server=utf8mb4 --collation-server=utf8mb4_unicode_ci --explicit_defaults_for_timestamp
networks:
- artemis-net
cap_add:
- SYS_NICE
networks:
artemis-net:
name: artemis-net