mirror of
				https://github.com/linuxserver/docker-transmission.git
				synced 2025-10-31 08:55:47 +01:00 
			
		
		
		
	Support nonroot and RO operation
This commit is contained in:
		| @@ -1,6 +1,6 @@ | |||||||
| # syntax=docker/dockerfile:1 | # syntax=docker/dockerfile:1 | ||||||
|  |  | ||||||
| FROM ghcr.io/linuxserver/unrar:latest as unrar | FROM ghcr.io/linuxserver/unrar:latest AS unrar | ||||||
|  |  | ||||||
| FROM ghcr.io/linuxserver/baseimage-alpine:edge | FROM ghcr.io/linuxserver/baseimage-alpine:edge | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| # syntax=docker/dockerfile:1 | # syntax=docker/dockerfile:1 | ||||||
|  |  | ||||||
| FROM ghcr.io/linuxserver/unrar:arm64v8-latest as unrar | FROM ghcr.io/linuxserver/unrar:arm64v8-latest AS unrar | ||||||
|  |  | ||||||
| FROM ghcr.io/linuxserver/baseimage-alpine:arm64v8-edge | FROM ghcr.io/linuxserver/baseimage-alpine:arm64v8-edge | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										18
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								README.md
									
									
									
									
									
								
							| @@ -83,6 +83,14 @@ Use `HOST_WHITELIST` to enable an list of dns names as host-whitelist. This enab | |||||||
