diff --git a/.gitignore b/.gitignore
index 83bd76f..f7d0ad5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,29 +7,21 @@
# Ignore everything inside Containers/*
/Containers/*/*
+!/Containers/*/compose.yml*
-# Except compose.yml and tailscale serve
-!/Containers/*/compose.yaml
-!/Containers/*/serveconfig/
-
-# navidrome toml for auto-clean
+# Some (safe) configs files
!/Containers/Navidrome/data/
/Containers/Navidrome/data/*
!/Containers/Navidrome/data/navidrome.toml
-!/Containers/HomeAssistant/config/
-/Containers/HomeAssistant/config/*
-!/Containers/HomeAssistant/config/configuration.yaml
-
# Scripts
!/Scripts/*
-# VMS (not used for the moment)
+# VMS
!/VMs/*
# Keep utility files in root
!.gitignore
!start_all.sh
!stop_all.sh
-!stop_very_all.sh
!README.md
diff --git a/Containers/AudiobookShelf/compose.yml b/Containers/AudiobookShelf/compose.yml
new file mode 100644
index 0000000..8dd0cf7
--- /dev/null
+++ b/Containers/AudiobookShelf/compose.yml
@@ -0,0 +1,16 @@
+services:
+ audiobookshelf:
+ restart: unless-stopped
+ image: ghcr.io/advplyr/audiobookshelf:latest
+ ports:
+ - 13378:80
+ volumes:
+ - /home/criz/Medias/Audiobooks:/audiobooks
+ - /home/criz/Medias/Podcasts:/podcasts
+ - ./config:/config
+ - ./metadata:/metadata
+ environment:
+ - TZ=Europe/Madrid
+ labels:
+ tsdproxy.enable: "true"
+ tsdproxy.name: "audio"
diff --git a/Containers/BentoPDF/compose.yml b/Containers/BentoPDF/compose.yml
new file mode 100644
index 0000000..6cb0a86
--- /dev/null
+++ b/Containers/BentoPDF/compose.yml
@@ -0,0 +1,10 @@
+services:
+ bentopdf:
+ image: bentopdf/bentopdf-simple:latest
+ container_name: bentopdf
+ restart: unless-stopped
+ ports:
+ - '8934:8080'
+ labels:
+ tsdproxy.enable: "true"
+ tsdproxy.name: "pdf"
diff --git a/Containers/Beszel/compose.yml b/Containers/Beszel/compose.yml
new file mode 100644
index 0000000..b21f21c
--- /dev/null
+++ b/Containers/Beszel/compose.yml
@@ -0,0 +1,28 @@
+services:
+ beszel:
+ image: henrygd/beszel
+ container_name: beszel
+ restart: unless-stopped
+ ports:
+ - 8090:8090
+ volumes:
+ - ./beszel_data:/beszel_data
+ labels:
+ tsdproxy.enable: "true"
+ tsdproxy.name: "dash"
+
+ beszel-agent:
+ image: henrygd/beszel-agent
+ container_name: beszel-agent
+ restart: unless-stopped
+ network_mode: host
+ volumes:
+ - /var/run/docker.sock:/var/run/docker.sock:ro
+ - ./beszel_agent_data:/var/lib/beszel-agent
+ # monitor other disks / partitions by mounting a folder in /extra-filesystems
+ - /mnt/disk/.beszel:/extra-filesystems/nvme0n1p2:ro
+ environment:
+ LISTEN: 45876
+ KEY: ${KEY}
+ TOKEN: ${TOKEN}
+ HUB_URL: ${HUB_URL}
diff --git a/Containers/Forgejo/compose.yaml b/Containers/Forgejo/compose.yml
similarity index 60%
rename from Containers/Forgejo/compose.yaml
rename to Containers/Forgejo/compose.yml
index 4b92105..93dc86c 100644
--- a/Containers/Forgejo/compose.yaml
+++ b/Containers/Forgejo/compose.yml
@@ -1,27 +1,11 @@
-services:
- forgejo-ts:
- image: tailscale/tailscale
- container_name: forgejo-ts
- cap_add:
- - net_admin
- devices:
- - /dev/net/tun:/dev/net/tun
- volumes:
- - ./tailscale/state:/var/lib/tailscale
- - ./serveconfig:/config
- environment:
- - TS_AUTHKEY=${TS_AUTHKEY}
- - TS_EXTRA_ARGS=--advertise-tags=tag:forgejo --reset
- - TS_STATE_DIR=/var/lib/tailscale
- - TS_SERVE_CONFIG=/config/serve-config.json
- - TS_USERSPACE=false
- hostname: git
- restart: unless-stopped
+networks:
+ forgejo:
+ external: false
+services:
forgejo:
image: codeberg.org/forgejo/forgejo:11
container_name: forgejo
- network_mode: service:forgejo-ts
environment:
- USER_UID=1000
- USER_GID=1000
@@ -29,19 +13,31 @@ services:
- FORGEJO__database__HOST=forgejo_db:5432
- FORGEJO__database__NAME=forgejo
- FORGEJO__database__USER=forgejo
- - FORGEJO__database__PASSWD=${POSTGRES_PASSWORD}
- FORGEJO__database__SSL_MODE=disable
+ - FORGEJO__database__PASSWD=${POSTGRES_PASSWORD}
- FORGEJO__database__SCHEMA=public
- FORGEJO__database__CHARSET=utf8
+ restart: unless-stopped
+ networks:
+ - forgejo
volumes:
- ./forgejo:/data
- # - /etc/timezone:/etc/timezone:ro
+ - /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
- restart: unless-stopped
+ ports:
+ - '3000:3000'
+ labels:
+ tsdproxy.enable: "true"
+ tsdproxy.name: "git"
+ tsdproxy.container_port: 3000
+ tsdproxy.funnel: "true"
forgejo_db:
image: postgres:16
container_name: forgejo-postgres
+ restart: always
+ networks:
+ - forgejo
environment:
- POSTGRES_DB=forgejo
- POSTGRES_USER=forgejo
@@ -49,4 +45,3 @@ services:
- POSTGRES_HOST_AUTH_METHOD=md5
volumes:
- ./postgres:/var/lib/postgresql/data
- restart: always
diff --git a/Containers/Forgejo/serveconfig/serve-config.json b/Containers/Forgejo/serveconfig/serve-config.json
deleted file mode 100644
index a5c125e..0000000
--- a/Containers/Forgejo/serveconfig/serve-config.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "TCP": {
- "443": {
- "HTTPS": true
- }
- },
- "Web": {
- "${TS_CERT_DOMAIN}:443": {
- "Handlers": {
- "/": {
- "Proxy": "http://127.0.0.1:3000"
- }
- }
- }
- },
- "AllowFunnel": {
- "${TS_CERT_DOMAIN}:443": true
- }
-}
diff --git a/Containers/Gotify/compose.yml b/Containers/Gotify/compose.yml
new file mode 100644
index 0000000..d7a1ec1
--- /dev/null
+++ b/Containers/Gotify/compose.yml
@@ -0,0 +1,17 @@
+services:
+ gotify:
+ container_name: gotify
+ restart: always
+ image: gotify/server
+ ports:
+ - 8084:80
+ environment:
+ GOTIFY_DEFAULTUSER_PASS: 'admin'
+ volumes:
+ - './gotify_data:/app/data'
+ labels:
+ tsdproxy.enable: "true"
+ tsdproxy.name: "gotify"
+ # to run gotify as a dedicated user:
+ # sudo chown -R 1234:1234 ./gotify_data
+ # user: "1234:1234"
diff --git a/Containers/HomeAssistant/compose.yaml b/Containers/HomeAssistant/compose.yaml
deleted file mode 100644
index e629a7d..0000000
--- a/Containers/HomeAssistant/compose.yaml
+++ /dev/null
@@ -1,34 +0,0 @@
-services:
- home-assistant-ts:
- image: tailscale/tailscale
- container_name: home-assistant-ts
- cap_add:
- - net_admin
- devices:
- - /dev/net/tun:/dev/net/tun
- volumes:
- - ./tailscale/state:/var/lib/tailscale
- - ./serveconfig:/config
- environment:
- - TS_AUTHKEY=${TS_AUTHKEY}
- - TS_EXTRA_ARGS=--advertise-tags=tag:home-assistant --reset
- - TS_STATE_DIR=/var/lib/tailscale
- - TS_SERVE_CONFIG=/config/serve-config.json
- - TS_USERSPACE=false
- hostname: home
- restart: unless-stopped
-
- home-assistant:
- container_name: home-assistant
- image: "ghcr.io/home-assistant/home-assistant:stable"
- volumes:
- - ./config:/config
- - /etc/localtime:/etc/localtime:ro
- - /run/dbus:/run/dbus:ro
- devices:
- - /dev/ttyUSB0:/dev/ttyUSB0
- restart: unless-stopped
- network_mode: service:home-assistant-ts
- environment:
- TZ: Europe/France
-
diff --git a/Containers/HomeAssistant/config/configuration.yaml b/Containers/HomeAssistant/config/configuration.yaml
deleted file mode 100644
index 2615661..0000000
--- a/Containers/HomeAssistant/config/configuration.yaml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-# Loads default set of integrations. Do not remove.
-default_config:
-
-# Load frontend themes from the themes folder
-frontend:
- themes: !include_dir_merge_named themes
-
-automation: !include automations.yaml
-script: !include scripts.yaml
-scene: !include scenes.yaml
-
-http:
- use_x_forwarded_for: true
- trusted_proxies:
- - 127.0.0.1
- - 100.64.0.0/10
-
diff --git a/Containers/HomeAssistant/serveconfig/serve-config.json b/Containers/HomeAssistant/serveconfig/serve-config.json
deleted file mode 100644
index 8661448..0000000
--- a/Containers/HomeAssistant/serveconfig/serve-config.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "TCP": {
- "443": {
- "HTTPS": true
- }
- },
- "Web": {
- "${TS_CERT_DOMAIN}:443": {
- "Handlers": {
- "/": {
- "Proxy": "http://127.0.0.1:8123"
- }
- }
- }
- },
- "AllowFunnel": {
- "${TS_CERT_DOMAIN}:443": false
- }
-}
diff --git a/Containers/Immich/compose.yml b/Containers/Immich/compose.yml
new file mode 100644
index 0000000..3b97c8d
--- /dev/null
+++ b/Containers/Immich/compose.yml
@@ -0,0 +1,77 @@
+#
+# WARNING: To install Immich, follow our guide: https://immich.app/docs/install/docker-compose
+#
+# Make sure to use the docker-compose.yml of the current release:
+#
+# https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml
+#
+# The compose file on main may not be compatible with the latest release.
+
+name: immich
+
+services:
+ immich-server:
+ container_name: immich_server
+ image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}
+ # extends:
+ # file: hwaccel.transcoding.yml
+ # service: cpu # set to one of [nvenc, quicksync, rkmpp, vaapi, vaapi-wsl] for accelerated transcoding
+ volumes:
+ # Do not edit the next line. If you want to change the media storage location on your system, edit the value of UPLOAD_LOCATION in the .env file
+ - ${UPLOAD_LOCATION}:/data
+ - /etc/localtime:/etc/localtime:ro
+ env_file:
+ - .env
+ ports:
+ - '2283:2283'
+ depends_on:
+ - redis
+ - database
+ restart: always
+ healthcheck:
+ disable: false
+ labels:
+ tsdproxy.enable: "true"
+ tsdproxy.name: "photos"
+
+ immich-machine-learning:
+ container_name: immich_machine_learning
+ # For hardware acceleration, add one of -[armnn, cuda, rocm, openvino, rknn] to the image tag.
+ # Example tag: ${IMMICH_VERSION:-release}-cuda
+ image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}
+ # extends: # uncomment this section for hardware acceleration - see https://immich.app/docs/features/ml-hardware-acceleration
+ # file: hwaccel.ml.yml
+ # service: cpu # set to one of [armnn, cuda, rocm, openvino, openvino-wsl, rknn] for accelerated inference - use the `-wsl` version for WSL2 where applicable
+ volumes:
+ - model-cache:/cache
+ env_file:
+ - .env
+ restart: always
+ healthcheck:
+ disable: false
+
+ redis:
+ container_name: immich_redis
+ image: docker.io/valkey/valkey:8-bookworm@sha256:a137a2b60aca1a75130022d6bb96af423fefae4eb55faf395732db3544803280
+ healthcheck:
+ test: redis-cli ping || exit 1
+ restart: always
+
+ database:
+ container_name: immich_postgres
+ image: ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0@sha256:32324a2f41df5de9efe1af166b7008c3f55646f8d0e00d9550c16c9822366b4a
+ environment:
+ POSTGRES_PASSWORD: ${DB_PASSWORD}
+ POSTGRES_USER: ${DB_USERNAME}
+ POSTGRES_DB: ${DB_DATABASE_NAME}
+ POSTGRES_INITDB_ARGS: '--data-checksums'
+ # Uncomment the DB_STORAGE_TYPE: 'HDD' var if your database isn't stored on SSDs
+ # DB_STORAGE_TYPE: 'HDD'
+ volumes:
+ # Do not edit the next line. If you want to change the database storage location on your system, edit the value of DB_DATA_LOCATION in the .env file
+ - ${DB_DATA_LOCATION}:/var/lib/postgresql/data
+ shm_size: 128mb
+ restart: always
+
+volumes:
+ model-cache:
diff --git a/Containers/Jellyfin/compose.yml b/Containers/Jellyfin/compose.yml
new file mode 100644
index 0000000..c4c1ec8
--- /dev/null
+++ b/Containers/Jellyfin/compose.yml
@@ -0,0 +1,20 @@
+services:
+ jellyfin:
+ restart: 'unless-stopped'
+ image: jellyfin/jellyfin
+ container_name: jellyfin
+ network_mode: 'host'
+ volumes:
+ - ./config:/config
+ - ./cache:/cache
+ - type: bind
+ source: /mnt/moviesHDD/JellyfinMedias
+ target: /media
+ devices:
+ - /dev/dri:/dev/dri
+ group_add:
+ - 44
+ - 922
+ labels:
+ tsdproxy.enable: "true"
+ tsdproxy.name: "stream"
diff --git a/Containers/Metube/compose.yml b/Containers/Metube/compose.yml
new file mode 100644
index 0000000..d2c87a0
--- /dev/null
+++ b/Containers/Metube/compose.yml
@@ -0,0 +1,14 @@
+services:
+ metube:
+ image: ghcr.io/alexta69/metube:latest
+ container_name: metube
+ restart: unless-stopped
+ ports:
+ - "8083:8081"
+ volumes:
+ - /home/criz/Medias/metube:/downloads
+ environment:
+ - MAX_CONCURRENT_DOWNLOADS=6
+ labels:
+ tsdproxy.enable: "true"
+ tsdproxy.name: "ytb-dl"
diff --git a/Containers/N8N/compose.yml b/Containers/N8N/compose.yml
new file mode 100644
index 0000000..44a290a
--- /dev/null
+++ b/Containers/N8N/compose.yml
@@ -0,0 +1,19 @@
+services:
+ n8n:
+ container_name: n8n
+ image: docker.n8n.io/n8nio/n8n
+ restart: always
+ ports:
+ - 5678:5678
+ environment:
+ # - N8N_PROTOCOL=http
+ - N8N_PORT=5678
+ - NODE_ENV=production
+ - WEBHOOK_URL=n8n.rufous-trench.ts.net
+ volumes:
+ - ./n8n:/home/node/.n8n
+ - ./local-files:/files
+ labels:
+ tsdproxy.enable: "true"
+ tsdproxy.name: "n8n"
+ tsdproxy.funnel: "true"
diff --git a/Containers/Navidrome/compose.yaml b/Containers/Navidrome/compose.yaml
deleted file mode 100644
index e91d23b..0000000
--- a/Containers/Navidrome/compose.yaml
+++ /dev/null
@@ -1,31 +0,0 @@
-services:
- navidrome-ts:
- image: tailscale/tailscale
- container_name: navidrome-ts
- cap_add:
- - net_admin
- devices:
- - /dev/net/tun:/dev/net/tun
- volumes:
- - ./tailscale/state:/var/lib/tailscale
- - ./serveconfig:/config
- environment:
- - TS_AUTHKEY=${TS_AUTHKEY}
- - TS_EXTRA_ARGS=--advertise-tags=tag:navidrome --reset
- - TS_STATE_DIR=/var/lib/tailscale
- - TS_SERVE_CONFIG=/config/serve-config.json
- - TS_USERSPACE=false
- hostname: music
- restart: unless-stopped
-
- navidrome:
- network_mode: service:navidrome-ts
- container_name: navidrome
- image: deluan/navidrome:latest
- user: 1000:1000 # should be owner of volumes
- # ports:
- # - "4533:4533"
- restart: unless-stopped
- volumes:
- - "./data:/data"
- - "/mnt/usb-ssd-01/music:/music:ro"
diff --git a/Containers/Navidrome/compose.yml b/Containers/Navidrome/compose.yml
new file mode 100644
index 0000000..ce23e19
--- /dev/null
+++ b/Containers/Navidrome/compose.yml
@@ -0,0 +1,15 @@
+services:
+ navidrome:
+ container_name: navidrome
+ image: deluan/navidrome:latest
+ user: 1000:1000 # should be owner of volumes
+ ports:
+ - "4533:4533"
+ restart: unless-stopped
+ volumes:
+ - "./data:/data"
+ - "/home/criz/Medias/Music:/music:ro"
+ labels:
+ tsdproxy.enable: "true"
+ tsdproxy.name: "music"
+ tsdproxy.funnel: "true"
diff --git a/Containers/Navidrome/serveconfig/serve-config.json b/Containers/Navidrome/serveconfig/serve-config.json
deleted file mode 100644
index 7c2f38e..0000000
--- a/Containers/Navidrome/serveconfig/serve-config.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "TCP": {
- "443": {
- "HTTPS": true
- }
- },
- "Web": {
- "${TS_CERT_DOMAIN}:443": {
- "Handlers": {
- "/": {
- "Proxy": "http://127.0.0.1:4533"
- }
- }
- }
- },
- "AllowFunnel": {
- "${TS_CERT_DOMAIN}:443": true
- }
-}
diff --git a/Containers/NextCloud/compose.yaml b/Containers/NextCloud/compose.yml
similarity index 51%
rename from Containers/NextCloud/compose.yaml
rename to Containers/NextCloud/compose.yml
index bf360c9..edbf1d1 100644
--- a/Containers/NextCloud/compose.yaml
+++ b/Containers/NextCloud/compose.yml
@@ -1,60 +1,53 @@
services:
- nextcloud-ts:
- image: tailscale/tailscale
- container_name: nextcloud-ts
- cap_add:
- - net_admin
- volumes:
- - ./tailscale/state:/var/lib/tailscale
- - ./serveconfig:/config
- devices:
- - /dev/net/tun:/dev/net/tun
- environment:
- - TS_AUTHKEY=${TS_AUTHKEY}
- - TS_EXTRA_ARGS=--advertise-tags=tag:nextcloud --reset
- - TS_STATE_DIR=/var/lib/tailscale
- - TS_SERVE_CONFIG=/config/serve-config.json
- - TS_USERSPACE=false
- hostname: cloud
- restart: unless-stopped
-
+
# Nextcloud
nextcloud:
image: nextcloud
container_name: nextcloud
restart: always
- network_mode: "service:nextcloud-ts"
+ ports:
+ - "8081:80"
+ networks:
+ - cloud
volumes:
- - ./nextcloud:/var/www/html
- - /mnt/usb-ssd-01/nextcloud/nextcloud-data:/var/www/html/data
-
- - /mnt/usb-ssd-01/metube:/mnt/metube
- - /mnt/usb-ssd-01/music:/mnt/music
-
- - /mnt/usb-ssd-01/nextcloud/ext1:/mnt/blender
+ - ./nextcloud_data:/var/www/html
+ - /home/criz/Medias:/mnt/medias
+ - /mnt/moviesHDD:/mnt/movieshdd
environment:
+ - PUID=1000
+ - PGID=1000
- REDIS_HOST=redis
- PHP_MEMORY_LIMIT=4G
- PHP_UPLOAD_LIMIT=64G
- PHP_OPCACHE_ENABLE=1
- PHP_OPCACHE_MEMORY_CONSUMPTION=256
- PHP_OPCACHE_MAX_ACCELERATED_FILES=100000
- - TRUSTED_PROXIES=100.64.0.0/10 127.0.0.1
+ - TRUSTED_PROXIES=100.64.0.0/10
- OVERWRITEPROTOCOL=https
- OVERWRITEHOST=cloud.rufous-trench.ts.net
-
+
+ labels:
+ tsdproxy.enable: "true"
+ tsdproxy.name: "cloud"
+ tsdproxy.funnel: "true"
+ tsdproxy.ephemeral: "false"
+
redis:
image: redis:alpine
container_name: redis
restart: always
volumes:
- ./redis:/data
+ networks:
+ - cloud
mariadb:
image: mariadb:10.11
container_name: nextcloud_db
restart: always
command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
+ networks:
+ - cloud
volumes:
- ./mariadb:/var/lib/mysql
environment:
@@ -64,4 +57,5 @@ services:
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
-
+networks:
+ cloud:
diff --git a/Containers/NextCloud/serveconfig/serve-config.json b/Containers/NextCloud/serveconfig/serve-config.json
deleted file mode 100644
index 99da2b9..0000000
--- a/Containers/NextCloud/serveconfig/serve-config.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "TCP": {
- "443": {
- "HTTPS": true
- }
- },
- "Web": {
- "${TS_CERT_DOMAIN}:443": {
- "Handlers": {
- "/": {
- "Proxy": "http://127.0.0.1:80"
- }
- }
- }
- },
- "AllowFunnel": {
- "${TS_CERT_DOMAIN}:443": true
- }
-}
diff --git a/Containers/Rsync/compose.yml b/Containers/Rsync/compose.yml
new file mode 100644
index 0000000..e50d280
--- /dev/null
+++ b/Containers/Rsync/compose.yml
@@ -0,0 +1,59 @@
+version: "3.9"
+
+services:
+ backup-sync:
+ image: eeacms/rsync:latest
+ container_name: backup_sync
+ restart: unless-stopped
+ volumes:
+ # Logs
+ - ./logs:/var/log
+ # Medias folder
+ - type: bind
+ source: /home/criz/Medias
+ target: /source/Medias
+ read_only: true
+ - type: bind
+ source: /mnt/backupSD/Medias
+ target: /dest/Medias
+ # Immich folder
+ - type: bind
+ source: /home/criz/SelfHosting/Containers/Immich/library
+ target: /source/Immich
+ read_only: true
+ - type: bind
+ source: /mnt/backupSD/Immich
+ target: /dest/Immich
+ # Nextcloud
+ - type: bind
+ source: /home/criz/SelfHosting/Containers/NextCloud/nextcloud_data/data/Crizomb/files
+ target: /source/NextCloud
+ read_only: true
+ - type: bind
+ source: /mnt/backupSD/NextCloud
+ target: /dest/NextCloud
+ # Forgejo
+ - type: bind
+ source: /home/criz/SelfHosting/Containers/Forgejo/forgejo/git
+ target: /source/Forgejo/git
+ read_only: true
+ - type: bind
+ source: /home/criz/SelfHosting/Containers/Forgejo/forgejo/gitea
+ target: /source/Forgejo/gitea
+ read_only: true
+
+ - type: bind
+ source: /mnt/backupSD/Forgejo/git
+ target: /dest/Forgejo/git
+ - type: bind
+ source: /mnt/backupSD/Forgejo/gitea
+ target: /dest/Forgejo/gitea
+
+ environment:
+ - TZ=Europe/Madrid
+ - CRON_TASK_1=0 4 * * * rsync -av --delete /source/Medias/ /dest/Medias/
+ - CRON_TASK_2=0 4 * * * rsync -av --delete /source/Immich/ /dest/Immich/
+ - CRON_TASK_3=0 4 * * * rsync -av --delete /source/NextCloud/ /dest/NextCloud/
+ - CRON_TASK_4=0 4 * * * rsync -av --delete /source/Forgejo/git /dest/Forgejo/git/
+ - CRON_TASK_5=0 4 * * * rsync -av --delete /source/Forgejo/gitea /dest/Forgejo/gitea/
+ command: ["client"]
diff --git a/Containers/TSDProxy/compose.yml b/Containers/TSDProxy/compose.yml
new file mode 100644
index 0000000..0dd8d52
--- /dev/null
+++ b/Containers/TSDProxy/compose.yml
@@ -0,0 +1,15 @@
+services:
+
+ ## tsdproxy
+ tsdproxy:
+ image: almeidapaulopt/tsdproxy:latest
+ container_name: tsdproxy
+ volumes:
+ - /var/run/docker.sock:/var/run/docker.sock
+ - ./data:/data
+ environment:
+ # Get AuthKey from your Tailscale account
+ - TSDPROXY_AUTHKEY=${TSD_PROXY_AUTH}
+ - DOCKER_HOST=unix:///var/run/docker.sock
+ restart: always
+
diff --git a/Containers/UptimeKuma/compose.yml b/Containers/UptimeKuma/compose.yml
new file mode 100644
index 0000000..9cf87fe
--- /dev/null
+++ b/Containers/UptimeKuma/compose.yml
@@ -0,0 +1,29 @@
+version: "3.8"
+
+services:
+ uptime-kuma:
+ image: louislam/uptime-kuma:latest
+ container_name: uptime-kuma
+ restart: always
+ ports:
+ - "2301:3001" # This maps the container port "3001" to the host port "3001"
+ volumes:
+ - /path/to/data:/app/data # Configuring persistent storage
+ environment:
+ - TZ=UTC+1 # Set the timezone (change to your preferred local timezone so monitoring times are the same)
+ - UMASK=0022 # Set your file permissions manually
+ healthcheck:
+ test: ["CMD", "curl", "-f", "http://localhost:3001"]
+ interval: 30s
+ retries: 3
+ start_period: 10s
+ timeout: 5s
+ logging:
+ driver: "json-file"
+ options:
+ max-size: "10m"
+ max-file: "3"
+ labels:
+ tsdproxy.enable: "true"
+ tsdproxy.name: "uptime"
+
diff --git a/README.md b/README.md
index 7b058d0..8dc3377 100644
--- a/README.md
+++ b/README.md
@@ -1,90 +1,59 @@
# Selfhosting personnal repo
-My very simple self-hosting setup.
-On my new mini-pc.
-Gettings things simpler & simpler overtime.
-Check branch : archive_01 for old setup.
+(Old setup on ideapad, using TSDProxy)
-Not 100% reproductible (Maybe one day NixOs?), some light debugging & manual adjust when migrating. See random dump at the end
+My very simple self-hosting setup.
+TSDProxy does heavy lifting to make things simple.
## Hardware & OS
-- Origimagic C2 Neo Mini PC
-- N95 Alder Lake
-- 12gb ddr5
-- 512gb internal nvme
-- 1 To external USB SSD (For nextcloud files)
+- ideapad 15ADA05 laptop
+- Ryzen 5 3500u
+- 12gb ddr4
+- 512gb nvme
## Stack
- Debian13
+- Docker
+- Incus for VMs management
- Tailscale (VPN)
-- Docker (with compose)
-
-## Networking
-
-Heavy use of Tailscale sidecar (see network_mode: "service:myapp-ts") :
-- Https without much efforts
-- Easy domain name with MagicDNS (ending in rufous-trench.ts.net).
-- Both VPN access for best-perf, and funnel for public access without opening ports.
-
-Inconvenients :
-- Vendor lock-in for networking. Even if tailscale seems cooler than cloudflare, it's still a vendor lock-in
-- Not so wide adoption, need often manual thinkering
+- TSDProxy (Tailscale proxy to have easily a domain per service)
## Services
- Forgejo (git repo management)
- Nextcloud (google drive replacement)
- Navidrome (Music streaming)
+- Metube (Video / Music downloader)
+- n8n (automation with graphs, selfhosted zapier)
+- Beszel (Ressources monitoring)
+- Immich (google photos replacement)
+- Bentopdf (ilovepdf.com replacement)
+- AudiobookShelf (audibooks & podcasts)
+- Affine (notes taking, obsidian replacement)
+- Gotify (Simple notifcation system)
+- PaperlessNGNX (OCR things)
+- UptimeKuma (Healthchecks)
## CI
-- Forgejo runners on my school computers for the moment lol. With podman for easy rootless containers.
+Done with a Forgejo runner in a VM. See VMs/ folder for more details.
## Backup
-#TODO rsync thingy to family NAS
+RSync backup important things (git, lfs, nextcloud documents) to an SD Card.
+Not ideal
-# Random dump / doc
+## Random dump
-### Nextcloud
-group & user : 33, chown nextcloud folders
-
-
-Music folder owned by 1000 (for navidrome access)
-But I want nextcloud to also be able to move those files (easy access & add)
-
-
-Solution :
+Medias is mounted on nextcloud, and other things (just me tube for the moment)
```bash
-sudo apt install acl
-sudo setfacl -R -m u:33:rwx /.../.../Music
+sudo setfacl -R -m u:33:rwx /home/yourusername/Medias
+sudo setfacl -R -m d:u:33:rwx /home/yourusername/Medias
```
-Also Nextcloud crontab thingy
-
-
-```bash
-sudo crontab -e
-*/5 * * * * docker exec -u www-data nextcloud php /var/www/html/cron.php
-```
-
-### Forgejo
-postgres complaining when networking change : Check pg_hba.conf, change it if needed
-
-### Navidrome
-Because external mess, Nextcloud can modify files etc...
-```toml
-[scanner]
-PurgeMissing = "always"
-```
-
-## TODO / Random vaguely related projects
-
-- Home assistant
-- Old laptop as test server (probably on new branch)
-- Wake on Wan for computer desktop via rasberry pi
-- Old phones used for dashboard
-- Maybe graphana things one day
+and metube doesn't like deleting videos externally
+Tailscale KEY last 3 month. Do not forget to update it (inside .env of TSDProxy)
+Nextcloud was a pain in the ass, do not use cringe ass AIO container. Works fine now.
diff --git a/Scripts/README.md b/Scripts/README.md
new file mode 100644
index 0000000..bde072a
--- /dev/null
+++ b/Scripts/README.md
@@ -0,0 +1 @@
+Pas encore utilisé
diff --git a/VMs/ForgejoRunner/README.md b/VMs/ForgejoRunner/README.md
new file mode 100644
index 0000000..c16c688
--- /dev/null
+++ b/VMs/ForgejoRunner/README.md
@@ -0,0 +1,12 @@
+# Forgejo runner setup
+
+Run forgejo runners instance inside a VM to do very dirty things but securely.
+The "dirty things" is just having forgejo running in priviliged container, with direct access to the host (VM) docker socket.
+Runners can easily get full access to host, but the host is a VM so it's ok
+I use [incus](https://linuxcontainers.org/incus/) to create the VM. I love it, very simple, docker like interface
+See launch_forgejo_runner_vm.sh for more information about the VM setup.
+
+
+To setup, you still need to enter VM, and follow forgejo [runner instalation guide](https://forgejo.org/docs/next/admin/actions/runner-installation/)
+It's still a little bit manual, but it's done in 30s
+
\ No newline at end of file
diff --git a/VMs/ForgejoRunner/compose.yml b/VMs/ForgejoRunner/compose.yml
new file mode 100644
index 0000000..fb55e78
--- /dev/null
+++ b/VMs/ForgejoRunner/compose.yml
@@ -0,0 +1,22 @@
+# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+# VERY INSECURE RUN THIS IN THE INCUS VM SEE LAUNCH SH FILE
+# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+services:
+ forgejo-runner:
+ image: data.forgejo.org/forgejo/runner:11
+ container_name: forgejo-runner
+ environment:
+ # Let the runner use the host Docker daemon via socket
+ DOCKER_HOST: unix:///var/run/docker.sock
+ # Run as root so the socket permissions don’t block access
+ user: 0:0
+ # Mount host docker.sock for sibling container access
+ volumes:
+ - ./data:/data
+ - /var/run/docker.sock:/var/run/docker.sock
+ - ./volume/config.yml:/config.yml
+ restart: unless-stopped
+ privileged: true
+ #command: /bin/sh -c "sleep 5; forgejo-runner daemon"
+ command: '/bin/sh -c "while : ; do sleep 1 ; done ;"'
diff --git a/VMs/ForgejoRunner/config.yml b/VMs/ForgejoRunner/config.yml
new file mode 100644
index 0000000..bc3ca30
--- /dev/null
+++ b/VMs/ForgejoRunner/config.yml
@@ -0,0 +1,194 @@
+# Example configuration file, it's safe to copy this as the default config file without any modification.
+
+# You don't have to copy this file to your instance,
+# just run `forgejo-runner generate-config > config.yaml` to generate a config file.
+
+#
+# The value of level or job_level can be trace, debug, info, warn, error or fatal
+#
+log:
+ #
+ # What is displayed in the output of the runner process but not sent
+ # to the Forgejo instance.
+ #
+ level: info
+ #
+ # What is sent to the Forgejo instance and therefore
+ # visible in the web UI for a given job.
+ #
+ job_level: info
+
+runner:
+ # Where to store the registration result.
+ file: .runner
+ # Execute how many tasks concurrently at the same time.
+ capacity: 1
+ # Extra environment variables to run jobs.
+ envs:
+ A_TEST_ENV_NAME_1: a_test_env_value_1
+ A_TEST_ENV_NAME_2: a_test_env_value_2
+ # Extra environment variables to run jobs from a file.
+ # It will be ignored if it's empty or the file doesn't exist.
+ env_file: .env
+ # The timeout for a job to be finished.
+ # Please note that the Forgejo instance also has a timeout (3h by default) for the job.
+ # So the job could be stopped by the Forgejo instance if it's timeout is shorter than this.
+ timeout: 3h
+ # The timeout for the runner to wait for running jobs to finish when
+ # shutting down because a TERM or INT signal has been received. Any
+ # running jobs that haven't finished after this timeout will be
+ # cancelled.
+ # If unset or zero the jobs will be cancelled immediately.
+ shutdown_timeout: 3h
+ # Whether skip verifying the TLS certificate of the instance.
+ insecure: false
+ # The timeout for fetching the job from the Forgejo instance.
+ fetch_timeout: 5s
+ # The interval for fetching the job from the Forgejo instance.
+ fetch_interval: 2s
+ # The interval for reporting the job status and logs to the Forgejo instance.
+ report_interval: 1s
+ # The labels of a runner are used to determine which jobs the runner can run, and how to run them.
+ # Like: ["macos-arm64:host", "ubuntu-latest:docker://node:20-bookworm", "ubuntu-22.04:docker://node:20-bookworm"]
+ # If it's empty when registering, it will ask for inputting labels.
+ # If it's empty when executing the `daemon`, it will use labels in the `.runner` file.
+ labels: []
+
+cache:
+ #
+ # When enabled, workflows will be given the ACTIONS_CACHE_URL environment variable
+ # used by the https://code.forgejo.org/actions/cache action. The server at this
+ # URL must implement a compliant REST API and it must also be reachable from
+ # the container or host running the workflows.
+ #
+ # See also https://forgejo.org/docs/next/user/actions/advanced-features/#cache
+ #
+ # When it is not enabled, none of the following options apply.
+ #
+ # It works as follows:
+ #
+ # - the workflow is given a one time use ACTIONS_CACHE_URL
+ # - a cache proxy listens to ACTIONS_CACHE_URL
+ # - the cache proxy securely communicates with the cache server using
+ # a shared secret
+ #
+ enabled: true
+ #
+ #######################################################################
+ #
+ # Only used for the internal cache server.
+ #
+ # If external_server is not set, the Forgejo runner will spawn a
+ # cache server that will be used by the cache proxy.
+ #
+ #######################################################################
+ #
+ # The port bound by the internal cache server.
+ # 0 means to use a random available port.
+ #
+ port: 0
+ #
+ # The directory to store the cache data.
+ #
+ # If empty, the cache data will be stored in $HOME/.cache/actcache.
+ #
+ dir: ""
+ #
+ #######################################################################
+ #
+ # Only used for the external cache server.
+ #
+ # If external_server is set, the internal cache server is not
+ # spawned.
+ #
+ #######################################################################
+ #
+ # The URL of the cache server. The URL should generally end with
+ # "/". The cache proxy will forward requests to the external
+ # server. The requests are authenticated with the "secret" that is
+ # shared with the external server.
+ #
+ external_server: ""
+ #
+ # The shared cache secret used to secure the communications between
+ # the cache proxy and the cache server.
+ #
+ # If empty, it will be generated to a new secret automatically when
+ # the server starts and it will stay the same until it restarts.
+ #
+ secret: ""
+ #
+ #######################################################################
+ #
+ # Common to the internal and external cache server
+ #
+ #######################################################################
+ #
+ # The IP or hostname (195.84.20.30 or example.com) to use when constructing
+ # ACTIONS_CACHE_URL which is the URL of the cache proxy.
+ #
+ # If empty it will be detected automatically.
+ #
+ # If the containers or host running the workflows reside on a
+ # different network than the Forgejo runner (for instance when the
+ # docker server used to create containers is not running on the same
+ # host as the Forgejo runner), it may be impossible to figure that
+ # out automatically. In that case you can specify which IP or
+ # hostname to use to reach the internal cache server created by the
+ # Forgejo runner.
+ #
+ host: ""
+ #
+ # The port bound by the internal cache proxy.
+ # 0 means to use a random available port.
+ #
+ proxy_port: 0
+ #
+ # Overrides the ACTIONS_CACHE_URL variable passed to workflow
+ # containers. The URL should generally not end with "/". This should only
+ # be used if the runner host is not reachable from the workflow containers,
+ # and requires further setup.
+ #
+ actions_cache_url_override: ""
+
+container:
+ # Specifies the network to which the container will connect.
+ # Could be host, bridge or the name of a custom network.
+ # If it's empty, create a network automatically.
+ network: ""
+ # Whether to create networks with IPv6 enabled. Requires the Docker daemon to be set up accordingly.
+ # Only takes effect if "network" is set to "".
+ enable_ipv6: false
+ # Whether to use privileged mode or not when launching task containers (privileged mode is required for Docker-in-Docker).
+ privileged: false
+ # And other options to be used when the container is started (eg, --volume /etc/ssl/certs:/etc/ssl/certs:ro).
+ options:
+ # The parent directory of a job's working directory.
+ # If it's empty, /workspace will be used.
+ workdir_parent:
+ # Volumes (including bind mounts) can be mounted to containers. Glob syntax is supported, see https://github.com/gobwas/glob
+ # You can specify multiple volumes. If the sequence is empty, no volumes can be mounted.
+ # For example, if you only allow containers to mount the `data` volume and all the json files in `/src`, you should change the config to:
+ # valid_volumes:
+ # - data
+ # - /etc/ssl/certs
+ # If you want to allow any volume, please use the following configuration:
+ # valid_volumes:
+ # - '**'
+ valid_volumes: []
+ # Overrides the docker host set by the DOCKER_HOST environment variable, and mounts on the job container.
+ # If "-" or "", no docker host will be mounted in the job container
+ # If "automount", an available docker host will automatically be found and mounted in the job container (e.g. /var/run/docker.sock).
+ # If it's a url, the specified docker host will be mounted in the job container
+ # Example urls: unix:///run/docker.socket or ssh://user@host
+ # The specified socket is mounted within the job container at /var/run/docker.sock
+ docker_host: "-"
+ # Pull docker image(s) even if already present
+ force_pull: true
+ # Rebuild local docker image(s) even if already present
+ force_rebuild: false
+
+host:
+ # The parent directory of a job's working directory.
+ # If it's empty, $HOME/.cache/act/ will be used.
+ workdir_parent:
diff --git a/VMs/ForgejoRunner/create_data.sh b/VMs/ForgejoRunner/create_data.sh
new file mode 100644
index 0000000..2a02ff9
--- /dev/null
+++ b/VMs/ForgejoRunner/create_data.sh
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+
+set -e
+
+mkdir -p data/.cache
+
+chown -R 1001:1001 data
+chmod 775 data/.cache
+chmod g+s data/.cache
diff --git a/VMs/ForgejoRunner/launch_forgejo_runner_vm.sh b/VMs/ForgejoRunner/launch_forgejo_runner_vm.sh
new file mode 100755
index 0000000..18608b6
--- /dev/null
+++ b/VMs/ForgejoRunner/launch_forgejo_runner_vm.sh
@@ -0,0 +1,106 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+########################################
+# Configuration
+########################################
+VM_NAME="forgejo-runner-vm"
+IMAGE="images:debian/trixie"
+MEMORY="2GiB"
+DISK="25GiB"
+CPUS="4"
+
+########################################
+# Helper functions
+########################################
+log() {
+ echo "[+] $*"
+}
+
+vm_exists() {
+ incus info "$VM_NAME" >/dev/null 2>&1
+}
+
+########################################
+# Create VM if needed
+########################################
+if vm_exists; then
+ log "VM '$VM_NAME' already exists, skipping creation"
+else
+ log "Creating VM '$VM_NAME'"
+ incus launch "$IMAGE" "$VM_NAME" \
+ --vm \
+ -c limits.memory="$MEMORY" \
+ -c limits.cpu="$CPUS" \
+ --device root,size="$DISK"
+fi
+
+########################################
+# Wait for VM to be ready
+########################################
+log "Waiting for VM to become ready"
+incus exec "$VM_NAME" -- cloud-init status --wait >/dev/null 2>&1 || true
+
+log "Waiting for Incus Agent to start"
+# This loop tries a simple command until it succeeds or times out
+RETRIES=0
+MAX_RETRIES=30
+until incus exec "$VM_NAME" -- uptime >/dev/null 2>&1; do
+ RETRIES=$((RETRIES + 1))
+ if [ $RETRIES -ge $MAX_RETRIES ]; then
+ echo "Error: Timeout waiting for VM agent to start."
+ exit 1
+ fi
+ echo "$RETRIES retries"
+ sleep 1
+done
+
+log "Agent is responsive. Proceeding..."
+########################################
+# Install Docker inside the VM
+########################################
+log "Installing Docker inside VM"
+
+incus exec "$VM_NAME" -- bash -eux <<'EOF'
+export DEBIAN_FRONTEND=noninteractive
+
+# Base packages
+apt-get update
+apt-get install -y \
+ ca-certificates \
+ curl \
+ gnupg
+
+# Docker GPG key
+install -m 0755 -d /etc/apt/keyrings
+curl -fsSL https://download.docker.com/linux/debian/gpg \
+ -o /etc/apt/keyrings/docker.asc
+chmod a+r /etc/apt/keyrings/docker.asc
+
+# Docker repository
+echo \
+ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] \
+ https://download.docker.com/linux/debian \
+ $(. /etc/os-release && echo "$VERSION_CODENAME") stable" \
+ > /etc/apt/sources.list.d/docker.list
+
+# Install Docker
+apt-get update
+apt-get install -y \
+ docker-ce \
+ docker-ce-cli \
+ containerd.io \
+ docker-buildx-plugin \
+ docker-compose-plugin
+
+# Enable Docker
+systemctl enable docker
+systemctl start docker
+EOF
+
+########################################
+# Done
+########################################
+log "Docker successfully installed in VM '$VM_NAME'"
+log "You can access it with:"
+echo " incus exec $VM_NAME -- bash"
diff --git a/start_all.sh b/start_all.sh
index 1aae618..1c006ec 100755
--- a/start_all.sh
+++ b/start_all.sh
@@ -1,3 +1,3 @@
for d in Containers/*/ ; do
- docker compose -f "$d/compose.yaml" up -d
+ docker compose -f "$d/compose.yml" up -d
done
diff --git a/stop_all.sh b/stop_all.sh
index e3d0f11..6e2507b 100755
--- a/stop_all.sh
+++ b/stop_all.sh
@@ -1,3 +1,4 @@
for d in Containers/*/ ; do
- docker compose -f "$d/compose.yaml" down
+ docker compose -f "$d/compose.yml" down
done
+
diff --git a/stop_very_all.sh b/stop_very_all.sh
deleted file mode 100755
index 183578c..0000000
--- a/stop_very_all.sh
+++ /dev/null
@@ -1 +0,0 @@
-docker stop $(docker ps -a -q)