Portainer (Community Edition)
Frontend para docker.
Levantar contenedor
- Crear una carpeta donde se meterá el archivo
docker-compose.yaml
. Yo, por ejemplo, lo meto en un disco externo.
- El archivo docker-compose.yaml será muy parecido a este:
docker-compose.yamlversion: "3"
services:
portainer:
image: portainer/portainer-ce
container_name: portainer
environment:
- TZ=Europe/Madrid
networks:
- rpipub
dns:
- 127.0.0.1
- 1.1.1.1
labels:
- traefik.enable=true
# CORS (Solo es útil en caso de usar DynHost)
- traefik.http.middlewares.portainer-cors-headers.headers.accesscontrolallowmethods=GET,OPTIONS,PUT
- traefik.http.middlewares.portainer-cors-headers.headers.accesscontrolalloworiginlist=https://subdomain.domain.tld # Cambiar a http si es necesario
- traefik.http.middlewares.portainer-cors-headers.headers.accesscontrolmaxage=100
- traefik.http.middlewares.portainer-cors-headers.headers.addvaryheader=true
# Direct Web UI (Comentar si se va a conectar siempre mediante dominio)
- traefik.http.routers.portainer.rule=PathPrefix(`/`)
- traefik.http.routers.portainer.entrypoints=portainer_interface
- traefik.http.routers.portainer.service=portainer-direct-service
- traefik.http.services.portainer-direct-service.loadbalancer.server.port=9000
# Web UI (Descomentar si no se usa HTTPS)
#- traefik.http.routers.portainer-http.rule=Host(`subdomain.domain.tld`) && PathPrefix(`/`)
#- traefik.http.routers.portainer-http.entrypoints=web
#- traefik.http.routers.portainer-http.middlewares=low-ratelimit@file
#- traefik.http.routers.portainer-http.service=portainer-http-service
#- traefik.http.services.portainer-http-service.loadbalancer.server.port=9000
# Secure Web UI (Descomentar si se usa HTTPS)
#- traefik.http.routers.portainer-https.rule=Host(`subdomain.domain.tld`) && PathPrefix(`/`)
#- traefik.http.routers.portainer-https.entrypoints=websecure
#- traefik.http.routers.portainer-https.middlewares=low-ratelimit@file,secure-headers@file,norobots-headers@file,portainer-cors-headers@docker
#- traefik.http.routers.portainer-https.tls=true
#- traefik.http.routers.portainer-https.tls.certresolver=letsencrypt
#- traefik.http.routers.portainer-https.tls.domains[0].main=domain.tld
#- traefik.http.routers.portainer-https.tls.domains[0].sans=*.domain.tld
#- traefik.http.routers.portainer-https.service=portainer-https-service
#- traefik.http.services.portainer-https-service.loadbalancer.server.port=9000
# 8000 TCP
- traefik.tcp.services.portainer.loadbalancer.server.port=8000
- traefik.tcp.routers.portainer_daemon.rule=HostSNI(`*`)
- traefik.tcp.routers.portainer_daemon.entrypoints=portainer_daemon
- traefik.tcp.routers.portainer_daemon.service=portainer
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./data:/data
restart: unless-stopped
hostname: "rpi-portainer"
networks:
rpipub:
name: "rpi-net-public"
- /!\ Cambiar 'domain.tld' y 'subdomain.domain.tld' por el dominio que vayas a usar
3. Levantar el contenedor en modo 'detached': docker-compose up -d
3.1. Lanzando docker ls
se debe ver el contenedor de portainer levantado
Configuración mínima
Para acceder al panel será una URL como http://rpi_ip:9000
.
- La primera vez que arranca pedirá que crear un usuario (por defecto admin).
- Una vez dentro lo primero que se tendrá que hacer es crear un 'endpoint' desde el menú "Endpoints".
2.1. Seleccionar el tipo "Docker"
2.2. Poner el nombre que queramos
2.3. Activar el check "Connect via socket"
2.4. Pulsar "+ Add Endpoint"
2.5. Ahora en a la sección "Containers" se debe ver que está levantado el propio contenedor de portainer.
Pi-Hole
Pihole es un programa con varios propósitos, pero el que nos atañe es el de hacer de Servidor DNS para cachear y filtrar. Nos proporciona una primera barrera contra trackers en cualquier dispositivo del hogar que tire de DHCP.
Se debe tener en cuenta que con esta configuración si cae la rpi (cae el servidor DNS), quedaremos sin poder resolver dominios y no se podra navegar con normalidad.
Levantar contenedor
- Crear una carpeta donde se meterá el archivo
docker-compose.yaml
. Yo, por ejemplo, lo meto en un disco externo.
- El archivo docker-compose.yaml será muy parecido a este:
docker-compose.yamlversion: "3"
# More info at https://github.com/pi-hole/docker-pi-hole/ and https://docs.pi-hole.net/
services:
pihole:
container_name: pihole
image: pihole/pihole:latest
networks:
- rpipub
dns:
- 127.0.0.1
- 1.1.1.1
ports:
- "53:53"
- "53:53/udp"
environment:
TZ: 'Europe/Madrid'
#WEBPASSWORD: 'establece una contraseña segura aquí o sino se generará una aleatoria'
# Volumes store your data between container upgrades
volumes:
- './data/etc-pihole/:/etc/pihole/'
- './data/etc-dnsmasq.d/:/etc/dnsmasq.d/'
# Recommended but not required (DHCP needs NET_ADMIN)
# https://github.com/pi-hole/docker-pi-hole#note-on-capabilities
#cap_add:
# - NET_ADMIN
labels:
- traefik.enable=true
# CORS (Solo es útil en caso de usar DynHost)
- traefik.http.middlewares.pihole-cors-headers.headers.accesscontrolallowmethods=GET,OPTIONS,PUT
- traefik.http.middlewares.pihole-cors-headers.headers.accesscontrolalloworiginlist=https://subdomain.domain.tld # Cambiar a http si es necesario
- traefik.http.middlewares.pihole-cors-headers.headers.accesscontrolmaxage=100
- traefik.http.middlewares.pihole-cors-headers.headers.addvaryheader=true
# Direct Web UI (Comentar si se va a conectar siempre mediante dominio)
- traefik.http.routers.pihole.rule=PathPrefix(`/`)
- traefik.http.routers.pihole.entrypoints=pihole_interface
- traefik.http.routers.pihole.service=pihole-direct-service
- traefik.http.services.pihole-direct-service.loadbalancer.server.port=80
# Web UI (Descomentar si no se usa HTTPS)
#- traefik.http.routers.pihole-http.rule=Host(`subdomain.domain.tld`) && PathPrefix(`/`)
#- traefik.http.routers.pihole-http.entrypoints=web
#- traefik.http.routers.pihole-http.middlewares=low-ratelimit@file
#- traefik.http.routers.pihole-http.service=pihole-http-service
#- traefik.http.services.pihole-http-service.loadbalancer.server.port=80
# Secure Web UI (Descomentar si se usa HTTPS)
#- traefik.http.routers.pihole-https.rule=Host(`subdomain.domain.tld`) && PathPrefix(`/`)
#- traefik.http.routers.pihole-https.entrypoints=websecure
#- traefik.http.routers.pihole-https.middlewares=low-ratelimit@file,secure-headers@file,norobots-headers@file,pihole-cors-headers@docker
#- traefik.http.routers.pihole-https.tls=true
#- traefik.http.routers.pihole-https.tls.certresolver=letsencrypt
#- traefik.http.routers.pihole-https.tls.domains[0].main=domain.tld
#- traefik.http.routers.pihole-https.tls.domains[0].sans=*.domain.tld
#- traefik.http.routers.pihole-https.service=pihole-https-service
#- traefik.http.services.pihole-https-service.loadbalancer.server.port=80
# DNS-over-TLS (No configurado, dejar comentado)
#- traefik.tcp.routers.dnstls.rule=HostSNI(`*`)
#- traefik.tcp.routers.dnstls.entrypoints=dnstls
#- traefik.tcp.routers.dnstls.tls.certresolver=mytlschallenge
#- traefik.tcp.routers.dnstls.service=pihole
# Normal DNS coming in on 53 TCP, no TLS
- traefik.tcp.routers.dns.rule=HostSNI(`*`)
- traefik.tcp.routers.dns.entrypoints=dns
- traefik.tcp.routers.dns.service=pihole
# recieves traffic from both the TLS and non-TLS traefik routers
- traefik.tcp.services.pihole.loadbalancer.server.port=53
# Normal DNS coming in on 53 UDP
- traefik.udp.routers.udpdns.entrypoints=udpdns
- traefik.udp.routers.udpdns.service=pihole
- traefik.udp.services.pihole.loadbalancer.server.port=53
restart: unless-stopped
hostname: 'rpi-pihole'
networks:
rpipub:
name: 'rpi-net-public'
- /!\ Revisar la variable "WEBPASSWORD"!!
- /!\ Cambiar 'domain.tld' y 'subdomain.domain.tld' por el dominio que vayamos a usar
Aquí no inventamos nada, el archivo anterior lo ofrecen en la propia documentación (ver https://hub.docker.com/r/pihole/pihole). Lo que si, ampliamos/cambiamos alguna cosa:
El tema de puertos se maneja por traefik
Establecido el 'hostname'. Así podemos referenciar desde otros contenedores fácilmente dentro de la misma red.
Establecida una red por defecto a 'rpi-net', para la configuración que usamos no es realmente necesario pero me gusta que este organizado y seguir un estándar en la nomenclatura.
Establecidas unas DNS para que apunten al sitio correcto (fallback a 1.1.1.1)
Levantar el contenedor en modo 'detached': docker-compose up -d
3.1. Tanto en portainer como lanzando docker ls
se debe ver el contenedor de pi-hole levantado
Configuración
Para acceder al panel será una URL como http://rpi_ip:9010
.
Aquí existen varios caminos, aquí comentaremos uno apoyándonos en el router:
- Vamos al apartado "Settings", allí a la sección "DNS"
1.1. Desmarcar todos los check del bloque de la izquierda llamado "Upstream DNS Servers"
1.2. Habilitar "Custom 1 (IPv4)" del bloque de la derecha llamado "Upstream DNS Servers"
1.2.1. Introducir la ip del router (por lo general 192.168.1.1
)
- Guardar los cambios
- Ir al apartado "Group Management", a la sección "Adlists"
3.1. Añadir las listas que consideres oportunas... En esta web se pueden consultar listas: https://firebog.net/
3.2. Ir a al apartado "Tools", a la sección "Update Gravity" y actualizar.
Configurando el router
- Abrir la configuración del router y cambiar el DHCP para que los servidores DNS apunten a la rpi
- Quizás se necesite habilitar el "DNS Proxy" para que se puedan procesar las peticiones desde la rpi.
- Este punto es opcional, pero recuerda que siempre podrás cambiar los servidores DNS del router para usar, por ejemplo, los de Cloudflare (
1.1.1.1
) o Quad9 (9.9.9.9
)
3.1. ¿Pero no dijimos de poner las DNS apuntando a la rpi? Si, pero en este caso no me refiero a la configuración DHCP, sino a la que usará el router (son diferentes apartados).
- Resetear las conexiones de nuestros dispositivos para que obtengan la nueva dirección del servidor DNS.
Deluge
Cliente bittorrent
Levantar contenedor
- Crear una carpeta donde se meterá el archivo
docker-compose.yaml
. Yo, por ejemplo, lo meto en un disco externo.
- El archivo docker-compose.yaml será muy parecido a este:
docker-compose.yamlversion: "3"
services:
deluge:
image: ghcr.io/linuxserver/deluge
container_name: deluge
environment:
- PUID=1000
- PGID=1000
- TZ=Europe/Madrid
- DELUGE_LOGLEVEL=error #optional
networks:
- rpipub
dns:
- 127.0.0.1
- 1.1.1.1
labels:
- traefik.enable=true
# CORS (Solo es útil en caso de usar DynHost)
- traefik.http.middlewares.deluge-cors-headers.headers.accesscontrolallowmethods=GET,OPTIONS,PUT
- traefik.http.middlewares.deluge-cors-headers.headers.accesscontrolalloworiginlist=https://subdomain.domain.tld # Cambiar a http si es necesario
- traefik.http.middlewares.deluge-cors-headers.headers.accesscontrolmaxage=100
- traefik.http.middlewares.deluge-cors-headers.headers.addvaryheader=true
# Direct Web UI (Comentar si se va a conectar siempre mediante dominio)
- traefik.http.routers.deluge.rule=PathPrefix(`/`)
- traefik.http.routers.deluge.entrypoints=deluge_interface
- traefik.http.routers.deluge.service=deluge-direct-service
- traefik.http.services.deluge-direct-service.loadbalancer.server.port=8112
# Web UI (Descomentar si no se usa HTTPS)
#- traefik.http.routers.deluge-http.rule=Host(`subdomain.domain.tld`) && PathPrefix(`/`)
#- traefik.http.routers.deluge-http.entrypoints=web
#- traefik.http.routers.deluge-http.middlewares=low-ratelimit@file
#- traefik.http.routers.deluge-http.service=deluge-http-service
#- traefik.http.services.deluge-http-service.loadbalancer.server.port=8112
# Secure Web UI (Descomentar si se usa HTTPS)
#- traefik.http.routers.deluge-https.rule=Host(`subdomain.domain.tld`) && PathPrefix(`/`)
#- traefik.http.routers.deluge-https.entrypoints=websecure
#- traefik.http.routers.deluge-https.middlewares=low-ratelimit@file,secure-headers@file,norobots-headers@file,deluge-cors-headers@docker
#- traefik.http.routers.deluge-https.tls=true
#- traefik.http.routers.deluge-https.tls.certresolver=letsencrypt
#- traefik.http.routers.deluge-https.tls.domains[0].main=domain.tld
#- traefik.http.routers.deluge-https.tls.domains[0].sans=*.domain.tld
#- traefik.http.routers.deluge-https.service=deluge-https-service
#- traefik.http.services.deluge-https-service.loadbalancer.server.port=8112
# 58846 TCP
- traefik.tcp.services.deluge.loadbalancer.server.port=58846
- traefik.tcp.routers.deluge_daemon.rule=HostSNI(`*`)
- traefik.tcp.routers.deluge_daemon.entrypoints=deluge_daemon
- traefik.tcp.routers.deluge_daemon.service=deluge
# 58946 TCP
- traefik.tcp.services.deluge_torrent.loadbalancer.server.port=58946
- traefik.tcp.routers.deluge_torrent.rule=HostSNI(`*`)
- traefik.tcp.routers.deluge_torrent.entrypoints=deluge_torrent
- traefik.tcp.routers.deluge_torrent.service=deluge_torrent
# 58946 UDP
- traefik.udp.routers.udpdeluge_torrent.entrypoints=udpdeluge_torrent
- traefik.udp.routers.udpdeluge_torrent.service=deluge_torrent
- traefik.udp.services.deluge_torrent.loadbalancer.server.port=58946
volumes:
- ./data/config:/config
- ./data/downloads:/downloads
- ./data/downloaded:/downloaded
restart: unless-stopped
hostname: "rpi-deluge"
networks:
rpipub:
name: "rpi-net-public"
- /!\ Cambiar 'domain.tld' y 'subdomain.domain.tld' por el dominio que vayas a usar
3. Este paso es opcional, se enlaza simbólicamente la carpeta ./data/downloaded
a una carpeta que está en un disco externo.
Las rutas aquí usadas dependerán de donde se hayan montado los discos y como se han nombrado las carpetas.
Por ejemplo, un disco montado en /media/e2rpi
y una carpeta llamada torrents
se queda en /media/e2rpi/torrents
.
3.1. Para hacer el enlace simbólico: ln -s /media/e2rpi/torrents ./data/downloaded
4. Levantar el contenedor en modo 'detached': docker-compose up -d
4.1. Tanto en portainer como lanzando docker ls
se debe ver el contenedor de deluge levantado
Configuración
Para acceder al panel será una URL como http://rpi_ip:8112
. La contraseña por defecto es deluge
.
- Desde la barra de herramientas ir la opción "Preferences", allí se puede cambiar el idioma, limites de velocidad, etc...
1.1. Sección 'plugins':
1.1.1. Habilitar blocklist
para bloquear ip's
1.1.1.1. Ir a la configuración de 'blocklist' y usar, por ejemplo, https://github.com/Naunter/BT_BlockLists/raw/master/bt_blocklists.gz
1.1.1.2. Pulsar el botón Check Download and Import
1.1.2. Habilitar label
1.1.3. Habilitar execute
1.2. Sección 'Deamon'
1.2.1. Habilitar Allow Remote Connections
(Esto es útil si instalamos el plugin indicado en 'extras')
Extras
- delugesiphon: https://chrome.google.com/webstore/detail/delugesiphon/gabdloknkpdefdpkkibplcfnkngbidim
PostgreSQL
Motor de base de datos
Levantar contenedor
- Crear una carpeta donde se meterá el archivo
docker-compose.yaml
. Yo, por ejemplo, lo meto en un disco externo.
- El archivo docker-compose.yaml será muy parecido a este:
docker-compose.yamlversion: "3"
services:
postgres:
image: postgres
container_name: postgres
environment:
- TZ=Europe/Madrid
#- POSTGRES_USER=TU_USUARIO
- POSTGRES_PASSWORD=TU_CONTRASEÑA
- PGDATA=/var/lib/postgresql/data/pgdata
networks:
- rpipub
dns:
- 127.0.0.1
- 1.1.1.1
labels:
- traefik.enable=true
# 5432 TCP
- traefik.tcp.services.postgres.loadbalancer.server.port=5432
- traefik.tcp.routers.postgres_daemon.rule=HostSNI(`*`)
- traefik.tcp.routers.postgres_daemon.entrypoints=postgres_daemon
- traefik.tcp.routers.posgres_daemon.service=postgres
volumes:
- ./data:/var/lib/postgresql/data
restart: unless-stopped
hostname: "rpi-postgres"
networks:
rpipub:
name: "rpi-net-public"
- /!\ Revisar la variable "POSTGRES_PASSWORD"!!
- /!\ Revisar la variable "POSTGRES_USER", si se deja comentado el usuario será 'postgres'
- /!\ SE RECOMIENDA FIJAR LA VERSION DE LA IMAGEN Y ES NECESARIO SI USAS WATCHTOWER
3. Levantar el contenedor en modo 'detached': docker-compose up -d
3.1. Tanto en portainer como lanzando docker ls
se debe ver el contenedor de postgres levantado o esperando a ser reiniciado.
Configuración
El login a la base de datos dependerá de lo que se haya puesto en POSTGRES_USER
y POSTGRES_PASSWORD
.
Gotify
Gotify es un servidor de notificaciones en tiempo real.
Levantar contenedor
- Se usará 'PostgreSQL' para almacenar las notificaciones.
- Crear una carpeta donde se meterá el archivo
docker-compose.yaml
. Yo, por ejemplo, lo meto en un disco externo.
- El archivo docker-compose.yaml será muy parecido a este:
docker-compose.yamlversion: "3"
services:
gotify:
image: gotify/server-arm64
container_name: gotify
environment:
- TZ=Europe/Madrid
- GOTIFY_DEFAULTUSER_PASS=CLAVE_PARA_USUARIO_POR_DEFECTO
- GOTIFY_DATABASE_DIALECT=postgres
- GOTIFY_DATABASE_CONNECTION=host=rpi-postgres port=5432 user=gotify dbname=gotify password=CLAVE_USUARIO_GOTIFY_POSTGRES sslmode=disable
networks:
- rpipub
dns:
- 127.0.0.1
- 1.1.1.1
volumes:
- ./data:/app/data
labels:
- traefik.enable=true
# CORS
- traefik.http.middlewares.gotify-cors-headers.headers.accesscontrolallowmethods=GET,OPTIONS,PUT
- traefik.http.middlewares.gotify-cors-headers.headers.accesscontrolalloworiginlist=https://subdomain.domain.tld
- traefik.http.middlewares.gotify-cors-headers.headers.accesscontrolmaxage=100
- traefik.http.middlewares.gotify-cors-headers.headers.addvaryheader=true
# Direct Web UI (Comentar si se va a conectar siempre mediante dominio)
- traefik.http.routers.gotify.rule=PathPrefix(`/`)
- traefik.http.routers.gotify.entrypoints=gotify
- traefik.http.routers.gotify.service=gotify-direct-service
- traefik.http.services.gotify-direct-service.loadbalancer.server.port=80
# Web UI (Descomentar si no se usa HTTPS)
#- traefik.http.routers.gotify-http.rule=Host(`subdomain.domain.tld`) && PathPrefix(`/`)
#- traefik.http.routers.gotify-http.entrypoints=web
#- traefik.http.routers.gotify-http.middlewares=low-ratelimit@file
#- traefik.http.routers.gotify-http.service=gotify-http-service
#- traefik.http.services.gotify-http-service.loadbalancer.server.port=80
# Secure Web UI (Descomentar si se usa HTTPS)
#- traefik.http.routers.gotify-https.rule=Host(`subdomain.domain.tld`) && PathPrefix(`/`)
#- traefik.http.routers.gotify-https.entrypoints=websecure
#- traefik.http.routers.gotify-https.middlewares=low-ratelimit@file,secure-headers@file,norobots-headers@file,gotify-cors-headers@docker
#- traefik.http.routers.gotify-https.tls=true
#- traefik.http.routers.gotify-https.tls.certresolver=letsencrypt
#- traefik.http.routers.gotify-https.tls.domains[0].main=domain.tld
#- traefik.http.routers.gotify-https.tls.domains[0].sans=*.domain.tld
#- traefik.http.routers.gotify-https.service=gotify-https-service
#- traefik.http.services.gotify-https-service.loadbalancer.server.port=80
restart: unless-stopped
hostname: "rpi-gotify"
networks:
rpipub:
name: 'rpi-net-public'
/!\ Revisar la variable 'GOTIFY_DEFAULTUSER_PASS'
/!\ Revisar la variable 'GOTIFY_DATABASE_CONNECTION'
/!\ Cambiar 'domain.tld' y 'subdomain.domain.tld' por el dominio que vayas a usar
4. Levantar el contenedor en modo 'detached': docker-compose up -d
4.1. Tanto en portainer como lanzando docker ls
se debe ver el contenedor de gotify levantado
Configuración
Para acceder al panel será una URL como http://rpi_ip:9050
.
Como se está usando "postgres" debemos asegurar que tenemos creado el usuario "gotify" y la base de datos "gotify".
Para empezar a trabajar se necesita crear, al menos, una app:
- Ir a la seccion "APPS" y pulsar en "Create Application"
1.1. Poner un nombre y descripción
Extras
- App para Android: https://f-droid.org/es/packages/com.github.gotify/
Notas
Si vas a conectarte a gotify desde fuera de la red local es imperativo el uso de https!!
Watchtower
Watchtower nos ayuda a tener nuestras imagenes actualizadas. Esto no es recomendable en entornos de producción, pero para nuestro servidor casero donde no nos importa que pueda romperse algo por alguna incompatibilidad pues es un gran aliado.
Levantar contenedor
- Se usará 'Gotify' como medio para recibir las notificaciones.
- Crear una carpeta donde se meterá el archivo
docker-compose.yaml
. Yo, por ejemplo, lo meto en un disco externo.
- El archivo docker-compose.yaml será muy parecido a este:
docker-compose.yamlversion: "3"
services:
watchtower:
image: containrrr/watchtower
container_name: watchtower
environment:
- TZ=Europe/Madrid
- WATCHTOWER_NOTIFICATIONS=gotify
- WATCHTOWER_NOTIFICATION_GOTIFY_URL=http://rpi-gotify
- WATCHTOWER_NOTIFICATION_GOTIFY_TOKEN=EL_TOKEN_SECRETO_CREADO_PARA_LA_APP
networks:
- rpipub
dns:
- 127.0.0.1
- 1.1.1.1
volumes:
- /var/run/docker.sock:/var/run/docker.sock
command: --cleanup
restart: unless-stopped
hostname: "rpi-watchtower"
networks:
rpipub:
name: 'rpi-net-public'
- /!\ Revisar la variable 'WATCHTOWER_NOTIFICATION_GOTIFY_TOKEN'
** Como se puede apreciar, usamos "http" para conectar con el servidor de notificaciones. Esto es así porque la conexión va a ser local (no sale a internet).
4. Levantar el contenedor en modo 'detached': docker-compose up -d
4.1. Tanto en portainer como lanzando docker ls
se debe ver el contenedor de watchtower levantado
Jellyfin
Jellyfin es una servidor media con capacidades de streaming. Clasifca el contenido, catalogalo usando servicios de internet: Carataluas, fechas, actores, etc...
Usamos la imagen de "linuxserver" en vez de la oficial porque es la que recomiendan en la propia documentación de jellyfin (https://jellyfin.org/docs/general/administration/hardware-acceleration.html#raspberry-pi-3-and-4)
Levantar contenedor
- Crear una carpeta donde se meterá el archivo
docker-compose.yaml
. Yo, por ejemplo, lo meto en un disco externo.
- El archivo docker-compose.yaml será muy parecido a este:
docker-compose.yamlversion: "2.1"
services:
jellyfin:
image: ghcr.io/linuxserver/jellyfin
container_name: jellyfin
environment:
- PUID=1000
- PGID=1000
- TZ=Europe/Madrid
- JELLYFIN_PublishedServerUrl=subdomain.domain.tld # <---- QUE NO SE OLVIDETE ESTE
networks:
- rpipub
#network_mode: host
dns:
- 127.0.0.1
- 1.1.1.1
volumes:
- ./data/downloads/video/peliculas:/data/movies
- ./data/downloads/video/series:/data/tvshows
- ./data/config:/config
- /opt/vc/lib:/opt/vc/lib # OpenMAX libs
- /dev/shm:/config/data/transcoding-temp/transcodes
devices:
- /dev/dri:/dev/dri # VAAPI enconding
- /dev/vcsm-cma:/dev/vcsm-cma # MMAL (OpenMAX H264 decode)
- /dev/vchiq:/dev/vchiq # OpenMAX encoding
- /dev/video10:/dev/video10 # V4L2 encoding
- /dev/video11:/dev/video11 # V4L2 encoding
- /dev/video12:/dev/video12 # V4L2 encoding
labels:
- traefik.enable=true
# CORS (Solo es útil en caso de usar DynHost)
- traefik.http.middlewares.jellyfin-cors-headers.headers.accesscontrolallowmethods=GET,OPTIONS,PUT
- traefik.http.middlewares.jellyfin-cors-headers.headers.accesscontrolalloworiginlist=https://subdomain.domain.tld
- traefik.http.middlewares.jellyfin-cors-headers.headers.accesscontrolmaxage=100
- traefik.http.middlewares.jellyfin-cors-headers.headers.addvaryheader=true
# Direct Web UI (Comentar si se va a conectar siempre mediante dominio)
- traefik.http.routers.jellyfin.rule=PathPrefix(`/`)
- traefik.http.routers.jellyfin.entrypoints=jellyfin_interface
- traefik.http.routers.jellyfin.service=jellyfin-direct-service
- traefik.http.services.jellyfin-direct-service.loadbalancer.server.port=8096
# Web UI (Descomentar si no se usa HTTPS)
#- traefik.http.routers.jellyfin-http.rule=Host(`subdomain.domain.tld`) && PathPrefix(`/`)
#- traefik.http.routers.jellyfin-http.entrypoints=web
#- traefik.http.routers.jellyfin-http.middlewares=low-ratelimit@file
#- traefik.http.routers.jellyfin-http.service=jellyfin-http-service
#- traefik.http.services.jellyfin-http-service.loadbalancer.server.port=8096
# Secure Web UI (Descomentar si se usa HTTPS)
#- traefik.http.routers.jellyfin-https.rule=Host(`subdomain.domain.tld`) && PathPrefix(`/`)
#- traefik.http.routers.jellyfin-https.entrypoints=websecure
#- traefik.http.routers.jellyfin-https.middlewares=low-ratelimit@file,secure-headers@file,norobots-headers@file,jellyfin-cors-headers@docker
#- traefik.http.routers.jellyfin-https.tls=true
#- traefik.http.routers.jellyfin-https.tls.certresolver=letsencrypt
#- traefik.http.routers.jellyfin-https.tls.domains[0].main=domain.tld
#- traefik.http.routers.jellyfin-https.tls.domains[0].sans=*.domain.tld
#- traefik.http.routers.jellyfin-https.service=jellyfin-https-service
#- traefik.http.services.jellyfin-https-service.loadbalancer.server.port=8096
# 7359 UDP
- traefik.udp.routers.udpjellyfin_discovery.entrypoints=udpjellyfin_discovery
- traefik.udp.routers.udpjellyfin_discovery.service=jellyfin_discovery
- traefik.udp.services.jellyfin_discovery.loadbalancer.server.port=7359
# 1900 UDP
- traefik.udp.routers.udpjellyfin_dlna.entrypoints=udpjellyfin_dlna
- traefik.udp.routers.udpjellyfin_dlna.service=jellyfin_dlna
- traefik.udp.services.jellyfin_dlna.loadbalancer.server.port=1900
restart: unless-stopped
hostname: "rpi-jellyfin"
networks:
rpipub:
name: "rpi-net-public"
- /!\ Cambiar 'domain.tld' por el dominio que vayas a usar
- **/!\ Los volumenes '/media/movies' y '/media/tvshows' son meros ejemplos, usa los nombres y puntos de montaje que quieras*
Requisitos
- Según la documentación se debe aumentar la memoria reservada para la gpu (https://jellyfin.org/docs/general/administration/hardware-acceleration.html#raspberry-pi-3-and-4 y https://www.raspberrypi.org/documentation/configuration/config-txt/memory.md)
1.1. Editar el archivo /boot/config.txt
1.1.1. Añadir: gpu_mem=320
1.1.2. Reiniciar: sudo reboot
Configuración
- Habilitar la aceleración por hardware. (Es importante tener la rpi con ventilación activa!!)
1.1. En Panel de control > Reproducción
dejar la aceleración por hardware en Video Aceleration API (VAAPI)
.
1.2. Grabar los cambios
Extras
- App para Android: https://f-droid.org/es/packages/org.jellyfin.mobile/
- Reproductor de música para Android: https://f-droid.org/es/packages/com.dkanada.gramophone/
** Más en: https://jellyfin.org/clients/
- Canales IPTV (M3U8) + EPG: https://tdtchannels.com/listas
Notas
No he sido capaz de hacer funcionar el descubrimiento del servidor DLNA, pero se puede obtener la url de streaming y usar programas como VLC para reprucidr las películas.
NextCloud
Levantar contenedor
- Se usará 'PostgreSQL' para almacenar los datos.
- Crear una carpeta donde se meterá el archivo
docker-compose.yaml
. Yo, por ejemplo, lo meto en un disco externo.
- El archivo docker-compose.yaml será muy parecido a este:
docker-compose.yamlversion: "3"
services:
nextcloud:
image: nextcloud
container_name: nextcloud
environment:
- TZ=Europe/Madrid
- NEXTCLOUD_ADMIN_USER=USUARIO_ADMIN
- NEXTCLOUD_PASSWORD=CONTRASEÑA_ADMIN
- NEXTCLOUD_DATA_DIR=/nextcloud_data
- POSTGRES_DB=NOMBRE_BASE_DE_DATOS
- POSTGRES_USER=USUARIO_BASE_DE_DATOS
- POSTGRES_PASSWORD=CONTRASEÑA_USUARIO_BASE_DE_DATOS
- POSTGRES_HOST=rpi-postgres
networks:
- rpipub
dns:
- 127.0.0.1
- 1.1.1.1
labels:
- traefik.enable=true
# CORS (Solo es útil en caso de usar DynHost)
- traefik.http.middlewares.nextcloud-cors-headers.headers.accesscontrolallowmethods=GET,OPTIONS,PUT
- traefik.http.middlewares.nextcloud-cors-headers.headers.accesscontrolalloworiginlist=https://subdomain.domain.tld # Cambiar a http si es necesario
- traefik.http.middlewares.nextcloud-cors-headers.headers.accesscontrolmaxage=100
- traefik.http.middlewares.nextcloud-cors-headers.headers.addvaryheader=true
# Web DAV
- traefik.http.middlewares.nextcloud-dav-redirect.redirectregex.permanent=true
- traefik.http.middlewares.nextcloud-dav-redirect.redirectregex.regex=https://(.*)/.well-known/(card|cal)dav
- traefik.http.middlewares.nextcloud-dav-redirect.redirectregex.replacement=https://$$1/remote.php/dav/
# Direct Web UI (Comentar si se va a conectar siempre mediante dominio)
- traefik.http.routers.nextcloud.rule=PathPrefix(`/`)
- traefik.http.routers.nextcloud.entrypoints=nextcloud_interface
- traefik.http.routers.nextcloud.service=nextcloud-direct-service
- traefik.http.services.nextcloud-direct-service.loadbalancer.server.port=80
# Web UI (Descomentar si no se usa HTTPS)
#- traefik.http.routers.nextcloud-http.rule=Host(`subdomain.domain.tld`) && PathPrefix(`/`)
#- traefik.http.routers.nextcloud-http.entrypoints=web
#- traefik.http.routers.nextcloud-http.middlewares=low-ratelimit@file
#- traefik.http.routers.nextcloud-http.service=nextcloud-http-service
#- traefik.http.services.nextcloud-http-service.loadbalancer.server.port=80
# Secure Web UI (Descomentar si se usa HTTPS)
#- traefik.http.routers.nextcloud-https.rule=Host(`subdomain.domain.tld`) && PathPrefix(`/`)
#- traefik.http.routers.nextcloud-https.entrypoints=websecure
#- traefik.http.routers.nextcloud-https.middlewares=medium-ratelimit@file,secure-headers@file,norobots-headers@file,nextcloud-cors-headers@docker,nextcloud-dav-redirect@docker
#- traefik.http.routers.nextcloud-https.tls=true
#- traefik.http.routers.nextcloud-https.tls.certresolver=letsencrypt
#- traefik.http.routers.nextcloud-https.tls.domains[0].main=domain.tld
#- traefik.http.routers.nextcloud-https.tls.domains[0].sans=*.domain.tld
#- traefik.http.routers.nextcloud-https.service=nextcloud-https-service
#- traefik.http.services.nextcloud-https-service.loadbalancer.server.port=80
volumes:
- ./data/html:/var/www/html
- ./data/data:/nextcloud_data
- ./data/config/nextcloud.ini:/usr/local/etc/php/conf.d/nextcloud.ini
restart: unless-stopped
hostname: "rpi-nextcloud"
cron:
image: rcdailey/nextcloud-cronjob
restart: always
container_name: nextcloud-cron
network_mode: none
depends_on:
- nextcloud
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- /etc/localtime:/etc/localtime:ro
environment:
- NEXTCLOUD_CONTAINER_NAME=nextcloud
networks:
rpipub:
name: "rpi-net-public"
/!\ Revisar la variable "NEXTCLOUD_ADMIN_USER"
/!\ Revisar la variable "NEXTCLOUD_PASSWORD"!!
/!\ Revisar la variable "POSTGRES_DB"
/!\ Revisar la variable "POSTGRES_USER"
/!\ Revisar la variable "POSTGRES_PASSWORD"!!
/!\ Cambiar 'domain.tld' y 'subdomain.domain.tld' por el dominio que vayas a usar
4. Este paso es opcional, enlazar simbólicamente la carpeta ./data/data
a una carpeta que está en otro disco externo.
Las rutas aquí usadas dependerán de donde se hayan montado los discos y como se han nombrado las carpetas.
Por ejemplo, un disco montado en /media/e2rpi
y una carpeta llamada nextcloud_data
queda en /media/e2rpi/nextcloud_data
.
4.1. Para hacer el enlace simbólico: ln -s /media/e2rpi/nextcloud_data ./data/data
5. Aplicar permisos a la carpeta ./data/data
5.1. Asignar grupo: sudo chown -R www-data: data/data
5.2. Asignar permisos: sudo chmod 0770 data/data
6. Crear el archivo de configuracion de PHP para nextcloud
6.1. Crear la carpeta: sudo mkdir data/config
6.2. Crear el archivo, ajustar los valores a lo que consideres oportuno: sudo nano data/config/nextcloud.ini
nextcloud.ini[PHP]
memory_limit = 1G
upload_max_filesize= 15G
post_max_size = 16G
max_execution_time = 3600
max_input_time = 3600
7. Levantar el contenedor en modo 'detached': docker-compose up -d
7.1. Tanto en portainer como lanzando docker ls
se debe ver el contenedor de nextcloud levantado
Configuración
La primera vez que arrancamos nos pedirá iniciar la instalación, como ya hemos puesto todo lo necesario en las variables de entorno del contenedor solo tendremos que pulsar en el bóton de instalar.
- Asegurarse de tener los permisos correctos en la carpeta
data
(desde la carpeta donde está el archivo docker-compose.yaml):
chown -R www-data:www-data data/
find data/ -type d -exec chmod 750 {} \;
find data/ -type f -exec chmod 640 {} \;
- Cambiar los trabajos en segundo plano a
cron
(Se usa una imagen de apoyo para ejecutar la tarea ya que la imagen de docker no puede ejecutar el cron si no es con permisos de root)
2.1. Para ello deberemos ir a la configuración al apartado Ajustes básicos
.
- Es aconsejable darse una vuelta por la configuración para dejarlo a nuestro gusto
- Es aconsejable darse una vuelta por las aplicaciones para instalar/desinstalar lo que queramos
4.1. Por ejemplo, si usamos certificado igual nos interese instalar la autentificación en dos pasos.
- Se pueden montar carpetas alojadas en otros discos o rutas fuera de la indicada para nextcloud.
5.1. Para ello se debe montar la carpeta en el contenedor ampliando docker-compose.yaml
.
5.2. Se tiene que instalar la aplicación de nextcloud para almacenamiento externo (External Storage) que saldrá como recomendada.
5.3. Una vez instalada se debe configurar el nuevo almacenamiento (en nuestro caso de tipo Local) desde la configuración.
Configuracion Extra
Los cambios se hacen en la configuración de nextcloud data/html/config/config.php
añadiendo las lineas necesarias.
- Si se va a usar por HTTPS se tiene que habilitar el forzado de protocolo
1.1. 'overwriteprotocol' => 'https'
- Si se usa DynHost (ver siguiente tema)
2.1. 'overwritehost' => 'subdomain.domain.tld'
2.1.1. Cambiar subdomain.domain.tld
por el que hayas puesto en el archivo docker-compose.yaml
2.2. 'trusted_domains' => array ( 0 => 'subdomain.domain.tld' )
2.2.1. Cambiar subdomain.domain.tld
por el que hayas puesto en el archivo docker-compose.yaml
2.3. 'trusted_proxies' => array ( 0 => 'subdomain.domain.tld' )
2.3.1. Cambiar subdomain.domain.tld
por el dominio que uses en DynHost
- Si se va a usar el listin telefónico
3.1. 'default_phone_region' => 'ES'
Notas
- Si se activa TOTP (se requiere HTTPS para ello) y se quiere conectar con una aplicación externa, seguramente se necesite crear una contraseña de aplicación desde
Configuración > Personal > Seguridad > Dispositivos y sesiones
Extras
- App para Android, permite auto-sincronizar archivos: https://f-droid.org/es/packages/com.nextcloud.client/
- Extensión de navegador para sincronizar marcadores: https://floccus.org/
Syncthing
Syncthing sirve para replicar archivos entre servidores.
Para funcionar con syncthing se debe tener una instancia funcionando en todos los equipos que estén involucrados. En nuestro caso tendremos un syncthing ejecutándose en el equipo de sobremesa y otro syncthing ejecutándose en la raspberry pi.
En este apartado se verá como configurar syncthing para tener: [ PC ] (Solo envía) --> [ RPI ] (Solo recibe y versionado de cambios)
Preparando syncthing en el equipo de sobremesa
Aquí se puede optar por usar docker o instalarlo mediante repositorios de tu distro. Lo más sencillo es usar los repositorios de tu distro. Una vez instalado se tiene acceso al panel en: http://127.0.0.1:8384/
Configuración
- Añadir la carpeta que queremos tener replicada
1.1. Pulsar en Agregar Carpeta
1.2. En la pestaña General
1.2.1. Poner la Etiqueta de la Carpeta
que se quiera para identificarla
1.2.1. Poner la Ruta de la carpeta
que se quiera replicar, en nuestro ejemplo: /home/test/mi_carpeta_sincronizada
1.3. En la pestaña Avanzado
cambiar el Tipo de carpeta
a Solo Enviar
- Añadir un dispositivo nuevo
2.1. Pulsar en Añadir un dispositivo
2.2. En la pestaña General
poner el ID del Dispositivo
de la rpi
2.2.1. Para saber este ID ir al panel de syncthing en la rpi (mirar el siguiente apartado para desplegar) y en el menú superior pulsar en Acciones
> Mostrar ID
2.3. Ir a la pestaña Avanzado
y cambiar Direcciones
a algo como tcp://IP_RPI:22000
(cambiar IP_RPI por la ip de la raspberry)
2.4. Guardar
Preparando syncthing en la rpi
Levantar contenedor
- Crear una carpeta donde se meterá el archivo
docker-compose.yaml
. Yo, por ejemplo, lo meto en un disco externo.
- El archivo docker-compose.yaml será muy parecido a este:
docker-compose.yamlversion: "3"
services:
syncthing:
image: syncthing/syncthing
container_name: syncthing
environment:
- TZ=Europe/Madrid
networks:
- rpipub
dns:
- 127.0.0.1
- 1.1.1.1
labels:
- traefik.enable=true
# CORS (Solo es útil en caso de usar DynHost)
- traefik.http.middlewares.syncthing-cors-headers.headers.accesscontrolallowmethods=GET,OPTIONS,PUT
- traefik.http.middlewares.syncthing-cors-headers.headers.accesscontrolalloworiginlist=https://subdomain.domain.tld
- traefik.http.middlewares.syncthing-cors-headers.headers.accesscontrolmaxage=100
- traefik.http.middlewares.syncthing-cors-headers.headers.addvaryheader=true
# Direct Web UI (Comentar si se va a conectar siempre mediante dominio)
- traefik.http.routers.syncthing.rule=PathPrefix(`/`)
- traefik.http.routers.syncthing.entrypoints=syncthing_interface
- traefik.http.routers.syncthing.service=syncthing-direct-service
- traefik.http.services.syncthing-direct-service.loadbalancer.server.port=8384
# Web UI (Descomentar si no se usa HTTPS)
#- traefik.http.routers.syncthing-http.rule=Host(`subdomain.domain.tld`) && PathPrefix(`/`)
#- traefik.http.routers.syncthing-http.entrypoints=web
#- traefik.http.routers.syncthing-http.middlewares=low-ratelimit@file
#- traefik.http.routers.syncthing-http.service=syncthing-http-service
#- traefik.http.services.syncthing-http-service.loadbalancer.server.port=8384
# Secure Web UI (Descomentar si se usa HTTPS)
#- traefik.http.routers.syncthing-https.rule=Host(`subdomain.domain.tld`) && PathPrefix(`/`)
#- traefik.http.routers.syncthing-https.entrypoints=websecure
#- traefik.http.routers.syncthing-https.middlewares=medium-ratelimit@file,secure-headers@file,norobots-headers@file,syncthing-cors-headers@docker
#- traefik.http.routers.syncthing-https.tls=true
#- traefik.http.routers.syncthing-https.tls.certresolver=letsencrypt
#- traefik.http.routers.syncthing-https.tls.domains[0].main=domain.tld
#- traefik.http.routers.syncthing-https.tls.domains[0].sans=*.domain.tld
#- traefik.http.routers.syncthing-https.service=syncthing-https-service
#- traefik.http.services.syncthing-https-service.loadbalancer.server.port=8384
# 22000 TCP
- traefik.tcp.services.syncthing_daemon.loadbalancer.server.port=22000
- traefik.tcp.routers.syncthing_daemon.rule=HostSNI(`*`)
- traefik.tcp.routers.syncthing_daemon.entrypoints=syncthing_daemon
- traefik.tcp.routers.syncthing_daemon.service=syncthing_daemon
# 22000 UDP
- traefik.udp.routers.udpsyncthing_daemon.entrypoints=udpsyncthing_daemon
- traefik.udp.routers.udpsyncthing_daemon.service=syncthing_daemon
- traefik.udp.services.syncthing_daemon.loadbalancer.server.port=22000
volumes:
- ./data:/var/syncthing
restart: unless-stopped
hostname: "rpi-syncthing"
networks:
rpipub:
name: "rpi-net-public"
- /!\ Cambiar 'domain.tld' y 'subdomain.domain.tld' por el dominio que vayas a usar
Configuración mínima
Añadir un dispositivo nuevo
1.1. Pulsar en Añadir un dispositivo
1.2. En la pestaña General
poner el ID del Dispositivo
del equipo de sobremesa
1.2.1. Para saber este ID ir al panel de syncthing en el equipo de sobremesa y en el menú superior pulsar en Acciones
> Mostrar ID
1.3. Ir a la pestaña Avanzado
y cambiar Direcciones
a algo como tcp://IP_RPI:22000
(cambiar IP_RPI por la ip de la raspberry)
1.4. Guardar
Añadir la carpeta donde queremos tener la replica
2.1. Pulsar en Agregar Carpeta
2.2. En la pestaña General
2.2.1. Poner la Etiqueta de la Carpeta
, en nuestro ejemplo: replica_sobremesa
2.2.2. Poner el ID de carpeta
que se va a replicar
2.2.2.1. Para saber este ID vamos al panel de syncthing en el equipo de sobremesa y el apartado Carpetas
desplegar la información de la carpeta que se quiere replicar y el primer apartado es el ID de carpeta
2.3. En la pestaña Compartiendo
seleccionar el equipo de sobremesa (debería ser la única opción disponible)
2.4. En la pestaña Versionado de ficheros
2.4.1. Cambiar el Versionado de ficheros
a Versionado escalonado de fichero
2.4.2. Puedes cambiar la Edad máxima
a lo que quieras, por ejemplo, 60
días
2.5. En la pestaña Avanzado
cambiar el Tipo de carpeta
a Solo Recibir
Poner una contraseña al panel
3.1. En el menú superior pulsar en Acciones
> Ajustes
3.1.1. Cambiar el Password de la Interfaz Gráfica de Usuario (GUI)
3.1.2. Guardar