Skip to content

Commit 70b22ee

Browse files
authored
feat: portainer via caddy (#8)
* feat: portainer via caddy * feat: caddy auth github * fix: duplicate global block * fix: lint * chore: lint and upgrade portainer * test: remove tls config to see * fix: change caddy ports * fix:caddy secrets from file * test: caddy portal on whoami * fix: caddy environement varaible interpolation * fix: revert caddy substitution * test: use env_file in bash container
1 parent b53fc13 commit 70b22ee

File tree

8 files changed

+104
-30
lines changed

8 files changed

+104
-30
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,42 @@
11
{
2-
# Global options block. Entirely optional, https is on by default
3-
# Optional email key for lets encrypt
4-
email youremail@domain.com
5-
# Optional staging lets encrypt for testing. Comment out for production.
6-
acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
2+
http_port 80
3+
https_port 443
4+
debug
5+
6+
order authenticate before respond
7+
order authorize before basicauth
8+
9+
security {
10+
oauth identity provider github {env.GITHUB_CLIENT_ID} {env.GITHUB_CLIENT_SECRET}
11+
12+
authentication portal myportal {
13+
crypto default token lifetime 3600
14+
crypto key sign-verify {env.JWT_SHARED_KEY}
15+
cookie domain {{domain}}
16+
enable identity provider github
17+
ui {
18+
links {
19+
"My Identity" "/whoami" icon "las la-user"
20+
}
21+
}
22+
23+
transform user {
24+
match realm github
25+
match sub github.com/{{github_org}}
26+
action add role authp/admin
27+
}
28+
}
29+
30+
authorization policy mypolicy {
31+
set auth url https://auth.{{domain}}:443/oauth2/github
32+
crypto key verify {env.JWT_SHARED_KEY}
33+
allow roles authp/admin authp/user
34+
validate bearer header
35+
inject headers with claims
36+
}
37+
}
38+
}
39+
40+
auth.{{domain}} {
41+
authenticate with myportal
742
}

ansible/roles/docker-swarm-app-caddy/assets/Dockerfile

+3
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,7 @@ FROM caddy:${CADDY_VERSION}-alpine
1010

1111
COPY --from=builder /usr/bin/caddy /usr/bin/caddy
1212

13+
COPY docker-entrypoint.sh /usr/local/bin/
14+
15+
ENTRYPOINT ["docker-entrypoint.sh"]
1316
CMD ["caddy", "docker-proxy"]

ansible/roles/docker-swarm-app-caddy/assets/caddy-stack.yml

+14-3
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,13 @@ services:
2121
- caddy_data:/data
2222
- caddy_config:/config
2323
secrets:
24-
- caddy_github_auth
24+
- caddy_github_client_id
25+
- caddy_github_client_secret
26+
- caddy_jwt_shared_key
27+
environment:
28+
GITHUB_CLIENT_ID_FILE: /run/secrets/caddy_github_client_id
29+
GITHUB_CLIENT_SECRET_FILE: /run/secrets/caddy_github_client_secret
30+
JWT_SHARED_KEY_FILE: /run/secrets/caddy_jwt_shared_key
2531
deploy:
2632
placement:
2733
constraints:
@@ -41,9 +47,10 @@ services:
4147
- caddy
4248
deploy:
4349
labels:
44-
caddy: whoami.nokwebspace.ovh
50+
caddy: whoami.{{domain}}
4551
# this include escape for ansible
4652
caddy.reverse_proxy: "{{ '{{' }}upstreams 80{{ '}}' }}"
53+
caddy.authenticate: with myportal
4754

4855
volumes:
4956
caddy_data:
@@ -54,5 +61,9 @@ networks:
5461
attachable: true
5562

5663
secrets:
57-
caddy_github_auth:
64+
caddy_github_client_id:
65+
external: true
66+
caddy_github_client_secret:
67+
external: true
68+
caddy_jwt_shared_key:
5869
external: true

ansible/roles/docker-swarm-app-caddy/assets/caddy_github_auth

-3
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# docker-entrypoint.sh
2+
3+
#!/bin/bash
4+
5+
set -e
6+
7+
file_env() {
8+
local var="$1"
9+
local fileVar="${var}_FILE"
10+
local def="${2:-}"
11+
local varValue=$(env | grep -E "^${var}=" | sed -E -e "s/^${var}=//")
12+
local fileVarValue=$(env | grep -E "^${fileVar}=" | sed -E -e "s/^${fileVar}=//")
13+
if [ -n "${varValue}" ] && [ -n "${fileVarValue}" ]; then
14+
echo >&2 "error: both $var and $fileVar are set (but are exclusive)"
15+
exit 1
16+
fi
17+
if [ -n "${varValue}" ]; then
18+
export "$var"="${varValue}"
19+
elif [ -n "${fileVarValue}" ]; then
20+
export "$var"="$(cat "${fileVarValue}")"
21+
elif [ -n "${def}" ]; then
22+
export "$var"="$def"
23+
fi
24+
unset "$fileVar"
25+
}
26+
27+
env | grep "_FILE" | while read -r line ; do
28+
echo "Processing ${line%_FILE*}"
29+
file_env "${line%_FILE*}"
30+
done
31+
32+
exec "$@"
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
caddy_dir: /var/data/caddy
2+
email: nokwebspace@gmail.com
23
domain: nokwebspace.ovh
34
github_org: xnok

ansible/roles/docker-swarm-app-caddy/tasks/main.yaml

+6-17
Original file line numberDiff line numberDiff line change
@@ -26,26 +26,15 @@
2626
###
2727
# Create Caddy Pre-requisits
2828
###
29-
- name: Create Secret file
30-
template:
31-
src: "{{ role_path }}/assets/caddy_github_auth"
32-
dest: "{{ caddy_dir }}/caddy_github_auth"
33-
mode: '0644'
34-
vars:
35-
github_client_id: "{{ lookup('env', 'CADDY_GITHUB_CLIENT_ID') }}"
36-
github_client_secret: "{{ lookup('env', 'CADDY_GITHUB_CLIENT_SECRET') }}"
37-
jwt_shared_key: "{{ lookup('env', 'CADDY_JWT_SHARED_KEY') | replace('\n', '\\n') }}"
38-
3929
- name: Create secret for github auth
4030
docker_secret:
41-
name: caddy_github_auth
42-
data: "{{ caddy_dir }}/caddy_github_auth"
31+
name: "{{ item.name }}"
32+
data: "{{ item.value }}"
4333
state: present
44-
45-
- name: Remove secrets file
46-
ansible.builtin.file:
47-
path: "{{ caddy_dir }}/caddy_github_auth"
48-
state: absent
34+
loop:
35+
- {name: 'caddy_github_client_id', value: "{{ lookup('env', 'CADDY_GITHUB_CLIENT_ID') }}"}
36+
- {name: 'caddy_github_client_secret', value: "{{ lookup('env', 'CADDY_GITHUB_CLIENT_SECRET') }}"}
37+
- {name: 'caddy_jwt_shared_key', value: "{{ lookup('env', 'CADDY_JWT_SHARED_KEY') | replace('\n', '\\n') }}"}
4938

5039
###
5140
# Start Container

ansible/roles/docker-swarm-app-portainer/assets/portainer-agent-stack.yml.j2

+8-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ version: '3.2'
22

33
services:
44
agent:
5-
image: portainer/agent:2.11.1
5+
image: portainer/agent:2.19.4
66
volumes:
77
- /var/run/docker.sock:/var/run/docker.sock
88
- /var/lib/docker/volumes:/var/lib/docker/volumes
@@ -14,7 +14,7 @@ services:
1414
constraints: [node.platform.os == linux]
1515

1616
portainer:
17-
image: portainer/portainer-ce:2.11.1
17+
image: portainer/portainer-ce:2.19.4
1818
command: -H tcp://tasks.agent:9001 --tlsskipverify
1919
{% if not caddy %}
2020
ports:
@@ -34,6 +34,12 @@ services:
3434
replicas: 1
3535
placement:
3636
constraints: [node.role == manager]
37+
{% if caddy %}
38+
labels:
39+
caddy: portainer.{{domain}}
40+
# this include escape for ansible
41+
caddy.reverse_proxy: "{{ '{{' }}upstreams 9000{{ '}}' }}"
42+
{% endif %}
3743

3844
networks:
3945
agent_network:

0 commit comments

Comments
 (0)