Instalación y configuración
Instalar y configurar un contenedor con transmission accesible exclusivamente desde la LAN.
Se realizará en Servicios - Compose - Archivos
El servicio será accesible a través de Nginx Proxy Manager para evitar exponer el puerto 9091 (Web UI / RPC)
Crear en Alamcenamiento - Carpetas compartidas la carpeta donde transmission descargará los archivos. También puede usarse la carpeta por defecto: CHANGE_TO_COMPOSE_DATA_PATH/transmission/downloads:/downloads
Nombre: files_transmission
Ruta : /srv/.../compartida/files_transmission
Si se va a usar/activar un puerto para las conexiones peer-to-peer (P2P)
Dedicir cuál será.
Abrir el puerto en el router.
En /etc/hosts incluir una nueva línea
192.168.0.20 transmission.local
Crear en Nginx Proxy Manager un nuevo Proxy hosts
transmission.local -> http://transmission:9091
# Date: 2026-09-26
# https://hub.docker.com/r/linuxserver/transmission
services:
transmission:
image: lscr.io/linuxserver/transmission:latest
container_name: transmission
environment:
- PUID=${{ uid:"appuser" }}
- PGID=${{ gid:"users" }}
- TZ=${{ tz }}
- PEERPORT=51413
volumes:
- CHANGE_TO_COMPOSE_DATA_PATH/transmission/config:/config
# Local path for downloads
- ${{ sf:"transmission-downloads" }}:/downloads
# Watch folder for torrent files.
- ${{ sf:"transmission-watch" }}:/watch
ports:
- 51413:51413
- 51413:51413/udp
networks:
- proxy_net
restart: unless-stopped
networks:
proxy_net:
external: true
name: proxy_net
Anterior:
# Date: 2025-06-01
# https://hub.docker.com/r/linuxserver/transmission
services:
transmission:
image: lscr.io/linuxserver/transmission:latest
container_name: transmission
environment:
- PUID=${{ uid:"appuser" }}
- PGID=${{ gid:"users" }}
- TZ=${{ tz }}
- PEERPORT=51413
volumes:
- CHANGE_TO_COMPOSE_DATA_PATH/transmission/config:/config
# Local path for downloads
- ${{ sf:"files_transmission" }}/downloads:/downloads
# Watch folder for torrent files.
- ${{ sf:"files_transmission" }}/watch:/watch
ports:
- 51413:51413
- 51413:51413/udp
networks:
- proxy_net
restart: unless-stopped
networks:
proxy_net:
external: true
name: proxy_net
${{ sf:"files_transmission" }}:/downloads : asigna a la carpeta donde transmission guarda las descargas la carpetas compartida files_transmission definida previamente.
PEERPORT=51413 : es una variable de entorno que configura el puerto que Transmission usará para las conexiones peer-to-peer (P2P) con otros clientes de BitTorrent.
La variable le dice a Transmission que use ese puerto internamente, y luego Docker lo expone al exterior. Esto se hace mapeaando el puerto 51413 del contenedor al puerto 51413 del host.
ports:
- 51413:51413
- 51413:51413/udp
El horario de funcionamiento de transmission se ajusta con el script toggle_transmission.sh que permite iniciarlo y detenerlo.
#!/bin/bash
#
# toggle_transmission.sh
# Alterna el estado de Transmission: si está corriendo, lo para;
# si está parado, lo arranca.
#
# Uso:
# ./toggle_transmission.sh # alterna estado
# ./toggle_transmission.sh status # solo muestra estado, no hace nada
# ./toggle_transmission.sh start # fuerza arranque
# ./toggle_transmission.sh stop # fuerza parada
#
# crontab -e
# # Apagar a las 23:00, encender a las 08:00
# 0 23 * * * /ruta/a/toggle_transmission.sh stop >> /var/log/transmission-toggle.log 2>&1
# 0 8 * * * /ruta/a/toggle_transmission.sh start >> /var/log/transmission-toggle.log 2>&1
#
# Versión: 1.01
# Fecha: 4 septiembre de 2026
set -euo pipefail
CONTAINER_NAME="transmission"
COMPOSE_DIR="/srv/dev-disk-by-uuid-215790a8-32eb-476b-aef3-23cd149f359b/contenedores/appdata/transmission"
# Reescribir echo para poner fecha / hora
_echo () {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] :: $1"
}
# Comprobar existencia del directorio
if [[ ! -d "$COMPOSE_DIR" ]]; then
_echo "Error: No existe $COMPOSE_DIR"
exit 1
fi
# Tiempo máximo total de espera al daemon Docker (segundos) y frecuencia de sondeo
DOCKER_WAIT_TIMEOUT=60
DOCKER_WAIT_INTERVAL=2
# --- Esperar a que el daemon Docker esté disponible ---
# Útil justo tras un reinicio del sistema, cuando el script puede lanzarse
# (por cron/systemd) antes de que dockerd haya terminado de arrancar.
elapsed=0
until docker info >/dev/null 2>&1; do
if (( elapsed >= DOCKER_WAIT_TIMEOUT )); then
_echo "Error: el daemon Docker no respondió tras ${DOCKER_WAIT_TIMEOUT}s de espera. Abortando." >&2
exit 1
fi
_echo "Docker aún no está disponible, esperando... (${elapsed}s/${DOCKER_WAIT_TIMEOUT}s)"
sleep "$DOCKER_WAIT_INTERVAL"
elapsed=$(( elapsed + DOCKER_WAIT_INTERVAL ))
done
# --- Comprobar que el contenedor existe ---
if ! docker inspect "$CONTAINER_NAME" >/dev/null 2>&1; then
_echo "Error: el contenedor '$CONTAINER_NAME' no existe." >&2
exit 1
fi
# --- Obtener estado real ---
# .State.Running devuelve "true" o "false" (string)
get_state() {
docker inspect "$CONTAINER_NAME" --format '{{.State.Running}}'
}
STATE=$(get_state)
# --- Modo "status": solo informar, sin actuar ---
if [[ "${1:-}" == "status" ]]; then
if [[ "$STATE" == "true" ]]; then
_echo "transmission: activo (running)"
else
_echo "transmission: inactivo (stopped)"
fi
exit 0
fi
# --- Determinar acción ---
ACTION="${1:-toggle}"
cd "$COMPOSE_DIR"
case "$ACTION" in
start)
if [[ "$STATE" == "true" ]]; then
_echo "transmission ya está activo, no se hace nada."
else
_echo "Arrancando transmission..."
docker compose start
fi
;;
stop)
if [[ "$STATE" == "false" ]]; then
_echo "transmission ya está parado, no se hace nada."
else
_echo "Parando transmission..."
docker compose stop
fi
;;
toggle)
if [[ "$STATE" == "true" ]]; then
_echo "transmission está activo -> parando..."
docker compose stop
else
_echo "transmission está parado -> arrancando..."
docker compose start
fi
;;
*)
_echo "Uso: $0 [status|start|stop]" >&2
exit 1
;;
esac
# --- Confirmar estado final ---
sleep 1
NEW_STATE=$(get_state)
if [[ "$NEW_STATE" == "true" ]]; then
_echo "Estado final: activo (running)"
else
_echo "Estado final: inactivo (stopped)"
fi