This commit is contained in:
Daniel 2025-08-16 14:11:37 +02:00 committed by GitHub
commit 47c1eb1c05
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 85 additions and 77 deletions

View file

@ -1,5 +1,6 @@
services: ---
services:
copyparty: copyparty:
image: copyparty/ac:latest image: copyparty/ac:latest
container_name: copyparty container_name: copyparty

View file

@ -2,48 +2,48 @@
> I am unable to guarantee the quality, safety, and security of anything in this folder; it is a combination of examples I found online. Please submit corrections or improvements 🙏 > I am unable to guarantee the quality, safety, and security of anything in this folder; it is a combination of examples I found online. Please submit corrections or improvements 🙏
to try this out with minimal adjustments: to try this out with minimal adjustments:
* specify what filesystem-path to share with copyparty, replacing the default/example value `/srv/pub` in `docker-compose.yml`
* add `127.0.0.1 fs.example.com traefik.example.com authelia.example.com` to your `/etc/hosts` - specify what filesystem-path to share with copyparty, replacing the default/example value `/srv/pub` in `docker-compose.yml`
* `sudo docker-compose up` - add `127.0.0.1 fs.example.com traefik.example.com authelia.example.com` to your `/etc/hosts`
* login to https://fs.example.com/ with username `authelia` password `authelia` - `sudo docker-compose up`
- login to https://fs.example.com/ with username `authelia` password `authelia`
to use this in a safe and secure manner: to use this in a safe and secure manner:
* follow a guide on setting up authelia properly (TODO:link) and use the copyparty-specific parts of this folder as inspiration for your own config; namely the `cpp` subfolder and the `copyparty` service in `docker-compose.yml`
- follow a guide on setting up [authelia](https://www.authelia.com/integration/proxies/traefik/#docker-compose) properly and use the copyparty-specific parts of this folder as inspiration for your own config; namely the `cpp` subfolder and the `copyparty` service in `docker-compose.yml`
this folder is based on: this folder is based on:
* https://github.com/authelia/authelia/tree/39763aaed24c4abdecd884b47357a052b235942d/examples/compose/lite
- https://github.com/authelia/authelia/tree/39763aaed24c4abdecd884b47357a052b235942d/examples/compose/lite
incomplete list of modifications made: incomplete list of modifications made:
* support for running with podman as root on fedora (`:z` volumes, `label:disable`)
* explicitly using authelia `v4.38.0-beta3` because config syntax changed since last stable release
* disabled automatic letsencrypt certificate signing
* reduced logging from debug to info
* added a warning that traefik is given access to the docker socket (as recommended by traefik docs) which means traefik is able to break out of the container and has full root access on the host machine
- support for running with podman as root on fedora (`:z` volumes, `label:disable`)
- explicitly using authelia `v4.38.0-beta3` because config syntax changed since last stable release
- reduced logging from debug to info
- implemented a docker socket-proxy to not bind the docker.socket directly to traefik
- using valkey instead of redis for caching
# security # security
there is probably/definitely room for improvement in this example setup. Some ideas taken from [github issue #62](https://github.com/9001/copyparty/issues/62): there is probably/definitely room for improvement in this example setup. Some ideas taken from [github issue #62](https://github.com/9001/copyparty/issues/62):
* Add in a redis password to limit attacker lateral movement in the system - Move valkey to a private network shared with just authelia
* Move redis to a private network shared with just authelia - Add `watchtower` to manage your image version updates
* Pin to image hashes (or go all in on updates and add `watchtower`) - Drop bridge networking for just exposing traefik's public ports
* Drop bridge networking for just exposing traefik's public ports
* Configure docker for non-root access to docker socket and then move traefik to use [non-root perms](https://docs.docker.com/engine/security/rootless/)
if you manage to improve on any of this, especially in a way that might be useful for other people, consider sending a PR :>
If you manage to improve on any of this, especially in a way that might be useful for other people, consider sending a PR :>
# performance # performance
currently **not optimal,** at least when compared to running the python sfx outside of docker... some numbers from my laptop (ryzen4500u/fedora39): currently **not optimal,** at least when compared to running the python sfx outside of docker... some numbers from my laptop (ryzen4500u/fedora39):
| req/s | https D/L | http D/L | approach | | req/s | https D/L | http D/L | approach |
| -----:| ----------:|:--------:| -------- | | ----: | ---------: | :------: | --------------------------------------------------------------------------------------------------------------- |
| 5200 | 1294 MiB/s | 5+ GiB/s | [copyparty-sfx.py](https://github.com/9001/copyparty/releases/latest/download/copyparty-sfx.py) running on host | | 5200 | 1294 MiB/s | 5+ GiB/s | [copyparty-sfx.py](https://github.com/9001/copyparty/releases/latest/download/copyparty-sfx.py) running on host |
| 4370 | 725 MiB/s | 4+ GiB/s | `docker run copyparty/ac` | | 4370 | 725 MiB/s | 4+ GiB/s | `docker run copyparty/ac` |
| 2420 | 694 MiB/s | n/a | `copyparty/ac` behind traefik | | 2420 | 694 MiB/s | n/a | `copyparty/ac` behind traefik |
| 75 | 694 MiB/s | n/a | traefik and authelia **(you are here)** | | 75 | 694 MiB/s | n/a | traefik and authelia **(you are here)** |
authelia is behaving strangely, handling 340 requests per second for a while, but then it suddenly drops to 75 and stays there... authelia is behaving strangely, handling 340 requests per second for a while, but then it suddenly drops to 75 and stays there...

View file

@ -1,15 +1,14 @@
# based on https://github.com/authelia/authelia/blob/39763aaed24c4abdecd884b47357a052b235942d/examples/compose/lite/authelia/configuration.yml
# Authelia configuration # Authelia configuration
# This secret can also be set using the env variables AUTHELIA_JWT_SECRET_FILE identity_validation:
jwt_secret: a_very_important_secret reset_password:
jwt_secret: 'a_very_important_secret'
server: server:
address: 'tcp://:9091' address: 'tcp://:9091'
log: log:
level: info # debug level: info
totp: totp:
issuer: authelia.com issuer: authelia.com
@ -21,29 +20,26 @@ authentication_backend:
access_control: access_control:
default_policy: deny default_policy: deny
rules: rules:
# Rules applied to everyone - domain: auth.example.com
- domain: traefik.example.com policy: bypass # Allow access to the login UI
policy: one_factor
- domain: fs.example.com - domain: fs.example.com
policy: one_factor policy: one_factor
session: session:
# This secret can also be set using the env variables AUTHELIA_SESSION_SECRET_FILE
secret: unsecure_session_secret secret: unsecure_session_secret
cookies: cookies:
- name: authelia_session - name: authelia_session
domain: example.com # Should match whatever your root protected domain is domain: example.com # Root protected domain
default_redirection_url: https://fs.example.com default_redirection_url: https://fs.example.com
authelia_url: https://authelia.example.com/ authelia_url: https://authelia.example.com/
expiration: 3600 # 1 hour expiration: 3600 # 1 hour
inactivity: 300 # 5 minutes inactivity: 300 # 5 minutes
redis: redis:
host: redis host: valkey
port: 6379 port: 6379
# This secret can also be set using the env variables AUTHELIA_SESSION_REDIS_PASSWORD_FILE password: your_secure_password_here
# password: authelia
regulation: regulation:
max_retries: 3 max_retries: 3
@ -58,9 +54,7 @@ storage:
notifier: notifier:
disable_startup_check: true disable_startup_check: true
smtp: smtp:
username: test address: 'smtp://127.0.0.1:25'
# This secret can also be set using the env variables AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE username: 'test'
password: password password: 'password'
host: mail.example.com sender: "Authelia <admin@example.com>"
port: 25
sender: admin@example.com

View file

@ -1,4 +1,4 @@
version: '3.3' ---
networks: networks:
net: net:
@ -6,7 +6,7 @@ networks:
services: services:
copyparty: copyparty:
image: copyparty/ac image: copyparty/ac:1.18.8@sha256:19348cf85bf0df2f0b5b476162d73c72ef8bcbe0f12dd910d3cb05c0312641aa
container_name: idp_copyparty container_name: idp_copyparty
user: "1000:1000" # should match the user/group of your fileshare volumes user: "1000:1000" # should match the user/group of your fileshare volumes
volumes: volumes:
@ -19,19 +19,19 @@ services:
labels: labels:
- 'traefik.enable=true' - 'traefik.enable=true'
- 'traefik.http.routers.copyparty.rule=Host(`fs.example.com`)' - 'traefik.http.routers.copyparty.rule=Host(`fs.example.com`)'
- 'traefik.http.routers.copyparty.entrypoints=https' - 'traefik.http.routers.copyparty.entrypoints=websecure'
- 'traefik.http.routers.copyparty.tls=true' - 'traefik.http.routers.copyparty.tls=true'
- 'traefik.http.routers.copyparty.tls.certresolver=letsencrypt' # ← THIS IS CRUCIAL
- 'traefik.http.routers.copyparty.middlewares=authelia@docker' - 'traefik.http.routers.copyparty.middlewares=authelia@docker'
stop_grace_period: 15s # thumbnailer is allowed to continue finishing up for 10s after the shutdown signal stop_grace_period: 15s # thumbnailer is allowed to continue finishing up for 10s after the shutdown signal
environment: environment:
LD_PRELOAD: /usr/lib/libmimalloc-secure.so.NOPE LD_PRELOAD: /usr/lib/libmimalloc-secure.so.NOPE
# enable mimalloc by replacing "NOPE" with "2" for a nice speed-boost (will use twice as much ram) # enable mimalloc by replacing "NOPE" with "2" for a nice speed-boost (will use twice as much ram)
PYTHONUNBUFFERED: 1 PYTHONUNBUFFERED: 1
# ensures log-messages are not delayed (but can reduce speed a tiny bit) # ensures log-messages are not delayed (but can reduce speed a tiny bit)
authelia: authelia:
image: authelia/authelia:v4.38.0-beta3 # the config files in the authelia folder use the new syntax image: authelia/authelia:4.39.5@sha256:023e02e5203dfa0ebaee7a48b5bae34f393d1f9cada4a9df7fbf87eb1759c671
container_name: idp_authelia container_name: idp_authelia
volumes: volumes:
- ./authelia:/config:z - ./authelia:/config:z
@ -40,25 +40,23 @@ services:
labels: labels:
- 'traefik.enable=true' - 'traefik.enable=true'
- 'traefik.http.routers.authelia.rule=Host(`authelia.example.com`)' - 'traefik.http.routers.authelia.rule=Host(`authelia.example.com`)'
- 'traefik.http.routers.authelia.entrypoints=https' - 'traefik.http.routers.authelia.entrypoints=websecure'
- 'traefik.http.routers.authelia.tls=true' - 'traefik.http.routers.authelia.tls=true'
#- 'traefik.http.routers.authelia.tls.certresolver=letsencrypt' # uncomment this to enable automatic certificate signing (1/2) - 'traefik.http.routers.authelia.tls.certresolver=letsencrypt'
- 'traefik.http.middlewares.authelia.forwardauth.address=http://authelia:9091/api/authz/forward-auth?authelia_url=https://authelia.example.com' - 'traefik.http.middlewares.authelia.forwardauth.address=http://authelia:9091/api/authz/forward-auth?authelia_url=https://authelia.example.com'
- 'traefik.http.middlewares.authelia.forwardauth.trustForwardHeader=true' - 'traefik.http.middlewares.authelia.forwardauth.trustForwardHeader=true'
- 'traefik.http.middlewares.authelia.forwardauth.authResponseHeaders=Remote-User,Remote-Groups,Remote-Name,Remote-Email' - 'traefik.http.middlewares.authelia.forwardauth.authResponseHeaders=Remote-User,Remote-Groups,Remote-Name,Remote-Email'
expose: expose:
- 9091 - 9091
restart: unless-stopped restart: unless-stopped
healthcheck:
disable: true
environment: environment:
- TZ=Etc/UTC - TZ=Etc/UTC
redis: valkey:
image: redis:7.2.4-alpine3.19 image: valkey/valkey:8.1.3-alpine3.22@sha256:0d27f0bca0249f61d060029a6aaf2e16b2c417d68d02a508e1dfb763fa2948b4
container_name: idp_redis container_name: idp_valkey
volumes: volumes:
- ./redis:/data:z - ./valkey:/data:z
networks: networks:
- net - net
expose: expose:
@ -66,40 +64,55 @@ services:
restart: unless-stopped restart: unless-stopped
environment: environment:
- TZ=Etc/UTC - TZ=Etc/UTC
- VALKEY_EXTRA_FLAGS=--requirepass your_secure_password_here
socket-proxy:
image: lscr.io/linuxserver/socket-proxy:3.2.3@sha256:63d2e0ce6bb0d12dfdbde5c3af31d08fee343ec3801a050c8197a3f5ffae8bed
container_name: idp_socket_proxy
environment:
- CONTAINERS=1
- NETWORKS=1
- EVENTS=1
- PING=1
- VERSION=1
- LOG_LEVEL=warning
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
security_opt:
- no-new-privileges:true
read_only: true
tmpfs:
- /run
networks:
- net
restart: unless-stopped
expose:
- 2375
traefik: traefik:
image: traefik:2.11.0 image: traefik:3.5.0@sha256:4e7175cfe19be83c6b928cae49dde2f2788fb307189a4dc9550b67acf30c11a5
container_name: idp_traefik container_name: idp_traefik
volumes: volumes:
- ./traefik:/etc/traefik:z - ./traefik:/etc/traefik:z
- /var/run/docker.sock:/var/run/docker.sock # WARNING: this gives traefik full root-access to the host OS, but is recommended/required(?) by traefik
security_opt:
- label:disable # disable selinux because it (rightly) blocks access to docker.sock
networks: networks:
- net - net
labels: labels:
- 'traefik.enable=true' - 'traefik.enable=true'
- 'traefik.http.routers.api.rule=Host(`traefik.example.com`)'
- 'traefik.http.routers.api.entrypoints=https'
- 'traefik.http.routers.api.service=api@internal'
- 'traefik.http.routers.api.tls=true'
#- 'traefik.http.routers.api.tls.certresolver=letsencrypt' # uncomment this to enable automatic certificate signing (2/2)
- 'traefik.http.routers.api.middlewares=authelia@docker' - 'traefik.http.routers.api.middlewares=authelia@docker'
ports: ports:
- '80:80' - '80:80'
- '443:443' - '443:443'
command: command:
- '--api' - '--global.sendAnonymousUsage=false'
- '--providers.docker=true' - '--providers.docker.endpoint=tcp://socket-proxy:2375'
- '--providers.docker.exposedByDefault=false' - '--providers.docker.exposedByDefault=false'
- '--entrypoints.http=true' - '--entrypoints.web.address=:80'
- '--entrypoints.http.address=:80' - '--entrypoints.web.http.redirections.entrypoint.to=websecure'
- '--entrypoints.http.http.redirections.entrypoint.to=https' - '--entrypoints.web.http.redirections.entrypoint.scheme=https'
- '--entrypoints.http.http.redirections.entrypoint.scheme=https' - '--entrypoints.websecure.address=:443'
- '--entrypoints.https=true'
- '--entrypoints.https.address=:443'
- '--certificatesResolvers.letsencrypt.acme.email=your-email@your-domain.com' - '--certificatesResolvers.letsencrypt.acme.email=your-email@your-domain.com'
- '--certificatesResolvers.letsencrypt.acme.storage=/etc/traefik/acme.json' - '--certificatesResolvers.letsencrypt.acme.storage=/etc/traefik/acme.json'
- '--certificatesResolvers.letsencrypt.acme.httpChallenge.entryPoint=http' - '--certificatesResolvers.letsencrypt.acme.httpChallenge.entryPoint=web'
- '--log=true' - '--log.level=INFO'
- '--log.level=WARNING' # DEBUG depends_on:
- socket-proxy