commit 9149959

grunfink  ·  2025-09-06 07:39:23 +0000 UTC
parents 6dae96d, ffaa7ae
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
+89, -0
 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+