• Home
  • Cloud VPS
    • Hong Kong VPS
    • US VPS
  • Dedicated Servers
    • Hong Kong Servers
    • US Servers
    • Singapore Servers
    • Japan Servers
  • Company
    • Contact Us
    • Blog
logo logo
  • Home
  • Cloud VPS
    • Hong Kong VPS
    • US VPS
  • Dedicated Servers
    • Hong Kong Servers
    • US Servers
    • Singapore Servers
    • Japan Servers
  • Company
    • Contact Us
    • Blog
ENEN
  • 简体简体
  • 繁體繁體
Client Area

How to Deploy Keycloak SSO on Hong Kong VPS: Self-Hosted Identity (2026)

July 28, 2026

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

ScaleRAMvCPUStorage
Up to 1,000 users2 GB220 GB NVMe
1,000–10,000 users4 GB440 GB NVMe
10,000+ users8 GB880 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 keycloak

Step 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 nginx

Step 3: Initial Keycloak Configuration

Visit https://auth.yourdomain.com and log in with the admin credentials.

Create a Realm

  1. Click the realm dropdown (top-left, shows “Keycloak”) → Create Realm
  2. Name: mycompany
  3. 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:

  1. Clients → Create client
  2. Client type: OpenID Connect
  3. Client ID: myapp
  4. Client name: My Application
  5. Next → Client authentication: On (for confidential client)
  6. Standard flow: On (for web apps)
  7. Valid redirect URIs: https://app.yourdomain.com/auth/callback
  8. Valid post logout redirect URIs: https://app.yourdomain.com
  9. 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:

  1. User Federation → Add provider → LDAP
  2. Vendor: Active Directory (or Other)
  3. Connection URL: ldap://your-ad-server:389
  4. Users DN: CN=Users,DC=company,DC=com
  5. Bind Type: Simple
  6. Bind DN: service account with read access
  7. Click Test connection then Test authentication
  8. 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:

Google

  1. Provider: Google
  2. Client ID and Secret from Google Cloud Console (OAuth 2.0 credentials)
  3. Redirect URI to configure in Google Console: https://auth.yourdomain.com/realms/mycompany/broker/google/endpoint

GitHub

  1. Provider: GitHub
  2. 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.

Recent Posts

  • Hong Kong VPS vs Cloudflare Workers: Which for Asia-Pacific APIs? (2026)
  • How to Self-Host Gitea on Hong Kong VPS: Private Git Server (2026)
  • WooCommerce for China Market on Hong Kong VPS: Sell Cross-Border in 2026
  • Game Server on Hong Kong VPS: CS2, Valheim, and Minecraft for Asia (2026)
  • Linux Kernel and Sysctl Hardening for Hong Kong VPS Security (2026)

Recent Comments

  1. Hong Kong VPS Uptime and SLA: What 99.9% Uptime Really Means for Your Business (2026) - Server.HK on How to Monitor Your Hong Kong VPS: Uptime, Performance, and Alert Setup Guide (2026)
  2. Best Hong Kong VPS Providers in 2026: Compared by Speed, Routing, and Value - Server.HK on How to Migrate Your Website to a Hong Kong VPS: Zero-Downtime Transfer Guide (2026)
  3. vibramycin injection on How to Choose the Right Hong Kong VPS Plan: A Buyer’s Guide for 2026
  4. allopurinol for gout on CN2 GIA vs BGP vs CN2 GT: What’s the Real Difference for China Connectivity?
  5. antibiotics online purchase on How to Set Up a WordPress Site on a Hong Kong VPS with aaPanel (Step-by-Step 2026)

Knowledge Base

Access detailed guides, tutorials, and resources.

Live Chat

Get instant help 24/7 from our support team.

Send Ticket

Our team typically responds within 10 minutes.

logo
Alipay Cc-paypal Cc-stripe Cc-visa Cc-mastercard Bitcoin
Cloud VPS
  • Hong Kong VPS
  • US VPS
Dedicated Servers
  • Hong Kong Servers
  • US Servers
  • Singapore Servers
  • Japan Servers
More
  • Contact Us
  • Blog
  • Legal
© 2026 Server.HK | Hosting Limited, Hong Kong | Company Registration No. 77008912
Telegram
Telegram @ServerHKBot