From 3130ceb2d055669c8c9bc373ccf76fe24d38d502 Mon Sep 17 00:00:00 2001 From: kenellorando Date: Fri, 10 Mar 2023 19:39:48 -0600 Subject: [PATCH 1/5] Begin templated configs --- .gitignore | 5 +++++ config/{cadence.env => cadence.env.example} | 2 +- config/{icecast.xml => icecast.xml.example} | 6 +++--- config/{liquidsoap.liq => liquidsoap.liq.example} | 2 +- config/{nginx.conf => nginx.conf.example} | 0 install.sh | 14 ++++++++++++++ 6 files changed, 24 insertions(+), 5 deletions(-) rename config/{cadence.env => cadence.env.example} (96%) rename config/{icecast.xml => icecast.xml.example} (90%) rename config/{liquidsoap.liq => liquidsoap.liq.example} (94%) rename config/{nginx.conf => nginx.conf.example} (100%) create mode 100755 install.sh diff --git a/.gitignore b/.gitignore index 3b735ec4..c8406eed 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,8 @@ # Go workspace file go.work + +cadence.env +icecast.xml +liquidsoap.liq +nginx.conf diff --git a/config/cadence.env b/config/cadence.env.example similarity index 96% rename from config/cadence.env rename to config/cadence.env.example index 2b7f64bb..7da2e8b2 100644 --- a/config/cadence.env +++ b/config/cadence.env.example @@ -1,6 +1,6 @@ CSERVER_MUSIC_DIR=/music/ CSERVER_REQRATELIMIT=180 -POSTGRES_PASSWORD=hackme +POSTGRES_PASSWORD={C_PASS} # #################################################### # If you are running Cadence through Docker simply as a user, diff --git a/config/icecast.xml b/config/icecast.xml.example similarity index 90% rename from config/icecast.xml rename to config/icecast.xml.example index 35820624..cffff875 100644 --- a/config/icecast.xml +++ b/config/icecast.xml.example @@ -15,12 +15,12 @@ - hackme + {C_PASS} - hackme + {C_PASS} admin - hackme + {C_PASS} localhost:8000 diff --git a/config/liquidsoap.liq b/config/liquidsoap.liq.example similarity index 94% rename from config/liquidsoap.liq rename to config/liquidsoap.liq.example index 3b8a54c6..0a03aba3 100644 --- a/config/liquidsoap.liq +++ b/config/liquidsoap.liq.example @@ -14,4 +14,4 @@ radio = fallback([ request.queue(id="request"), default]) full = fallback(track_sensitive=false, [input.http("http://localhost:8000/live.ogg"), radio]) # Output the full stream in OGG -output.icecast(%vorbis.cbr(bitrate=192), host="icecast2",port=8000,password="hackme", mount="cadence1",full) +output.icecast(%vorbis.cbr(bitrate=192), host="icecast2",port=8000,password="{C_PASS}", mount="cadence1",full) diff --git a/config/nginx.conf b/config/nginx.conf.example similarity index 100% rename from config/nginx.conf rename to config/nginx.conf.example diff --git a/install.sh b/install.sh new file mode 100755 index 00000000..942755a0 --- /dev/null +++ b/install.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +read -p "Music directory absolute path (/music/): " C_PATH +read -p "Stream hostname (localhost): " C_HOST +read -p "Rate limit timeout (180): " C_RATE +read -s -p "Service password: " C_PASS + +read -p "Do you have DNS? [y/n]: " HAS_DNS + +cp ./config/cadence.env.example ./config/cadence.env +cp ./config/icecast.xml.example ./config/icecast.xml +cp ./config/liquidsoap.liq.example ./config/liquidsoap.liq +cp ./config/nginx.conf.example ./config/nginx.conf + From 4be2bf612126deeeb3d234765fc0c583a83c2348 Mon Sep 17 00:00:00 2001 From: kenellorando Date: Fri, 10 Mar 2023 21:12:39 -0600 Subject: [PATCH 2/5] Add all other configuration data --- README.md | 25 ++++------------- config/cadence.env.example | 10 +++---- config/icecast.xml.example | 12 ++++---- config/liquidsoap.liq.example | 4 +-- config/nginx.conf.example | 4 +-- docker-compose.yml | 4 +-- install.sh | 53 +++++++++++++++++++++++++++++++---- 7 files changed, 70 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index a7fccb5f..905e7151 100644 --- a/README.md +++ b/README.md @@ -29,28 +29,15 @@ All components are mostly pre-configured so there is hardly any configuration re 1. You must have [Docker](https://docs.docker.com/engine/install/) installed. If you are on a Linux server, additionally install the [Compose plugin](https://docs.docker.com/compose/install/linux/). ### Installation -1. Edit `config/cadence.env` - 1. Change all instances of `hackme` to a new password. - 2. Set `CSERVER_MUSIC_DIR` to an absolute path which contains music files (`.mp3`, `.flac`) for play. The target is not recursively searched. - 3. Set `CSERVER_REQRATELIMIT` to an integer that sets the song request cooldown period in seconds. Set this value to `0` to disable rate limiting. -2. Edit `config/icecast.xml` - 1. Change all instances of `hackme` to a new password. - 2. Set the `` value to a URL you expect your audience to connect to. This value is what is set in the UI's stream source. This may be a DNS name or a public or private IP address. You can leave the default value `localhost` if your radio is meant to be accessible locally only. -3. Edit `config/liquidsoap.liq` - 1. Change all instances of `hackme` to a new password. - 2. If you changed `CSERVER_MUSIC_DIR` in step 1, change any instances of the default value `/music/` to match it here. -4. Edit `docker-compose.yml` - 1. If you changed `CSERVER_MUSIC_DIR` in step 1, change any instances of the `Volumes` defined, replacing `/music:/music` with `/YOURDIR:/music`. -5. (_Optional_) Edit `config/nginx.conf` - 1. For advanced users deploying Cadence to a server with DNS, Cadence ships with a reverse proxy that can forward requests based on domain-name to backend services. Simply configure the `server_name` values with your domain names. The stream server domain should match the value you set in step 2. -6. `docker compose up` - -After configuration is initially completed, you may simply run `docker compose up` again in the future to start your station. +1. Run `./install.sh`. + 1. You will be prompted to provide inputs: a music directory path, a stream hostname, a rate limit timeout, a service password, and optional DNS. Cadence should automatically start. + +After initial installation, you may simply run `docker compose up` again in the future to start your station. Run `install.sh` again at any time to reconfigure. ### Accessing Services -- Assuming you kept the default values above, Cadence will become accessible in a browser at `localhost:8080`. -- If you optionally followed step 4, open firewall port `80` and point DNS to your server. +- By default, Cadence will become accessible in a browser at `localhost:8080`. +- If you optionally provided DNS, open firewall port `80` and point DNS to your server. ## 👩‍💻 Developing diff --git a/config/cadence.env.example b/config/cadence.env.example index 7da2e8b2..9f8452b5 100644 --- a/config/cadence.env.example +++ b/config/cadence.env.example @@ -1,6 +1,6 @@ -CSERVER_MUSIC_DIR=/music/ -CSERVER_REQRATELIMIT=180 -POSTGRES_PASSWORD={C_PASS} +CSERVER_MUSIC_DIR=CADENCE_PATH_EXAMPLE +CSERVER_REQRATELIMIT=CADENCE_RATE_EXAMPLE +POSTGRES_PASSWORD=CADENCE_PASS_EXAMPLE # #################################################### # If you are running Cadence through Docker simply as a user, @@ -8,8 +8,8 @@ POSTGRES_PASSWORD={C_PASS} # Development CSERVER_DEVMODE=0 -CSERVER_VERSION=5.3.2 -CSERVER_LOGLEVEL=4 +CSERVER_VERSION=5.4.0-prototype +CSERVER_LOGLEVEL=5 CSERVER_ROOTPATH=/cadence/server/ # Service Addresses diff --git a/config/icecast.xml.example b/config/icecast.xml.example index cffff875..89db7034 100644 --- a/config/icecast.xml.example +++ b/config/icecast.xml.example @@ -1,6 +1,6 @@ - Chicago, United States of America - Ken Ellorando (kenellorando.com) + Internet + Source: Cadence Radio (github.com/kenellorando/cadence) 100 @@ -15,15 +15,15 @@ - {C_PASS} + CADENCE_PASS_EXAMPLE - {C_PASS} + CADENCE_PASS_EXAMPLE admin - {C_PASS} + CADENCE_PASS_EXAMPLE - localhost:8000 + CADENCE_HOST_EXAMPLE 8000 diff --git a/config/liquidsoap.liq.example b/config/liquidsoap.liq.example index 0a03aba3..92c4d784 100644 --- a/config/liquidsoap.liq.example +++ b/config/liquidsoap.liq.example @@ -7,11 +7,11 @@ set("server.telnet", true) set("server.telnet.bind_addr", "0.0.0.0") # 1. Lowest priority: play all music in the target directory at random. -default = mksafe(playlist(mode="randomize", "/music/")) +default = mksafe(playlist(mode="randomize", "CADENCE_PATH_EXAMPLE")) # 2. Next priority: play user requests first if there are any in the queue. radio = fallback([ request.queue(id="request"), default]) # 3. Next priority: play live input stream if one is connected. full = fallback(track_sensitive=false, [input.http("http://localhost:8000/live.ogg"), radio]) # Output the full stream in OGG -output.icecast(%vorbis.cbr(bitrate=192), host="icecast2",port=8000,password="{C_PASS}", mount="cadence1",full) +output.icecast(%vorbis.cbr(bitrate=192), host="icecast2",port=8000,password="CADENCE_PASS_EXAMPLE", mount="cadence1",full) diff --git a/config/nginx.conf.example b/config/nginx.conf.example index 6f760dae..5c4ac3b5 100644 --- a/config/nginx.conf.example +++ b/config/nginx.conf.example @@ -6,7 +6,7 @@ http { # This server forwards requests to the Icecast service. server { listen 80; - server_name stream.cadenceradio.com; + server_name CADENCE_STREAM_DNS_EXAMPLE; access_log off; location / { proxy_pass http://icecast2:8000/; @@ -16,7 +16,7 @@ http { # This server forwards requests to the API/UI server. server { listen 80; - server_name cadenceradio.com; + server_name CADENCE_WEB_DNS_EXAMPLE; access_log off; # Server-sent event API needs special configuration to get through the proxy. location /api/radiodata/sse { diff --git a/docker-compose.yml b/docker-compose.yml index 335af318..23bda1a9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -41,7 +41,7 @@ services: restart: always volumes: - ./config/liquidsoap.liq:/etc/liquidsoap/cadence.liq - - /music:/music + - CADENCE_PATH_EXAMPLE:CADENCE_PATH_EXAMPLE depends_on: - icecast2 expose: @@ -62,7 +62,7 @@ services: env_file: - ./config/cadence.env volumes: - - /music:/music + - CADENCE_PATH_EXAMPLE:CADENCE_PATH_EXAMPLE depends_on: - icecast2 - liquidsoap diff --git a/install.sh b/install.sh index 942755a0..177802b5 100755 --- a/install.sh +++ b/install.sh @@ -1,14 +1,55 @@ #!/bin/bash -read -p "Music directory absolute path (/music/): " C_PATH -read -p "Stream hostname (localhost): " C_HOST -read -p "Rate limit timeout (180): " C_RATE -read -s -p "Service password: " C_PASS - -read -p "Do you have DNS? [y/n]: " HAS_DNS +echo "[1/5] Music Directory Target" +echo "Set the absolute path of a directory containing audio files " +echo "(e.g. mp3, flac) meant for radio play. This target directory " +echo "will not be recursively searched. Example: /music/" +read -p " Music path: " CADENCE_PATH +echo "==============================================================" +echo "[2/5] Stream Host Address" +echo "Set a stream host address for Cadence Icecast. This may be a " +echo "DNS name, public IP, or private IP. Set this to localhost:8000" +echo "if your Cadence instance is meant for local use only." +read -p " Stream address: " CADENCE_HOST +echo "==============================================================" +echo "[3/5] Rate Limiter Timeout" +echo "Set a rate limit timeout in integer seconds. This prevents the " +echo "same listener from requesting songs within the configured " +echo "timeframe. Set to 0 to disable. Example: 180" +read -p " Rate limit: " CADENCE_RATE +echo "==============================================================" +echo "[4/5] Radio Service Password" +echo "Set a secure, unique service password. Input is hidden." +read -s -p " Password: " CADENCE_PASS +echo "" +echo "==============================================================" +echo "[5/5] Domain Names - LEAVE BLANK TO SKIP" +echo "OPTIONAL: if you are an advanced administrator routing DNS to " +echo "your Cadence stack, provide your domain names here. You will " +echo "be prompted for two domains: one for your Cadence Icecast " +echo "stream, one for the Cadence web UI. Subdomains are acceptable." +read -p " Cadence Audio Stream Domain: " CADENCE_STREAM_DNS +read -p " Cadence Web UI Domain: " CADENCE_WEB_DNS cp ./config/cadence.env.example ./config/cadence.env cp ./config/icecast.xml.example ./config/icecast.xml cp ./config/liquidsoap.liq.example ./config/liquidsoap.liq cp ./config/nginx.conf.example ./config/nginx.conf +cp ./docker-compose.yml.example ./docker-compose.yml + +sed -i 's|CADENCE_PASS_EXAMPLE|'"$CADENCE_PASS"'|g' ./config/cadence.env +sed -i 's|CADENCE_PASS_EXAMPLE|'"$CADENCE_PASS"'|g' ./config/icecast.xml +sed -i 's|CADENCE_PASS_EXAMPLE|'"$CADENCE_PASS"'|g' ./config/liquidsoap.liq +sed -i 's|CADENCE_RATE_EXAMPLE|'"$CADENCE_RATE"'|g' ./config/cadence.env +sed -i 's|CADENCE_HOST_EXAMPLE|'"$CADENCE_HOST"'|g' ./config/icecast.xml +sed -i 's|CADENCE_PATH_EXAMPLE|'"$CADENCE_PATH"'|g' ./config/cadence.env +sed -i 's|CADENCE_PATH_EXAMPLE|'"$CADENCE_PATH"'|g' ./config/liquidsoap.liq +sed -i 's|CADENCE_STREAM_DNS_EXAMPLE|'"$CADENCE_STREAM_DNS"'|g' ./config/nginx.conf +sed -i 's|CADENCE_WEB_DNS_EXAMPLE|'"$CADENCE_WEB_DNS"'|g' ./config/nginx.conf +sed -i 's|CADENCE_PATH_EXAMPLE|'"$CADENCE_PATH"'|g' ./docker-compose.yml +echo "=========================================" +echo "Configuration completed." +echo "If it does not begin automatically, run 'docker compose up' to start Cadence." +docker compose down +docker compose up From ec55d1e489eea271fb56e02dc9635e10a5c5e665 Mon Sep 17 00:00:00 2001 From: Ken Ellorando Date: Fri, 10 Mar 2023 23:53:44 -0600 Subject: [PATCH 3/5] Update README.md - squash Update README.md Update README.md Update README.md Update README.md Update README.md --- README.md | 44 ++++++++++++++++---------------------------- 1 file changed, 16 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 905e7151..0f823c1e 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,12 @@ # CadenceRadio -**Cadence** is an all-in-one web radio suite that lets you start a self-hosted radio website. +**Cadence** is an all-in-one suite that lets you start a self-hosted web radio website. -In minutes, you can create an internet audio broadcast complete with library search, song request, album artwork, and a browser UI with real-time stream information working out-of-the-box. - -All components are mostly pre-configured so there is hardly any configuration required to get started. Simply provide target directory containing music files, set a few service passwords and hostnames, and deploy! +In minutes, create your internet broadcast with library search, song request, album artwork, and a browser UI with real-time stream information. All components are mostly pre-configured to work out-of-the-box. Simply run an interactive installation script and deploy! **[See a live demo!](https://cadenceradio.com/)** -## 🖼️ Image Gallery +## 🖼️ Gallery
Browser UI Screenshot @@ -23,34 +21,24 @@ All components are mostly pre-configured so there is hardly any configuration re
-## 🏃 Get Started +## 🏃 Start Here ### Requirements -1. You must have [Docker](https://docs.docker.com/engine/install/) installed. If you are on a Linux server, additionally install the [Compose plugin](https://docs.docker.com/compose/install/linux/). +You must have [Docker](https://docs.docker.com/engine/install/) and [Docker Compose](https://docs.docker.com/compose/install/) installed. ### Installation -1. Run `./install.sh`. - 1. You will be prompted to provide inputs: a music directory path, a stream hostname, a rate limit timeout, a service password, and optional DNS. Cadence should automatically start. - -After initial installation, you may simply run `docker compose up` again in the future to start your station. Run `install.sh` again at any time to reconfigure. - -### Accessing Services - -- By default, Cadence will become accessible in a browser at `localhost:8080`. -- If you optionally provided DNS, open firewall port `80` and point DNS to your server. - -## 👩‍💻 Developing - -### Building the Stack -If you changed code or updated a container image, append the `--build` flag to rebuild exactly what you have. +```bash +chmod +x ./install.sh +./install.sh +``` -1. `docker compose down; docker compose up --build` +You will be interactively prompted for a music directory path, a stream hostname, a rate limit timeout, a service password, and optional DNS. After the last prompt, the radio stack will automatically launch and Cadence's web UI will become accessible at `localhost:8080`. -### Enable Development API -Cadence provides an optionally-enabled API with special administrative controls that may be useful for testing. Don't enable development mode on a production server. +After initial installation, simply run `docker compose up` to start your station. Use `install.sh` again at any time to reconfigure inputs. -1. Edit `config/cadence.env`. - 1. Set `CSERVER_DEVMODE` to `1` (enabled). +## 📚 Knowledge Base +Cadence's GitHub Wiki provides various resources to help you use, administrate, and develop for your station. If you need any further assistance, we warmly welcome you to [open an issue](https://github.com/kenellorando/cadence/issues). -### API Reference -[Cadence's API Reference](https://github.com/kenellorando/cadence/wiki/API-Reference) provides usage details and complete request/response examples. +- [API Reference](https://github.com/kenellorando/cadence/wiki/API-Reference) +- [Development and Code Style Guide](https://github.com/kenellorando/cadence/wiki/Development-and-Code-Style) +- [Installation Guide](https://github.com/kenellorando/cadence/wiki/Installation) From e143ff74df8e8e794c9dab3d954ab2385d38aa4b Mon Sep 17 00:00:00 2001 From: kenellorando Date: Sat, 11 Mar 2023 14:43:13 -0600 Subject: [PATCH 4/5] Clarify instructions --- install.sh | 45 ++++++++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/install.sh b/install.sh index 177802b5..4d68bbcc 100755 --- a/install.sh +++ b/install.sh @@ -1,36 +1,47 @@ #!/bin/bash echo "[1/5] Music Directory Target" -echo "Set the absolute path of a directory containing audio files " -echo "(e.g. mp3, flac) meant for radio play. This target directory " -echo "will not be recursively searched. Example: /music/" +echo "Set the absolute path of a directory containing audio files (e.g. mp3, flac)" +echo "meant for radio play. Only files at the directory base will be seen, not those" +echo "in nested subdirectories." +echo "Example: /music/" read -p " Music path: " CADENCE_PATH -echo "==============================================================" +echo "================================================================================" echo "[2/5] Stream Host Address" -echo "Set a stream host address for Cadence Icecast. This may be a " -echo "DNS name, public IP, or private IP. Set this to localhost:8000" -echo "if your Cadence instance is meant for local use only." +echo "Set the stream host address for Cadence Icecast. This may be a DNS name, public" +echo "IP, or private IP. Set this to localhost:8000 if your Cadence instance is meant" +echo "for local use only." +echo "Example: localhost:8000" read -p " Stream address: " CADENCE_HOST -echo "==============================================================" +echo "================================================================================" echo "[3/5] Rate Limiter Timeout" -echo "Set a rate limit timeout in integer seconds. This prevents the " -echo "same listener from requesting songs within the configured " -echo "timeframe. Set to 0 to disable. Example: 180" +echo "Set a rate limit timeout in integer seconds. This prevents the same listener" +echo "from requesting songs within the configured timeframe. Set to 0 to disable." +echo "Example: 180" read -p " Rate limit: " CADENCE_RATE -echo "==============================================================" +echo "================================================================================" echo "[4/5] Radio Service Password" echo "Set a secure, unique service password. Input is hidden." read -s -p " Password: " CADENCE_PASS echo "" -echo "==============================================================" +echo "================================================================================" echo "[5/5] Domain Names - LEAVE BLANK TO SKIP" -echo "OPTIONAL: if you are an advanced administrator routing DNS to " -echo "your Cadence stack, provide your domain names here. You will " -echo "be prompted for two domains: one for your Cadence Icecast " -echo "stream, one for the Cadence web UI. Subdomains are acceptable." +echo "OPTIONAL: if you are an advanced administrator routing DNS to your Cadence" +echo "stack, provide your domain names here. You will be prompted for two domains: one" +echo "for Cadence Icecast, one for Cadence web UI. Subdomains are acceptable." read -p " Cadence Audio Stream Domain: " CADENCE_STREAM_DNS read -p " Cadence Web UI Domain: " CADENCE_WEB_DNS +if [ -z "$CADENCE_STREAM_DNS" ] +then + CADENCE_STREAM_DNS=stream.cadenceradio.com +fi + +if [ -z "$CADENCE_WEB_DNS" ] +then + CADENCE_WEB_DNS=cadenceradio.com +fi + cp ./config/cadence.env.example ./config/cadence.env cp ./config/icecast.xml.example ./config/icecast.xml cp ./config/liquidsoap.liq.example ./config/liquidsoap.liq From b7f48da04cf6727cef8cb91786f00c2afce3268d Mon Sep 17 00:00:00 2001 From: kenellorando Date: Sat, 11 Mar 2023 14:43:20 -0600 Subject: [PATCH 5/5] Template compose --- docker-compose.yml | 4 +- docker-compose.yml.example | 94 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+), 2 deletions(-) create mode 100644 docker-compose.yml.example diff --git a/docker-compose.yml b/docker-compose.yml index 23bda1a9..335af318 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -41,7 +41,7 @@ services: restart: always volumes: - ./config/liquidsoap.liq:/etc/liquidsoap/cadence.liq - - CADENCE_PATH_EXAMPLE:CADENCE_PATH_EXAMPLE + - /music:/music depends_on: - icecast2 expose: @@ -62,7 +62,7 @@ services: env_file: - ./config/cadence.env volumes: - - CADENCE_PATH_EXAMPLE:CADENCE_PATH_EXAMPLE + - /music:/music depends_on: - icecast2 - liquidsoap diff --git a/docker-compose.yml.example b/docker-compose.yml.example new file mode 100644 index 00000000..23bda1a9 --- /dev/null +++ b/docker-compose.yml.example @@ -0,0 +1,94 @@ +version: "3" +services: + + redis: + image: redis/redis-stack-server:latest + container_name: redis + expose: + - 6379 + networks: + internal_services: + + postgres: + image: postgres:15-alpine + container_name: postgres + expose: + - 5432 + env_file: + - ./config/cadence.env + networks: + internal_services: + + icecast2: + build: + dockerfile: ./cadence/icecast2.Dockerfile + image: kenellorando/cadence_icecast2:latest + container_name: icecast2 + restart: always + ports: + - 8000:8000 + volumes: + - ./config/icecast.xml:/etc/icecast/cadence.xml + networks: + external_services: + stream_delivery: + + liquidsoap: + build: + dockerfile: ./cadence/liquidsoap.Dockerfile + image: kenellorando/cadence_liquidsoap:latest + container_name: liquidsoap + restart: always + volumes: + - ./config/liquidsoap.liq:/etc/liquidsoap/cadence.liq + - CADENCE_PATH_EXAMPLE:CADENCE_PATH_EXAMPLE + depends_on: + - icecast2 + expose: + - 1234 + networks: + internal_services: + stream_delivery: + + cadence: + build: + context: ./cadence + dockerfile: ./cadence.Dockerfile + image: kenellorando/cadence + container_name: cadence + restart: always + ports: + - 8080:8080 + env_file: + - ./config/cadence.env + volumes: + - CADENCE_PATH_EXAMPLE:CADENCE_PATH_EXAMPLE + depends_on: + - icecast2 + - liquidsoap + - redis + - postgres + networks: + internal_services: + external_services: + + nginx: + image: nginx:latest + volumes: + - ./config/nginx.conf:/etc/nginx/nginx.conf + container_name: nginx + restart: on-failure + ports: + - 80:80 + depends_on: + - cadence + networks: + external_services: + +networks: + external_services: + driver: bridge + internal_services: + driver: bridge + stream_delivery: + driver: bridge