Compare commits

...

2 Commits

Author SHA1 Message Date
Adrian Amaglio
be32063fdc update 2023-06-01 15:26:12 +02:00
Adrian Amaglio
308da4955d some doc 2023-05-23 12:26:03 +02:00
27 changed files with 793 additions and 225 deletions

View File

@ -67,16 +67,19 @@ run mkdir -p "$new_nginx_conf_path"
for dir in /docker/* ; do for dir in /docker/* ; do
service="$(basename "$dir")" service="$(basename "$dir")"
# Ignore _ prefixed directories # Ignore _ prefixed directories
[ "${service::1}" == '_' ] && continue [ "${service::1}" == '_' ] && continue
[ ! -d "$dir" ] && continue [ ! -d "$dir" ] && continue
export DATA_DIR="/data/$service"
mkdir -p "$DATA_DIR"
docker_service="$(echo "$service" | tr '.' '_')" docker_service="$(echo "$service" | tr '.' '_')"
driglibash_section_prefix="[$service] " driglibash_section_prefix="[$service] "
export DATA_DIR="/data/$service"
export HTTP_DIR="/srv/http/$service"
export JC_SERVICE="$service"
line_in_file "HTTP_DIR='$HTTP_DIR'" "/docker/$service/.env"
line_in_file "DATA_DIR='$DATA_DIR'" "/docker/$service/.env"
line_in_file "JC_SERVICE='$JC_SERVICE'" "/docker/$service/.env"
cd "/docker/$service" cd "/docker/$service"
# Is service meant to be on this server? # Is service meant to be on this server?
@ -88,6 +91,7 @@ for dir in /docker/* ; do
section "--------------------" section "--------------------"
section "Removing service" section "Removing service"
docker-compose down --rmi all --remove-orphans docker-compose down --rmi all --remove-orphans
[ -d "$HTTP_DIR" ] && rm -r "$HTTP_DIR"
fi fi
# If there is an install script? # If there is an install script?
@ -97,12 +101,18 @@ for dir in /docker/* ; do
stop stop
unset -f start stop reload restart unset -f start stop reload restart
fi fi
# TODO check for leftover wg interfaces
continue continue
fi fi
mkdir -p "$DATA_DIR" "$HTTP_DIR"
# If there is a docker-compose file and it has services in it # If there is a docker-compose file and it has services in it
if [ -f "/docker/$service/docker-compose.yml" ] && [ -n "$(grep '^[^#]*services' "/docker/$service/docker-compose.yml")" ] ; then if [ -f "/docker/$service/docker-compose.yml" ] && [ -n "$(grep '^[^#]*services' "/docker/$service/docker-compose.yml")" ] ; then
section "-------------------- $service" section "-------------------- $service"
section "Logging to registry" section "Logging to registry"
# XXX Login to docker registry # XXX Login to docker registry
@ -114,7 +124,7 @@ for dir in /docker/* ; do
fi fi
# If there is an install script? # If there is an install script
if [ -f "/docker/$service/install.sh" ] ; then if [ -f "/docker/$service/install.sh" ] ; then
section "Running install script" section "Running install script"
. "/docker/$service/install.sh" . "/docker/$service/install.sh"
@ -123,15 +133,26 @@ for dir in /docker/* ; do
fi fi
# If there is a wireguard vpn script
for file in "/docker/$service/"wg-*.sh ; do
section "Starting wg interface"
if [ -x "$file" ] ; then
wgif="$(basename "$file")"
wgif="${wgif:3:-3}"
"$file" $wgif > "/etc/wireguard/$wgif.conf"
systemctl enable "wg-quick@$wgif"
startwg.sh $wgif
fi
done
# If there is a nginx conf file # If there is a nginx conf file
if [ -f "/docker/$service/nginx_server.conf" ] ; then if [ -f "/docker/$service/nginx_server.conf" ] ; then
section "Copy nginx conf" section "Copy nginx conf"
run cp "/docker/$service/nginx_server.conf" "$new_nginx_conf_path/$service" run cp "/docker/$service/nginx_server.conf" "$new_nginx_conf_path/$service"
if [ -f "/docker/$service/.env" ] ; then section "Template nginx conf with vars from '.env' file"
section "Template nginx conf with vars from '.env' file" run template.sh "/docker/$service/.env" < "/docker/$service/nginx_server.conf" > "$new_nginx_conf_path/$service"
run template.sh "/docker/$service/.env" < "/docker/$service/nginx_server.conf" > "$new_nginx_conf_path/$service"
fi
fi fi
# Do we need dummy cert? # Do we need dummy cert?

View File

View File

@ -1,8 +1,11 @@
#!/bin/bash #!/bin/bash
if [ "$#" -ne 1 ] ; then if [ "$1" = '-h' ] || [ "$1" = '--help' ] ; then
echo "Usage: $0 <env_file>" >&2 echo "Usage: $0 <env_file>" >&2
echo "This script read env_file variables and replace theire occurences in stdin" >&2 echo "This script read env_file variables and replace theire occurences in stdin" >&2
exit 1 exit 0
fi
if [ -f "$1" ] ; then
bash -c 'set -a && . '"$1"' && envsubst "$(cat '"$1"' | grep -o ^.*= | sed "s/=//" | sed "s/^/$/")"'
else
cat /dev/stdin
fi fi
bash -c 'set -a && . '"$1"' && envsubst "$(cat '"$1"' | grep -o ^.*= | sed "s/=//" | sed "s/^/$/")"'

View File

@ -1,6 +1,6 @@
$TTL 604800 $TTL 604800
@ IN SOA ns1.jean-cloud.net. contact.jean-cloud.org. ( @ IN SOA ns1.jean-cloud.net. contact.jean-cloud.org. (
2023020700 ; Serial 2023060100 ; Serial
7200 ; Refresh 7200 ; Refresh
7200 ; Retry 7200 ; Retry
2419200 ; Expire 2419200 ; Expire
@ -22,6 +22,6 @@ $TTL 604800
ns1 IN A 51.255.33.248 ns1 IN A 51.255.33.248
ns2 IN A 172.104.154.21 ns2 IN A 172.104.154.21
benevoles IN A 51.178.80.171 benevoles IN CNAME max.jean-cloud.org.
benevoles31 IN A 51.178.80.171 benevoles31 IN CNAME max.jean-cloud.org.

View File

@ -1,23 +1,32 @@
$TTL 604800 $TTL 604800
@ IN SOA ns1.jean-cloud.net. contact.jean-cloud.org. ( @ IN SOA max.jean-cloud.org. contact.jean-cloud.org. (
2023042200 ; Serial 2023052300 ; Serial
604800 ; Refresh 604800 ; Refresh
7200 ; Retry 7200 ; Retry
2419200 ; Expire 2419200 ; Expire
604800 ) ; Negative Cache TTL 604800 ) ; Negative Cache TTL
@ IN NS ns1.jean-cloud.net. ; NS
@ IN NS ns5.he.net.
@ IN NS ns4.he.net.
@ IN NS ns3.he.net.
@ IN NS ns2.he.net.
@ IN NS max.jean-cloud.org.
@ IN NS tetede.jean-cloud.org.
; MAIL
@ IN MX 1 mx0.mail.ovh.net.
@ IN MX 5 mx1.mail.ovh.net.
@ IN MX 50 mx2.mail.ovh.net.
@ IN MX 100 mx3.mail.ovh.net.
@ IN MX 200 mx4.mail.ovh.net.
@ IN TXT "v=spf1 include:mx.ovh.com ~all"
_autodiscover._tcp IN SRV 0 0 443 mailconfig.ovh.net.
_imaps._tcp IN SRV 0 0 993 ssl0.ovh.net.
_submission._tcp IN SRV 0 0 465 ssl0.ovh.net.
; web
@ IN A 51.255.33.248 @ IN A 51.255.33.248
@ IN MX 1 mx1.mail.ovh.net.
@ IN MX 5 mx2.mail.ovh.net.
@ IN MX 10 mx3.mail.ovh.net.
www IN CNAME vandamme.jean-cloud.net. www IN CNAME vandamme.jean-cloud.net.
www.registry IN CNAME nougaro.jean-cloud.net. www.registry IN CNAME nougaro.jean-cloud.net.
@ -32,19 +41,16 @@ radiodemo IN CNAME tetede.jean-cloud.net.
radiodemo-back IN CNAME montbonnot.jean-cloud.net. radiodemo-back IN CNAME montbonnot.jean-cloud.net.
_autodiscover._tcp IN SRV 0 0 443 mailconfig.ovh.net.
_imaps._tcp IN SRV 0 0 993 ssl0.ovh.net.
_submission._tcp IN SRV 0 0 465 ssl0.ovh.net.
;autoconfig IN SRV mailconfig.ovh.net. ;autoconfig IN SRV mailconfig.ovh.net.
imap IN CNAME ssl0.ovh.net. imap IN CNAME ssl0.ovh.net.
smtp IN CNAME ssl0.ovh.net. smtp IN CNAME ssl0.ovh.net.
mail IN CNAME ssl0.ovh.net. mail IN CNAME ssl0.ovh.net.
pop3 IN CNAME ssl0.ovh.net. pop3 IN CNAME ssl0.ovh.net.
stream.paj.ports IN TXT 9002 stream.paj._ports IN TXT 9002
control.paj.ports IN TXT 9492 control.paj._ports IN TXT 9492
pa1.studios IN CNAME carcasse.jean-cloud.net. pa1.studios IN CNAME tetede.jean-cloud.net.
montpellier1.studios IN CNAME tetede.jean-cloud.net. montpellier1.studios IN CNAME tetede.jean-cloud.net.
npm IN CNAME vandamme.jean-cloud.net. npm IN CNAME vandamme.jean-cloud.net.

30
readme.md Normal file
View File

@ -0,0 +1,30 @@
# Services Jean-Cloud
## Dossier installing
Contient des scripts sh pour installer debian sur un disque dur. Qui ira ensuite se brancher dans un ordi :)
## Dossier provisioning
Contient
- des rôles ansible pour configurer les serveurs
- un rôle ansible pour envoyer les services sur les serveurs
- des scripts maisons à envoyer sur les serveurs
- la conf DNS à envoyer sur les serveurs
## Dossier services
Les services à faire tourner.
## scripts
Le script deployer.sh va pour chaque service
- Démarrer docker-compose si besoin
- Copier le fichier nginx.conf dans sites-enabled si besoin (en remplaçant certaines variables) (en créant un faux certificat ssl si besoin)
- Démarrer et activer une interface wg si un fichier `wg-*.conf` est présent.
- Exécuter le script install.sh du service sil existe
Le script letsencrypt.sh va renouveler tous les certificats dont le serveur a besoin (il va lire dans /etc/nginx/sites-enabled).
## Variables
Le script deployer.sh crée les variables
- DATA_DIR : là où sauvegarder des données
- HTTP_DIR : là où mettre les fichiers web si ils sont statiques. Ce dossier peut être détruit à tout moment, il nest pas sauvegardé.
- JC_SERVICE : le nom du dossier service. Correspond souvent à ladresse du service.
Ces variables sont ajoutées au ficher .env du service. (écrasées si existantes donc).

View File

@ -9,7 +9,6 @@ events {
} }
http { http {
## ##
# Basic Settings # Basic Settings
## ##
@ -70,18 +69,17 @@ http {
## ##
include /etc/nginx/conf.d/*.conf; include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*; include /etc/nginx/sites-enabled/*;
server{ server{
listen 80 default_server; listen 80 default_server;
listen [::]:80 default_server; listen [::]:80 default_server;
location '/.well-known/acme-challenge' { location '/.well-known/acme-challenge' {
root /var/www/letsencrypt; root /var/www/letsencrypt;
default_type "text/plain"; default_type "text/plain";
try_files $uri $uri/ =404; try_files $uri $uri/ =404;
} }
location / { location / {
return 301 https://$host$request_uri; return 301 https://$host$request_uri;
} }
} }
} }

View File

@ -1,2 +0,0 @@
DATA_DIR=/data/benevoles.karnaval.fr
JC_HOST=benevoles.karnaval.fr

View File

@ -1,60 +0,0 @@
version: '3'
services:
app:
image: jeancloud/site-benevole:dev-karna
environment:
UID: 33
MOUNT: /
volumes:
- /tmp/uwsgi/$JC_HOST:/tmp/uwsgi
- $DATA_DIR/assets:/usr/src/app/assets
- $DATA_DIR/media:/usr/src/app/media
- $DATA_DIR/local_settings.py:/usr/src/app/site_benevole/local_settings.py
restart: unless-stopped
networks:
default:
ipv4_address: 172.29.17.100
db:
image: postgres:9.6-alpine
env_file: $DATA_DIR/postgres.env
environment:
POSTGRES_USER: benevoles
POSTGRES_DB: benevoles
volumes:
- $DATA_DIR/db:/var/lib/postgresql/data
networks:
default:
ipv4_address: 172.29.17.101
app2:
image: jeancloud/site-benevole:dev-karna-debian
environment:
UID: 33
MOUNT: /
volumes:
- /tmp/uwsgi/app2/$JC_HOST:/tmp/uwsgi
- $DATA_DIR/app2/assets:/usr/src/app/assets
- $DATA_DIR/app2/media:/usr/src/app/media
- $DATA_DIR/app2/local_settings.py:/usr/src/app/site_benevole/local_settings.py
restart: unless-stopped
networks:
default:
ipv4_address: 172.29.17.110
db2:
image: postgres:9.6-alpine
env_file: $DATA_DIR/postgres.env
environment:
POSTGRES_USER: benevoles
POSTGRES_DB: benevoles
volumes:
- $DATA_DIR/db2:/var/lib/postgresql/data
networks:
default:
ipv4_address: 172.29.17.111
networks:
default:
ipam:
config:
- subnet: 172.29.17.0/24

View File

@ -1,110 +0,0 @@
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
ssl_certificate /etc/letsencrypt/live/$JC_HOST/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/$JC_HOST/privkey.pem;
server_name $JC_HOST benevoles31.karnaval.fr;
root /data/benevoles.karnaval.fr/assets;
gzip on;
gzip_static on;
gzip_types application/javascript image/* text/css application/font-woff application/font-woff2;
gunzip on;
ssl_session_tickets off;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_buffer_size 4k;
client_max_body_size 4M;
location / {
include uwsgi_params;
uwsgi_pass unix:/tmp/uwsgi/benevoles.karnaval.fr/uwsgi.sock;
}
location = /favicon.ico {
root /data/benevoles.karnaval.fr/assets/;
}
location = /favicon-admin.ico {
root /data/benevoles.karnaval.fr/assets/;
}
location /assets/ {
alias /data/benevoles.karnaval.fr/assets/;
access_log off;
sendfile on;
tcp_nopush on;
sendfile_max_chunk 1m;
keepalive_timeout 65;
location ~* \.(jpg|jpeg|png|gif|ico|woff|woff2)$ {
access_log off;
expires 5d;
}
}
location /media/ {
alias /data/benevoles.karnaval.fr/media/;
access_log off;
sendfile on;
tcp_nopush on;
sendfile_max_chunk 1m;
keepalive_timeout 65;
}
}
server {
listen 444 ssl http2;
listen [::]:444 ssl http2;
ssl_certificate /etc/letsencrypt/live/$JC_HOST/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/$JC_HOST/privkey.pem;
server_name $JC_HOST;
root /data/benevoles.karnaval.fr/app2/assets;
gzip on;
gzip_static on;
gzip_types application/javascript image/* text/css application/font-woff application/font-woff2;
gunzip on;
ssl_session_tickets off;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_buffer_size 4k;
client_max_body_size 4M;
location / {
include uwsgi_params;
uwsgi_pass unix:/tmp/uwsgi/app2/benevoles.karnaval.fr/app2/uwsgi.sock;
}
location = /favicon.ico {
root /data/benevoles.karnaval.fr/app2/assets/;
}
location = /favicon-admin.ico {
root /data/benevoles.karnaval.fr/app2/assets/;
}
location /assets/ {
alias /data/benevoles.karnaval.fr/app2/assets/;
access_log off;
sendfile on;
tcp_nopush on;
sendfile_max_chunk 1m;
keepalive_timeout 65;
location ~* \.(jpg|jpeg|png|gif|ico|woff|woff2)$ {
access_log off;
expires 5d;
}
}
location /media/ {
alias /data/benevoles.karnaval.fr/app2/media/;
access_log off;
sendfile on;
tcp_nopush on;
sendfile_max_chunk 1m;
keepalive_timeout 65;
}
}

View File

@ -0,0 +1,12 @@
server {
listen 443;
listen [::]:443;
server_name $SERVER_HOST;
ssl_certificate /etc/letsencrypt/live/deployer.jean-cloud.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/deployer.jean-cloud.org/privkey.pem;
location /reload {
fastcgi_param SCRIPT_FILENAME /var/www/html/test.sh;
fastcgi_pass unix:/var/run/fcgiwrap.socket;
}
}

2
services/jean-cloud.net/install.sh Normal file → Executable file
View File

@ -3,7 +3,7 @@ set -euo pipefail
start() { start() {
podman pull docker.io/jeancloud/pelican-rclone-builder podman pull docker.io/jeancloud/pelican-rclone-builder
podman run -i --rm --env-file "$DATA_DIR/.env" -v "$DATA_DIR:/usr/local/app" docker.io/jeancloud/pelican-rclone-builder podman run -i --rm -e GIT_SOURCE_REPO='https://git.jean-cloud.net/adrian/jean-cloud_website' -v "$HTTP_DIR:/usr/local/app" docker.io/jeancloud/pelican-rclone-builder
} }
restart () { restart () {

View File

@ -4,7 +4,7 @@ server {
ssl_certificate /etc/letsencrypt/live/jean-cloud.net/fullchain.pem; ssl_certificate /etc/letsencrypt/live/jean-cloud.net/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/jean-cloud.net/privkey.pem; ssl_certificate_key /etc/letsencrypt/live/jean-cloud.net/privkey.pem;
server_name jean-cloud.net www.jean-cloud.net jean-cloud.org www.jean-cloud.org; server_name jean-cloud.net www.jean-cloud.net jean-cloud.org www.jean-cloud.org;
root /data/jean-cloud.net/output; root $HTTP_DIR/output;
# Security headers # Security headers
# We can create a file with the base security headers and include it. # We can create a file with the base security headers and include it.

View File

@ -4,7 +4,7 @@ set -euo pipefail
start() { start() {
mkdir -p "$DATA_DIR/git" mkdir -p "$DATA_DIR/git"
podman pull docker.io/jeancloud/pelican-rclone-builder podman pull docker.io/jeancloud/pelican-rclone-builder
podman run -i --rm --env-file "$DATA_DIR/.env" -v "$DATA_DIR/git:/usr/local/app" docker.io/jeancloud/pelican-rclone-builder podman run -i --rm --env-file "$DATA_DIR/.env" -v "$HTTP_DIR:/usr/local/app" docker.io/jeancloud/pelican-rclone-builder
} }
restart () { restart () {

View File

@ -4,7 +4,7 @@ server {
ssl_certificate /etc/letsencrypt/live/lexicographe.jean-cloud.net/fullchain.pem; ssl_certificate /etc/letsencrypt/live/lexicographe.jean-cloud.net/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/lexicographe.jean-cloud.net/privkey.pem; ssl_certificate_key /etc/letsencrypt/live/lexicographe.jean-cloud.net/privkey.pem;
server_name lexicographe.jean-cloud.net; server_name lexicographe.jean-cloud.net;
root /data/lexicographe.jean-cloud.net/git/output; root $HTTP_DIR/output;
# Security headers # Security headers
# We can create a file with the base security headers and include it. # We can create a file with the base security headers and include it.

View File

@ -0,0 +1,24 @@
#!/bin/bash
set -euo pipefail
. .env
filename="$(basename "$0")"
ifname="${filename:3:-3}"
echo "
[Interface]
PrivateKey = $(cat $DATA_DIR/privatekey)
ListenPort = 51820
Address = 10.100.1.254/32
[Peer] # adrian
PublicKey = 14yKNmSfD2lrWU+d/RJBPNvh9pZ/nW4bK27F9nTgvk0=
AllowedIPs = 10.100.1.253/32
PersistentKeepalive = 25
[Peer] # Passerelle
PublicKey = ZTKOW5DE8jPO8oMh5hAw/c1MQSlUaVxInMPz9Zdwzwo=
AllowedIPs = 10.100.1.0/24,192.168.100.0/24
PersistentKeepalive = 25
"

View File

@ -0,0 +1,24 @@
NET=172.29.0
TELECOM=.101
MUX=.100
ICECAST=.110
WEBSERVER=.105
SYSTEM_API=.107
TZ=Europe/Paris
OMA_DOCKER_VERSION=dev
WEBSOCKET_PORT=2004
TELECOM_SERVER_PORT=3494
MUX_SERVER_PORT=9004
RADIO_NAME_SIMPLE=radiodemo
OMA_CONFIG_NomRadio=radiodemo
OMA_CONFIG_LogLevel=8
RADIO_NAME_PRETTY="Radio Démo"
RADIO_HOST=radiodemo.oma-radio.fr
COMPOSE_NAME=radiodemo-backoma-radiofr
DOCKER_INSTANCES_PREFIX=radiodemo-backoma-radiofr
DOCKER_INSTANCES_SUFIX=-1
DATA_DIR=/home/data/radiodemo-back.oma-radio.fr
SOUNDBASE_DIR=/home/data/radiodemo-back.oma-radio.fr/core/radioDemo
USE_SSL=true
PUBLIC_WEBSITE_UPSTREAM=https://static.oma-radio.fr/player-interface/1.5.0
MANAGER_WEBSITE_UPSTREAM=https://static.oma-radio.fr/single-manager/1.1.1

View File

@ -0,0 +1,232 @@
version: '3'
services:
ambre_mux:
image: registry.oma-radio.fr/mux:$OMA_DOCKER_VERSION
env_file: .env
environment:
OMA_CONFIG_Client1Host: $NET.108
OMA_CONFIG_TelecommandeHost: $NET$TELECOM
volumes:
- $SOUNDBASE_DIR/pige:/app/pige
ports:
- $MUX_SERVER_PORT:9000
restart: unless-stopped
networks:
default:
ipv4_address: $NET$MUX
deploy:
resources:
limits:
cpus: '0.50'
memory: 100M
saphir_telecom_server:
image: registry.oma-radio.fr/telecom-server:$OMA_DOCKER_VERSION
env_file: .env
ports:
- $TELECOM_SERVER_PORT:3490
restart: unless-stopped
networks:
default:
ipv4_address: $NET$TELECOM
deploy:
resources:
limits:
cpus: '0.50'
memory: 100M
anthracite_jukebox:
image: registry.oma-radio.fr/jukebox:$OMA_DOCKER_VERSION
env_file: .env
environment:
OMA_CONFIG_TelecommandeHost: $NET$TELECOM
OMA_CONFIG_Client1Host: $NET$MUX
volumes:
- $SOUNDBASE_DIR:/app/soundBase
- $DATA_DIR/secours-jingle.wavM:/app/secours/secours-jingle.wavM
restart: unless-stopped
networks:
default:
ipv4_address: $NET.102
deploy:
resources:
limits:
cpus: '0.50'
memory: 100M
azurite_jukebox_simulator:
image: registry.oma-radio.fr/jukebox-simulator:$OMA_DOCKER_VERSION
env_file: .env
environment:
OMA_CONFIG_TelecommandeHost: $NET$TELECOM
volumes:
- $SOUNDBASE_DIR:/app/soundBase
restart: unless-stopped
networks:
default:
ipv4_address: $NET.103
deploy:
resources:
limits:
cpus: '0.50'
memory: 100M
# aventurine_transcode:
# image: registry.oma-radio.fr/transcode:$OMA_DOCKER_VERSION
# env_file: .env
# restart: unless-stopped
agate_importer:
image: registry.oma-radio.fr/baseimport:$OMA_DOCKER_VERSION
env_file: .env
environment:
OMA_CONFIG_TelecommandeHost: $NET$TELECOM
volumes:
- $SOUNDBASE_DIR:/app/soundBase
restart: unless-stopped
networks:
default:
ipv4_address: $NET.104
deploy:
resources:
limits:
cpus: '0.50'
memory: 500M
amarante_webserver:
image: registry.oma-radio.fr/webserver:$OMA_DOCKER_VERSION
env_file: .env
environment:
OMA_CONFIG_TelecommandeHost: $NET$TELECOM
OMA_CONFIG_PigeTxtLoadFic: off
restart: unless-stopped
volumes:
- $SOUNDBASE_DIR:/soundbase
networks:
default:
ipv4_address: $NET$WEBSERVER
deploy:
resources:
limits:
cpus: '0.50'
memory: 100M
rubis_base_mg:
image: registry.oma-radio.fr/base-mg:$OMA_DOCKER_VERSION
env_file: .env
environment:
OMA_CONFIG_TelecommandeHost: $NET$TELECOM
restart: unless-stopped
volumes:
- $SOUNDBASE_DIR:/soundbase
networks:
default:
ipv4_address: $NET.106
deploy:
resources:
limits:
cpus: '0.50'
memory: 100M
system_api:
image: registry.oma-radio.fr/system-api:dev
env_file: .env
environment:
OMA_CONFIG_TelecommandeHost: $NET$TELECOM
UID: 33
SOUNDBASE_PATH: /soundbase
MOUNT: /api
CONFIG_PATH: /config
restart: unless-stopped
volumes:
- /tmp/uwsgi/$RADIO_HOST:/tmp/uwsgi
- /var/run/docker.sock:/var/run/docker.sock
- $SOUNDBASE_DIR:/soundbase
networks:
default:
ipv4_address: $NET.107
deploy:
resources:
limits:
cpus: '0.50'
memory: 500M
transcode:
image: savonet/liquidsoap:v2.1.4
env_file: .env
volumes:
- ./icecast.liq:/transcode.liq
- $SOUNDBASE_DIR:/soundbase
command: /transcode.liq
restart: unless-stopped
networks:
default:
ipv4_address: $NET.108
#radioking:
# image: registry.oma-radio.fr/liquidsoap:1.3.7
# env_file: .env
# volumes:
# - ./radioking.liq:/radioking.liq
# command: /radioking.liq
# restart: unless-stopped
# networks:
# default:
# ipv4_address: $NET.111
#ammolite_mp3_addon:
# image: registry.oma-radio.fr/mp3addon:$OMA_DOCKER_VERSION
# env_file: .env
# environment:
# OMA_CONFIG_TelecommandeHost: $NET.101
# OMA_CONFIG_PigePrefix: /opt
# restart: unless-stopped
# volumes:
# - $SOUNDBASE_DIR:/app/soundbase
# networks:
# default:
# ipv4_address: $NET.109
# deploy:
# resources:
# limits:
# cpus: '0.05'
# doxy:
# image: qnib/doxy
# volumes:
# - /tmp/radiodemo.oma-radio.fr/doxy:/tmp/doxy
# - /data/radiodemo.oma-radio.fr/doxy.pattern:/etc/doxy.pattern
# - /var/run/docker.sock:/var/run/docker.sock
# environment:
# DOXY_PROXY_SOCKET: /tmp/doxy/doxy.sock
icecast:
image: infiniteproject/icecast
restart: unless-stopped
environment:
# echo -n "source:pass" | base64
ICECAST_SOURCE_PASSWORD: JsCabjWJUZXrrrKCaaRZma5wD4YKj5LQLXv6f
ICECAST_ADMIN_PASSWORD: STh5LrPMvp876KPoajCPEUpehE98JPqZ6sEixSnzJ42CR2MdyPMBYfzjGpbAzajNgw8jsuLh
ICECAST_RELAY_PASSWORD: r2LgmDocgyYh7DqhSsey8tM99wxdViTpLtyi9tcWHtokC73QnC6kQLRRb58VUy5FXYnStRsG
ICECAST_ADMIN_USERNAME: admin
ICECAST_ADMIN_EMAIL: contact@oma-radio.fr
ICECAST_LOCATION: Rhône-Alpes
TZ: Europe/Paris
healthcheck:
test: "wget http://localhost:8000/direct.ogg -O - -t 1 -T 3 -S --spider 2>&1 | grep '200 OK' && wget http://localhost:8000/direct.mp3 -O - -t 1 -T 3 -S --spider 2>&1 | grep '200 OK'"
interval: 5m0s
timeout: 10s
retries: 3
start_period: 1m0s
networks:
default:
ipv4_address: $NET$ICECAST
networks:
default:
ipam:
config:
- subnet: $NET.0/24

View File

@ -0,0 +1,20 @@
function extract_ports_from_compose {
if [ "$#" -ne 1 ] ; then
echo "function extract_ports_from_dockerfile needs 1 parameter : docker-compose file" >&2
exit 1
fi
ports=false
while read line ; do
if [ "$line" = 'ports:' ] ; then
ports=true
elif "$ports" ; then
if [[ "$line" != -* ]] ; then
ports=false
else
echo $line | tr -d ' ' | tail -c +2
fi
fi
done < docker-compose.yml
}
extract_ports_from_compose docker-compose.yml | ../_deployer/template.sh .env

View File

@ -0,0 +1,40 @@
#!/usr/bin/liquidsoap
#
def integrity_check(filename)
log.important("Integrity check of #{filename}.")
ts = string.split(separator='/', filename)
ts = int_of_string(list.hd(string.split(separator='\.', list.nth(ts, list.length(ts)-1))))
if ts mod 60 == 0 then
log.important("#{filename} is ok")
else
log.important("#{filename} is to fix")
end
end
# Mux
input1 = mksafe(input.harbor("direct.ogg",port=8000,password="JsCabjWJUZXrrrKCaaRZma5wD4YKj5LQLXv6f"))
# Direct mp3
output.icecast(
%mp3(bitrate=128, samplerate=22050, stereo=false),
mount="/direct.mp3",
host="icecast", port=8000, password="JsCabjWJUZXrrrKCaaRZma5wD4YKj5LQLXv6f",
input1)
# Radioking
#output.icecast(
# %mp3(bitrate=128, samplerate=22050, stereo=false),
# mount="/test355",
# host="live.radioking.com", port=80, user="", password="",
# input)
# Direct ogg
output.icecast(
%vorbis(samplerate=44100, channels=1, quality=0.2),
mount="/direct.ogg",
host="icecast", port=8000, password="JsCabjWJUZXrrrKCaaRZma5wD4YKj5LQLXv6f",
input1)
# Pige
output.file(%vorbis(samplerate=44100, channels=1, quality=0.2), {"/soundbase/pige/#{int_of_float(time())}.ogg"}, input1, reopen_when={0s}, reopen_delay=1.0, on_close=integrity_check)

View File

@ -0,0 +1,223 @@
# Parameters:
# radio name
# file path
# ws port (local)
# wss port (open)
# upload service port
# ssl certs location
# TODO
# /speedtest-down returns random data
# can use : openssl enc -aes-256-ctr -pass pass:"$(dd if=/dev/urandom bs=128 count=1 2>/dev/null | base64)" -nosalt < /dev/zero > randomfile.bin
# /speedtest-up just eat everything it can
server {
listen 80;
listen [::]:80;
server_name $RADIO_HOST;
root $SOUNDBASE_DIR/website;
index index.html;
add_header Access-Control-Allow-Origin https://radio.karnaval.fr;
location = /direct.ogg {
proxy_pass http://172.29.0.110:8000/direct.ogg;
# kill cache
add_header Last-Modified $date_gmt;
add_header Cache-Control 'private no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
if_modified_since off;
expires off;
etag off;
}
location = /direct.mp3 {
proxy_pass http://172.29.0.110:8000/direct.mp3;
# kill cache
add_header Last-Modified $date_gmt;
add_header Cache-Control 'private no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
if_modified_since off;
expires off;
etag off;
}
location = /api { rewrite ^ /api/; }
location ~ /api/pigeindex(/.*) {
include uwsgi_params;
uwsgi_param PATH_INFO "/pigeindex$1";
uwsgi_param SCRIPT_NAME /api;
uwsgi_pass unix:/tmp/uwsgi/$RADIO_HOST/uwsgi-api.sock;
client_max_body_size 0;
uwsgi_connect_timeout 6000;
uwsgi_send_timeout 6000;
uwsgi_read_timeout 6000;
send_timeout 6000;
# kill cache
add_header Last-Modified $date_gmt;
add_header Cache-Control 'private no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
if_modified_since off;
expires off;
etag off;
}
location ~ /api(/.*) {
auth_basic "Entrez votre identifiant et mot de passe";
auth_basic_user_file $SOUNDBASE_DIR/users.htpasswd;
include uwsgi_params;
uwsgi_param PATH_INFO "$1";
uwsgi_param SCRIPT_NAME /api;
uwsgi_pass unix:/tmp/uwsgi/$RADIO_HOST/uwsgi-api.sock;
client_max_body_size 0;
proxy_connect_timeout 6000;
proxy_send_timeout 60000;
proxy_read_timeout 6000;
send_timeout 6000;
# kill cache
add_header Last-Modified $date_gmt;
add_header Cache-Control 'private no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
add_header Access-Control-Allow-Origin https://radio.karnaval.fr;
if_modified_since off;
expires off;
etag off;
}
location /pige{
alias $SOUNDBASE_DIR/pige;
try_files $uri $uri/ =404;
}
location /pigeMp3{
alias $SOUNDBASE_DIR/pigeMp3;
try_files $uri $uri/ =404;
}
location /png {
alias $SOUNDBASE_DIR/png;
try_files $uri $uri/ =404;
}
location /webpL {
alias $SOUNDBASE_DIR/webpL;
try_files $uri $uri/ =404;
}
location /webpH {
alias $SOUNDBASE_DIR/webpH;
try_files $uri $uri/ =404;
}
location /ogg {
alias $SOUNDBASE_DIR/ogg;
try_files $uri $uri/ =404;
}
location /txt {
# kill cache
add_header Last-Modified $date_gmt;
add_header Cache-Control 'private no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
add_header Access-Control-Allow-Origin https://radio.karnaval.fr;
if_modified_since off;
expires off;
etag off;
alias $SOUNDBASE_DIR/txt;
try_files $uri $uri/ =404;
}
location /wavM {
# kill cache
add_header Last-Modified $date_gmt;
add_header Cache-Control 'private no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
if_modified_since off;
expires off;
etag off;
alias $SOUNDBASE_DIR/wavM;
try_files $uri $uri/ =404;
}
location /import {
# kill cache
add_header Last-Modified $date_gmt;
add_header Cache-Control 'private no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
if_modified_since off;
expires off;
etag off;
alias $SOUNDBASE_DIR/import;
try_files $uri $uri/ =404;
}
location /export {
# kill cache
add_header Last-Modified $date_gmt;
add_header Cache-Control 'private no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
if_modified_since off;
expires off;
etag off;
alias $SOUNDBASE_DIR/export;
try_files $uri $uri/ =404;
}
location /wav {
# kill cache
add_header Last-Modified $date_gmt;
add_header Cache-Control 'private no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
if_modified_since off;
expires off;
etag off;
alias $SOUNDBASE_DIR/wav;
try_files $uri $uri/ =404;
}
location /fiches {
alias $SOUNDBASE_DIR/fiches;
try_files $uri $uri/ =404;
# kill cache
add_header Last-Modified $date_gmt;
add_header Cache-Control 'private no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
add_header Access-Control-Allow-Origin https://radio.karnaval.fr;
if_modified_since off;
expires off;
etag off;
}
location /prg {
# kill cache
add_header Last-Modified $date_gmt;
add_header Cache-Control 'private no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
if_modified_since off;
expires off;
etag off;
alias $SOUNDBASE_DIR/prg;
try_files $uri $uri/ =404;
}
location /listes {
# kill cache
add_header Last-Modified $date_gmt;
add_header Cache-Control 'private no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
if_modified_since off;
expires off;
etag off;
alias $SOUNDBASE_DIR/listes;
try_files $uri $uri/ =404;
}
location /statique {
alias $SOUNDBASE_DIR/statique;
try_files $uri $uri/ =404;
# kill cache
add_header Last-Modified $date_gmt;
add_header Cache-Control 'private no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
add_header Access-Control-Allow-Origin https://radio.karnaval.fr;
if_modified_since off;
expires off;
etag off;
}
# Admin interface
location /manager {
auth_basic "Entrez votre identifiant et mot de passe";
auth_basic_user_file $SOUNDBASE_DIR/users.htpasswd;
try_files $uri $uri/ =404;
}
location = /favicon.ico {
return 301 /favicon.webp;
}
# for js, css, html — dynamic site, players
location / {
try_files $uri $uri/ =404;
add_header Cache-Control 'public must-revalidate';
add_header Access-Control-Allow-Origin https://radio.karnaval.fr;
}
}

View File

@ -0,0 +1,7 @@
input = mksafe(input.http("http://172.29.0.110:8000/direct.mp3"))
output.icecast(
%mp3(bitrate=128, samplerate=22050, stereo=false),
mount="/test355",
host="live.radioking.com", port=80, user="test_test29", password="S9tx3VBhl",
input)

View File

@ -0,0 +1,20 @@
#!/bin/bash
set -euo pipefail
. .env
[ -f "$DATA_DIR/privatekey" ] || echo 'No privatekey found' && exit 1
echo "
[Interface]
PrivateKey = $(cat "$DATA_DIR/privatekey")
Address = 10.29.0.1/32
ListenPort = 55820
[Peer]
PublicKey = uXAXi3rthdRY2zkSgHpl3EqxQnxdw3aiAwNX6HhFHgI=
AllowedIPs = 10.29.0.254/32
Endpoint = radiodemo.oma-radio.fr:55820
PersistentKeepalive = 30
"

View File

@ -0,0 +1,9 @@
ENDPOINT=10.29.0.1
WEBSERVER=.105
MUX=.100
TELECOM=.101
NET=172.29.0
WEBSOCKET_PORT=2004
RADIO_HOST=radiodemo.oma-radio.fr
MUX_SERVER_PORT=9004
TELECOM_SERVER_PORT=3494

View File

@ -0,0 +1 @@
version: '3'

View File

@ -0,0 +1,37 @@
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server{
listen $WEBSOCKET_PORT ssl;
listen [::]:$WEBSOCKET_PORT ssl;
ssl_certificate /etc/letsencrypt/live/$RADIO_HOST/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/$RADIO_HOST/privkey.pem;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://172.29.0.105:9000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 120s;
}
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name $RADIO_HOST;
ssl_certificate /etc/letsencrypt/live/$RADIO_HOST/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/$RADIO_HOST/privkey.pem;
location / {
proxy_pass http://$ENDPOINT;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
}

View File

@ -0,0 +1,33 @@
#!/bin/bash
set -euo pipefail
. .env
wgif="$1"
echo "
[Interface]
PrivateKey = $(cat $DATA_DIR/privatekey)
Address = 10.29.0.254/32
ListenPort = 55820
# packet forwarding
PreUp = sysctl -w net.ipv4.ip_forward=1
# port forwarding
PreUp = iptables -t nat -A PREROUTING -p tcp --dport $MUX_SERVER_PORT -j DNAT --to-destination $ENDPOINT:$MUX_SERVER_PORT
PreUp = iptables -t nat -A PREROUTING -p tcp --dport $TELECOM_SERVER_PORT -j DNAT --to-destination $ENDPOINT:$TELECOM_SERVER_PORT
PostDown = iptables -t nat -D PREROUTING -p tcp --dport $MUX_SERVER_PORT -j DNAT --to-destination $ENDPOINT:$MUX_SERVER_PORT
PostDown = iptables -t nat -D PREROUTING -p tcp --dport $TELECOM_SERVER_PORT -j DNAT --to-destination $ENDPOINT:$TELECOM_SERVER_PORT
# packet masquerading
PreUp = iptables -t nat -A POSTROUTING -o $wgif -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -o $wgif-j MASQUERADE
# remote settings for the private server
[Peer]
PublicKey = 1YIpMhZGrZRnZPlrTjtCfjvXXGk8j0Ug2AfcHEtN/hE=
AllowedIPs = 10.29.0.1/32,$NET.0/24
"