Docker Compose stack for the Kimai time-tracking application.
Kimai Docker Compose Deployment #
Folder Structure #
# Create folder structure
sudo mkdir -p /opt/kimai && cd /opt/kimai
Environment File #
# Create .env file
sudo vi .env
# .env
MYSQL_PW=kimai-pw
MYSQL_ROOT_PW=sql-root-pw
Docker Compose #
# Create Docker Compose file
sudo vi docker-compose.yml
HTTP Version #
version: "3.9"
services:
app:
container_name: kimai
image: kimai/kimai2:apache
ports:
- "80:8001"
depends_on:
- db
environment:
- DATABASE_URL=mysql://kimai:${MYSQL_PW}@db:3306/kimai
- TRUSTED_HOSTS=localhost,kimai.jklug.work
volumes:
- ./public:/opt/kimai/public
restart: unless-stopped
db:
image: mysql:8
container_name: db
environment:
- MYSQL_DATABASE=kimai
- MYSQL_USER=kimai
- MYSQL_PASSWORD=${MYSQL_PW}
- MYSQL_ROOT_PASSWORD={$MYSQL_ROOT_PW}
volumes:
- ./mysql:/var/lib/mysql
restart: unless-stopped
Traefik Reverse Proxy Version #
version: "3.9"
services:
app:
container_name: kimai
image: kimai/kimai2:apache
ports:
- "8001"
depends_on:
- db
environment:
- DATABASE_URL=mysql://kimai:${MYSQL_PW}@db:3306/kimai
- TRUSTED_HOSTS=localhost,kimai.jklug.work
volumes:
- ./public:/opt/kimai/public
restart: unless-stopped
labels:
- "traefik.enable=true"
- "traefik.docker.network=traefik"
- "traefik.http.services.kimai-service.loadbalancer.server.port=8001"
# HTTPS Router
- "traefik.http.routers.kimai.entrypoints=websecure"
- "traefik.http.routers.kimai.tls=true"
- "traefik.http.routers.kimai.rule=Host(`kimai.jklug.work`)"
# HTTP Router
- "traefik.http.routers.kimai-http.rule=Host(`kimai.jklug.work`)"
- "traefik.http.routers.kimai-http.entrypoints=web"
- "traefik.http.routers.kimai-http.middlewares=redirect-to-https"
# Middleware for HTTP to HTTPS redirection
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
networks:
- intern
- traefik
db:
image: mysql:8
container_name: db
environment:
- MYSQL_DATABASE=kimai
- MYSQL_USER=kimai
- MYSQL_PASSWORD=${MYSQL_PW}
- MYSQL_ROOT_PASSWORD={$MYSQL_ROOT_PW}
volumes:
- ./mysql:/var/lib/mysql
restart: unless-stopped
labels:
- "traefik.enable = false"
networks:
- intern
networks:
traefik:
external: true
intern:
Start Container #
# Create / start Docker container
sudo docker compose up -d
Create Admin User #
# Create admin user: Define username & email
sudo docker exec -ti kimai \
/opt/kimai/bin/console kimai:user:create admin admin@example.com ROLE_SUPER_ADMIN
# Shell output:
Please enter the password: # Define admin pw
Webinterface #
# HTTP Version
192.168.30.92:80
# Reverse Proxy Version
kimai.jklug.work
Traefik Reverse Proxy #
For the following Traefik reverse proxy setup I use a Let’s Encrypt wildcard certificate.
Docker Network #
# Create a reverse proxy network
sudo docker network create traefik
Folder Structure #
# Create folder structure
sudo mkdir -p /opt/traefik/certs && cd /opt/traefik/
Docker Compose #
# Create Docker Compose file
sudo vi docker-compose.yml
version: '3'
services:
reverse-proxy:
image: traefik:v2.10
container_name: Traefik-Reverse-Proxy
restart: unless-stopped
command:
- --api.insecure=true
- --providers.docker
- --providers.file.directory=/etc/traefik/dynamic
- --entryPoints.web.address=:80
- --entryPoints.websecure.address=:443
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./tls-configuration.yaml:/etc/traefik/dynamic/tls-configuration.yaml
- ./certs/:/etc/certs/
networks:
- traefik
networks:
traefik:
external: true
Traefik Dynamic Configuration #
# Create file for dynamic configuration
sudo vi tls-configuration.yaml
# tls-configuration.yaml
tls:
certificates:
- certFile: /etc/certs/fullchain.pem
keyFile: /etc/certs/privkey.pem
Note: The Let’s Encrypt wildcard certificates fullchain.pem
& privkey.pem
must be placed inside the /opt/traefik/certificates
directory before the Docker
stack is started.
Start Docker Compose Container #
# Start Docker Compose Container
sudo docker compose up -d
Links #
# Official Documentation
https://www.kimai.org/documentation/docker.html
# Official Documentation
https://www.kimai.org/documentation/docker-compose.html