diff --git a/README.md b/README.md
index f403636..8e85a0b 100644
--- a/README.md
+++ b/README.md
@@ -76,10 +76,31 @@ sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin dock
## Copy your ssh key to the machine
ssh-copy-id -p 2222 bapasqui@localhost
+## for peertube
+What you need to do in Keycloak
+1. Go to https://keycloak.chatons.duckdns.org > Admin Console
+2. Create realm chatons (if it doesn't exist)
+3. Go to Clients > Create client:
+ - Client type: OpenID Connect
+ - Client ID: peertube
+4. On the next page:
+ - Client authentication: ON
+ - Valid redirect URIs: https://peertube.chatons.duckdns.org/plugins/auth-openid-connect/0.0.1/auth/openid-connect/callback
+ - Web origins: https://peertube.chatons.duckdns.org
+5. Save, go to Credentials tab, copy the Client Secret
+6. Paste it in core/peertube/.env replacing REPLACE_WITH_KEYCLOAK_CLIENT_SECRET
+Then you also need to install the auth-openid-connect plugin in PeerTube:
+- Go to PeerTube Admin > Plugins > search for auth-openid-connect > Install
+
+
```
### Ressources
+
+https://keepgrowing.in/tools/keycloak-in-docker-1-how-to-run-keycloak-in-a-docker-container/
https://zenn.dev/zenogawa/articles/gitea_keycloak?locale=en
+https://rcasys.com/en/blog/how-to-setup-saml-based-single-sign-on-authentication-with-keycloak
https://caddyserver.com/docs/
+https://docker.recipes/media/peertube-video
diff --git a/core/caddy/compose.yml b/core/caddy/compose.yml
index 4ff373a..add6e68 100644
--- a/core/caddy/compose.yml
+++ b/core/caddy/compose.yml
@@ -10,6 +10,7 @@ services:
- caddy-data:/data
- caddy-config:/config
- caddy-diagrams:/srv/diagrams
+ - nextcloud-data:/var/www/html:ro
networks:
- proxy
restart: unless-stopped
@@ -23,6 +24,9 @@ volumes:
caddy-diagrams:
name: caddy-diagrams
external: true
+ nextcloud-data:
+ name: nextcloud-data
+ external: true
networks:
proxy:
diff --git a/core/caddy/config/Caddyfile b/core/caddy/config/Caddyfile
index b902fc2..2435e96 100644
--- a/core/caddy/config/Caddyfile
+++ b/core/caddy/config/Caddyfile
@@ -1,5 +1,5 @@
{
- #local_certs
+ local_certs
default_bind 0.0.0.0
}
diff --git a/core/caddy/config/sites/cloud.caddy b/core/caddy/config/sites/cloud.caddy
new file mode 100644
index 0000000..50b5e0c
--- /dev/null
+++ b/core/caddy/config/sites/cloud.caddy
@@ -0,0 +1,27 @@
+cloud.chatons.duckdns.org {
+ root * /var/www/html
+ php_fastcgi nextcloud:9000
+ file_server
+
+ redir /.well-known/carddav /remote.php/dav/ 301
+ redir /.well-known/caldav /remote.php/dav/ 301
+ redir /.well-known/webfinger /index.php/.well-known/webfinger 301
+ redir /.well-known/nodeinfo /index.php/.well-known/nodeinfo 301
+
+ header {
+ Strict-Transport-Security "max-age=15552000;"
+ }
+
+ @forbidden {
+ path /build/*
+ path /tests/*
+ path /config/*
+ path /lib/*
+ path /3rdparty/*
+ path /templates/*
+ path /data/*
+ path /.htaccess
+ path /.user.ini
+ }
+ respond @forbidden 404
+}
\ No newline at end of file
diff --git a/core/caddy/config/sites/outils.caddy b/core/caddy/config/sites/outils.caddy
index 848c80e..a1e7d2d 100644
--- a/core/caddy/config/sites/outils.caddy
+++ b/core/caddy/config/sites/outils.caddy
@@ -38,4 +38,21 @@ outils.chatons.duckdns.org {
handle_path /teapot {
respond "HTML Tea! Tea! Teapot!" 418
}
+
+ handle_path /links {
+ header Content-Type text/html
+ respond <
+
Links
+
+
+
+
+ HTML 200
+ }
}
\ No newline at end of file
diff --git a/core/caddy/config/sites/peertube.caddy b/core/caddy/config/sites/peertube.caddy
new file mode 100644
index 0000000..ec52b49
--- /dev/null
+++ b/core/caddy/config/sites/peertube.caddy
@@ -0,0 +1,3 @@
+peertube.chatons.duckdns.org {
+ reverse_proxy peertube:9000
+}
\ No newline at end of file
diff --git a/core/git/compose.yml b/core/git/compose.yml
index 1f3bd2e..5c07110 100644
--- a/core/git/compose.yml
+++ b/core/git/compose.yml
@@ -26,6 +26,8 @@ services:
image: library/postgres
container_name: gitea-postgres
restart: always
+ volumes:
+ - gitea-postgres:/var/lib/postgresql
networks:
- proxy
environment:
@@ -35,6 +37,7 @@ services:
volumes:
gitea-data:
+ gitea-postgres:
networks:
proxy:
diff --git a/core/nextcloud/compose.yml b/core/nextcloud/compose.yml
new file mode 100644
index 0000000..a2c5eb6
--- /dev/null
+++ b/core/nextcloud/compose.yml
@@ -0,0 +1,69 @@
+services:
+ nextcloud:
+ image: library/nextcloud:fpm
+ container_name: nextcloud
+ restart: unless-stopped
+ networks:
+ - proxy
+ volumes:
+ - nextcloud-data:/var/www/html
+ depends_on:
+ - postgres-next
+ - redis-next
+ environment:
+ - POSTGRES_DB=nextcloud
+ - POSTGRES_USER=nextcloud
+ - POSTGRES_PASSWORD=${NEXTCLOUD_POSTGRES_PASSWORD}
+ - POSTGRES_HOST=nextcloud-postgres:3232
+ - NEXTCLOUD_ADMIN_USER=admin
+ - NEXTCLOUD_ADMIN_PASSWORD=admin
+ - NEXTCLOUD_TRUSTED_DOMAINS=cloud.chatons.duckdns.org
+ - NEXTCLOUD_TRUSTED_PROXIES=caddy
+ - OVERWRITEPROTOCOL=https
+ - OVERWRITECLIURL=https://cloud.chatons.duckdns.org
+
+
+ postgres-next:
+ image: library/postgres
+ container_name: nextcloud-postgres
+ restart: unless-stopped
+ volumes:
+ - nextcloud-postgres:/var/lib/postgresql
+ networks:
+ - proxy
+ environment:
+ - POSTGRES_USER=nextcloud
+ - POSTGRES_PASSWORD=${NEXTCLOUD_POSTGRES_PASSWORD}
+ - POSTGRES_DB=nextcloud
+ - PGPORT=3232
+ - REDIS_HOST=redis-next
+ - REDIS_HOST_PASSWORD=password
+
+ redis-next:
+ image: library/redis
+ container_name: redis
+ restart: unless-stopped
+ command: redis-server
+ ports:
+ - '6379:6379'
+ volumes:
+ - redis-data:/data
+ environment:
+ - REDIS_ARGS=--requirepass password --appendonly yes
+ networks:
+ - proxy
+
+
+
+volumes:
+ nextcloud-data:
+ name: nextcloud-data
+ redis-data:
+ name: redis-data
+ nextcloud-postgres:
+ name: nextcloud-postgres
+
+networks:
+ proxy:
+ name: proxy
+ external: true
\ No newline at end of file
diff --git a/core/peertube/compose.yml b/core/peertube/compose.yml
new file mode 100644
index 0000000..a250406
--- /dev/null
+++ b/core/peertube/compose.yml
@@ -0,0 +1,75 @@
+services:
+ peertube:
+ image: chocobozzz/peertube:production-bookworm
+ container_name: peertube
+ networks:
+ - proxy
+ ports:
+ - "1935"
+ depends_on:
+ postgres-peertube:
+ condition: service_healthy
+ redis-peertube:
+ condition: service_started
+ environment:
+ - PEERTUBE_DB_USERNAME=${POSTGRES_USER}
+ - PEERTUBE_DB_PASSWORD=${POSTGRES_PASSWORD}
+ - PEERTUBE_DB_SSL=false
+ - PEERTUBE_DB_HOSTNAME=postgres-peertube
+ - PEERTUBE_REDIS_HOSTNAME=redis-peertube
+ - PEERTUBE_WEBSERVER_HOSTNAME=${PEERTUBE_HOSTNAME}
+ - PEERTUBE_TRUST_PROXY=["127.0.0.1", "loopback", "172.18.0.0/16"]
+ - PEERTUBE_SECRET=${PEERTUBE_SECRET}
+ - PEERTUBE_ADMIN_EMAIL=${PEERTUBE_ADMIN_EMAIL}
+ - PT_INITIAL_ROOT_PASSWORD=${PT_INITIAL_ROOT_PASSWORD}
+ - PEERTUBE_PLUGIN_AUTH_OPENID_CONNECT_DISCOVER_URL=https://keycloak.chatons.duckdns.org/realms/chatons/.well-known/openid-configuration
+ - PEERTUBE_PLUGIN_AUTH_OPENID_CONNECT_CLIENT_ID=peertube
+ - PEERTUBE_PLUGIN_AUTH_OPENID_CONNECT_CLIENT_SECRET=${PEERTUBE_OIDC_CLIENT_SECRET}
+ - PEERTUBE_PLUGIN_AUTH_OPENID_CONNECT_SCOPE=openid profile email
+ - PEERTUBE_PLUGIN_AUTH_OPENID_CONNECT_USERNAME_PROPERTY=preferred_username
+ - PEERTUBE_PLUGIN_AUTH_OPENID_CONNECT_MAIL_PROPERTY=email
+ - PEERTUBE_PLUGIN_AUTH_OPENID_CONNECT_DISPLAY_NAME_PROPERTY=name
+ volumes:
+ - peertube-data:/data
+ - peertube-config:/config
+
+ postgres-peertube:
+ image: library/postgres
+ container_name: peertube-db
+ environment:
+ - POSTGRES_USER=${POSTGRES_USER}
+ - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
+ - POSTGRES_DB=peertube
+ volumes:
+ - postgres-peer-data:/var/lib/postgresql
+ networks:
+ - proxy
+ healthcheck:
+ test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d peertube"]
+ interval: 5s
+ timeout: 5s
+ retries: 5
+
+ redis-peertube:
+ image: library/redis
+ container_name: peertube-redis
+ volumes:
+ - redis-peer-data:/data
+ networks:
+ - proxy
+
+
+volumes:
+ peertube-data:
+ name: peertube-data
+ peertube-config:
+ name: peertube-config
+ postgres-peer-data:
+ name: postgres-peer-data
+ redis-peer-data:
+ name: redis-peer-data
+
+networks:
+ proxy:
+ name: proxy
+ external: true
\ No newline at end of file
diff --git a/core/postgresql/compose.yml b/core/postgresql/compose.yml
index b82a7e0..8d456c3 100644
--- a/core/postgresql/compose.yml
+++ b/core/postgresql/compose.yml
@@ -4,6 +4,8 @@ services:
container_name: postgres
networks:
- proxy
+ volumes:
+ - keycloak-postgres:/var/lib/postgresql
environment:
POSTGRES_USER: bapasqui
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
@@ -11,6 +13,10 @@ services:
POSTGRES_DB: keycloak
restart: unless-stopped
+volumes:
+ keycloak-postgres:
+
+
networks:
proxy:
name: proxy
diff --git a/core/tools/mini-moulinette.sh b/core/tools/mini-moulinette.sh
new file mode 100644
index 0000000..0c66dd8
--- /dev/null
+++ b/core/tools/mini-moulinette.sh
@@ -0,0 +1,98 @@
+#!/bin/bash
+
+set -euo pipefail
+
+# ft_chatons audit script
+# La Contre-Voie x 42
+# Date: 2025-10-27
+# Author: neil
+
+# Move to the Core folder
+cd core
+
+# Computes tab width depending on the longest Core folder name length
+audit_name_width() {
+ local width=0
+ for srv in $(find . -maxdepth 1 -type d); do
+ [ $width -lt ${#srv} ] && width=${#srv}
+ done
+ echo $width
+}
+
+# Used to switch colors on results screen
+chkbool() {
+ if [[ -z "$1" ]]; then
+ c_red "NO"
+ else
+ c_green "$1"
+ fi
+}
+
+c_red() {
+ echo -ne '\033[0;31m'$1'\033[0m'
+}
+
+c_green() {
+ echo -ne '\033[0;32m'$1'\033[0m'
+}
+
+# Audits a single container given as parameter
+# example: audit_single caddy
+audit_single() {
+ local max_width=$([ $# -ge 3 ] && echo $3 || echo 14)
+
+ printf "%-*s " "$max_width" "$1"
+
+ RUNNING=$(docker ps -q -f name=^$1\$)
+ if [[ -z $RUNNING ]]; then
+ c_red "DOWN\t"
+ else
+ c_green "UP!\t"
+ fi
+
+ chkbool "$(grep "pids_limit" $1/compose.yml | xargs | sed 's/pids_limit: //g')"
+ echo -ne "\t\t"
+
+ chkbool "$(grep "cpu_shares" $1/compose.yml | xargs | sed 's/cpu_shares: //g')"
+ echo -ne "\t\t"
+
+ chkbool "$(grep "mem_limit" $1/compose.yml | xargs | sed 's/mem_limit: //g')"
+
+ if ! [[ -z $RUNNING ]]; then
+ echo -ne "\t\t"
+
+ chkbool "$(docker inspect --format '{{ .Id }}:ReadonlyRootfs={{ .HostConfig.ReadonlyRootfs }}' $1 | grep -o "true" | sed 's/true/YES/g')"
+ echo -ne "\t\t"
+
+ chkbool "$(ps -p $(docker inspect --format='{{ .State.Pid }}' $1) -o user | tail -n 1 | sed 's/root//g' | sed -E 's/.+/YES/g')"
+ echo -ne "\t\t"
+
+ chkbool "$(docker inspect --format '{{ .Id }}:SecurityOpt={{ .HostConfig.SecurityOpt }}' $1 | grep "no-new-privileges" | sed -E 's/.+/YES/g')"
+
+ echo -ne "\t\t"
+ chkbool "$($(docker run --rm -it --net container:$1 alpine:latest netstat -tnul | tail -n +3 | awk '$1=$1' | cut -d ' ' -f4 | grep -q -e '0.0.0.0' -e ":::") || echo "YES")"
+ fi
+
+ echo ""
+}
+
+# Displays the results header
+audit_tabheader() {
+ local max_width=$([ $# -ge 1 ] && echo $1 || echo 14)
+ printf "%-*s " $max_width "NAME"
+ printf "STATUS\tPID LIMIT\tCPU SHARES\tRAM LIMIT\tREAD-ONLY\tUNPRIVILEGED\tRESTR.PRIV.\tFIXED ADDR."
+ printf "\n"
+}
+
+# Audit all running containers based on the Core folder content
+audit_all() {
+ local max_width=$(audit_name_width)
+ audit_tabheader $max_width
+ for srv in $(find . -maxdepth 1 -type d ! -name '.' ! -name '.git' ! -name 'tools' -printf '%P\n'); do
+ audit_single $srv "" $max_width
+ done
+}
+
+
+# main #
+audit_all
diff --git a/justfile b/justfile
index 0bcba89..6881c15 100644
--- a/justfile
+++ b/justfile
@@ -16,7 +16,7 @@ down container="":
## Delete all container, volumes, etc...
clean container="": (down container)
docker volume rm $(docker volume ls -q) || true
- docker system prune -af
+ #docker system prune -af
docker volume prune -f
diff --git a/startup b/startup
index de36f6c..fb338a6 100755
--- a/startup
+++ b/startup
@@ -22,34 +22,42 @@ case "$1" in
ssh -p 2222 bapasqui@localhost
;;
start)
+ just start nextcloud
just start duckdns
just start caddy
just start doh
just start postgresql
just start keycloak
just start git
+ just start peertube
;;
down)
+ just down nextcloud
just down duckdns
just down caddy
just down doh
just down postgresql
just down keycloak
just down git
+ just down peertube
;;
clean)
+ just clean nextcloud
just clean duckdns
- #just clean caddy
+ just clean caddy
just clean doh
just clean postgresql
- #just clean keycloak
- #just clean git
+ just clean keycloak
+ just clean git
+ just clean peertube
;;
restart)
- just re duckdns
- #just re caddy
- just re doh
- just re postgresql
+ just re nextcloud
+ #just re duckdns
+ just re caddy
+ just re peertube
+ #just re doh
+ #just re postgresql
#just re git
#just re keycloak
;;