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