├── frontend ├── Dockerfile ├── src │ ├── keycloak.php │ ├── index.php │ ├── styles.css │ └── app.js ├── frontend-ingress.yaml └── frontend.yaml ├── backend ├── Dockerfile ├── src │ ├── keycloak.json │ ├── package.json │ └── app.js ├── backend-ingress.yaml └── backend.yaml ├── keycloak ├── keycloak-ingress.yaml ├── keycloak.yaml └── realm.json └── README.md /frontend/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM php:7.0-apache 2 | COPY src/ /var/www/html/ 3 | -------------------------------------------------------------------------------- /backend/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:9 2 | 3 | EXPOSE 8080 4 | 5 | WORKDIR /home/node/app 6 | 7 | COPY src/ /home/node/app 8 | 9 | RUN npm install 10 | 11 | CMD npm start 12 | -------------------------------------------------------------------------------- /backend/src/keycloak.json: -------------------------------------------------------------------------------- 1 | { 2 | "realm": "demo", 3 | "bearer-only": true, 4 | "auth-server-url": "${env.KEYCLOAK_URL}", 5 | "ssl-required": "external", 6 | "resource": "service-nodejs" 7 | } 8 | -------------------------------------------------------------------------------- /frontend/src/keycloak.php: -------------------------------------------------------------------------------- 1 | 'demo', 6 | 'auth-server-url' => $_ENV['KEYCLOAK_URL'], 7 | 'resource' => "app" 8 | ); 9 | 10 | echo json_encode($config, JSON_UNESCAPED_SLASHES); 11 | ?> 12 | 13 | 14 | -------------------------------------------------------------------------------- /backend/backend-ingress.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Ingress 3 | metadata: 4 | name: backend 5 | spec: 6 | tls: 7 | - hosts: 8 | - BACKEND_HOST 9 | rules: 10 | - host: BACKEND_HOST 11 | http: 12 | paths: 13 | - backend: 14 | serviceName: backend 15 | servicePort: 8080 16 | 17 | -------------------------------------------------------------------------------- /frontend/frontend-ingress.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Ingress 3 | metadata: 4 | name: frontend 5 | spec: 6 | tls: 7 | - hosts: 8 | - FRONTEND_HOST 9 | rules: 10 | - host: FRONTEND_HOST 11 | http: 12 | paths: 13 | - backend: 14 | serviceName: frontend 15 | servicePort: 80 16 | 17 | -------------------------------------------------------------------------------- /keycloak/keycloak-ingress.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Ingress 3 | metadata: 4 | name: keycloak 5 | spec: 6 | tls: 7 | - hosts: 8 | - KEYCLOAK_HOST 9 | rules: 10 | - host: KEYCLOAK_HOST 11 | http: 12 | paths: 13 | - backend: 14 | serviceName: keycloak 15 | servicePort: 8080 16 | 17 | -------------------------------------------------------------------------------- /backend/src/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "service-nodejs", 3 | "version": "0.0.1", 4 | "scripts": { 5 | "start": "node app.js" 6 | }, 7 | "dependencies": { 8 | "keycloak-connect": "4.0.0-beta.3", 9 | "body-parser": "^1.13.3", 10 | "express": "^4.13.3", 11 | "express-session": "^1.14.2", 12 | "cors": "^2.8.1" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /backend/backend.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: backend 5 | labels: 6 | app: backend 7 | spec: 8 | ports: 9 | - name: http 10 | port: 8080 11 | targetPort: 8080 12 | selector: 13 | app: backend 14 | type: LoadBalancer 15 | --- 16 | apiVersion: apps/v1 17 | kind: Deployment 18 | metadata: 19 | name: backend 20 | namespace: default 21 | spec: 22 | replicas: 1 23 | selector: 24 | matchLabels: 25 | app: backend 26 | template: 27 | metadata: 28 | labels: 29 | app: backend 30 | spec: 31 | containers: 32 | - name: backend 33 | image: kube-demo-backend 34 | imagePullPolicy: Never 35 | env: 36 | - name: KEYCLOAK_URL 37 | value: https://KEYCLOAK_HOST/auth 38 | ports: 39 | - name: http 40 | containerPort: 8080 41 | readinessProbe: 42 | httpGet: 43 | path: /public 44 | port: 8080 45 | -------------------------------------------------------------------------------- /frontend/frontend.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: frontend 5 | labels: 6 | app: frontend 7 | spec: 8 | ports: 9 | - name: http 10 | port: 80 11 | targetPort: 80 12 | selector: 13 | app: frontend 14 | type: LoadBalancer 15 | --- 16 | apiVersion: apps/v1 17 | kind: Deployment 18 | metadata: 19 | name: frontend 20 | namespace: default 21 | spec: 22 | replicas: 1 23 | selector: 24 | matchLabels: 25 | app: frontend 26 | template: 27 | metadata: 28 | labels: 29 | app: frontend 30 | spec: 31 | containers: 32 | - name: frontend 33 | image: kube-demo-frontend 34 | imagePullPolicy: Never 35 | env: 36 | - name: KEYCLOAK_URL 37 | value: https://KEYCLOAK_HOST/auth 38 | - name: SERVICE_URL 39 | value: https://BACKEND_HOST 40 | ports: 41 | - name: http 42 | containerPort: 80 43 | readinessProbe: 44 | httpGet: 45 | path: / 46 | port: 80 47 | -------------------------------------------------------------------------------- /keycloak/keycloak.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: keycloak 5 | labels: 6 | app: keycloak 7 | spec: 8 | ports: 9 | - name: http 10 | port: 8080 11 | targetPort: 8080 12 | selector: 13 | app: keycloak 14 | type: LoadBalancer 15 | --- 16 | apiVersion: apps/v1 17 | kind: Deployment 18 | metadata: 19 | name: keycloak 20 | namespace: default 21 | spec: 22 | replicas: 1 23 | selector: 24 | matchLabels: 25 | app: keycloak 26 | template: 27 | metadata: 28 | labels: 29 | app: keycloak 30 | spec: 31 | containers: 32 | - name: keycloak 33 | image: jboss/keycloak 34 | env: 35 | - name: KEYCLOAK_USER 36 | value: "admin" 37 | - name: KEYCLOAK_PASSWORD 38 | value: "admin" 39 | - name: PROXY_ADDRESS_FORWARDING 40 | value: "true" 41 | ports: 42 | - name: http 43 | containerPort: 8080 44 | - name: https 45 | containerPort: 8443 46 | readinessProbe: 47 | httpGet: 48 | path: /auth/realms/master 49 | port: 8080 50 | -------------------------------------------------------------------------------- /keycloak/realm.json: -------------------------------------------------------------------------------- 1 | { 2 | "realm": "demo", 3 | "enabled": true, 4 | "users": [ 5 | { 6 | "username": "stian", 7 | "enabled": true, 8 | "credentials": [ 9 | { 10 | "type": "password", 11 | "value": "pass" 12 | } 13 | ], 14 | "realmRoles": [ 15 | "user" 16 | ], 17 | "clientRoles": { 18 | "account": [ 19 | "manage-account" 20 | ] 21 | } 22 | } 23 | ], 24 | "roles": { 25 | "realm": [ 26 | { 27 | "name": "user", 28 | "description": "User privileges" 29 | }, 30 | { 31 | "name": "admin", 32 | "description": "Administrator privileges" 33 | } 34 | ] 35 | }, 36 | "defaultRoles": [ 37 | "user" 38 | ], 39 | "clients": [ 40 | { 41 | "clientId": "app", 42 | "enabled": true, 43 | "publicClient": true, 44 | "redirectUris": [ 45 | "*" 46 | ], 47 | "webOrigins": [ 48 | "*" 49 | ] 50 | } 51 | ] 52 | } 53 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Keycloak Kubernetes Demo 2 | 3 | This demo assumes you have minikube installed with the ingress addon enabled. 4 | 5 | ## Setup URLs 6 | 7 | The following URLs uses nip.io to prevent having to modify `/etc/hosts`. 8 | 9 | export MINIKUBE_IP=`minikube ip` 10 | export KEYCLOAK_HOST=keycloak.$MINIKUBE_IP.nip.io 11 | export BACKEND_HOST=backend.$MINIKUBE_IP.nip.io 12 | export FRONTEND_HOST=frontend.$MINIKUBE_IP.nip.io 13 | 14 | ## Keycloak 15 | 16 | kubectl create -f keycloak/keycloak.yaml 17 | 18 | cat keycloak/keycloak-ingress.yaml | sed "s/KEYCLOAK_HOST/$KEYCLOAK_HOST/" \ 19 | | kubectl create -f - 20 | 21 | echo https://$KEYCLOAK_HOST 22 | 23 | The Keycloak admin console should now be opened in your browser. Ignore the warning caused by the self-signed certificate. Login with admin/admin. Create a new realm and import `keycloak/realm.json`. 24 | 25 | The client config for the frontend allows any redirect-uri and web-origin. This is to simplify configuration for the demo. For a production system always use the real URL of the application for the redirect-uri and web-origin. 26 | 27 | ## Backend 28 | 29 | eval `minikube docker-env` 30 | docker build -t kube-demo-backend backend 31 | 32 | cat backend/backend.yaml | sed "s/KEYCLOAK_HOST/$KEYCLOAK_HOST/" | \ 33 | kubectl create -f - 34 | 35 | cat backend/backend-ingress.yaml | sed "s/BACKEND_HOST/$BACKEND_HOST/" | \ 36 | kubectl create -f - 37 | 38 | echo https://$BACKEND_HOST/public 39 | 40 | ## Frontend 41 | 42 | eval `minikube docker-env` 43 | docker build -t kube-demo-frontend frontend 44 | 45 | cat frontend/frontend.yaml | sed "s/KEYCLOAK_HOST/$KEYCLOAK_HOST/" | \ 46 | sed "s/BACKEND_HOST/$BACKEND_HOST/" | \ 47 | kubectl create -f - 48 | 49 | cat frontend/frontend-ingress.yaml | sed "s/FRONTEND_HOST/$FRONTEND_HOST/" | \ 50 | kubectl create -f - 51 | 52 | echo https://$FRONTEND_HOST 53 | 54 | The frontend application should now be opened in your browser. Login with stian/pass. You should be able to invoke public and invoke secured, but not invoke admin. To be able to invoke admin go back to the Keycloak admin console and add the `admin` role to the user `stian`. 55 | -------------------------------------------------------------------------------- /frontend/src/index.php: -------------------------------------------------------------------------------- 1 | 17 | 18 | 19 |
20 | 21 |