App - Transmission

Instalación y configuración

Versión 1.0

Última modificación: 24/09/2026 21:16

Objetivo ⮴

Instalar y configurar un contenedor con transmission accesible exclusivamente desde la LAN.

Instalación-Configuración ⮴

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)

Previamente ⮴

  1. 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

  2. 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.

  3. En /etc/hosts incluir una nueva línea

    
    192.168.0.20 transmission.local
    
  4. Crear en Nginx Proxy Manager un nuevo Proxy hosts

    
    transmission.local -> http://transmission:9091
    

El archivo yml ⮴


# 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

Notas sobre el archivo yml ⮴

  • ${{ 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
    

Programación ⮴

El horario de funcionamiento de transmission se ajusta con el script toggle_transmission.sh que permite iniciarlo y detenerlo.

script toggle_transmission.sh ⮴


#!/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