- Single-node Docker swarm is used to benefit from single stack definition w/o need for installing docker-compose and lots of python libs on host.
- Multi-node swarm is not supported here.
- nginx is used as a reverse proxy in a separate container with certs maintained by host.
This tutorial is assuming some information you need to adopt to work on your server:
- idp.example.com must be the FQDN of your host.
<db-user-secret>
and<db-root-secret>
must be random strings of sufficient length.- /opt/keycloak is name of the folder containing files specific to the docker stack. You can keep it like that.
- Admin account name will be
john.doe
. You should use a different name for sure. Usingadmin
is an option, but an obvious one. Using different name slightly increases security.
- Start with vanilla host (Ubuntu Linux).
- Install Docker according to official tutorial.
- Enable swarm mode:
docker swarm init
apt install nginx
- Replace content of file /etc/nginx/sites-enabled/default with:
server { listen 80 default_server; location /.well-known { root /var/www/certbot; } location / { return 308 https://$host$request_uri; } }
mkdir /var/www/certbot
systemctl restart nginx
apt install snapd
snap install --classic certbot
- Create file /etc/letsencrypt/renewal-hooks/deploy/kc.sh with content
#!/bin/sh docker stack rm keycloak sleep 10 docker stack deploy -c /opt/keycloak/docker-compose.yml keycloak
chmod 0755 /etc/letsencrypt/renewal-hooks/deploy/kc.sh
certbot certonly --webroot -w /var/www/certbot -d idp.example.com
mkdir /opt/keycloak
cd /opt/keycloak
- Create file admin-pw containing desired admin password.
chmod 0400 admin-pw
- Create file docker-compose.yml containing
version: "3.8" services: idp: image: jboss/keycloak secrets: - admin-pw environment: KEYCLOAK_USER: john.doe KEYCLOAK_PASSWORD_FILE: /run/secrets/admin-pw KEYCLOAK_FRONTEND_URL: "https://idp.example.com/auth/" PROXY_ADDRESS_FORWARDING: "true" DB_VENDOR: mysql DB_ADDR: mysql DB_USER: keycloak DB_PASSWORD: "<db-user-secret>" networks: - db - www mysql: image: mysql environment: MYSQL_DATABASE: keycloak MYSQL_USER: keycloak MYSQL_PASSWORD: "<db-user-secret>" MYSQL_ROOT_PASSWORD: "<db-root-secret>" volumes: - "mysql:/var/lib/mysql" networks: - db nginx: image: nginx ports: - target: 443 published: 443 protocol: tcp mode: host configs: - source: nginx.conf target: /etc/nginx/conf.d/keycloak.conf uid: "101" gid: "101" mode: 0400 secrets: - ssl.key - ssl.cert networks: - www secrets: admin-pw: file: ./admin-pw ssl.cert: file: /etc/letsencrypt/live/idp.example.com/fullchain.pem ssl.key: file: /etc/letsencrypt/live/idp.example.com/privkey.pem configs: nginx.conf: file: ./nginx.conf volumes: mysql: networks: db: www:
- Create file nginx.conf with following content:
proxy_buffer_size 128k; proxy_buffers 4 256k; proxy_busy_buffers_size 256k; server { listen 443 ssl default_server http2; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains"; ssl_session_cache shared:SSL:20m; ssl_session_timeout 10m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; ssl_ciphers 'ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5'; ssl_certificate /run/secrets/ssl.cert; ssl_certificate_key /run/secrets/ssl.key; location / { proxy_pass http://idp:8080/; proxy_set_header Host idp.example.com; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Real-IP $remote_addr; } }
docker stack deploy -c /opt/keycloak/docker-compose.yml keycloak
docker stack rm keycloak
docker stack services keycloak
Basically follow steps described here.
You probably will have issues with accessing account console for testing login as a regular user as instructed. This is due to some missing definition of permitted web origins for the account console.
- Open admin console.
- Select the realm you'd like to test.
- Click "Clients" in left panel.
- Click on "account-console" in list of clients for editing.
- In "Settings" tab, look for field labelled "Web Origins", enter
*
there and click on "Save" button.