Keycloak is the leading open-source Identity and Access Management (IAM) platform — providing single sign-on (SSO), OAuth 2.0, OpenID Connect (OIDC), and SAML 2.0 for your applications. Deployed on a Hong Kong VPS, it gives your Asia-Pacific users and employees a centralised login experience across all internal tools and SaaS products, with CN2 GIA routing keeping authentication responses fast from mainland China.
What Keycloak Replaces
- Auth0, Okta, Azure AD B2C (per-MAU pricing eliminated)
- Separate user databases in each application
- Manual user provisioning across tools
- Per-application password reset flows
VPS Requirements
| Scale | RAM | vCPU | Storage |
|---|---|---|---|
| Up to 1,000 users | 2 GB | 2 | 20 GB NVMe |
| 1,000–10,000 users | 4 GB | 4 | 40 GB NVMe |
| 10,000+ users | 8 GB | 8 | 80 GB NVMe |
Step 1: Deploy Keycloak with Docker Compose
apt update && apt upgrade -y
curl -fsSL https://get.docker.com | sh
systemctl enable --now docker
mkdir -p /opt/keycloak && cd /opt/keycloak
cat > docker-compose.yml << 'EOF'
version: '3.8'
services:
postgres:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_DB: keycloak
POSTGRES_USER: keycloak
POSTGRES_PASSWORD: StrongKeycloakDBPass!
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- keycloak-internal
healthcheck:
test: ["CMD-SHELL", "pg_isready -U keycloak"]
interval: 10s
timeout: 5s
retries: 5
keycloak:
image: quay.io/keycloak/keycloak:24.0
restart: unless-stopped
command: start
environment:
KC_DB: postgres
KC_DB_URL: jdbc:postgresql://postgres:5432/keycloak
KC_DB_USERNAME: keycloak
KC_DB_PASSWORD: StrongKeycloakDBPass!
KC_HOSTNAME: auth.yourdomain.com
KC_HOSTNAME_STRICT: "true"
KC_PROXY: edge
KC_HTTP_ENABLED: "true"
KC_HTTPS_ENABLED: "false" # TLS terminated at Nginx
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: ChangeThisAdminPassword!
KC_HEALTH_ENABLED: "true"
KC_METRICS_ENABLED: "true"
# Performance tuning
JAVA_OPTS_APPEND: "-Xms512m -Xmx1g -XX:+UseG1GC"
ports:
- "127.0.0.1:8080:8080"
depends_on:
postgres:
condition: service_healthy
networks:
- keycloak-internal
volumes:
postgres_data:
networks:
keycloak-internal:
driver: bridge
EOF
docker compose up -d
# Wait ~60 seconds for Keycloak to initialise
docker compose logs -f keycloakStep 2: Configure Nginx Reverse Proxy
apt install -y nginx certbot python3-certbot-nginx
cat > /etc/nginx/sites-available/keycloak << 'EOF'
server {
listen 80;
server_name auth.yourdomain.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name auth.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/auth.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/auth.yourdomain.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
client_max_body_size 10m;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Port 443;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
proxy_read_timeout 120s;
}
}
EOF
ln -s /etc/nginx/sites-available/keycloak /etc/nginx/sites-enabled/
certbot --nginx -d auth.yourdomain.com
nginx -t && systemctl reload nginxStep 3: Initial Keycloak Configuration
Visit https://auth.yourdomain.com and log in with the admin credentials.
Create a Realm
- Click the realm dropdown (top-left, shows “Keycloak”) → Create Realm
- Name:
mycompany - Enabled: On → Create
Configure Realm Settings
In Realm Settings → General:
- Display Name: Your Company
- Frontend URL:
https://auth.yourdomain.com - Default locale: English (or your primary language)
In Realm Settings → Login:
- User registration: Off (invite-only) or On (self-registration)
- Email as username: On (recommended for B2B)
- Forgot password: On
- Remember me: On
- Login with email: On
Configure Email (for verification and password reset)
In Realm Settings → Email: enter your SMTP server details and click Test Connection.
Step 4: Create an OIDC Client (for Your Application)
Each application that uses Keycloak for authentication needs a registered client:
- Clients → Create client
- Client type: OpenID Connect
- Client ID:
myapp - Client name: My Application
- Next → Client authentication: On (for confidential client)
- Standard flow: On (for web apps)
- Valid redirect URIs:
https://app.yourdomain.com/auth/callback - Valid post logout redirect URIs:
https://app.yourdomain.com - Web origins:
https://app.yourdomain.com
After saving, go to the Credentials tab to get the Client Secret.
Step 5: Integrate Keycloak with Your Application
Node.js with Passport-Keycloak
npm install openid-client express-session
const { Issuer, generators } = require('openid-client');
async function setupKeycloak(app) {
const issuer = await Issuer.discover(
'https://auth.yourdomain.com/realms/mycompany'
);
const client = new issuer.Client({
client_id: 'myapp',
client_secret: 'YOUR_CLIENT_SECRET',
redirect_uris: ['https://app.yourdomain.com/auth/callback'],
response_types: ['code'],
});
// Login route
app.get('/auth/login', (req, res) => {
const codeVerifier = generators.codeVerifier();
const codeChallenge = generators.codeChallenge(codeVerifier);
req.session.codeVerifier = codeVerifier;
const authUrl = client.authorizationUrl({
scope: 'openid email profile',
code_challenge: codeChallenge,
code_challenge_method: 'S256',
});
res.redirect(authUrl);
});
// Callback route
app.get('/auth/callback', async (req, res) => {
const params = client.callbackParams(req);
const tokenSet = await client.callback(
'https://app.yourdomain.com/auth/callback',
params,
{ code_verifier: req.session.codeVerifier }
);
const userinfo = await client.userinfo(tokenSet.access_token);
req.session.user = userinfo;
req.session.tokens = tokenSet;
res.redirect('/dashboard');
});
// Auth middleware
app.use('/dashboard', (req, res, next) => {
if (!req.session.user) return res.redirect('/auth/login');
next();
});
}Python/Django with django-allauth or mozilla-django-oidc
pip install mozilla-django-oidc
# In settings.py:
INSTALLED_APPS += ['mozilla_django_oidc']
AUTHENTICATION_BACKENDS = ['mozilla_django_oidc.auth.OIDCAuthenticationBackend']
OIDC_RP_CLIENT_ID = 'myapp'
OIDC_RP_CLIENT_SECRET = 'YOUR_CLIENT_SECRET'
OIDC_OP_AUTHORIZATION_ENDPOINT = 'https://auth.yourdomain.com/realms/mycompany/protocol/openid-connect/auth'
OIDC_OP_TOKEN_ENDPOINT = 'https://auth.yourdomain.com/realms/mycompany/protocol/openid-connect/token'
OIDC_OP_USER_ENDPOINT = 'https://auth.yourdomain.com/realms/mycompany/protocol/openid-connect/userinfo'
OIDC_OP_JWKS_ENDPOINT = 'https://auth.yourdomain.com/realms/mycompany/protocol/openid-connect/certs'
OIDC_RP_SIGN_ALGO = 'RS256'
LOGIN_REDIRECT_URL = '/dashboard'
LOGOUT_REDIRECT_URL = '/'Step 6: User Federation with LDAP/Active Directory
For enterprises with existing Active Directory or LDAP user directories:
- User Federation → Add provider → LDAP
- Vendor: Active Directory (or Other)
- Connection URL:
ldap://your-ad-server:389 - Users DN:
CN=Users,DC=company,DC=com - Bind Type: Simple
- Bind DN: service account with read access
- Click Test connection then Test authentication
- Click Synchronize all users
AD users can now log in to all Keycloak-integrated applications with their corporate credentials.
Step 7: Social Login (Google, GitHub, WeChat)
In Identity Providers → Add provider:
- Provider: Google
- Client ID and Secret from Google Cloud Console (OAuth 2.0 credentials)
- Redirect URI to configure in Google Console:
https://auth.yourdomain.com/realms/mycompany/broker/google/endpoint
GitHub
- Provider: GitHub
- Client ID and Secret from GitHub OAuth App settings
After adding providers, users see “Login with Google” or “Login with GitHub” buttons on the Keycloak login page — no code changes required in your application.
Step 8: Automated Backup
<code">cat > /opt/keycloak/backup.sh << 'EOF' #!/bin/bash DATE=$(date +%Y%m%d_%H%M%S) BACKUP_DIR="/opt/backups/keycloak" mkdir -p $BACKUP_DIR docker compose -f /opt/keycloak/docker-compose.yml exec -T postgres \ pg_dump -U keycloak keycloak | gzip > $BACKUP_DIR/keycloak_$DATE.sql.gz
find $BACKUP_DIR -name "*.sql.gz" -mtime +14 -delete
echo "Keycloak backup complete: $DATE"
EOF
chmod +x /opt/keycloak/backup.sh
crontab -l | { cat; echo "0 2 * * * /opt/keycloak/backup.sh"; } | crontab -Conclusion
Keycloak on a Hong Kong VPS provides enterprise-grade SSO for Asia-Pacific organisations — OIDC integration for modern web and mobile apps, LDAP/AD federation for existing corporate directories, and social login providers — all without per-MAU pricing. CN2 GIA routing ensures authentication requests from mainland Chinese users complete in 30–50ms, keeping login flows fast for your entire Asia-Pacific user base.
Deploy your identity platform: Browse Server.HK Hong Kong VPS plans — a 4 GB plan handles Keycloak for organisations up to 10,000 active users.