|  |  | ||||||
| Use `PEERPORT` to specify the port(s) Transmission should listen on.  This disables random port selection.  This should be the same as the port mapped in your docker configuration. | Use `PEERPORT` to specify the port(s) Transmission should listen on.  This disables random port selection.  This should be the same as the port mapped in your docker configuration. | ||||||
|  |  | ||||||
|  | ## Read-Only Operation | ||||||
|  |  | ||||||
|  | This image can be run with a read-only container filesystem. For details please [read the docs](https://docs.linuxserver.io/misc/read-only/). | ||||||
|  |  | ||||||
|  | ## Non-Root Operation | ||||||
|  |  | ||||||
|  | This image can be run with a non-root user. For details please [read the docs](https://docs.linuxserver.io/misc/non-root/). | ||||||
|  |  | ||||||
| ## Usage | ## Usage | ||||||
|  |  | ||||||
| To help you get started creating a container from this image you can either use docker-compose or the docker cli. | To help you get started creating a container from this image you can either use docker-compose or the docker cli. | ||||||
| @@ -110,8 +118,8 @@ services: | |||||||
|       - HOST_WHITELIST= #optional |       - HOST_WHITELIST= #optional | ||||||
|     volumes: |     volumes: | ||||||
|       - /path/to/transmission/data:/config |       - /path/to/transmission/data:/config | ||||||
|       - /path/to/downloads:/downloads |       - /path/to/downloads:/downloads #optional | ||||||
|       - /path/to/watch/folder:/watch |       - /path/to/watch/folder:/watch #optional | ||||||
|     ports: |     ports: | ||||||
|       - 9091:9091 |       - 9091:9091 | ||||||
|       - 51413:51413 |       - 51413:51413 | ||||||
| @@ -137,8 +145,8 @@ docker run -d \ | |||||||
|   -p 51413:51413 \ |   -p 51413:51413 \ | ||||||
|   -p 51413:51413/udp \ |   -p 51413:51413/udp \ | ||||||
|   -v /path/to/transmission/data:/config \ |   -v /path/to/transmission/data:/config \ | ||||||
|   -v /path/to/downloads:/downloads \ |   -v /path/to/downloads:/downloads `#optional` \ | ||||||
|   -v /path/to/watch/folder:/watch \ |   -v /path/to/watch/folder:/watch `#optional` \ | ||||||
|   --restart unless-stopped \ |   --restart unless-stopped \ | ||||||
|   lscr.io/linuxserver/transmission:latest |   lscr.io/linuxserver/transmission:latest | ||||||
| ``` | ``` | ||||||
| @@ -164,6 +172,8 @@ Containers are configured using parameters passed at runtime (such as those abov | |||||||
| | `-v /config` | Where transmission should store config files and logs. | | | `-v /config` | Where transmission should store config files and logs. | | ||||||
| | `-v /downloads` | Local path for downloads. | | | `-v /downloads` | Local path for downloads. | | ||||||
| | `-v /watch` | Watch folder for torrent files. | | | `-v /watch` | Watch folder for torrent files. | | ||||||
|  | | `--read-only=true` | Run container with a read-only filesystem. Please [read the docs](https://docs.linuxserver.io/misc/read-only/). | | ||||||
|  | | `--user=1000:1000` | Run container with a non-root user. Please [read the docs](https://docs.linuxserver.io/misc/non-root/). | | ||||||
|  |  | ||||||
| ## Environment variables from files (Docker secrets) | ## Environment variables from files (Docker secrets) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -16,6 +16,8 @@ param_container_name: "{{ project_name }}" | |||||||
| param_usage_include_vols: true | param_usage_include_vols: true | ||||||
| param_volumes: | param_volumes: | ||||||
|   - {vol_path: "/config", vol_host_path: "/path/to/{{ project_name }}/data", desc: "Where transmission should store config files and logs."} |   - {vol_path: "/config", vol_host_path: "/path/to/{{ project_name }}/data", desc: "Where transmission should store config files and logs."} | ||||||
|  | opt_param_usage_include_vols: true | ||||||
|  | opt_param_volumes: | ||||||
|   - {vol_path: "/downloads", vol_host_path: "/path/to/downloads", desc: "Local path for downloads."} |   - {vol_path: "/downloads", vol_host_path: "/path/to/downloads", desc: "Local path for downloads."} | ||||||
|   - {vol_path: "/watch", vol_host_path: "/path/to/watch/folder", desc: "Watch folder for torrent files."} |   - {vol_path: "/watch", vol_host_path: "/path/to/watch/folder", desc: "Watch folder for torrent files."} | ||||||
| param_usage_include_ports: true | param_usage_include_ports: true | ||||||
| @@ -32,6 +34,8 @@ opt_param_env_vars: | |||||||
|   - {env_var: "WHITELIST", env_value: "", desc: "Specify an optional list of comma separated ip whitelist. Fills rpc-whitelist setting."} |   - {env_var: "WHITELIST", env_value: "", desc: "Specify an optional list of comma separated ip whitelist. Fills rpc-whitelist setting."} | ||||||
|   - {env_var: "PEERPORT", env_value: "", desc: "Specify an optional port for torrent TCP/UDP connections. Fills peer-port setting."} |   - {env_var: "PEERPORT", env_value: "", desc: "Specify an optional port for torrent TCP/UDP connections. Fills peer-port setting."} | ||||||
|   - {env_var: "HOST_WHITELIST", env_value: "", desc: "Specify an optional list of comma separated dns name whitelist. Fills rpc-host-whitelist setting."} |   - {env_var: "HOST_WHITELIST", env_value: "", desc: "Specify an optional list of comma separated dns name whitelist. Fills rpc-host-whitelist setting."} | ||||||
|  | readonly_supported: true | ||||||
|  | nonroot_supported: true | ||||||
| # application setup block | # application setup block | ||||||
| app_setup_block_enabled: true | app_setup_block_enabled: true | ||||||
| app_setup_block: | | app_setup_block: | | ||||||
|   | |||||||
| @@ -1,10 +1,6 @@ | |||||||
| #!/usr/bin/with-contenv bash | #!/usr/bin/with-contenv bash | ||||||
| # shellcheck shell=bash | # shellcheck shell=bash | ||||||
|  |  | ||||||
| # make folders |  | ||||||
| mkdir -p \ |  | ||||||
|     /downloads/{complete,incomplete} /watch |  | ||||||
|  |  | ||||||
| # copy config | # copy config | ||||||
| if [[ ! -f /config/settings.json ]]; then | if [[ ! -f /config/settings.json ]]; then | ||||||
|     cp /defaults/settings.json /config/settings.json |     cp /defaults/settings.json /config/settings.json | ||||||
| @@ -12,25 +8,25 @@ fi | |||||||
|  |  | ||||||
| if [[ -n "${USER}" ]] && [[ -n "${PASS}" ]]; then | if [[ -n "${USER}" ]] && [[ -n "${PASS}" ]]; then | ||||||
|     echo -E "$(jq -r '.["rpc-authentication-required"] = true' /config/settings.json)" >/config/settings.json |     echo -E "$(jq -r '.["rpc-authentication-required"] = true' /config/settings.json)" >/config/settings.json | ||||||
|  |     echo -E "$(jq -r --arg user "${USER}" '.["rpc-username"] = $user' /config/settings.json)" >/config/settings.json | ||||||
|  |     echo -E "$(jq -r --arg pass "${PASS}" '.["rpc-password"] = $pass' /config/settings.json)" >/config/settings.json | ||||||
| else | else | ||||||
|     echo -E "$(jq -r '.["rpc-authentication-required"] = false' /config/settings.json)" >/config/settings.json |     echo -E "$(jq -r '.["rpc-authentication-required"] = false' /config/settings.json)" >/config/settings.json | ||||||
| fi | fi | ||||||
| echo -E "$(jq -r --arg user "${USER}" '.["rpc-username"] = $user' /config/settings.json)" >/config/settings.json |  | ||||||
| echo -E "$(jq -r --arg pass "${PASS}" '.["rpc-password"] = $pass' /config/settings.json)" >/config/settings.json |  | ||||||
|  |  | ||||||
| if [[ -n "${WHITELIST}" ]]; then | if [[ -n "${WHITELIST}" ]]; then | ||||||
|     echo -E "$(jq -r '.["rpc-whitelist-enabled"] = true' /config/settings.json)" >/config/settings.json |     echo -E "$(jq -r '.["rpc-whitelist-enabled"] = true' /config/settings.json)" >/config/settings.json | ||||||
|  |     echo -E "$(jq -r --arg whitelist "${WHITELIST}" '.["rpc-whitelist"] = $whitelist' /config/settings.json)" >/config/settings.json | ||||||
| else | else | ||||||
|     echo -E "$(jq -r '.["rpc-whitelist-enabled"] = false' /config/settings.json)" >/config/settings.json |     echo -E "$(jq -r '.["rpc-whitelist-enabled"] = false' /config/settings.json)" >/config/settings.json | ||||||
| fi | fi | ||||||
| echo -E "$(jq -r --arg whitelist "${WHITELIST}" '.["rpc-whitelist"] = $whitelist' /config/settings.json)" >/config/settings.json |  | ||||||
|  |  | ||||||
| if [[ -n "${HOST_WHITELIST}" ]]; then | if [[ -n "${HOST_WHITELIST}" ]]; then | ||||||
|     echo -E "$(jq -r '.["rpc-host-whitelist-enabled"] = true' /config/settings.json)" >/config/settings.json |     echo -E "$(jq -r '.["rpc-host-whitelist-enabled"] = true' /config/settings.json)" >/config/settings.json | ||||||
|  |     echo -E "$(jq -r --arg host_whitelist "${HOST_WHITELIST}" '.["rpc-host-whitelist"] = $host_whitelist' /config/settings.json)" >/config/settings.json | ||||||
| else | else | ||||||
|     echo -E "$(jq -r '.["rpc-host-whitelist-enabled"] = false' /config/settings.json)" >/config/settings.json |     echo -E "$(jq -r '.["rpc-host-whitelist-enabled"] = false' /config/settings.json)" >/config/settings.json | ||||||
| fi | fi | ||||||
| echo -E "$(jq -r --arg host_whitelist "${HOST_WHITELIST}" '.["rpc-host-whitelist"] = $host_whitelist' /config/settings.json)" >/config/settings.json |  | ||||||
|  |  | ||||||
| if [[ -n "${PEERPORT}" ]]; then | if [[ -n "${PEERPORT}" ]]; then | ||||||
|     echo -E "$(jq -r --argjson peerport "${PEERPORT}" '.["peer-port"] = $peerport' /config/settings.json)" >/config/settings.json |     echo -E "$(jq -r --argjson peerport "${PEERPORT}" '.["peer-port"] = $peerport' /config/settings.json)" >/config/settings.json | ||||||
| @@ -41,14 +37,17 @@ if [[ -n "${UMASK}" ]]; then | |||||||
|     echo -E "$(jq -r --arg umask "${UMASK}" '.["umask"] = $umask' /config/settings.json)" >/config/settings.json |     echo -E "$(jq -r --arg umask "${UMASK}" '.["umask"] = $umask' /config/settings.json)" >/config/settings.json | ||||||
| fi | fi | ||||||
|  |  | ||||||
|  | if [[ -z ${LSIO_NON_ROOT_USER} ]] && [[ -z ${LSIO_READ_ONLY_FS} ]]; then | ||||||
|     # Handle old theme locations |     # Handle old theme locations | ||||||
|     mkdir -p {/transmissionic,/combustion-release,/flood-for-transmission,/kettu,/transmission-web-control} |     mkdir -p {/transmissionic,/combustion-release,/flood-for-transmission,/kettu,/transmission-web-control} | ||||||
|     echo /transmissionic /combustion-release /flood-for-transmission /kettu /transmission-web-control | xargs -n1 ln -s /defaults/index.html |     echo /transmissionic /combustion-release /flood-for-transmission /kettu /transmission-web-control | xargs -n1 ln -s /defaults/index.html | ||||||
|  | fi | ||||||
|  |  | ||||||
| # permissions | if [[ -z ${LSIO_NON_ROOT_USER} ]]; then | ||||||
| lsiown abc:abc \ |     lsiown -R abc:abc \ | ||||||
|     /config/settings.json |         /config | ||||||
|  |  | ||||||
|  |     if grep -qe ' /downloads ' /proc/mounts; then | ||||||
|         if [[ "$(stat -c '%U' /downloads)" != "abc" ]]; then |         if [[ "$(stat -c '%U' /downloads)" != "abc" ]]; then | ||||||
|             lsiown abc:abc /downloads |             lsiown abc:abc /downloads | ||||||
|         fi |         fi | ||||||
| @@ -60,7 +59,11 @@ fi | |||||||
|         if [[ "$(stat -c '%U' /downloads/incomplete)" != "abc" ]]; then |         if [[ "$(stat -c '%U' /downloads/incomplete)" != "abc" ]]; then | ||||||
|             lsiown abc:abc /downloads/incomplete |             lsiown abc:abc /downloads/incomplete | ||||||
|         fi |         fi | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     if grep -qe ' /watch ' /proc/mounts; then | ||||||
|         if [[ "$(stat -c '%U' /watch)" != "abc" ]]; then |         if [[ "$(stat -c '%U' /watch)" != "abc" ]]; then | ||||||
|             lsiown abc:abc /watch |             lsiown abc:abc /watch | ||||||
|         fi |         fi | ||||||
|  |     fi | ||||||
|  | fi | ||||||
|   | |||||||
| @@ -3,6 +3,12 @@ | |||||||
|  |  | ||||||
| PORT=$(jq '.["rpc-port"]' /config/settings.json) | PORT=$(jq '.["rpc-port"]' /config/settings.json) | ||||||
|  |  | ||||||
|  | if [[ -z ${LSIO_NON_ROOT_USER} ]]; then | ||||||
|     s6-notifyoncheck -d -n 300 -w 1000 -c "nc -z localhost ${PORT:-9091}" \ |     s6-notifyoncheck -d -n 300 -w 1000 -c "nc -z localhost ${PORT:-9091}" \ | ||||||
|         s6-setuidgid abc /usr/bin/transmission-daemon \ |         s6-setuidgid abc /usr/bin/transmission-daemon \ | ||||||
|         -g /config -f |         -g /config -f | ||||||
|  | else | ||||||
|  |     s6-notifyoncheck -d -n 300 -w 1000 -c "nc -z localhost ${PORT:-9091}" \ | ||||||
|  |         /usr/bin/transmission-daemon \ | ||||||
|  |         -g /config -f | ||||||
|  | fi | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user