Guide
1. Set up docker-compose.yml
version: "3"
volumes:
postgres_data:
driver: local
services:
postgres:
image: postgres:latest
networks:
- db
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
POSTGRES_DB: keycloak
POSTGRES_USER: keycloak
POSTGRES_PASSWORD: <postgres_password>
keycloak:
image: jboss/keycloak:latest
deploy:
restart_policy:
condition: always
delay: 5s
window: 120s
networks:
- web
- db
environment:
DB_VENDOR: POSTGRES
DB_ADDR: postgres
DB_DATABASE: keycloak
DB_USER: keycloak
DB_SCHEMA: public
DB_PASSWORD: <postgres_password>
KEYCLOAK_USER: admin
KEYCLOAK_PASSWORD: <keycloak_password>
KC_HOSTNAME: <idp-hostname>
PROXY_ADDRESS_FORWARDING: true
KEYCLOAK_FRONTEND_URL: https://<idp-hostname>/auth
depends_on:
- postgres
web:
image: nginx
networks:
- web
depends_on:
- keycloak
volumes:
- ./web/nginx.conf:/etc/nginx/nginx.conf
- ./certbot/www:/var/www/certbot/:ro
- ./certbot/conf/:/etc/nginx/ssl/:ro
ports:
- "80:80"
- "443:443"
environment:
- NGINX_PORT=80
certbot:
image: certbot/certbot:latest
volumes:
- ./certbot/www/:/var/www/certbot/:rw
- ./certbot/conf/:/etc/letsencrypt/:rw
networks:
web: {}
db: {}
Replace <idp-hostname>, <keycloak-password> and <postgres_password>. Preferably store them securely.
2. Run initial nginx server
This step is needed in order to generate Let's encrypt certificate with certbot before running actual Keycloak server.
Place this file in web/nginx.conf (relative to your docker-compose.yml file).
worker_processes 5; ## Default: 1
worker_rlimit_nofile 8192;
events {
worker_connections 4096; ## Default: 1024
}
http {
index index.html index.htm index.php;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] $status '
'"$request" $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
sendfile on;
tcp_nopush on;
server_names_hash_bucket_size 128; # this seems to be required for some vhosts
server { # Required for certbot
server_name idp;
listen 80;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
}
}
3. Run certbot
docker-compose up -d web
docker-compose run --rm certbot certonly --webroot --webroot-path /var/www/certbot/ -d <idp-hostname>
4. Configure Nginx
Now add Keycloak behind Nginx. Add this to your web/nginx.conf file. Again, replace <idp-hostname> with your own.
...
server {
listen 443 default_server ssl http2;
listen [::]:443 ssl http2;
server_name <idp-hostname>;
ssl_certificate /etc/nginx/ssl/live/<idp-hostname>/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/live/<idp-hostname>/privkey.pem;
location /auth/admin/ {
allow 127.0.0.1; # Only allow localhost to access admin, or change this to your IP-address
deny all;
proxy_pass http://keycloak:8080/auth/admin/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /auth/js/ {
proxy_pass http://keycloak:8080/auth/js/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /auth/realms/ {
proxy_pass http://keycloak:8080/auth/realms/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
}
location /auth/resources/ {
proxy_pass http://keycloak:8080/auth/resources/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /auth/robots.txt {
proxy_pass http://keycloak:8080/auth/robots.txt;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
5. Start everything
docker-compose restart web
docker-compose up -d postgres keycloak
Now you should be able to access Keycloak at https://<idp-hostname>/auth