Alternative: Docker Compose Setup
Getting Started with Docker Compose
- Install Docker Desktop or Docker Engine and Docker CLI with the Docker Compose Plugin ( - docker composecommand).- We DON’T support the usage of the Compose standalone binary ( - docker-composecommand) 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 upin the directory- docker/
- Open the Artemis instance in your browser at https://localhost 
- Run - docker compose downin the directory- docker/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
 
Overview of the Artemis Docker / Docker Compose structure
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 DB
- artemis-dev-postgres.yml: Artemis-Dev-Postgres Setup containing the development build of Artemis and a PostgreSQL DB
- artemis-prod-mysql.yml: Artemis-Prod-MySQL Setup containing the production build of Artemis and a MySQL DB
- artemis-prod-postgres.yml: Artemis-Prod-Postgres Setup containing the production build of Artemis and a PostgreSQL DB
- monitoring.yml: Prometheus-Grafana Setup containing a Prometheus and Grafana instance
- mysql.yml: MySQL Setup containing a MySQL DB instance
- nginx.yml: Nginx Setup containing a preconfigured Nginx instance
- postgres.yml: Postgres Setup containing a PostgreSQL DB instance
Example command to run such setups:
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 Service
- mysql.yml: MySQL DB Service
- nginx.yml: Nginx Service
- postgres.yml: PostgreSQL DB Service
- jenkins.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 bashor if the container is not yet running:- docker compose run --rm artemis-app bash
- mysql container: - docker compose exec mysql bashor directly into MySQL- docker 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. 
- Stop a service: - docker compose stop <name of the service>(restart via- docker 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.4.0
    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