summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar daltux2025-09-04 19:00:34 -0300
committerGravatar daltux2025-09-04 19:00:34 -0300
commitffaa7aeb808c1db3594b5ad1989e20d2154d547c (patch)
treea2466245854438bff8c8d50d2db4b51d2cfc2cfe
parentMerge branch 'master' of https://codeberg.org/daltux/snac2 into docker_tzdata (diff)
downloadpenes-snac2-ffaa7aeb808c1db3594b5ad1989e20d2154d547c.tar.gz
penes-snac2-ffaa7aeb808c1db3594b5ad1989e20d2154d547c.tar.xz
penes-snac2-ffaa7aeb808c1db3594b5ad1989e20d2154d547c.zip
Examples: Docker Swarm with Traefik and container build script.
Example files for setting a complete SNAC + Traefik v3 stack on Docker Swarm mode, including Let's Encrypt certificates, HTTP security headers, and caching of */s/* (SNAC static files) for 24 hours with souin. A script for building the SNAC container with Docker and optionally pushing it to a registry.
-rw-r--r--examples/docker-swarm-traefik/snac_stack.yml114
-rw-r--r--examples/docker-swarm-traefik/traefik_config.yml89
-rwxr-xr-xexamples/docker_build_snac.sh44
3 files changed, 247 insertions, 0 deletions
diff --git a/examples/docker-swarm-traefik/snac_stack.yml b/examples/docker-swarm-traefik/snac_stack.yml
new file mode 100644
index 0000000..e799475
--- /dev/null
+++ b/examples/docker-swarm-traefik/snac_stack.yml
@@ -0,0 +1,114 @@
1---
2# Example of a SNAC + Traefik stack on Docker Swarm mode
3# SNAC behind Traefik v3 reverse proxy
4# including Let's Encrypt certificates, HTTP security headers
5# and caching */s/* (SNAC static files) for 24h with souin.
6#
7# docker stack deploy -c snac_stack.yml snac
8
9services:
10 traefik:
11 image: traefik:v3
12 hostname: '{{.Node.Hostname}}'
13 ports:
14 # listen on host ports without ingress network
15 - target: 80
16 published: 80
17 protocol: tcp
18 mode: host
19 - target: 443
20 published: 443
21 protocol: tcp
22 mode: host
23 - target: 443
24 published: 443
25 protocol: udp # for HTTP3
26 mode: host
27 networks:
28 - proxy
29 volumes:
30 - /opt/docker/traefik/traefik.yml:/etc/traefik/traefik_config.yml # main Traefik static configuration
31 - /opt/docker/traefik/dynamic:/etc/traefik/dynamic # for Traefik dynamic configuration files
32 - /opt/docker/acme:/acme # directory for certificate storage files
33 - /opt/docker/traefik/log:/var/log
34 - /var/run/docker.sock:/var/run/docker.sock:ro
35 - /usr/share/zoneinfo/America/Sao_Paulo:/etc/localtime:ro # Change this to another or comment/remove to use UTC
36 - /etc/timezone:/etc/timezone:ro # Comment/remove to use UTC
37 environment:
38 - TZ=America/Sao_Paulo # Change it to another or comment/remove to use UTC
39 deploy:
40 mode: global
41 placement:
42 constraints:
43 - node.role==manager
44 labels:
45 - traefik.enable=true
46 - traefik.http.routers.mydashboard.rule=Host(`traefik.example.net`) # for Traefik dashboard
47 - traefik.http.routers.mydashboard.service=api@internal
48 - traefik.http.routers.mydashboard.middlewares=traefik_auth,traefik_retry
49 - traefik.http.services.mydashboard.loadbalancer.server.port=1337
50 - traefik.http.middlewares.traefik_retry.retry.attempts=3
51 - traefik.http.middlewares.traefik_retry.retry.initialinterval=200ms
52 # How to generate a password hash: echo $(htpasswd -nB desired_username) | sed -e s/\\$/\\$\\$/g
53 - traefik.http.middlewares.traefik_auth.basicauth.users=desired_username:PASTE_THE_PASSWORD_HASH_HERE
54 resources:
55 limits:
56 cpus: "2"
57 memory: 1g
58 reservations:
59 memory: 256m
60
61 snac:
62 image: codeberg.org/daltux/snac:2.82-dev_daltux3
63 hostname: '{{.Node.Hostname}}'
64 restart: unless-stopped
65 security_opt:
66 - no-new-privileges:true
67 volumes:
68 - /opt/snac:/data
69 networks:
70 - proxy
71 depends_on:
72 - traefik
73 environment:
74 - TZ=America/Sao_Paulo # Change this to your own or comment/remove it to use UTC.
75 deploy:
76 mode: replicated
77 replicas: 1
78 labels:
79 - traefik.enable=true
80 - traefik.http.services.snac.loadbalancer.server.port=8001
81 - traefik.http.routers.snac.rule=Host(`snac.example.net`)
82 - traefik.http.routers.snac.priority=1
83 - traefik.http.routers.snac.middlewares=snac_headers@swarm,traefik_retry@swarm
84 - "traefik.http.routers.snac_static.rule=Host(`snac.example.net`) && PathRegexp(`^/.+/s/.+`)"
85 - "traefik.http.routers.snac_static.priority=2"
86 - "traefik.http.routers.snac_static.middlewares=snac_headers@swarm,snac_cache_static@swarm,traefik_retry@swarm"
87 - traefik.http.middlewares.snac_headers.headers.stsSeconds=31536000
88 - traefik.http.middlewares.snac_headers.headers.stsIncludeSubdomains=false
89 - traefik.http.middlewares.snac_headers.headers.stsPreload=false
90 - traefik.http.middlewares.snac_headers.headers.customFrameOptionsValue=SAMEORIGIN
91 - traefik.http.middlewares.snac_headers.headers.contentTypeNosniff=true
92 - traefik.http.middlewares.snac_headers.headers.browserXssFilter=true
93 - traefik.http.middlewares.snac_headers.headers.referrerPolicy=strict-origin-when-cross-origin
94 - "traefik.http.middlewares.snac_headers.headers.contentSecurityPolicy=default-src 'self'; base-uri 'self'; script-src 'none'; style-src 'self' 'unsafe-inline'; form-action 'self'; img-src https: data:; font-src 'self'; media-src https: data:; connect-src 'none'; frame-src 'none'; frame-ancestors 'none';"
95 - traefik.http.middlewares.snac_cache_static.plugin.souin.api.souin=true
96 - traefik.http.middlewares.snac_cache_static.plugin.souin.log_level=info
97 - traefik.http.middlewares.snac_cache_static.plugin.souin.default_cache.ttl=1440m
98 - traefik.http.middlewares.snac_cache_static.plugin.souin.default_cache.allowed_http_verbs=GET,HEAD
99 - traefik.http.middlewares.snac_cache_static.plugin.souin.default_cache.stale=1h
100 - traefik.http.middlewares.snac_cache_static.plugin.souin.default_cache.etag=true
101 - "traefik.http.middlewares.snac_cache_static.plugin.souin.default_cache.default_cache_control=public, max-age=86400"
102 resources:
103 limits:
104 cpus: "3"
105 memory: 1g
106 reservations:
107 memory: 256m
108
109networks:
110 proxy:
111 name: proxy
112 driver: overlay
113 attachable: true
114 external: true
diff --git a/examples/docker-swarm-traefik/traefik_config.yml b/examples/docker-swarm-traefik/traefik_config.yml
new file mode 100644
index 0000000..045408c
--- /dev/null
+++ b/examples/docker-swarm-traefik/traefik_config.yml
@@ -0,0 +1,89 @@
1---
2# Traefik main config file
3# e.g. /opt/docker/traefik/traefik_config.yml
4
5entryPoints:
6 web:
7 address: ":80"
8 http:
9 encodeQuerySemicolons: true
10 redirections:
11 entryPoint:
12 to: websecure
13 scheme: https
14 permanent: true
15 websecure:
16 address: ":443"
17 asDefault: true
18 http:
19 encodeQuerySemicolons: true
20 tls:
21 certResolver: letsencrypt
22 http2:
23 maxConcurrentStreams: 100
24 http3: {}
25
26certificatesResolvers:
27 letsencrypt:
28 acme:
29 email: you@example.net
30 storage: "/acme/letsencrypt.json"
31 keyType: EC384
32 httpChallenge:
33 entryPoint: web
34# buypass:
35# acme:
36# email: you@example.net
37# caServer: "https://api.buypass.com/acme/directory"
38# storage: "/acme/buypass.json"
39# keyType: EC256
40# certificatesDuration: 4320
41# httpChallenge:
42# entryPoint: web
43
44ocsp: {}
45
46tls:
47 stores:
48 default:
49 defaultGeneratedCert:
50 resolver: letsencrypt
51 domain:
52 main: snac.example.net
53 # sans:
54 # - other.example.net
55 # - another.example.net
56
57providers:
58 file:
59 directory: "/etc/traefik/dynamic"
60 watch: true
61 swarm:
62 network: "proxy"
63 endpoint: "unix:///var/run/docker.sock"
64 exposedByDefault: false
65 watch: true
66 allowEmptyServices: true
67
68api:
69 dashboard: true
70 insecure: false
71 debug: false
72 disabledashboardad: true
73
74log:
75 level: "INFO"
76 filePath: "/var/log/server.log"
77
78accessLog:
79 filePath: "/var/log/traefik-access.log"
80 bufferingSize: 15
81 fields:
82 names:
83 StartUTC: "drop"
84
85experimental:
86 plugins:
87 souin:
88 moduleName: "github.com/darkweak/souin"
89 version: "v1.7.7"
diff --git a/examples/docker_build_snac.sh b/examples/docker_build_snac.sh
new file mode 100755
index 0000000..387aa49
--- /dev/null
+++ b/examples/docker_build_snac.sh
@@ -0,0 +1,44 @@
1#!/bin/sh
2#
3# docker_build_snac.sh : build a SNAC container image
4# and optionally send it to a container registry.
5#
6# Set variables e.g. if you want version to be different from 'latest':
7# img_version=2.82 ./docker_build_snac.sh
8
9src_dir=${src_dir:-"$HOME/src/snac2"}
10img_name=${img_name:-'snac'}
11img_version=${img_version:-'latest'}
12#registry=${registry:-'codeberg.org'}
13#reg_user=${reg_user:-'daltux'}
14
15if [ -z "$tag" ] ; then
16 if [ -n "$reg_user" ] && [ -z "$registry" ] ; then
17 echo "Missing container registry name. Set variable \"registry\"." >&2
18 exit 10
19 fi
20
21 if [ -z "$registry" ] ; then
22 tag="$img_name:$img_version"
23 elif [ -z "$reg_user" ] ; then
24 echo "Container registry user unknown. Set variable \"reg_user\"." >&2
25 exit 20
26 else
27 tag="$registry/$reg_user/$img_name:$img_version"
28 fi
29fi
30
31if [ -d "$src_dir" ] ; then
32 echo "Entering directory \"$src_dir\"..."
33 cd "$src_dir" || exit $?
34 docker build --no-cache -f Dockerfile -t "$tag" . || exit $?
35else
36 echo "Invalid directory \"$src_dir\"" >&2
37 exit 30
38fi
39
40if [ -n "$registry" ] ; then
41 #docker login "$registry" || $?
42 docker image push "$tag"
43fi
44