Skip to content

Commit f1b34bb

Browse files
author
bjornol
committed
Added example
1 parent f0a462d commit f1b34bb

File tree

1,111 files changed

+284451
-2
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,111 files changed

+284451
-2
lines changed

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
doc/
2+
*.deb
3+
*.lic
4+
*.ovpn

README.md

+97-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,97 @@
1-
# nginx_ssl_keycloak_mysql_redis-docker
2-
Handy docker compose example file that sets up a nginx_ssl_keycloak_mysql_redis-docker
1+
# Nginx_ssl_keycloak_mysql_redis-docker
2+
Handy docker compose example file that sets up a nginx_ssl_keycloak_mysql_redis as a service ready to use.
3+
This compose file is based on serveral other repos and online articles. This repos works as an example of use only.
4+
5+
## Pre-Requirements
6+
Knowledge about all elements in the compose file before use.
7+
> Nginx and Let’s Encrypt it taken from this repo. You can find more information here https://github.com/wmnnd/nginx-certbot.
8+
9+
> The `init-letsencrypt.sh` fetched from https://github.com/wmnnd/nginx-certbot has been slightly modefied in this example.
10+
> In this example you can add domains from comand line, like this:
11+
12+
- `./init-letsencrypt.sh [staging | production] <domain1 domain2 ...> `
13+
14+
> Note: In this example The mariadb is build from compose file to use timezone Europe/Oslo. Remove if not needed.
15+
16+
## Handy styff
17+
This docker compose file sets up:
18+
19+
- nginx with ssl sertificates
20+
- Inclues config app.conf file but to be used as example only.
21+
- based on some articles and repos
22+
https://github.com/wmnnd/nginx-certbot
23+
https://medium.com/@pentacent/nginx-and-lets-encrypt-with-docker-in-less-than-5-minutes-b4b8a60d3a71
24+
25+
- Keycloak for authentication with custom "adminlte" login page
26+
- based on some articles:
27+
https://medium.com/@shivangbhandari/custom-themes-for-keycloak-631bdd3e04e5
28+
https://www.mai1015.com/development/2019/05/05/docker-keycloak-proxy-behind-nginx/
29+
https://www.keycloak.org/docs/4.8/authorization_services/
30+
https://www.youtube.com/watch?v=XJYy6Aq-PJ8
31+
- Example theme from:
32+
https://github.com/MAXIMUS-DeltaWare/adminlte-keycloak-theme
33+
34+
- mysql with config
35+
- Inclues config my.cnf file but to be used as example only. Remember to change my.cnf gile dependent of what kind of mariadb version you use.
36+
37+
- Redis
38+
39+
40+
## Run with ssl sertificates
41+
```
42+
# Run the docker compose
43+
docker-compose up -d --build
44+
45+
# Init you sertificates
46+
# Depending on you user rights it could be that you have to give the user access to run the shell file.
47+
# Also use staging when testing or you will have to wait for a while between each run.
48+
# Example: chmod +x username:usergroup ./init-letsencrypt.sh
49+
./init-letsencrypt.sh [staging | production] <domain1 domain2 ...>
50+
51+
```
52+
53+
## Run without ssl sertificates ( local testing)
54+
```
55+
# Run the docker compose
56+
docker-compose -f docker-compose-without-ssl.yml up -d --build
57+
```
58+
59+
## Test the stuff
60+
Examples below will help you test that stuff is running correctly.
61+
62+
### Nginx test
63+
```
64+
# go to your browser:
65+
# expected result: web site opens
66+
http://127.0.0.1:8180
67+
```
68+
69+
### Keycloak test
70+
```
71+
# go to your browser:
72+
# expected result: web site opens
73+
http://127.0.0.1:8180
74+
```
75+
Now, log in as admin and change the default theme for the one in this example:
76+
[![](screenshots/keycloak_theme_example_01.png)](screenshots/keycloak_theme_example_01.png) [![](screenshots/keycloak_theme_example_02.png)](screenshots/keycloak_theme_example_02.png) [![](screenshots/screen3_sm.png)](screenshots/screen3.png)
77+
78+
### Monetdb test
79+
```
80+
# In command line:
81+
# expected result:
82+
# +--------------------+
83+
# | Database |
84+
# +--------------------+
85+
# | information_schema |
86+
# | keycloak |
87+
# +--------------------+
88+
docker exec -it mariadb mysql -ukeycloak -pkeycloak -e "SHOW DATABASES;"
89+
```
90+
91+
### Redis test
92+
```
93+
# In command line:
94+
# expected result: < PONG
95+
docker exec -it redis redis-cli PING
96+
97+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<#import "template.ftl" as layout>
2+
<@layout.registrationLayout displayMessage=false; section>
3+
<#if section = "title">
4+
${msg("errorTitle")}
5+
<#elseif section = "header">
6+
${msg("errorTitleHtml")?no_esc}
7+
<#elseif section = "form">
8+
<div id="kc-error-message">
9+
<p class="instruction">${message.summary}</p>
10+
<#if client?? && client.baseUrl?has_content>
11+
<p><a id="backToApplication" href="${client.baseUrl}">${msg("backToApplication")}</a></p>
12+
</#if>
13+
</div>
14+
</#if>
15+
</@layout.registrationLayout>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<#import "template.ftl" as layout>
2+
<@layout.registrationLayout displayInfo=true; section>
3+
<#if section = "title">
4+
${msg("loginTotpTitle")}
5+
<#elseif section = "header">
6+
${msg("loginTotpTitle")}
7+
<#elseif section = "form">
8+
<ol id="kc-totp-settings">
9+
<li>
10+
<p>${msg("loginTotpStep1")}</p>
11+
</li>
12+
<li>
13+
<p>${msg("loginTotpStep2")}</p>
14+
<img src="data:image/png;base64, ${totp.totpSecretQrCode}" alt="Figure: Barcode"><br/>
15+
<span class="code">${totp.totpSecretEncoded}</span>
16+
</li>
17+
<li>
18+
<p>${msg("loginTotpStep3")}</p>
19+
</li>
20+
</ol>
21+
<form action="${url.loginAction}" class="form config-totp ${properties.kcFormClass!}" id="kc-totp-settings-form" method="post">
22+
<div class="${properties.kcFormGroupClass!} row">
23+
<div class="${properties.kcInputWrapperClass!} col-xs-12">
24+
<input type="text" id="totp" name="totp" autocomplete="off" class="form-control ${properties.kcInputClass!}" />
25+
</div>
26+
<input type="hidden" id="totpSecret" name="totpSecret" value="${totp.totpSecret}" />
27+
</div>
28+
<div class="row config-totp-button-container">
29+
<div class="col-xs-6 col-xs-offset-6 col-sm-4 col-sm-offset-8">
30+
<input class="btn btn-primary btn-flat btn-block ${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonLargeClass!}" type="submit" value="${msg("doSubmit")}"/>
31+
</div>
32+
</div>
33+
</form>
34+
</#if>
35+
</@layout.registrationLayout>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<#import "template.ftl" as layout>
2+
<@layout.registrationLayout displayInfo=true; section>
3+
<#if section = "title">
4+
${msg("emailForgotTitle")}
5+
<#elseif section = "header">
6+
${msg("emailForgotTitle")}
7+
<#elseif section = "form">
8+
<form id="kc-reset-password-form" class="form reset-password ${properties.kcFormClass!}" action="${url.loginAction}" method="post">
9+
<div class="reset-password-field ${properties.kcFormGroupClass!}">
10+
<div class="${properties.kcLabelWrapperClass!}">
11+
<label for="username" class="${properties.kcLabelClass!}"><#if !realm.loginWithEmailAllowed>${msg("username")}<#elseif !realm.registrationEmailAsUsername>${msg("usernameOrEmail")}<#else>${msg("email")}</#if></label>
12+
</div>
13+
<div class="${properties.kcInputWrapperClass!}">
14+
<input type="text" id="username" name="username" class="form-control ${properties.kcInputClass!}" autofocus/>
15+
</div>
16+
</div>
17+
18+
<div class="${properties.kcFormGroupClass!} row">
19+
<div id="kc-form-options" class="${properties.kcFormOptionsClass!} col-xs-5">
20+
<div class="${properties.kcFormOptionsWrapperClass!}">
21+
<span>
22+
<a class="btn btn-default btn-flat btn-block" href="${url.loginUrl}"><i class="fa fa-caret-left"></i>&nbsp;&nbsp;${msg("backToLogin")}</a>
23+
</span>
24+
</div>
25+
</div>
26+
27+
<div id="kc-form-buttons" class="${properties.kcFormButtonsClass!} col-xs-7">
28+
<input class="btn btn-primary btn-flat btn-block ${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonLargeClass!}" type="submit" value="${msg("doSubmit")}"/>
29+
</div>
30+
</div>
31+
</form>
32+
<#elseif section = "info" >
33+
<hr />
34+
${msg("emailInstruction")}
35+
</#if>
36+
</@layout.registrationLayout>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<#import "template.ftl" as layout>
2+
<@layout.registrationLayout; section>
3+
<#if section = "title">
4+
${msg("loginTitle",realm.displayName)}
5+
<#elseif section = "header">
6+
${msg("loginTitleHtml",realm.displayNameHtml)?no_esc}
7+
<#elseif section = "form">
8+
<form id="kc-totp-login-form" class="form totp ${properties.kcFormClass!}" action="${url.loginAction}" method="post">
9+
<div class="${properties.kcFormGroupClass!}">
10+
<div class="${properties.kcLabelWrapperClass!}">
11+
<label for="totp" class="${properties.kcLabelClass!}">${msg("loginTotpOneTime")}</label>
12+
</div>
13+
14+
<div class="${properties.kcInputWrapperClass!}">
15+
<input id="totp" name="totp" autocomplete="off" type="text" class="form-control ${properties.kcInputClass!}" autofocus />
16+
</div>
17+
</div>
18+
19+
<div class="${properties.kcFormGroupClass!} totp-button-container">
20+
<div id="kc-form-options" class="${properties.kcFormOptionsClass!}">
21+
<div class="${properties.kcFormOptionsWrapperClass!}">
22+
</div>
23+
</div>
24+
25+
<div id="kc-form-buttons" class="${properties.kcFormButtonsClass!}">
26+
<div class="${properties.kcFormButtonsWrapperClass!} row">
27+
<div class="col-xs-6 col-xs-push-6 col-sm-8 col-sm-push-4">
28+
<input class="btn btn-primary btn-flat btn-block ${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonLargeClass!}" name="login" id="kc-login" type="submit" value="${msg("doLogIn")}"/>
29+
</div>
30+
<div class="col-xs-6 col-xs-pull-6 col-sm-4 col-sm-pull-8">
31+
<input class="btn btn-default btn-flat btn-block ${properties.kcButtonClass!} ${properties.kcButtonDefaultClass!} ${properties.kcButtonLargeClass!}" name="cancel" id="kc-cancel" type="submit" value="${msg("doCancel")}"/>
32+
</div>
33+
</div>
34+
</div>
35+
</div>
36+
</form>
37+
</#if>
38+
</@layout.registrationLayout>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<#import "template.ftl" as layout>
2+
<@layout.registrationLayout displayInfo=true; section>
3+
<#if section = "title">
4+
${msg("updatePasswordTitle")}
5+
<#elseif section = "header">
6+
${msg("updatePasswordTitle")}
7+
<#elseif section = "form">
8+
<form id="kc-passwd-update-form" class="form update-password ${properties.kcFormClass!}" action="${url.loginAction}" method="post">
9+
<input type="text" readonly value="this is not a login form" style="display: none;">
10+
<input type="password" readonly value="this is not a login form" style="display: none;">
11+
12+
<div class="update-password-field ${properties.kcFormGroupClass!}">
13+
<div class="${properties.kcLabelWrapperClass!}">
14+
<label for="password-new" class="${properties.kcLabelClass!}">${msg("passwordNew")}</label>
15+
</div>
16+
<div class="${properties.kcInputWrapperClass!}">
17+
<input type="password" id="password-new" name="password-new" class="form-control ${properties.kcInputClass!}" autofocus autocomplete="off" />
18+
</div>
19+
</div>
20+
21+
<div class="update-password-field ${properties.kcFormGroupClass!}">
22+
<div class="${properties.kcLabelWrapperClass!}">
23+
<label for="password-confirm" class="${properties.kcLabelClass!}">${msg("passwordConfirm")}</label>
24+
</div>
25+
<div class="${properties.kcInputWrapperClass!}">
26+
<input type="password" id="password-confirm" name="password-confirm" class="form-control ${properties.kcInputClass!}" autocomplete="off" />
27+
</div>
28+
</div>
29+
30+
<div class="${properties.kcFormGroupClass!} row update-password-button-container">
31+
<div id="kc-form-options" class="${properties.kcFormOptionsClass!} col-xs-6 col-sm-8">
32+
<div class="${properties.kcFormOptionsWrapperClass!}">
33+
</div>
34+
</div>
35+
36+
<div id="kc-form-buttons" class="${properties.kcFormButtonsClass!} col-xs-6 col-sm-4">
37+
<input class="btn btn-primary btn-flat btn-block ${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonLargeClass!}" type="submit" value="${msg("doSubmit")}"/>
38+
</div>
39+
</div>
40+
</form>
41+
</#if>
42+
</@layout.registrationLayout>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<#import "template.ftl" as layout>
2+
<@layout.registrationLayout; section>
3+
<#if section = "title">
4+
${msg("loginProfileTitle")}
5+
<#elseif section = "header">
6+
${msg("loginProfileTitle")}
7+
<#elseif section = "form">
8+
<form id="kc-update-profile-form" class="form update-profile ${properties.kcFormClass!}" action="${url.loginAction}" method="post">
9+
<#if user.editUsernameAllowed>
10+
<div class="update-profile-field ${properties.kcFormGroupClass!} ${messagesPerField.printIfExists('username',properties.kcFormGroupErrorClass!)}">
11+
<div class="${properties.kcLabelWrapperClass!}">
12+
<label for="username" class="${properties.kcLabelClass!}">${msg("username")}</label>
13+
</div>
14+
<div class="${properties.kcInputWrapperClass!}">
15+
<input type="text" id="username" name="username" value="${(user.username!'')}" class="form-control ${properties.kcInputClass!}"/>
16+
</div>
17+
</div>
18+
</#if>
19+
<div class="update-profile-field ${properties.kcFormGroupClass!} ${messagesPerField.printIfExists('email',properties.kcFormGroupErrorClass!)}">
20+
<div class="${properties.kcLabelWrapperClass!}">
21+
<label for="email" class="${properties.kcLabelClass!}">${msg("email")}</label>
22+
</div>
23+
<div class="${properties.kcInputWrapperClass!}">
24+
<input type="text" id="email" name="email" value="${(user.email!'')}" class="form-control ${properties.kcInputClass!}" />
25+
</div>
26+
</div>
27+
28+
<div class="update-profile-field ${properties.kcFormGroupClass!} ${messagesPerField.printIfExists('firstName',properties.kcFormGroupErrorClass!)}">
29+
<div class="${properties.kcLabelWrapperClass!}">
30+
<label for="firstName" class="${properties.kcLabelClass!}">${msg("firstName")}</label>
31+
</div>
32+
<div class="${properties.kcInputWrapperClass!}">
33+
<input type="text" id="firstName" name="firstName" value="${(user.firstName!'')}" class="form-control ${properties.kcInputClass!}" />
34+
</div>
35+
</div>
36+
37+
<div class="update-profile-field ${properties.kcFormGroupClass!} ${messagesPerField.printIfExists('lastName',properties.kcFormGroupErrorClass!)}">
38+
<div class="${properties.kcLabelWrapperClass!}">
39+
<label for="lastName" class="${properties.kcLabelClass!}">${msg("lastName")}</label>
40+
</div>
41+
<div class="${properties.kcInputWrapperClass!}">
42+
<input type="text" id="lastName" name="lastName" value="${(user.lastName!'')}" class="form-control ${properties.kcInputClass!}" />
43+
</div>
44+
</div>
45+
46+
<div class="${properties.kcFormGroupClass!} row update-profile-button-container">
47+
<div id="kc-form-options" class="${properties.kcFormOptionsClass!}">
48+
<div class="${properties.kcFormOptionsWrapperClass!}">
49+
</div>
50+
</div>
51+
52+
<div id="kc-form-buttons" class="${properties.kcFormButtonsClass!} col-xs-6 xs-xs-offset-6 col-sm-4 col-sm-offset-8">
53+
<input class="btn btn-primary btn-flat btn-block ${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonLargeClass!}" type="submit" value="${msg("doSubmit")}" />
54+
</div>
55+
</div>
56+
</form>
57+
</#if>
58+
</@layout.registrationLayout>

0 commit comments

Comments
 (0)