forked from L4GSP1KE/Upload-Assistant
-
Notifications
You must be signed in to change notification settings - Fork 131
refactor(docker): enhance Docker setup and documentation #1245
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
f983a59
refactor(docker): enhance Docker setup and documentation
maksii fa14398
refactor(docker): improve defaults directory setup in Dockerfile
maksii 65bb2b6
feat(webui): implement error boundary and loading state for config page
maksii 896a8aa
refactor(docker): enhance Docker configuration and file handling
maksii 25db34d
docs: update Docker and WebUI documentation for browse roots and sess…
maksii 705c8e0
docs: clarify session secret handling and directory ownership in Dock…
maksii aea026e
Merge branch 'master' into docker-impro
maksii 749dd33
coderabbitai review suggestion
maksii f8a3765
Enhance configuration handling and permissions in Docker entrypoint a…
maksii ff95ee7
Implement dynamic configuration reload in do_the_thing function
maksii 1288872
Merge branch 'master' into docker-impro
maksii cb6098e
coderabbitai review
maksii File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| # Version control | ||
| .git | ||
| .gitignore | ||
| .github | ||
|
|
||
| # Python bytecode & caches | ||
| **/__pycache__ | ||
| **/*.pyc | ||
| **/*.pyo | ||
| *.egg-info | ||
| .mypy_cache | ||
| .ruff_cache | ||
|
|
||
| # Virtual environments (host-side; the image builds its own at /venv) | ||
| venv | ||
| .venv | ||
|
|
||
| # IDE / editor | ||
| .vscode | ||
| .cursor | ||
| .idea | ||
| *.swp | ||
| *.swo | ||
|
|
||
| # Docker files (not needed inside the image) | ||
| docker-compose.yml | ||
| Dockerfile | ||
| .dockerignore | ||
|
|
||
| # Documentation (not needed at runtime) | ||
| docs | ||
|
|
||
| # Runtime artifacts that should not leak into the build context | ||
| tmp | ||
| *.torrent | ||
| *.log | ||
|
|
||
| # OS junk | ||
| Thumbs.db | ||
| .DS_Store | ||
|
|
||
| # Tests / CI | ||
| tests | ||
| .bandit.yaml | ||
| bandit.yaml |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| # Ensure shell scripts always have Unix line endings (LF), even on Windows. | ||
| # Docker exec fails with "no such file or directory" if CRLF leaks into shebangs. | ||
| *.sh text eol=lf | ||
| docker-entrypoint.sh text eol=lf |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,31 +1,99 @@ | ||
| # Upload Assistant — Docker Compose | ||
| # Docs: docs/docker-wiki-full.md & docs/docker-gui-wiki-full.md | ||
| # | ||
| # The entrypoint handles directory permissions and privilege-drop. | ||
| # Pass arguments via `command:`. | ||
| # | ||
| # ── WebUI service ──────────────────────────────────────────────────── | ||
| services: | ||
| upload-assistant-cli: | ||
| upload-assistant: | ||
| image: ghcr.io/audionut/upload-assistant:latest | ||
| container_name: UA | ||
| container_name: upload-assistant | ||
| restart: unless-stopped | ||
|
|
||
| networks: | ||
| - yournetwork #change to the network with ur torrent instance | ||
| ports: | ||
| # Change left side to your specific port. Use 0.0.0.0:5000:5000 to expose to ANY device. | ||
| # 127.0.0.1 means only accessible from the host machine. If you change to 0.0.0.0:5000:5000 it will be accessible from any device on the network | ||
| # including devices outside your network if your router/reverse proxy allows it. | ||
| - yournetwork # change to the network with your torrent client | ||
|
|
||
| ports: | ||
| # Change host-side port/binding as needed. | ||
| # 127.0.0.1 → accessible only from the host machine | ||
| # 0.0.0.0 → accessible from any device on the network | ||
| - "127.0.0.1:5000:5000" | ||
|
|
||
| # ── Pass --webui as the CMD (appended to the ENTRYPOINT) ──────── | ||
| command: ["--webui", "0.0.0.0:5000"] | ||
|
|
||
| environment: | ||
| # Required if not using paths from terminal: allowlisted roots the Web UI is allowed to browse/execute within | ||
| # Optional: run the app as a specific user/group (recommended). | ||
| # The entrypoint starts as root, fixes directory ownership, then | ||
| # drops to this UID/GID before running the app. | ||
| # If omitted the app runs as root inside the container. | ||
| - PUID=1000 | ||
| - PGID=1000 | ||
|
|
||
| # Required in Docker: container-side roots the WebUI is allowed to browse. | ||
| # Docker typically runs with `--webui` only (no paths), so without this the | ||
| # app would use a dummy path and the file browser would not work. | ||
| # Must match the right side (container path) of each `volumes:` entry. | ||
| # Enables granular access: mount a volume but only expose specific | ||
| # subpaths to the WebUI (e.g. omit /torrent_storage_dir). | ||
| - UA_BROWSE_ROOTS=/data/torrents,/Upload-Assistant/tmp | ||
| # Optional: set secret key as key, or use file variant to read from a file. (minimum 32 bytes) permissions handling will apply. | ||
| # - ENV_SESSION_SECRET="SESSION_SECRET" | ||
| # - ENV_SESSION_SECRET_FILE="SESSION_SECRET_FILE" | ||
| # Optional: only needed if you serve the UI from a different origin/domain. | ||
|
|
||
| # Optional: explicit Docker detection (auto-detected in most cases). | ||
| # Accepts: 1, true, yes. Also recognised as RUNNING_IN_CONTAINER. | ||
| # - IN_DOCKER=1 | ||
|
|
||
| # Optional: stable session secret so encrypted WebUI credentials | ||
| # survive container recreates. Provide either the raw value or a | ||
| # path to a file (minimum 32 bytes). | ||
| # - SESSION_SECRET=your-secret-here | ||
| # - SESSION_SECRET_FILE=/Upload-Assistant/data/session_secret | ||
| # | ||
| # NOTE: If you mount a volume to SESSION_SECRET_FILE and the host | ||
| # path does not already exist as a *file*, Docker will create it as | ||
| # a directory. The entrypoint fixes ownership of /Upload-Assistant/ | ||
| # session_secret when PUID/PGID are set, so the app can create the | ||
| # file inside. The recommended approach is to mount the webui-auth | ||
| # volume (see below) and let the app auto-generate the secret there. | ||
|
|
||
| # Optional: only needed if you serve the UI from a different origin. | ||
| # - UA_WEBUI_CORS_ORIGINS=https://your-ui-host | ||
| entrypoint: /bin/bash | ||
| command: -c "source /venv/bin/activate && exec python /Upload-Assistant/upload.py --webui 0.0.0.0:5000" | ||
|
|
||
| # Optional: override the XDG config directory inside the container. | ||
| # Default is /root/.config/upload-assistant (stores session_secret, | ||
| # webui_auth.json). Only change if you mount a different path. | ||
| # - XDG_CONFIG_HOME=/custom/config/path | ||
|
|
||
| volumes: | ||
| - /path/to/torrents/:/data/torrents/:rw #map this to qbit download location, map exactly as qbittorent template on both sides. | ||
| - /mnt/user/appdata/Upload-Assistant/data/config.py:/Upload-Assistant/data/config.py:rw # Optional: will be created automatically if missing | ||
| - /mnt/user/appdata/qBittorrent/data/BT_backup/:/torrent_storage_dir:rw #map this to your qbittorrent bt_backup | ||
| - /mnt/user/appdata/Upload-Assistant/tmp/:/Upload-Assistant/tmp:rw #map this to your /tmp folder. | ||
| - /mnt/user/appdata/Upload-Assistant/webui-auth:/root/.config/upload-assistant:rw # persist web UI session auth config | ||
| # Map your torrent download directory (match qBittorrent paths). | ||
| - /path/to/torrents:/data/torrents:rw | ||
|
|
||
| # Application data — config.py is created automatically from | ||
| # example-config.py on first WebUI start. The directory does NOT | ||
| # need to exist on the host; Docker + the entrypoint create it | ||
| # with the correct ownership. | ||
| - /path/to/appdata/Upload-Assistant/data:/Upload-Assistant/data:rw | ||
|
|
||
| # qBittorrent BT_backup for torrent reuse. | ||
| - /path/to/qBittorrent/BT_backup:/torrent_storage_dir:rw | ||
|
|
||
| # Temp directory for screenshots / processing. | ||
| - /path/to/appdata/Upload-Assistant/tmp:/Upload-Assistant/tmp:rw | ||
|
|
||
| # Persist WebUI session auth config (webui_auth.json, session_secret). | ||
| # This maps to the XDG config dir used inside the container. | ||
| - /path/to/appdata/Upload-Assistant/webui-auth:/root/.config/upload-assistant:rw | ||
|
|
||
| # Give the app time to finish any in-flight work on shutdown. | ||
| stop_grace_period: 15s | ||
|
|
||
| healthcheck: | ||
| test: ["CMD", "curl", "-sf", "http://localhost:5000/api/health"] | ||
| interval: 30s | ||
| timeout: 5s | ||
| start_period: 10s | ||
| retries: 3 | ||
|
|
||
| networks: | ||
| "yournetwork": #change this to your network | ||
| external: true | ||
| yournetwork: # change to your network | ||
| external: true | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| #!/bin/sh | ||
| set -e | ||
|
|
||
| # ── Docker entrypoint ───────────────────────────────────────────────── | ||
| # Handles directory ownership so that fresh volume mounts (created as | ||
| # root by Docker) are writable by the runtime user. | ||
| # | ||
| # Supports two modes: | ||
| # 1. PUID/PGID env vars (recommended) — container starts as root, | ||
| # fixes permissions, then drops to the requested UID/GID. | ||
| # 2. No PUID/PGID — runs as whatever user Docker started (root or | ||
| # the UID from `user:` in compose / --user on CLI). | ||
| # ────────────────────────────────────────────────────────────────────── | ||
|
|
||
| TARGET_UID="${PUID:-}" | ||
| TARGET_GID="${PGID:-}" | ||
|
|
||
| # ── Fix directory ownership (only possible when running as root) ────── | ||
| if [ "$(id -u)" = "0" ]; then | ||
| # Directories the app needs write access to | ||
| # - data, tmp: config, temp files | ||
| # - session_secret: when SESSION_SECRET_FILE points to a path that Docker | ||
| # created as a directory (host path didn't exist), the app creates a | ||
| # session_secret file inside it; the runtime user must be able to write | ||
| # - /root/.config/upload-assistant: webui-auth mount; when PUID is set, | ||
| # the runtime user must traverse /root and write there | ||
| for dir in /Upload-Assistant/data /Upload-Assistant/tmp /Upload-Assistant/session_secret /root/.config/upload-assistant; do | ||
| # If the path already exists as a non-directory (e.g. a file bind-mount), | ||
| # fix its ownership but don't try mkdir -p (which would fail under set -e). | ||
| if [ -e "$dir" ] && [ ! -d "$dir" ]; then | ||
| if [ -n "$TARGET_UID" ]; then | ||
| chown "$TARGET_UID:${TARGET_GID:-$TARGET_UID}" "$dir" 2>/dev/null || true | ||
| fi | ||
| continue | ||
| fi | ||
| mkdir -p "$dir" | ||
| if [ -n "$TARGET_UID" ]; then | ||
| # Recursively fix ownership so that user-placed files (e.g. config.py | ||
| # copied onto the host while the container was stopped) are owned by | ||
| # the runtime user. | ||
| chown -R "$TARGET_UID:${TARGET_GID:-$TARGET_UID}" "$dir" 2>/dev/null || true | ||
| fi | ||
| # Ensure sane permissions: directories traversable, files readable/writable | ||
| # by the owner. Bind mounts from Unraid / NAS hosts can arrive with any | ||
| # mode bits; normalise them so the app can always read and write. | ||
| find "$dir" -type d ! -perm -u=rwx -exec chmod u+rwx {} + 2>/dev/null || true | ||
| find "$dir" -type f ! -perm -u=rw -exec chmod u+rw {} + 2>/dev/null || true | ||
| done | ||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| # When dropping to non-root, the runtime user must traverse /root to reach | ||
| # /root/.config/upload-assistant (webui-auth mount). Make /root traversable. | ||
| if [ -n "$TARGET_UID" ] && [ "$TARGET_UID" != "0" ]; then | ||
| chmod 711 /root 2>/dev/null || true | ||
| fi | ||
|
|
||
| # Drop privileges if PUID was set | ||
| if [ -n "$TARGET_UID" ] && [ "$TARGET_UID" != "0" ]; then | ||
| # Ensure XDG_CONFIG_HOME is set so the app resolves the config | ||
| # directory reliably after gosu drops privileges. When the target | ||
| # UID has no /etc/passwd entry (common in containers), Path.home() | ||
| # returns "/" and the mounted /root/.config/upload-assistant would | ||
| # never be found. | ||
| export XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-/root/.config}" | ||
|
|
||
| exec gosu "$TARGET_UID:${TARGET_GID:-$TARGET_UID}" python /Upload-Assistant/upload.py "$@" | ||
| fi | ||
| fi | ||
|
|
||
| # Fallback: run as current user (root, or whatever `user:` specified) | ||
| exec python /Upload-Assistant/upload.py "$@" | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.