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
service="$(basename "$dir")"
# Ignore _ prefixed directories
[ "${service::1}" == '_' ] && continue
[ ! -d "$dir" ] && continue
export DATA_DIR="/data/$service"
mkdir -p "$DATA_DIR"
docker_service="$(echo "$service" | tr '.' '_')"
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"
# Is service meant to be on this server?
@ -88,6 +91,7 @@ for dir in /docker/* ; do
section "--------------------"
section "Removing service"
docker-compose down --rmi all --remove-orphans
[ -d "$HTTP_DIR" ] && rm -r "$HTTP_DIR"
fi
# If there is an install script?
@ -97,12 +101,18 @@ for dir in /docker/* ; do
stop
unset -f start stop reload restart
fi
# TODO check for leftover wg interfaces
continue
fi
mkdir -p "$DATA_DIR" "$HTTP_DIR"
# 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
section "-------------------- $service"
section "Logging to registry"
# XXX Login to docker registry
@ -114,7 +124,7 @@ for dir in /docker/* ; do
fi
# If there is an install script?
# If there is an install script
if [ -f "/docker/$service/install.sh" ] ; then
section "Running install script"
. "/docker/$service/install.sh"
@ -123,16 +133,27 @@ for dir in /docker/* ; do
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 [ -f "/docker/$service/nginx_server.conf" ] ; then
section "Copy nginx conf"
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"
run template.sh "/docker/$service/.env" < "/docker/$service/nginx_server.conf" > "$new_nginx_conf_path/$service"
fi
fi
# Do we need dummy cert?
if [ ! -e "$certs_path/$service/fullchain.pem" ] ; then

View File

View File

@ -1,8 +1,11 @@
#!/bin/bash
if [ "$#" -ne 1 ] ; then
if [ "$1" = '-h' ] || [ "$1" = '--help' ] ; then
echo "Usage: $0 <env_file>" >&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
bash -c 'set -a && . '"$1"' && envsubst "$(cat '"$1"' | grep -o ^.*= | sed "s/=//" | sed "s/^/$/")"'

View File

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

View File

@ -1,23 +1,32 @@
$TTL 604800
@ IN SOA ns1.jean-cloud.net. contact.jean-cloud.org. (
2023042200 ; Serial
@ IN SOA max.jean-cloud.org. contact.jean-cloud.org. (
2023052300 ; Serial
604800 ; Refresh
7200 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
@ IN NS ns1.jean-cloud.net.
@ IN NS ns5.he.net.
@ IN NS ns4.he.net.
@ IN NS ns3.he.net.
@ IN NS ns2.he.net.
; NS
@ 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 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.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.
_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.
imap IN CNAME ssl0.ovh.net.
smtp IN CNAME ssl0.ovh.net.
mail IN CNAME ssl0.ovh.net.
pop3 IN CNAME ssl0.ovh.net.
stream.paj.ports IN TXT 9002
control.paj.ports IN TXT 9492
stream.paj._ports IN TXT 9002
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.
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 {
##
# Basic Settings
##
@ -70,7 +69,7 @@ http {
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
server{
server{
listen 80 default_server;
listen [::]:80 default_server;
location '/.well-known/acme-challenge' {
@ -82,6 +81,5 @@ server{
location / {
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() {
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 () {

View File

@ -4,7 +4,7 @@ server {
ssl_certificate /etc/letsencrypt/live/jean-cloud.net/fullchain.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;
root /data/jean-cloud.net/output;
root $HTTP_DIR/output;
# Security headers
# We can create a file with the base security headers and include it.

View File

@ -4,7 +4,7 @@ set -euo pipefail
start() {
mkdir -p "$DATA_DIR/git"
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 () {

View File

@ -4,7 +4,7 @@ server {
ssl_certificate /etc/letsencrypt/live/lexicographe.jean-cloud.net/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/lexicographe.jean-cloud.net/privkey.pem;
server_name lexicographe.jean-cloud.net;
root /data/lexicographe.jean-cloud.net/git/output;
root $HTTP_DIR/output;
# Security headers
# 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
"