AzuraCast in a Single Docker Image (#5167)
This commit is contained in:
parent
d1ee9db407
commit
27260729bc
|
@ -45,7 +45,7 @@ jobs:
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v2
|
||||||
with:
|
with:
|
||||||
path: vendor
|
path: vendor
|
||||||
key: ${{ runner.OS }}-build-${{ hashFiles('**/composer.lock') }}
|
key: ${{ runner.OS }}-build-${{ hashFiles('composer.lock') }}
|
||||||
|
|
||||||
- name: Set console permissions and clear static assets.
|
- name: Set console permissions and clear static assets.
|
||||||
run: |
|
run: |
|
||||||
|
@ -117,8 +117,8 @@ jobs:
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
load: true
|
load: true
|
||||||
tags: ghcr.io/azuracast/web:latest
|
tags: ghcr.io/azuracast/azuracast:latest
|
||||||
cache-from: type=registry,ref=ghcr.io/azuracast/web:buildcache
|
cache-from: type=registry,ref=ghcr.io/azuracast/azuracast:buildcache
|
||||||
|
|
||||||
- name: Set up functional test environment.
|
- name: Set up functional test environment.
|
||||||
run: |
|
run: |
|
||||||
|
@ -126,13 +126,12 @@ jobs:
|
||||||
cp azuracast.sample.env azuracast.env
|
cp azuracast.sample.env azuracast.env
|
||||||
cp docker-compose.sample.yml docker-compose.yml
|
cp docker-compose.sample.yml docker-compose.yml
|
||||||
cp docker-compose.testing.yml docker-compose.override.yml
|
cp docker-compose.testing.yml docker-compose.override.yml
|
||||||
docker-compose run --rm --user="azuracast" web azuracast_install
|
|
||||||
|
|
||||||
- name: Run functional test suite.
|
- name: Run functional test suite.
|
||||||
run: |
|
run: |
|
||||||
chmod 777 tests/_output/
|
chmod 777 tests/_output/
|
||||||
chmod 777 tests/_support/_generated
|
chmod 777 tests/_support/_generated
|
||||||
docker-compose run --rm --user="azuracast" web composer codeception-no-coverage
|
docker-compose run --rm web azuracast_ci
|
||||||
|
|
||||||
- name: Stop all running containers.
|
- name: Stop all running containers.
|
||||||
run: |
|
run: |
|
||||||
|
@ -202,8 +201,8 @@ jobs:
|
||||||
uses: docker/metadata-action@v3
|
uses: docker/metadata-action@v3
|
||||||
with:
|
with:
|
||||||
images: |
|
images: |
|
||||||
azuracast/azuracast_web_v2
|
azuracast/azuracast
|
||||||
ghcr.io/azuracast/web
|
ghcr.io/azuracast/azuracast
|
||||||
tags: |
|
tags: |
|
||||||
type=raw,value=latest,enable=${{ endsWith(github.ref, github.event.repository.default_branch) }}
|
type=raw,value=latest,enable=${{ endsWith(github.ref, github.event.repository.default_branch) }}
|
||||||
type=ref,event=branch
|
type=ref,event=branch
|
||||||
|
@ -217,5 +216,5 @@ jobs:
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
tags: ${{ steps.meta.outputs.tags }}
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
labels: ${{ steps.meta.outputs.labels }}
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
cache-from: type=registry,ref=ghcr.io/azuracast/web:buildcache
|
cache-from: type=registry,ref=ghcr.io/azuracast/azuracast:buildcache
|
||||||
cache-to: type=registry,ref=ghcr.io/azuracast/web:buildcache,mode=max
|
cache-to: type=registry,ref=ghcr.io/azuracast/azuracast:buildcache,mode=max
|
||||||
|
|
59
Dockerfile
59
Dockerfile
|
@ -1,3 +1,11 @@
|
||||||
|
#
|
||||||
|
# Icecast build stage (for later copy)
|
||||||
|
#
|
||||||
|
FROM ghcr.io/azuracast/icecast-kh-ac:2.4.0-kh15-ac2 AS icecast
|
||||||
|
|
||||||
|
#
|
||||||
|
# Golang dependencies build step
|
||||||
|
#
|
||||||
FROM golang:1.17-buster AS dockerize
|
FROM golang:1.17-buster AS dockerize
|
||||||
|
|
||||||
RUN apt-get update \
|
RUN apt-get update \
|
||||||
|
@ -5,22 +13,49 @@ RUN apt-get update \
|
||||||
|
|
||||||
RUN go install github.com/jwilder/dockerize@latest
|
RUN go install github.com/jwilder/dockerize@latest
|
||||||
|
|
||||||
|
#
|
||||||
# Final build image
|
# Final build image
|
||||||
FROM ubuntu:focal
|
#
|
||||||
|
FROM mariadb:10.5-focal
|
||||||
|
|
||||||
ENV TZ="UTC"
|
ENV TZ="UTC"
|
||||||
|
|
||||||
# Add Dockerize
|
# Add Dockerize
|
||||||
COPY --from=dockerize /go/bin/dockerize /usr/local/bin
|
COPY --from=dockerize /go/bin/dockerize /usr/local/bin
|
||||||
|
|
||||||
# Run base build process
|
# Import Icecast-KH from build container
|
||||||
COPY ./util/docker/web /bd_build/
|
COPY --from=icecast /usr/local/bin/icecast /usr/local/bin/icecast
|
||||||
|
COPY --from=icecast /usr/local/share/icecast /usr/local/share/icecast
|
||||||
|
|
||||||
|
# Run base build process
|
||||||
|
COPY ./util/docker/common /bd_build/
|
||||||
RUN chmod a+x /bd_build/*.sh \
|
RUN chmod a+x /bd_build/*.sh \
|
||||||
&& /bd_build/prepare.sh \
|
&& /bd_build/prepare.sh \
|
||||||
&& /bd_build/add_user.sh \
|
&& /bd_build/add_user.sh \
|
||||||
&& /bd_build/setup.sh \
|
&& /bd_build/cleanup.sh
|
||||||
&& /bd_build/cleanup.sh \
|
|
||||||
|
# Build each set of dependencies in their own step for cacheability.
|
||||||
|
COPY ./util/docker/stations /bd_build/stations/
|
||||||
|
RUN bash /bd_build/stations/setup.sh \
|
||||||
|
&& bash /bd_build/cleanup.sh \
|
||||||
|
&& rm -rf /bd_build/stations
|
||||||
|
|
||||||
|
COPY ./util/docker/web /bd_build/web/
|
||||||
|
RUN bash /bd_build/web/setup.sh \
|
||||||
|
&& bash /bd_build/cleanup.sh \
|
||||||
|
&& rm -rf /bd_build/web
|
||||||
|
|
||||||
|
COPY ./util/docker/mariadb /bd_build/mariadb/
|
||||||
|
RUN bash /bd_build/mariadb/setup.sh \
|
||||||
|
&& bash /bd_build/cleanup.sh \
|
||||||
|
&& rm -rf /bd_build/mariadb
|
||||||
|
|
||||||
|
COPY ./util/docker/redis /bd_build/redis/
|
||||||
|
RUN bash /bd_build/redis/setup.sh \
|
||||||
|
&& bash /bd_build/cleanup.sh \
|
||||||
|
&& rm -rf /bd_build/redis
|
||||||
|
|
||||||
|
RUN bash /bd_build/post_setup.sh \
|
||||||
&& rm -rf /bd_build
|
&& rm -rf /bd_build
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -42,7 +77,8 @@ COPY --chown=azuracast:azuracast . .
|
||||||
RUN composer dump-autoload --optimize --classmap-authoritative \
|
RUN composer dump-autoload --optimize --classmap-authoritative \
|
||||||
&& touch /var/azuracast/.docker
|
&& touch /var/azuracast/.docker
|
||||||
|
|
||||||
VOLUME ["/var/azuracast/www_tmp", "/var/azuracast/uploads", "/var/azuracast/backups", "/var/azuracast/sftpgo/persist"]
|
VOLUME ["/var/azuracast/stations", "/var/azuracast/www_tmp", "/var/azuracast/uploads", "/var/azuracast/backups", "/var/azuracast/sftpgo/persist", "/var/azuracast/servers/shoutcast2"]
|
||||||
|
ENV PATH="${PATH}:/var/azuracast/servers/shoutcast2"
|
||||||
|
|
||||||
#
|
#
|
||||||
# END Operations as `azuracast` user
|
# END Operations as `azuracast` user
|
||||||
|
@ -50,18 +86,19 @@ VOLUME ["/var/azuracast/www_tmp", "/var/azuracast/uploads", "/var/azuracast/back
|
||||||
USER root
|
USER root
|
||||||
|
|
||||||
EXPOSE 80 2022
|
EXPOSE 80 2022
|
||||||
|
EXPOSE 8000-8999
|
||||||
|
|
||||||
# Sensible default environment variables.
|
# Sensible default environment variables.
|
||||||
ENV LANG="en_US.UTF-8" \
|
ENV LANG="en_US.UTF-8" \
|
||||||
|
DOCKER_IS_STANDALONE="true" \
|
||||||
APPLICATION_ENV="production" \
|
APPLICATION_ENV="production" \
|
||||||
ENABLE_ADVANCED_FEATURES="false" \
|
MYSQL_HOST="localhost" \
|
||||||
MYSQL_HOST="mariadb" \
|
|
||||||
MYSQL_PORT=3306 \
|
MYSQL_PORT=3306 \
|
||||||
MYSQL_USER="azuracast" \
|
MYSQL_USER="azuracast" \
|
||||||
MYSQL_PASSWORD="azur4c457" \
|
MYSQL_PASSWORD="azur4c457" \
|
||||||
MYSQL_DATABASE="azuracast" \
|
MYSQL_DATABASE="azuracast" \
|
||||||
ENABLE_REDIS="true" \
|
ENABLE_REDIS="true" \
|
||||||
REDIS_HOST="redis" \
|
REDIS_HOST="localhost" \
|
||||||
REDIS_PORT=6379 \
|
REDIS_PORT=6379 \
|
||||||
REDIS_DB=1 \
|
REDIS_DB=1 \
|
||||||
NGINX_RADIO_PORTS="default" \
|
NGINX_RADIO_PORTS="default" \
|
||||||
|
@ -75,5 +112,5 @@ ENV LANG="en_US.UTF-8" \
|
||||||
PROFILING_EXTENSION_HTTP_IP_WHITELIST=*
|
PROFILING_EXTENSION_HTTP_IP_WHITELIST=*
|
||||||
|
|
||||||
# Entrypoint and default command
|
# Entrypoint and default command
|
||||||
ENTRYPOINT ["/usr/local/bin/uptime_wait"]
|
ENTRYPOINT ["/usr/local/bin/my_init"]
|
||||||
CMD ["/usr/local/bin/my_init"]
|
CMD ["--no-main-command"]
|
||||||
|
|
4
Makefile
4
Makefile
|
@ -26,8 +26,8 @@ build: # Rebuild all containers and restart
|
||||||
update: # Update everything (i.e. after a branch update)
|
update: # Update everything (i.e. after a branch update)
|
||||||
docker-compose build
|
docker-compose build
|
||||||
$(MAKE) down
|
$(MAKE) down
|
||||||
docker-compose run --rm --user=azuracast web composer install
|
docker-compose run --rm web gosu azuracast composer install
|
||||||
docker-compose run --rm --user=azuracast web azuracast_cli azuracast:setup:initialize
|
docker-compose run --rm web azuracast_cli azuracast:setup:initialize
|
||||||
$(MAKE) frontend-build
|
$(MAKE) frontend-build
|
||||||
$(MAKE) up
|
$(MAKE) up
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
APPLICATION_ENV=development
|
APPLICATION_ENV=development
|
||||||
LOG_LEVEL=debug
|
LOG_LEVEL=debug
|
||||||
ENABLE_ADVANCED_FEATURES=true
|
|
||||||
COMPOSER_PLUGIN_MODE=false
|
COMPOSER_PLUGIN_MODE=false
|
||||||
|
|
||||||
# Limit station port range
|
# Limit station port range
|
||||||
|
|
|
@ -39,17 +39,17 @@ AUTO_ASSIGN_PORT_MAX=8499
|
||||||
|
|
||||||
# The host to connect to. Leave this as the default value unless you're connecting
|
# The host to connect to. Leave this as the default value unless you're connecting
|
||||||
# to an external database server.
|
# to an external database server.
|
||||||
# Default: mariadb
|
# Default: localhost
|
||||||
MYSQL_HOST=mariadb
|
# MYSQL_HOST=localhost
|
||||||
|
|
||||||
# The port to connect to. Leave this as the default value unless you're connecting
|
# The port to connect to. Leave this as the default value unless you're connecting
|
||||||
# to an external database server.
|
# to an external database server.
|
||||||
# Default: 3306
|
# Default: 3306
|
||||||
MYSQL_PORT=3306
|
# MYSQL_PORT=3306
|
||||||
|
|
||||||
# The username AzuraCast will use to connect to the database.
|
# The username AzuraCast will use to connect to the database.
|
||||||
# Default: azuracast
|
# Default: azuracast
|
||||||
MYSQL_USER=azuracast
|
# MYSQL_USER=azuracast
|
||||||
|
|
||||||
# The password AzuraCast will use to connect to the database.
|
# The password AzuraCast will use to connect to the database.
|
||||||
# By default, the database is not exposed to the Internet at all and this is only
|
# By default, the database is not exposed to the Internet at all and this is only
|
||||||
|
@ -59,7 +59,7 @@ MYSQL_PASSWORD=azur4c457
|
||||||
|
|
||||||
# The name of the AzuraCast database.
|
# The name of the AzuraCast database.
|
||||||
# Default: azuracast
|
# Default: azuracast
|
||||||
MYSQL_DATABASE=azuracast
|
# MYSQL_DATABASE=azuracast
|
||||||
|
|
||||||
# Automatically generate a random root password upon the first database spin-up.
|
# Automatically generate a random root password upon the first database spin-up.
|
||||||
# This password will be visible in the mariadb container's logs.
|
# This password will be visible in the mariadb container's logs.
|
||||||
|
@ -71,12 +71,12 @@ MYSQL_RANDOM_ROOT_PASSWORD=yes
|
||||||
# To read the slow query log once enabled, run:
|
# To read the slow query log once enabled, run:
|
||||||
# docker-compose exec mariadb slow_queries
|
# docker-compose exec mariadb slow_queries
|
||||||
# Default: 0
|
# Default: 0
|
||||||
MYSQL_SLOW_QUERY_LOG=0
|
# MYSQL_SLOW_QUERY_LOG=0
|
||||||
|
|
||||||
# Set the amount of allowed connections to the database. This value should be increased
|
# Set the amount of allowed connections to the database. This value should be increased
|
||||||
# if you are seeing the `Too many connections` error in the logs.
|
# if you are seeing the `Too many connections` error in the logs.
|
||||||
# Default: 100
|
# Default: 100
|
||||||
MYSQL_MAX_CONNECTIONS=100
|
# MYSQL_MAX_CONNECTIONS=100
|
||||||
|
|
||||||
#
|
#
|
||||||
# Redis Configuration
|
# Redis Configuration
|
||||||
|
@ -90,8 +90,8 @@ MYSQL_MAX_CONNECTIONS=100
|
||||||
# ENABLE_REDIS=true
|
# ENABLE_REDIS=true
|
||||||
|
|
||||||
# Name of the Redis host.
|
# Name of the Redis host.
|
||||||
# Default: redis
|
# Default: localhost
|
||||||
# REDIS_HOST=redis
|
# REDIS_HOST=localhost
|
||||||
|
|
||||||
# Port to connect to on the Redis host.
|
# Port to connect to on the Redis host.
|
||||||
# Default: 6379
|
# Default: 6379
|
||||||
|
|
|
@ -92,8 +92,10 @@ class UptimeWait
|
||||||
protected function checkDatabase(): bool
|
protected function checkDatabase(): bool
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
$defaultHost = $this->isStandalone() ? 'localhost' : 'mariadb';
|
||||||
|
|
||||||
$dbOptions = [
|
$dbOptions = [
|
||||||
'host' => $_ENV['MYSQL_HOST'] ?? 'mariadb',
|
'host' => $_ENV['MYSQL_HOST'] ?? $defaultHost,
|
||||||
'port' => (int)($_ENV['MYSQL_PORT'] ?? 3306),
|
'port' => (int)($_ENV['MYSQL_PORT'] ?? 3306),
|
||||||
'dbname' => $_ENV['MYSQL_DATABASE'] ?? 'azuracast',
|
'dbname' => $_ENV['MYSQL_DATABASE'] ?? 'azuracast',
|
||||||
'user' => $_ENV['MYSQL_USER'] ?? 'azuracast',
|
'user' => $_ENV['MYSQL_USER'] ?? 'azuracast',
|
||||||
|
@ -119,8 +121,10 @@ class UptimeWait
|
||||||
|
|
||||||
protected function checkRedis(): bool
|
protected function checkRedis(): bool
|
||||||
{
|
{
|
||||||
|
$defaultHost = $this->isStandalone() ? 'localhost' : 'redis';
|
||||||
|
|
||||||
$enableRedis = $this->envToBool($_ENV['ENABLE_REDIS'] ?? true);
|
$enableRedis = $this->envToBool($_ENV['ENABLE_REDIS'] ?? true);
|
||||||
$redisHost = $_ENV['REDIS_HOST'] ?? 'redis';
|
$redisHost = $_ENV['REDIS_HOST'] ?? $defaultHost;
|
||||||
$redisPort = (int)($_ENV['REDIS_PORT'] ?? 6379);
|
$redisPort = (int)($_ENV['REDIS_PORT'] ?? 6379);
|
||||||
$redisDb = (int)($_ENV['REDIS_DB'] ?? 1);
|
$redisDb = (int)($_ENV['REDIS_DB'] ?? 1);
|
||||||
|
|
||||||
|
@ -157,6 +161,11 @@ class UptimeWait
|
||||||
|| '1' === $value;
|
|| '1' === $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function isStandalone(): bool
|
||||||
|
{
|
||||||
|
return $this->envToBool($_ENV['DOCKER_IS_STANDALONE'] ?? false);
|
||||||
|
}
|
||||||
|
|
||||||
protected function println(string $line): void
|
protected function println(string $line): void
|
||||||
{
|
{
|
||||||
echo $line . "\n";
|
echo $line . "\n";
|
||||||
|
|
|
@ -1,28 +1,13 @@
|
||||||
services :
|
services:
|
||||||
web :
|
web:
|
||||||
build :
|
build:
|
||||||
context : .
|
context: .
|
||||||
volumes :
|
ports:
|
||||||
|
- "127.0.0.1:3306:3306"
|
||||||
|
- "127.0.0.1:6379:6379"
|
||||||
|
volumes:
|
||||||
- ./util/local_ssl:/etc/nginx/certs
|
- ./util/local_ssl:/etc/nginx/certs
|
||||||
- ./vendor:/var/azuracast/www/vendor
|
- ./vendor:/var/azuracast/www/vendor
|
||||||
- .:/var/azuracast/www
|
- .:/var/azuracast/www
|
||||||
extra_hosts:
|
extra_hosts:
|
||||||
- "host.docker.internal:host-gateway"
|
- "host.docker.internal:host-gateway"
|
||||||
|
|
||||||
mariadb :
|
|
||||||
build :
|
|
||||||
context : ../docker-azuracast-db
|
|
||||||
ports :
|
|
||||||
- "127.0.0.1:3306:3306"
|
|
||||||
|
|
||||||
redis :
|
|
||||||
build :
|
|
||||||
context : ../docker-azuracast-redis
|
|
||||||
ports :
|
|
||||||
- "127.0.0.1:6379:6379"
|
|
||||||
|
|
||||||
stations :
|
|
||||||
build :
|
|
||||||
context : ../docker-azuracast-radio
|
|
||||||
volumes :
|
|
||||||
- ./util/local_ssl:/etc/nginx/certs
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
services :
|
services :
|
||||||
installer :
|
installer :
|
||||||
container_name : azuracast_installer
|
container_name: azuracast_installer
|
||||||
image : 'ghcr.io/azuracast/web:${AZURACAST_VERSION:-latest}'
|
image: 'ghcr.io/azuracast/web:${AZURACAST_VERSION:-latest}'
|
||||||
volumes :
|
volumes:
|
||||||
- './:/installer'
|
- './:/installer'
|
||||||
restart : 'no'
|
restart: 'no'
|
||||||
user : root
|
user: root
|
||||||
entrypoint : docker_installer
|
entrypoint: minimal_init
|
||||||
command : install
|
command: docker_installer install
|
||||||
|
|
|
@ -12,83 +12,14 @@
|
||||||
|
|
||||||
services:
|
services:
|
||||||
web:
|
web:
|
||||||
container_name: azuracast_web
|
container_name: azuracast
|
||||||
image: "ghcr.io/azuracast/web:${AZURACAST_VERSION:-latest}"
|
image: "ghcr.io/azuracast/azuracast:${AZURACAST_VERSION:-latest}"
|
||||||
# Want to customize the HTTP/S ports? Follow the instructions here:
|
# Want to customize the HTTP/S ports? Follow the instructions here:
|
||||||
# https://docs.azuracast.com/en/administration/docker#using-non-standard-ports
|
# https://docs.azuracast.com/en/administration/docker#using-non-standard-ports
|
||||||
ports:
|
ports:
|
||||||
- '${AZURACAST_HTTP_PORT:-80}:80'
|
- '${AZURACAST_HTTP_PORT:-80}:80'
|
||||||
- '${AZURACAST_HTTPS_PORT:-443}:443'
|
- '${AZURACAST_HTTPS_PORT:-443}:443'
|
||||||
- '${AZURACAST_SFTP_PORT:-2022}:2022'
|
- '${AZURACAST_SFTP_PORT:-2022}:2022'
|
||||||
depends_on:
|
|
||||||
- mariadb
|
|
||||||
- stations
|
|
||||||
- redis
|
|
||||||
env_file: azuracast.env
|
|
||||||
environment:
|
|
||||||
LANG: ${LANG:-en_US.UTF-8}
|
|
||||||
AZURACAST_DC_REVISION: 13
|
|
||||||
AZURACAST_VERSION: ${AZURACAST_VERSION:-latest}
|
|
||||||
AZURACAST_SFTP_PORT: ${AZURACAST_SFTP_PORT:-2022}
|
|
||||||
NGINX_TIMEOUT: ${NGINX_TIMEOUT:-1800}
|
|
||||||
LETSENCRYPT_HOST: ${LETSENCRYPT_HOST:-}
|
|
||||||
LETSENCRYPT_EMAIL: ${LETSENCRYPT_EMAIL:-}
|
|
||||||
PUID: ${AZURACAST_PUID:-1000}
|
|
||||||
PGID: ${AZURACAST_PGID:-1000}
|
|
||||||
volumes:
|
|
||||||
- letsencrypt:/etc/nginx/certs
|
|
||||||
- letsencrypt_acme:/etc/acme.sh
|
|
||||||
- www_vendor:/var/azuracast/www/vendor
|
|
||||||
- www_uploads:/var/azuracast/uploads
|
|
||||||
- tmp_data:/var/azuracast/www_tmp
|
|
||||||
- station_data:/var/azuracast/stations
|
|
||||||
- shoutcast2_install:/var/azuracast/servers/shoutcast2
|
|
||||||
- geolite_install:/var/azuracast/geoip
|
|
||||||
- sftpgo_data:/var/azuracast/sftpgo/persist
|
|
||||||
- backups:/var/azuracast/backups
|
|
||||||
networks:
|
|
||||||
- frontend
|
|
||||||
- backend
|
|
||||||
restart: unless-stopped
|
|
||||||
ulimits: &default-ulimits
|
|
||||||
nofile:
|
|
||||||
soft: 65536
|
|
||||||
hard: 65536
|
|
||||||
logging: &default-logging
|
|
||||||
options:
|
|
||||||
max-size: "1m"
|
|
||||||
max-file: "5"
|
|
||||||
|
|
||||||
mariadb:
|
|
||||||
container_name: azuracast_mariadb
|
|
||||||
image: "ghcr.io/azuracast/db:${AZURACAST_VERSION:-latest}"
|
|
||||||
volumes:
|
|
||||||
- db_data:/var/lib/mysql
|
|
||||||
env_file: azuracast.env
|
|
||||||
networks:
|
|
||||||
- backend
|
|
||||||
restart: unless-stopped
|
|
||||||
logging: *default-logging
|
|
||||||
|
|
||||||
redis:
|
|
||||||
container_name: azuracast_redis
|
|
||||||
image: "ghcr.io/azuracast/redis:${AZURACAST_VERSION:-latest}"
|
|
||||||
sysctls:
|
|
||||||
net.core.somaxconn: 1024
|
|
||||||
volumes:
|
|
||||||
- redis_data:/data
|
|
||||||
networks:
|
|
||||||
- backend
|
|
||||||
restart: unless-stopped
|
|
||||||
logging: *default-logging
|
|
||||||
|
|
||||||
stations:
|
|
||||||
container_name: azuracast_stations
|
|
||||||
image: "ghcr.io/azuracast/radio:${AZURACAST_VERSION:-latest}"
|
|
||||||
environment:
|
|
||||||
PUID: ${AZURACAST_PUID:-1000}
|
|
||||||
PGID: ${AZURACAST_PGID:-1000}
|
|
||||||
ports:
|
|
||||||
# This default mapping is the outgoing and incoming ports for the first 50 stations.
|
# This default mapping is the outgoing and incoming ports for the first 50 stations.
|
||||||
# You can override this port mapping in your own docker-compose.override.yml file.
|
# You can override this port mapping in your own docker-compose.override.yml file.
|
||||||
# For instructions, see:
|
# For instructions, see:
|
||||||
|
@ -240,24 +171,38 @@ services:
|
||||||
- '8490:8490'
|
- '8490:8490'
|
||||||
- '8495:8495'
|
- '8495:8495'
|
||||||
- '8496:8496'
|
- '8496:8496'
|
||||||
|
env_file: azuracast.env
|
||||||
|
environment:
|
||||||
|
LANG: ${LANG:-en_US.UTF-8}
|
||||||
|
AZURACAST_DC_REVISION: 14
|
||||||
|
AZURACAST_VERSION: ${AZURACAST_VERSION:-latest}
|
||||||
|
AZURACAST_SFTP_PORT: ${AZURACAST_SFTP_PORT:-2022}
|
||||||
|
NGINX_TIMEOUT: ${NGINX_TIMEOUT:-1800}
|
||||||
|
LETSENCRYPT_HOST: ${LETSENCRYPT_HOST:-}
|
||||||
|
LETSENCRYPT_EMAIL: ${LETSENCRYPT_EMAIL:-}
|
||||||
|
PUID: ${AZURACAST_PUID:-1000}
|
||||||
|
PGID: ${AZURACAST_PGID:-1000}
|
||||||
volumes:
|
volumes:
|
||||||
|
- letsencrypt:/etc/nginx/certs
|
||||||
|
- letsencrypt_acme:/etc/acme.sh
|
||||||
|
- www_vendor:/var/azuracast/www/vendor
|
||||||
|
- www_uploads:/var/azuracast/uploads
|
||||||
|
- tmp_data:/var/azuracast/www_tmp
|
||||||
- station_data:/var/azuracast/stations
|
- station_data:/var/azuracast/stations
|
||||||
- shoutcast2_install:/var/azuracast/servers/shoutcast2
|
- shoutcast2_install:/var/azuracast/servers/shoutcast2
|
||||||
- letsencrypt:/etc/nginx/certs
|
- geolite_install:/var/azuracast/geoip
|
||||||
- tmp_data:/var/azuracast/www_tmp
|
- sftpgo_data:/var/azuracast/sftpgo/persist
|
||||||
networks:
|
- backups:/var/azuracast/backups
|
||||||
- frontend
|
- db_data:/var/lib/mysql
|
||||||
- backend
|
|
||||||
init: true
|
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
ulimits: *default-ulimits
|
ulimits: &default-ulimits
|
||||||
logging: *default-logging
|
nofile:
|
||||||
|
soft: 65536
|
||||||
networks:
|
hard: 65536
|
||||||
frontend:
|
logging: &default-logging
|
||||||
driver: bridge
|
options:
|
||||||
backend:
|
max-size: "1m"
|
||||||
driver: bridge
|
max-file: "5"
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
db_data: { }
|
db_data: { }
|
||||||
|
@ -270,5 +215,4 @@ volumes:
|
||||||
www_vendor: { }
|
www_vendor: { }
|
||||||
www_uploads: { }
|
www_uploads: { }
|
||||||
tmp_data: { }
|
tmp_data: { }
|
||||||
redis_data: { }
|
|
||||||
backups: { }
|
backups: { }
|
||||||
|
|
15
docker.sh
15
docker.sh
|
@ -378,6 +378,7 @@ run-installer() {
|
||||||
fi
|
fi
|
||||||
|
|
||||||
curl -fsSL https://raw.githubusercontent.com/AzuraCast/AzuraCast/$AZURACAST_RELEASE_BRANCH/docker-compose.installer.yml -o docker-compose.installer.yml
|
curl -fsSL https://raw.githubusercontent.com/AzuraCast/AzuraCast/$AZURACAST_RELEASE_BRANCH/docker-compose.installer.yml -o docker-compose.installer.yml
|
||||||
|
|
||||||
docker-compose -p azuracast_installer -f docker-compose.installer.yml pull
|
docker-compose -p azuracast_installer -f docker-compose.installer.yml pull
|
||||||
docker-compose -p azuracast_installer -f docker-compose.installer.yml run --rm installer install "$@"
|
docker-compose -p azuracast_installer -f docker-compose.installer.yml run --rm installer install "$@"
|
||||||
|
|
||||||
|
@ -454,14 +455,6 @@ install-dev() {
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ ! -d ../docker-azuracast-radio ]]; then
|
|
||||||
if ask "Clone related repositories?" Y; then
|
|
||||||
git clone https://github.com/AzuraCast/docker-azuracast-db.git ../docker-azuracast-db
|
|
||||||
git clone https://github.com/AzuraCast/docker-azuracast-redis.git ../docker-azuracast-redis
|
|
||||||
git clone https://github.com/AzuraCast/docker-azuracast-radio.git ../docker-azuracast-radio
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ ! -f docker-compose.yml ]]; then
|
if [[ ! -f docker-compose.yml ]]; then
|
||||||
cp docker-compose.sample.yml docker-compose.yml
|
cp docker-compose.sample.yml docker-compose.yml
|
||||||
fi
|
fi
|
||||||
|
@ -485,7 +478,7 @@ install-dev() {
|
||||||
fi
|
fi
|
||||||
|
|
||||||
docker-compose build
|
docker-compose build
|
||||||
docker-compose run --rm --user="azuracast" web azuracast_install "$@"
|
docker-compose run --rm web azuracast_install "$@"
|
||||||
|
|
||||||
docker-compose -f frontend/docker-compose.yml build
|
docker-compose -f frontend/docker-compose.yml build
|
||||||
docker-compose -f frontend/docker-compose.yml run --rm frontend npm run dev-build
|
docker-compose -f frontend/docker-compose.yml run --rm frontend npm run dev-build
|
||||||
|
@ -563,7 +556,7 @@ update() {
|
||||||
docker volume rm azuracast_tmp_data
|
docker volume rm azuracast_tmp_data
|
||||||
docker volume rm azuracast_redis_data
|
docker volume rm azuracast_redis_data
|
||||||
|
|
||||||
docker-compose run --rm --user="azuracast" web azuracast_update "$@"
|
docker-compose run --rm web azuracast_update "$@"
|
||||||
docker-compose up -d
|
docker-compose up -d
|
||||||
|
|
||||||
if ask "Clean up all stopped Docker containers and images to save space?" Y; then
|
if ask "Clean up all stopped Docker containers and images to save space?" Y; then
|
||||||
|
@ -654,7 +647,7 @@ backup() {
|
||||||
.env --file .env set AZURACAST_PGID="$(id -g)"
|
.env --file .env set AZURACAST_PGID="$(id -g)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
docker-compose run --rm web azuracast_cli azuracast:backup "/var/azuracast/backups/${BACKUP_FILENAME}" "$@"
|
docker-compose exec web azuracast_cli azuracast:backup "/var/azuracast/backups/${BACKUP_FILENAME}" "$@"
|
||||||
|
|
||||||
# Move from Docker volume to local filesystem
|
# Move from Docker volume to local filesystem
|
||||||
docker run --rm -v "azuracast_backups:/backup_src" \
|
docker run --rm -v "azuracast_backups:/backup_src" \
|
||||||
|
|
|
@ -34,6 +34,7 @@ class Environment
|
||||||
public const ASSET_URL = 'ASSETS_URL';
|
public const ASSET_URL = 'ASSETS_URL';
|
||||||
|
|
||||||
public const DOCKER_REVISION = 'AZURACAST_DC_REVISION';
|
public const DOCKER_REVISION = 'AZURACAST_DC_REVISION';
|
||||||
|
public const DOCKER_IS_STANDALONE = 'DOCKER_IS_STANDALONE';
|
||||||
|
|
||||||
public const LANG = 'LANG';
|
public const LANG = 'LANG';
|
||||||
|
|
||||||
|
@ -208,22 +209,32 @@ class Environment
|
||||||
return ($compareVersion >= $version);
|
return ($compareVersion >= $version);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getUriToWeb(): UriInterface
|
public function isDockerStandalone(): bool
|
||||||
{
|
{
|
||||||
if ($this->isDocker()) {
|
if (!$this->isDocker()) {
|
||||||
return $this->isDockerRevisionAtLeast(5)
|
return false;
|
||||||
? new Uri('http://web')
|
|
||||||
: new Uri('http://nginx');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Uri('http://127.0.0.1');
|
return self::envToBool($this->data[self::DOCKER_IS_STANDALONE] ?? false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUriToWeb(): UriInterface
|
||||||
|
{
|
||||||
|
return match (true) {
|
||||||
|
$this->isDockerStandalone() => new Uri('http://127.0.0.1'),
|
||||||
|
$this->isDockerRevisionAtLeast(5) => new Uri('http://web'),
|
||||||
|
$this->isDocker() => new Uri('http://nginx'),
|
||||||
|
default => new Uri('http://127.0.0.1')
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getUriToStations(): UriInterface
|
public function getUriToStations(): UriInterface
|
||||||
{
|
{
|
||||||
return $this->isDocker()
|
return match (true) {
|
||||||
? new Uri('http://stations')
|
$this->isDockerStandalone() => new Uri('http://127.0.0.1'),
|
||||||
: new Uri('http://127.0.0.1');
|
$this->isDocker() => new Uri('http://stations'),
|
||||||
|
default => new Uri('http://127.0.0.1'),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getLang(): ?string
|
public function getLang(): ?string
|
||||||
|
@ -296,11 +307,17 @@ class Environment
|
||||||
*/
|
*/
|
||||||
public function getDatabaseSettings(): array
|
public function getDatabaseSettings(): array
|
||||||
{
|
{
|
||||||
|
$defaultHost = match (true) {
|
||||||
|
$this->isDockerStandalone() => 'localhost',
|
||||||
|
$this->isDocker() => 'mariadb',
|
||||||
|
default => 'localhost'
|
||||||
|
};
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'host' => $this->data[self::DB_HOST] ?? ($this->isDocker() ? 'mariadb' : 'localhost'),
|
'host' => $this->data[self::DB_HOST] ?? $defaultHost,
|
||||||
'port' => (int)($this->data[self::DB_PORT] ?? 3306),
|
'port' => (int)($this->data[self::DB_PORT] ?? 3306),
|
||||||
'dbname' => $this->data[self::DB_NAME] ?? 'azuracast',
|
'dbname' => $this->data[self::DB_NAME] ?? 'azuracast',
|
||||||
'user' => $this->data[self::DB_USER] ?? 'azuracast',
|
'user' => $this->data[self::DB_USER] ?? 'azuracast',
|
||||||
'password' => $this->data[self::DB_PASSWORD] ?? 'azur4c457',
|
'password' => $this->data[self::DB_PASSWORD] ?? 'azur4c457',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -315,10 +332,16 @@ class Environment
|
||||||
*/
|
*/
|
||||||
public function getRedisSettings(): array
|
public function getRedisSettings(): array
|
||||||
{
|
{
|
||||||
|
$defaultHost = match (true) {
|
||||||
|
$this->isDockerStandalone() => 'localhost',
|
||||||
|
$this->isDocker() => 'redis',
|
||||||
|
default => 'localhost'
|
||||||
|
};
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'host' => $this->data[self::REDIS_HOST] ?? ($this->isDocker() ? 'redis' : 'localhost'),
|
'host' => $this->data[self::REDIS_HOST] ?? $defaultHost,
|
||||||
'port' => (int)($this->data[self::REDIS_PORT] ?? 6379),
|
'port' => (int)($this->data[self::REDIS_PORT] ?? 6379),
|
||||||
'db' => (int)($this->data[self::REDIS_DB] ?? 1),
|
'db' => (int)($this->data[self::REDIS_DB] ?? 1),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -337,6 +360,15 @@ class Environment
|
||||||
return $this->data[self::PROFILING_EXTENSION_HTTP_KEY] ?? 'dev';
|
return $this->data[self::PROFILING_EXTENSION_HTTP_KEY] ?? 'dev';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function getDefaultsForEnvironment(Environment $existingEnv): self
|
||||||
|
{
|
||||||
|
return new self([
|
||||||
|
self::IS_CLI => $existingEnv->isCli(),
|
||||||
|
self::IS_DOCKER => $existingEnv->isDocker(),
|
||||||
|
self::DOCKER_IS_STANDALONE => $existingEnv->isDockerStandalone(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
public static function envToBool(mixed $value): bool
|
public static function envToBool(mixed $value): bool
|
||||||
{
|
{
|
||||||
if (is_bool($value)) {
|
if (is_bool($value)) {
|
||||||
|
|
|
@ -102,11 +102,11 @@ class InstallCommand extends Command
|
||||||
$locale = SupportedLocales::getValidLocale($azuracastEnv[Environment::LANG] ?? null);
|
$locale = SupportedLocales::getValidLocale($azuracastEnv[Environment::LANG] ?? null);
|
||||||
$locale->register($this->environment);
|
$locale->register($this->environment);
|
||||||
|
|
||||||
$envConfig = EnvFile::getConfiguration();
|
$envConfig = EnvFile::getConfiguration($this->environment);
|
||||||
$env->setFromDefaults();
|
$env->setFromDefaults($this->environment);
|
||||||
|
|
||||||
$azuracastEnvConfig = AzuraCastEnvFile::getConfiguration();
|
$azuracastEnvConfig = AzuraCastEnvFile::getConfiguration($this->environment);
|
||||||
$azuracastEnv->setFromDefaults();
|
$azuracastEnv->setFromDefaults($this->environment);
|
||||||
|
|
||||||
// Apply values passed via flags
|
// Apply values passed via flags
|
||||||
if (null !== $releaseChannel) {
|
if (null !== $releaseChannel) {
|
||||||
|
@ -156,6 +156,16 @@ class InstallCommand extends Command
|
||||||
$azuracastEnv['MYSQL_RANDOM_ROOT_PASSWORD'] = 'yes';
|
$azuracastEnv['MYSQL_RANDOM_ROOT_PASSWORD'] = 'yes';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Special fixes for transitioning to standalone installations.
|
||||||
|
if ($this->environment->isDockerStandalone()) {
|
||||||
|
if ('mariadb' === $azuracastEnv['MYSQL_HOST']) {
|
||||||
|
unset($azuracastEnv['MYSQL_HOST']);
|
||||||
|
}
|
||||||
|
if ('redis' === $azuracastEnv['REDIS_HOST']) {
|
||||||
|
unset($azuracastEnv['REDIS_HOST']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Display header messages
|
// Display header messages
|
||||||
if ($isNewInstall) {
|
if ($isNewInstall) {
|
||||||
$io->title(
|
$io->title(
|
||||||
|
@ -253,8 +263,8 @@ class InstallCommand extends Command
|
||||||
__('Writing configuration files...')
|
__('Writing configuration files...')
|
||||||
);
|
);
|
||||||
|
|
||||||
$envStr = $env->writeToFile();
|
$envStr = $env->writeToFile($this->environment);
|
||||||
$azuracastEnvStr = $azuracastEnv->writeToFile();
|
$azuracastEnvStr = $azuracastEnv->writeToFile($this->environment);
|
||||||
|
|
||||||
if ($io->isVerbose()) {
|
if ($io->isVerbose()) {
|
||||||
$io->section($env->getBasename());
|
$io->section($env->getBasename());
|
||||||
|
@ -289,10 +299,12 @@ class InstallCommand extends Command
|
||||||
$sampleFile = $this->environment->getBaseDirectory() . '/docker-compose.sample.yml';
|
$sampleFile = $this->environment->getBaseDirectory() . '/docker-compose.sample.yml';
|
||||||
$yaml = Yaml::parseFile($sampleFile);
|
$yaml = Yaml::parseFile($sampleFile);
|
||||||
|
|
||||||
|
$isStandalone = $this->environment->isDockerStandalone();
|
||||||
|
|
||||||
// Parse port listing and convert into YAML format.
|
// Parse port listing and convert into YAML format.
|
||||||
$ports = $env['AZURACAST_STATION_PORTS'] ?? '';
|
$ports = $env['AZURACAST_STATION_PORTS'] ?? '';
|
||||||
|
|
||||||
$envConfig = $env::getConfiguration();
|
$envConfig = $env::getConfiguration($this->environment);
|
||||||
$defaultPorts = $envConfig['AZURACAST_STATION_PORTS']['default'];
|
$defaultPorts = $envConfig['AZURACAST_STATION_PORTS']['default'];
|
||||||
|
|
||||||
if (!empty($ports) && 0 !== strcmp($ports, $defaultPorts)) {
|
if (!empty($ports) && 0 !== strcmp($ports, $defaultPorts)) {
|
||||||
|
@ -316,7 +328,18 @@ class InstallCommand extends Command
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($yamlPorts)) {
|
if (!empty($yamlPorts)) {
|
||||||
$yaml['services']['stations']['ports'] = $yamlPorts;
|
if ($isStandalone) {
|
||||||
|
$existingPorts = [];
|
||||||
|
foreach ($yaml['services']['ports'] as $port) {
|
||||||
|
if (str_starts_with('$', $port)) {
|
||||||
|
$existingPorts[] = $port;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$yaml['services']['web']['ports'] = array_merge($existingPorts, $yamlPorts);
|
||||||
|
} else {
|
||||||
|
$yaml['services']['stations']['ports'] = $yamlPorts;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!empty($nginxRadioPorts)) {
|
if (!empty($nginxRadioPorts)) {
|
||||||
$nginxRadioPortsStr = '(' . implode('|', $nginxRadioPorts) . ')';
|
$nginxRadioPortsStr = '(' . implode('|', $nginxRadioPorts) . ')';
|
||||||
|
@ -329,9 +352,11 @@ class InstallCommand extends Command
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove Redis if it's not enabled.
|
// Remove Redis if it's not enabled.
|
||||||
$enableRedis = $azuracastEnv->getAsBool(Environment::ENABLE_REDIS, true);
|
if (!$isStandalone) {
|
||||||
if (!$enableRedis) {
|
$enableRedis = $azuracastEnv->getAsBool(Environment::ENABLE_REDIS, true);
|
||||||
unset($yaml['services']['redis']);
|
if (!$enableRedis) {
|
||||||
|
unset($yaml['services']['redis']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove privileged-mode settings if not enabled.
|
// Remove privileged-mode settings if not enabled.
|
||||||
|
|
|
@ -32,12 +32,12 @@ abstract class AbstractEnvFile implements ArrayAccess
|
||||||
return basename($this->path);
|
return basename($this->path);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setFromDefaults(): void
|
public function setFromDefaults(Environment $environment): void
|
||||||
{
|
{
|
||||||
$currentVars = array_filter($this->data);
|
$currentVars = array_filter($this->data);
|
||||||
|
|
||||||
$defaults = [];
|
$defaults = [];
|
||||||
foreach (static::getConfiguration() as $key => $keyInfo) {
|
foreach (static::getConfiguration($environment) as $key => $keyInfo) {
|
||||||
if (isset($keyInfo['default'])) {
|
if (isset($keyInfo['default'])) {
|
||||||
$defaults[$key] = $keyInfo['default'] ?? null;
|
$defaults[$key] = $keyInfo['default'] ?? null;
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,7 @@ abstract class AbstractEnvFile implements ArrayAccess
|
||||||
unset($this->data[$offset]);
|
unset($this->data[$offset]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function writeToFile(): string
|
public function writeToFile(Environment $environment): string
|
||||||
{
|
{
|
||||||
$values = array_filter($this->data);
|
$values = array_filter($this->data);
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ abstract class AbstractEnvFile implements ArrayAccess
|
||||||
'',
|
'',
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach (static::getConfiguration() as $key => $keyInfo) {
|
foreach (static::getConfiguration($environment) as $key => $keyInfo) {
|
||||||
$envFile[] = '# ' . ($keyInfo['name'] ?? $key);
|
$envFile[] = '# ' . ($keyInfo['name'] ?? $key);
|
||||||
|
|
||||||
if (!empty($keyInfo['description'])) {
|
if (!empty($keyInfo['description'])) {
|
||||||
|
@ -180,7 +180,7 @@ abstract class AbstractEnvFile implements ArrayAccess
|
||||||
/**
|
/**
|
||||||
* @return mixed[]
|
* @return mixed[]
|
||||||
*/
|
*/
|
||||||
abstract public static function getConfiguration(): array;
|
abstract public static function getConfiguration(Environment $environment): array;
|
||||||
|
|
||||||
abstract public static function buildPathFromBase(string $baseDir): string;
|
abstract public static function buildPathFromBase(string $baseDir): string;
|
||||||
|
|
||||||
|
|
|
@ -14,12 +14,12 @@ use function __;
|
||||||
class AzuraCastEnvFile extends AbstractEnvFile
|
class AzuraCastEnvFile extends AbstractEnvFile
|
||||||
{
|
{
|
||||||
/** @inheritDoc */
|
/** @inheritDoc */
|
||||||
public static function getConfiguration(): array
|
public static function getConfiguration(Environment $environment): array
|
||||||
{
|
{
|
||||||
static $config = null;
|
static $config = null;
|
||||||
|
|
||||||
if (null === $config) {
|
if (null === $config) {
|
||||||
$emptyEnv = new Environment([]);
|
$emptyEnv = Environment::getDefaultsForEnvironment($environment);
|
||||||
$defaults = $emptyEnv->toArray();
|
$defaults = $emptyEnv->toArray();
|
||||||
|
|
||||||
$langOptions = [];
|
$langOptions = [];
|
||||||
|
|
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace App\Installer\EnvFiles;
|
namespace App\Installer\EnvFiles;
|
||||||
|
|
||||||
|
use App\Environment;
|
||||||
use App\Radio\Configuration;
|
use App\Radio\Configuration;
|
||||||
|
|
||||||
use function __;
|
use function __;
|
||||||
|
@ -11,7 +12,7 @@ use function __;
|
||||||
class EnvFile extends AbstractEnvFile
|
class EnvFile extends AbstractEnvFile
|
||||||
{
|
{
|
||||||
/** @inheritDoc */
|
/** @inheritDoc */
|
||||||
public static function getConfiguration(): array
|
public static function getConfiguration(Environment $environment): array
|
||||||
{
|
{
|
||||||
static $config = null;
|
static $config = null;
|
||||||
|
|
||||||
|
|
|
@ -125,7 +125,11 @@ class ConfigWriter implements EventSubscriberInterface
|
||||||
$configDir = $station->getRadioConfigDir();
|
$configDir = $station->getRadioConfigDir();
|
||||||
$pidfile = $configDir . DIRECTORY_SEPARATOR . 'liquidsoap.pid';
|
$pidfile = $configDir . DIRECTORY_SEPARATOR . 'liquidsoap.pid';
|
||||||
|
|
||||||
$telnetBindAddr = $this->environment->isDocker() ? '0.0.0.0' : '127.0.0.1';
|
$telnetBindAddr = match (true) {
|
||||||
|
$this->environment->isDockerStandalone() => '127.0.0.1',
|
||||||
|
$this->environment->isDocker() => '0.0.0.0',
|
||||||
|
default => '127.0.0.1',
|
||||||
|
};
|
||||||
$telnetPort = $this->liquidsoap->getTelnetPort($station);
|
$telnetPort = $this->liquidsoap->getTelnetPort($station);
|
||||||
|
|
||||||
$stationTz = self::cleanUpString($station->getTimezone());
|
$stationTz = self::cleanUpString($station->getTimezone());
|
||||||
|
|
|
@ -13,7 +13,8 @@ adduser --home /var/azuracast --disabled-password --gecos "" azuracast
|
||||||
usermod -aG docker_env azuracast
|
usermod -aG docker_env azuracast
|
||||||
usermod -aG www-data azuracast
|
usermod -aG www-data azuracast
|
||||||
|
|
||||||
mkdir -p /var/azuracast/www /var/azuracast/backups /var/azuracast/www_tmp \
|
mkdir -p /var/azuracast/www /var/azuracast/stations /var/azuracast/servers/shoutcast2 \
|
||||||
|
/var/azuracast/backups /var/azuracast/www_tmp \
|
||||||
/var/azuracast/uploads /var/azuracast/geoip /var/azuracast/dbip
|
/var/azuracast/uploads /var/azuracast/geoip /var/azuracast/dbip
|
||||||
|
|
||||||
chown -R azuracast:azuracast /var/azuracast
|
chown -R azuracast:azuracast /var/azuracast
|
|
@ -0,0 +1,16 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
source /bd_build/buildconfig
|
||||||
|
set -x
|
||||||
|
|
||||||
|
chmod -R a+x /usr/local/bin
|
||||||
|
chmod -R +x /etc/my_init.d
|
||||||
|
chmod -R +x /etc/my_init.pre_shutdown.d
|
||||||
|
chmod -R +x /etc/my_init.post_shutdown.d
|
||||||
|
|
||||||
|
ln -s /etc/service.minimal/* /etc/service
|
||||||
|
ln -s /etc/service.full/* /etc/service
|
||||||
|
|
||||||
|
chmod -R +x /etc/service.minimal
|
||||||
|
chmod -R +x /etc/service.full
|
||||||
|
chmod -R +x /etc/service
|
|
@ -67,4 +67,14 @@ chmod 700 /etc/container_environment
|
||||||
groupadd -g 8377 docker_env
|
groupadd -g 8377 docker_env
|
||||||
chown :docker_env /etc/container_environment.sh /etc/container_environment.json
|
chown :docker_env /etc/container_environment.sh /etc/container_environment.json
|
||||||
chmod 640 /etc/container_environment.sh /etc/container_environment.json
|
chmod 640 /etc/container_environment.sh /etc/container_environment.json
|
||||||
ln -s /etc/container_environment.sh /etc/profile.d/
|
ln -s /etc/container_environment.sh /etc/profile.d/
|
||||||
|
|
||||||
|
# Install runit and other common scripts.
|
||||||
|
$minimal_apt_get_install runit gosu curl wget tar zip unzip git rsync tzdata gpg-agent openssh-client
|
||||||
|
|
||||||
|
# Add scripts
|
||||||
|
cp -rT /bd_build/scripts/ /usr/local/bin
|
||||||
|
chmod -R a+x /usr/local/bin
|
||||||
|
|
||||||
|
mkdir -p /etc/service.full/
|
||||||
|
mkdir -p /etc/service.minimal/
|
|
@ -30,41 +30,33 @@ terminated_child_processes = {}
|
||||||
|
|
||||||
_find_unsafe = re.compile(r'[^\w@%+=:,./-]').search
|
_find_unsafe = re.compile(r'[^\w@%+=:,./-]').search
|
||||||
|
|
||||||
|
|
||||||
class AlarmException(Exception):
|
class AlarmException(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def error(message):
|
def error(message):
|
||||||
if log_level >= LOG_LEVEL_ERROR:
|
if log_level >= LOG_LEVEL_ERROR:
|
||||||
sys.stderr.write("*** %s\n" % message)
|
sys.stderr.write("*** %s\n" % message)
|
||||||
|
|
||||||
|
|
||||||
def warn(message):
|
def warn(message):
|
||||||
if log_level >= LOG_LEVEL_WARN:
|
if log_level >= LOG_LEVEL_WARN:
|
||||||
sys.stderr.write("*** %s\n" % message)
|
sys.stderr.write("*** %s\n" % message)
|
||||||
|
|
||||||
|
|
||||||
def info(message):
|
def info(message):
|
||||||
if log_level >= LOG_LEVEL_INFO:
|
if log_level >= LOG_LEVEL_INFO:
|
||||||
sys.stderr.write("*** %s\n" % message)
|
sys.stderr.write("*** %s\n" % message)
|
||||||
|
|
||||||
|
|
||||||
def debug(message):
|
def debug(message):
|
||||||
if log_level >= LOG_LEVEL_DEBUG:
|
if log_level >= LOG_LEVEL_DEBUG:
|
||||||
sys.stderr.write("*** %s\n" % message)
|
sys.stderr.write("*** %s\n" % message)
|
||||||
|
|
||||||
|
|
||||||
def ignore_signals_and_raise_keyboard_interrupt(signame):
|
def ignore_signals_and_raise_keyboard_interrupt(signame):
|
||||||
signal.signal(signal.SIGTERM, signal.SIG_IGN)
|
signal.signal(signal.SIGTERM, signal.SIG_IGN)
|
||||||
signal.signal(signal.SIGINT, signal.SIG_IGN)
|
signal.signal(signal.SIGINT, signal.SIG_IGN)
|
||||||
raise KeyboardInterrupt(signame)
|
raise KeyboardInterrupt(signame)
|
||||||
|
|
||||||
|
|
||||||
def raise_alarm_exception():
|
def raise_alarm_exception():
|
||||||
raise AlarmException('Alarm')
|
raise AlarmException('Alarm')
|
||||||
|
|
||||||
|
|
||||||
def listdir(path):
|
def listdir(path):
|
||||||
try:
|
try:
|
||||||
result = os.stat(path)
|
result = os.stat(path)
|
||||||
|
@ -75,14 +67,12 @@ def listdir(path):
|
||||||
else:
|
else:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
def is_exe(path):
|
def is_exe(path):
|
||||||
try:
|
try:
|
||||||
return os.path.isfile(path) and os.access(path, os.X_OK)
|
return os.path.isfile(path) and os.access(path, os.X_OK)
|
||||||
except OSError:
|
except OSError:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def import_envvars(clear_existing_environment=True, override_existing_environment=True):
|
def import_envvars(clear_existing_environment=True, override_existing_environment=True):
|
||||||
if not os.path.exists("/etc/container_environment"):
|
if not os.path.exists("/etc/container_environment"):
|
||||||
return
|
return
|
||||||
|
@ -101,7 +91,6 @@ def import_envvars(clear_existing_environment=True, override_existing_environmen
|
||||||
if override_existing_environment or name not in os.environ:
|
if override_existing_environment or name not in os.environ:
|
||||||
os.environ[name] = value
|
os.environ[name] = value
|
||||||
|
|
||||||
|
|
||||||
def export_envvars(to_dir=True):
|
def export_envvars(to_dir=True):
|
||||||
if not os.path.exists("/etc/container_environment"):
|
if not os.path.exists("/etc/container_environment"):
|
||||||
return
|
return
|
||||||
|
@ -118,7 +107,6 @@ def export_envvars(to_dir=True):
|
||||||
with open("/etc/container_environment.json", "w") as f:
|
with open("/etc/container_environment.json", "w") as f:
|
||||||
f.write(json.dumps(dict(os.environ)))
|
f.write(json.dumps(dict(os.environ)))
|
||||||
|
|
||||||
|
|
||||||
def shquote(s):
|
def shquote(s):
|
||||||
"""Return a shell-escaped version of the string *s*."""
|
"""Return a shell-escaped version of the string *s*."""
|
||||||
if not s:
|
if not s:
|
||||||
|
@ -130,16 +118,13 @@ def shquote(s):
|
||||||
# the string $'b is then quoted as '$'"'"'b'
|
# the string $'b is then quoted as '$'"'"'b'
|
||||||
return "'" + s.replace("'", "'\"'\"'") + "'"
|
return "'" + s.replace("'", "'\"'\"'") + "'"
|
||||||
|
|
||||||
|
|
||||||
def sanitize_shenvname(s):
|
def sanitize_shenvname(s):
|
||||||
"""Return string with [0-9a-zA-Z_] characters"""
|
"""Return string with [0-9a-zA-Z_] characters"""
|
||||||
return re.sub(SHENV_NAME_WHITELIST_REGEX, "_", s)
|
return re.sub(SHENV_NAME_WHITELIST_REGEX, "_", s)
|
||||||
|
|
||||||
|
|
||||||
# Waits for the child process with the given PID, while at the same time
|
# Waits for the child process with the given PID, while at the same time
|
||||||
# reaping any other child processes that have exited (e.g. adopted child
|
# reaping any other child processes that have exited (e.g. adopted child
|
||||||
# processes that have terminated).
|
# processes that have terminated).
|
||||||
|
|
||||||
def waitpid_reap_other_children(pid):
|
def waitpid_reap_other_children(pid):
|
||||||
global terminated_child_processes
|
global terminated_child_processes
|
||||||
|
|
||||||
|
@ -172,7 +157,6 @@ def waitpid_reap_other_children(pid):
|
||||||
raise
|
raise
|
||||||
return status
|
return status
|
||||||
|
|
||||||
|
|
||||||
def stop_child_process(name, pid, signo=signal.SIGTERM, time_limit=KILL_PROCESS_TIMEOUT):
|
def stop_child_process(name, pid, signo=signal.SIGTERM, time_limit=KILL_PROCESS_TIMEOUT):
|
||||||
info("Shutting down %s (PID %d)..." % (name, pid))
|
info("Shutting down %s (PID %d)..." % (name, pid))
|
||||||
try:
|
try:
|
||||||
|
@ -198,7 +182,6 @@ def stop_child_process(name, pid, signo=signal.SIGTERM, time_limit=KILL_PROCESS_
|
||||||
finally:
|
finally:
|
||||||
signal.alarm(0)
|
signal.alarm(0)
|
||||||
|
|
||||||
|
|
||||||
def run_command_killable(*argv):
|
def run_command_killable(*argv):
|
||||||
filename = argv[0]
|
filename = argv[0]
|
||||||
status = None
|
status = None
|
||||||
|
@ -216,13 +199,11 @@ def run_command_killable(*argv):
|
||||||
error("%s failed with status %d\n" % (filename, os.WEXITSTATUS(status)))
|
error("%s failed with status %d\n" % (filename, os.WEXITSTATUS(status)))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
def run_command_killable_and_import_envvars(*argv):
|
def run_command_killable_and_import_envvars(*argv):
|
||||||
run_command_killable(*argv)
|
run_command_killable(*argv)
|
||||||
import_envvars()
|
import_envvars()
|
||||||
export_envvars(False)
|
export_envvars(False)
|
||||||
|
|
||||||
|
|
||||||
def kill_all_processes(time_limit):
|
def kill_all_processes(time_limit):
|
||||||
info("Killing all processes...")
|
info("Killing all processes...")
|
||||||
try:
|
try:
|
||||||
|
@ -264,7 +245,6 @@ def run_startup_files():
|
||||||
info("Running /etc/rc.local...")
|
info("Running /etc/rc.local...")
|
||||||
run_command_killable_and_import_envvars("/etc/rc.local")
|
run_command_killable_and_import_envvars("/etc/rc.local")
|
||||||
|
|
||||||
|
|
||||||
def run_pre_shutdown_scripts():
|
def run_pre_shutdown_scripts():
|
||||||
debug("Running pre-shutdown scripts...")
|
debug("Running pre-shutdown scripts...")
|
||||||
|
|
||||||
|
@ -275,7 +255,6 @@ def run_pre_shutdown_scripts():
|
||||||
info("Running %s..." % filename)
|
info("Running %s..." % filename)
|
||||||
run_command_killable(filename)
|
run_command_killable(filename)
|
||||||
|
|
||||||
|
|
||||||
def run_post_shutdown_scripts():
|
def run_post_shutdown_scripts():
|
||||||
debug("Running post-shutdown scripts...")
|
debug("Running post-shutdown scripts...")
|
||||||
|
|
||||||
|
@ -286,31 +265,26 @@ def run_post_shutdown_scripts():
|
||||||
info("Running %s..." % filename)
|
info("Running %s..." % filename)
|
||||||
run_command_killable(filename)
|
run_command_killable(filename)
|
||||||
|
|
||||||
|
def start_runit(runit_services_dir):
|
||||||
def start_runit():
|
|
||||||
info("Booting runit daemon...")
|
info("Booting runit daemon...")
|
||||||
pid = os.spawnl(os.P_NOWAIT, "/usr/bin/runsvdir", "/usr/bin/runsvdir",
|
pid = os.spawnl(os.P_NOWAIT, "/usr/bin/runsvdir", "/usr/bin/runsvdir", "-P", runit_services_dir)
|
||||||
"-P", "/etc/service")
|
|
||||||
info("Runit started as PID %d" % pid)
|
info("Runit started as PID %d" % pid)
|
||||||
return pid
|
return pid
|
||||||
|
|
||||||
|
|
||||||
def wait_for_runit_or_interrupt(pid):
|
def wait_for_runit_or_interrupt(pid):
|
||||||
status = waitpid_reap_other_children(pid)
|
status = waitpid_reap_other_children(pid)
|
||||||
return (True, status)
|
return (True, status)
|
||||||
|
|
||||||
|
def shutdown_runit_services(runit_services_dir, quiet=False):
|
||||||
def shutdown_runit_services(quiet=False):
|
|
||||||
if not quiet:
|
if not quiet:
|
||||||
debug("Begin shutting down runit services...")
|
debug("Begin shutting down runit services...")
|
||||||
os.system("/usr/bin/sv -w %d force-stop /etc/service/* > /dev/null" % KILL_PROCESS_TIMEOUT)
|
os.system("/usr/bin/sv -w %d force-stop %s/* > /dev/null" % (KILL_PROCESS_TIMEOUT, runit_services_dir))
|
||||||
|
|
||||||
|
def wait_for_runit_services(runit_services_dir):
|
||||||
def wait_for_runit_services():
|
|
||||||
debug("Waiting for runit services to exit...")
|
debug("Waiting for runit services to exit...")
|
||||||
done = False
|
done = False
|
||||||
while not done:
|
while not done:
|
||||||
done = os.system("/usr/bin/sv status /etc/service/* | grep -q '^run:'") != 0
|
done = os.system("/usr/bin/sv status %s/* | grep -q '^run:'" % runit_services_dir) != 0
|
||||||
if not done:
|
if not done:
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
# According to https://github.com/phusion/baseimage-docker/issues/315
|
# According to https://github.com/phusion/baseimage-docker/issues/315
|
||||||
|
@ -318,32 +292,28 @@ def wait_for_runit_services():
|
||||||
# not to shutdown services that are already being started.
|
# not to shutdown services that are already being started.
|
||||||
# So during shutdown we repeatedly instruct Runit to shutdown
|
# So during shutdown we repeatedly instruct Runit to shutdown
|
||||||
# services.
|
# services.
|
||||||
shutdown_runit_services(True)
|
shutdown_runit_services(runit_services_dir, True)
|
||||||
|
|
||||||
|
|
||||||
def install_insecure_key():
|
|
||||||
info("Installing insecure SSH key for user root")
|
|
||||||
run_command_killable("/usr/sbin/enable_insecure_key")
|
|
||||||
|
|
||||||
|
|
||||||
def main(args):
|
def main(args):
|
||||||
import_envvars(False, False)
|
import_envvars(False, False)
|
||||||
export_envvars()
|
export_envvars()
|
||||||
|
|
||||||
if args.enable_insecure_key:
|
|
||||||
install_insecure_key()
|
|
||||||
|
|
||||||
if not args.skip_startup_files:
|
if not args.skip_startup_files:
|
||||||
run_startup_files()
|
run_startup_files()
|
||||||
|
|
||||||
runit_exited = False
|
runit_exited = False
|
||||||
exit_code = None
|
exit_code = None
|
||||||
|
|
||||||
if not args.skip_runit:
|
if not args.skip_runit:
|
||||||
runit_pid = start_runit()
|
runit_services_dir = '/etc/service.minimal'
|
||||||
|
if len(args.main_command) == 0 or args.no_main_command:
|
||||||
|
runit_services_dir = '/etc/service'
|
||||||
|
|
||||||
|
runit_pid = start_runit(runit_services_dir)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
exit_status = None
|
exit_status = None
|
||||||
if len(args.main_command) == 0:
|
if len(args.main_command) == 0 or args.no_main_command:
|
||||||
runit_exited, exit_code = wait_for_runit_or_interrupt(runit_pid)
|
runit_exited, exit_code = wait_for_runit_or_interrupt(runit_pid)
|
||||||
if runit_exited:
|
if runit_exited:
|
||||||
if exit_code is None:
|
if exit_code is None:
|
||||||
|
@ -353,52 +323,63 @@ def main(args):
|
||||||
exit_status = os.WEXITSTATUS(exit_code)
|
exit_status = os.WEXITSTATUS(exit_code)
|
||||||
info("Runit exited with status %d" % exit_status)
|
info("Runit exited with status %d" % exit_status)
|
||||||
else:
|
else:
|
||||||
info("Running %s..." % " ".join(args.main_command))
|
main_command = ["uptime_wait"] + args.main_command
|
||||||
pid = os.spawnvp(os.P_NOWAIT, args.main_command[0], args.main_command)
|
|
||||||
|
info("Running %s..." % " ".join(main_command))
|
||||||
|
pid = os.spawnvp(os.P_NOWAIT, main_command[0], main_command)
|
||||||
try:
|
try:
|
||||||
exit_code = waitpid_reap_other_children(pid)
|
exit_code = waitpid_reap_other_children(pid)
|
||||||
if exit_code is None:
|
if exit_code is None:
|
||||||
info("%s exited with unknown status." % args.main_command[0])
|
info("%s exited with unknown status." % main_command[0])
|
||||||
exit_status = 1
|
exit_status = 1
|
||||||
else:
|
else:
|
||||||
exit_status = os.WEXITSTATUS(exit_code)
|
exit_status = os.WEXITSTATUS(exit_code)
|
||||||
info("%s exited with status %d." % (args.main_command[0], exit_status))
|
info("%s exited with status %d." % (main_command[0], exit_status))
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
stop_child_process(args.main_command[0], pid)
|
stop_child_process(main_command[0], pid)
|
||||||
raise
|
raise
|
||||||
except BaseException:
|
except BaseException:
|
||||||
warn("An error occurred. Aborting.")
|
warn("An error occurred. Aborting.")
|
||||||
stop_child_process(args.main_command[0], pid)
|
stop_child_process(main_command[0], pid)
|
||||||
raise
|
raise
|
||||||
sys.exit(exit_status)
|
sys.exit(exit_status)
|
||||||
finally:
|
finally:
|
||||||
if not args.skip_runit:
|
if not args.skip_runit:
|
||||||
run_pre_shutdown_scripts()
|
run_pre_shutdown_scripts()
|
||||||
shutdown_runit_services()
|
shutdown_runit_services(runit_services_dir)
|
||||||
|
|
||||||
if not runit_exited:
|
if not runit_exited:
|
||||||
stop_child_process("runit daemon", runit_pid)
|
stop_child_process("runit daemon", runit_pid)
|
||||||
wait_for_runit_services()
|
|
||||||
|
wait_for_runit_services(runit_services_dir)
|
||||||
run_post_shutdown_scripts()
|
run_post_shutdown_scripts()
|
||||||
|
|
||||||
# Parse options.
|
# Parse options.
|
||||||
parser = argparse.ArgumentParser(description='Initialize the system.')
|
parser = argparse.ArgumentParser(description='Initialize the system.')
|
||||||
|
|
||||||
parser.add_argument('main_command', metavar='MAIN_COMMAND', type=str, nargs='*',
|
parser.add_argument('main_command', metavar='MAIN_COMMAND', type=str, nargs='*',
|
||||||
help='The main command to run. (default: runit)')
|
help='The main command to run. (default: runit)')
|
||||||
parser.add_argument('--enable-insecure-key', dest='enable_insecure_key',
|
|
||||||
|
parser.add_argument('--no-main-command', dest='no_main_command',
|
||||||
action='store_const', const=True, default=False,
|
action='store_const', const=True, default=False,
|
||||||
help='Install the insecure SSH key')
|
help='Flag to provide as main command in the absence of one.')
|
||||||
|
|
||||||
parser.add_argument('--skip-startup-files', dest='skip_startup_files',
|
parser.add_argument('--skip-startup-files', dest='skip_startup_files',
|
||||||
action='store_const', const=True, default=False,
|
action='store_const', const=True, default=False,
|
||||||
help='Skip running /etc/my_init.d/* and /etc/rc.local')
|
help='Skip running /etc/my_init.d/* and /etc/rc.local')
|
||||||
|
|
||||||
parser.add_argument('--skip-runit', dest='skip_runit',
|
parser.add_argument('--skip-runit', dest='skip_runit',
|
||||||
action='store_const', const=True, default=False,
|
action='store_const', const=True, default=False,
|
||||||
help='Do not run runit services')
|
help='Do not run runit services')
|
||||||
|
|
||||||
parser.add_argument('--no-kill-all-on-exit', dest='kill_all_on_exit',
|
parser.add_argument('--no-kill-all-on-exit', dest='kill_all_on_exit',
|
||||||
action='store_const', const=False, default=True,
|
action='store_const', const=False, default=True,
|
||||||
help='Don\'t kill all processes on the system upon exiting')
|
help='Don\'t kill all processes on the system upon exiting')
|
||||||
|
|
||||||
parser.add_argument('--quiet', dest='log_level',
|
parser.add_argument('--quiet', dest='log_level',
|
||||||
action='store_const', const=LOG_LEVEL_WARN, default=LOG_LEVEL_INFO,
|
action='store_const', const=LOG_LEVEL_WARN, default=LOG_LEVEL_INFO,
|
||||||
help='Only print warnings and errors')
|
help='Only print warnings and errors')
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
log_level = args.log_level
|
log_level = args.log_level
|
||||||
|
|
||||||
|
@ -410,6 +391,7 @@ if args.skip_runit and len(args.main_command) == 0:
|
||||||
signal.signal(signal.SIGTERM, lambda signum, frame: ignore_signals_and_raise_keyboard_interrupt('SIGTERM'))
|
signal.signal(signal.SIGTERM, lambda signum, frame: ignore_signals_and_raise_keyboard_interrupt('SIGTERM'))
|
||||||
signal.signal(signal.SIGINT, lambda signum, frame: ignore_signals_and_raise_keyboard_interrupt('SIGINT'))
|
signal.signal(signal.SIGINT, lambda signum, frame: ignore_signals_and_raise_keyboard_interrupt('SIGINT'))
|
||||||
signal.signal(signal.SIGALRM, lambda signum, frame: raise_alarm_exception())
|
signal.signal(signal.SIGALRM, lambda signum, frame: raise_alarm_exception())
|
||||||
|
|
||||||
try:
|
try:
|
||||||
main(args)
|
main(args)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
|
@ -417,4 +399,4 @@ except KeyboardInterrupt:
|
||||||
exit(2)
|
exit(2)
|
||||||
finally:
|
finally:
|
||||||
if args.kill_all_on_exit:
|
if args.kill_all_on_exit:
|
||||||
kill_all_processes(KILL_ALL_PROCESSES_TIMEOUT)
|
kill_all_processes(KILL_ALL_PROCESSES_TIMEOUT)
|
|
@ -0,0 +1,11 @@
|
||||||
|
[mysqld]
|
||||||
|
character-set-server=utf8mb4
|
||||||
|
|
||||||
|
slow_query_log = {{ default .Env.MYSQL_SLOW_QUERY_LOG "0" }}
|
||||||
|
slow_query_log_file = /var/log/mysql/slow.log
|
||||||
|
long_query_time = 0.2
|
||||||
|
|
||||||
|
max_connections = {{ default .Env.MYSQL_MAX_CONNECTIONS "100" }}
|
||||||
|
|
||||||
|
[client]
|
||||||
|
default-character-set=utf8mb4
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,7 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
MYSQL_USER="${MYSQL_USER:-azuracast}"
|
||||||
|
MYSQL_PASSWORD="${MYSQL_PASSWORD:-azur4c457}"
|
||||||
|
MYSQL_DATABASE="${MYSQL_DATABASE:-azuracast}"
|
||||||
|
|
||||||
|
exec gosu mysql mysql -u${MYSQL_USER} -p${MYSQL_PASSWORD} -D ${MYSQL_DATABASE}
|
|
@ -0,0 +1,7 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
MYSQL_USER="${MYSQL_USER:-azuracast}"
|
||||||
|
MYSQL_PASSWORD="${MYSQL_PASSWORD:-azur4c457}"
|
||||||
|
MYSQL_DATABASE="${MYSQL_DATABASE:-azuracast}"
|
||||||
|
|
||||||
|
cat $1 | mysql -u${MYSQL_USER} -p${MYSQL_PASSWORD} -D ${MYSQL_DATABASE}
|
|
@ -0,0 +1,124 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
if [ "$(id -u)" = "0" ]; then
|
||||||
|
echo "Switching to dedicated user 'mysql'"
|
||||||
|
exec gosu mysql "$BASH_SOURCE" "$@"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# usage: file_env VAR [DEFAULT]
|
||||||
|
# ie: file_env 'XYZ_DB_PASSWORD' 'example'
|
||||||
|
# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of
|
||||||
|
# "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature)
|
||||||
|
file_env() {
|
||||||
|
local var="$1"
|
||||||
|
local fileVar="${var}_FILE"
|
||||||
|
local def="${2:-}"
|
||||||
|
if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then
|
||||||
|
mysql_error "Both $var and $fileVar are set (but are exclusive)"
|
||||||
|
fi
|
||||||
|
local val="$def"
|
||||||
|
if [ "${!var:-}" ]; then
|
||||||
|
val="${!var}"
|
||||||
|
elif [ "${!fileVar:-}" ]; then
|
||||||
|
val="$(< "${!fileVar}")"
|
||||||
|
fi
|
||||||
|
export "$var"="$val"
|
||||||
|
unset "$fileVar"
|
||||||
|
}
|
||||||
|
|
||||||
|
# set MARIADB_xyz from MYSQL_xyz when MARIADB_xyz is unset
|
||||||
|
# and make them the same value (so user scripts can use either)
|
||||||
|
_mariadb_file_env() {
|
||||||
|
local var="$1"; shift
|
||||||
|
local maria="MARIADB_${var#MYSQL_}"
|
||||||
|
file_env "$var" "$@"
|
||||||
|
file_env "$maria" "${!var}"
|
||||||
|
if [ "${!maria:-}" ]; then
|
||||||
|
export "$var"="${!maria}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# SQL escape the string $1 to be placed in a string literal.
|
||||||
|
# escape, \ followed by '
|
||||||
|
docker_sql_escape_string_literal() {
|
||||||
|
local newline=$'\n'
|
||||||
|
local escaped=${1//\\/\\\\}
|
||||||
|
escaped="${escaped//$newline/\\n}"
|
||||||
|
echo "${escaped//\'/\\\'}"
|
||||||
|
}
|
||||||
|
|
||||||
|
mysql_get_config() {
|
||||||
|
local conf="$1"; shift
|
||||||
|
mysqld --verbose --help 2>/dev/null \
|
||||||
|
| awk -v conf="$conf" '$1 == conf && /^[^ \t]/ { sub(/^[^ \t]+[ \t]+/, ""); print; exit }'
|
||||||
|
}
|
||||||
|
|
||||||
|
# Build env vars
|
||||||
|
DATADIR="$(mysql_get_config 'datadir')"
|
||||||
|
SOCKET="$(mysql_get_config 'socket')"
|
||||||
|
|
||||||
|
_mariadb_file_env 'MYSQL_ROOT_HOST' '%'
|
||||||
|
_mariadb_file_env 'MYSQL_ROOT_PASSWORD'
|
||||||
|
|
||||||
|
: "${MARIADB_ALLOW_EMPTY_ROOT_PASSWORD:=${MYSQL_ALLOW_EMPTY_PASSWORD:-}}"
|
||||||
|
export MYSQL_ALLOW_EMPTY_PASSWORD="$MARIADB_ALLOW_EMPTY_ROOT_PASSWORD" MARIADB_ALLOW_EMPTY_ROOT_PASSWORD
|
||||||
|
: "${MARIADB_RANDOM_ROOT_PASSWORD:=${MYSQL_RANDOM_ROOT_PASSWORD:-}}"
|
||||||
|
export MYSQL_RANDOM_ROOT_PASSWORD="$MARIADB_RANDOM_ROOT_PASSWORD" MARIADB_RANDOM_ROOT_PASSWORD
|
||||||
|
: "${MARIADB_INITDB_SKIP_TZINFO:=${MYSQL_INITDB_SKIP_TZINFO:-}}"
|
||||||
|
export MYSQL_INITDB_SKIP_TZINFO="$MARIADB_INITDB_SKIP_TZINFO" MARIADB_INITDB_SKIP_TZINFO
|
||||||
|
|
||||||
|
if [ -z "$MARIADB_ROOT_PASSWORD" -a -z "$MARIADB_ALLOW_EMPTY_ROOT_PASSWORD" -a -z "$MARIADB_RANDOM_ROOT_PASSWORD" ]; then
|
||||||
|
mysql_error $'Database is uninitialized and password option is not specified\n\tYou need to specify one of MARIADB_ROOT_PASSWORD, MARIADB_ALLOW_EMPTY_ROOT_PASSWORD and MARIADB_RANDOM_ROOT_PASSWORD'
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Spin up temp server
|
||||||
|
echo "Starting temporary MariaDB server..."
|
||||||
|
|
||||||
|
mysqld --skip-networking --skip-grant-tables --socket="${SOCKET}" &
|
||||||
|
|
||||||
|
echo "Waiting for server startup"
|
||||||
|
for i in {30..0}; do
|
||||||
|
if mysql --protocol=socket -hlocalhost -uroot --socket="${SOCKET}" --database=mysql <<<'SELECT 1'; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
if [ "$i" = 0 ]; then
|
||||||
|
echo "Unable to start temporary server."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Try password reset
|
||||||
|
echo "Resetting root password..."
|
||||||
|
|
||||||
|
if [ -n "$MARIADB_RANDOM_ROOT_PASSWORD" ]; then
|
||||||
|
MARIADB_ROOT_PASSWORD="$(pwgen --numerals --capitalize --symbols --remove-chars="'\\" -1 32)"
|
||||||
|
export MARIADB_ROOT_PASSWORD MYSQL_ROOT_PASSWORD=$MARIADB_ROOT_PASSWORD
|
||||||
|
echo "GENERATED ROOT PASSWORD: $MARIADB_ROOT_PASSWORD"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Sets root password and creates root users for non-localhost hosts
|
||||||
|
rootCreate=
|
||||||
|
rootPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_ROOT_PASSWORD}" )
|
||||||
|
|
||||||
|
# default root to listen for connections from anywhere
|
||||||
|
if [ -n "$MARIADB_ROOT_HOST" ] && [ "$MARIADB_ROOT_HOST" != 'localhost' ]; then
|
||||||
|
# no, we don't care if read finds a terminating character in this heredoc
|
||||||
|
# https://unix.stackexchange.com/questions/265149/why-is-set-o-errexit-breaking-this-read-heredoc-expression/265151#265151
|
||||||
|
read -r -d '' rootCreate <<-EOSQL || true
|
||||||
|
ALTER USER 'root'@'${MARIADB_ROOT_HOST}' IDENTIFIED BY '${rootPasswordEscaped}' ;
|
||||||
|
GRANT ALL ON *.* TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION ;
|
||||||
|
EOSQL
|
||||||
|
fi
|
||||||
|
|
||||||
|
# tell docker_process_sql to not use MARIADB_ROOT_PASSWORD since it is just now being set
|
||||||
|
# --binary-mode to save us from the semi-mad users go out of their way to confuse the encoding.
|
||||||
|
mysql --protocol=socket -uroot -hlocalhost --socket="${SOCKET}" --database=mysql --binary-mode <<-EOSQL
|
||||||
|
FLUSH PRIVILEGES ;
|
||||||
|
ALTER USER 'root'@'localhost' IDENTIFIED BY '${rootPasswordEscaped}' ;
|
||||||
|
GRANT ALL ON *.* TO 'root'@'localhost' WITH GRANT OPTION ;
|
||||||
|
|
||||||
|
${rootCreate}
|
||||||
|
EOSQL
|
||||||
|
|
||||||
|
echo "Password reset complete."
|
|
@ -0,0 +1,9 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
if [ ${MYSQL_SLOW_QUERY_LOG} != 1 ]; then
|
||||||
|
echo "MariaDB Slow Query Log is not currently enabled on this instance."
|
||||||
|
echo "Set MYSQL_SLOW_QUERY_LOG=1 in your environment variables (azuracast.env), then restart to enable."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
exec gosu mysql mysqldumpslow /var/log/mysql/slow.log
|
|
@ -0,0 +1,37 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
if [ "$(id -u)" = "0" ]; then
|
||||||
|
echo "Switching to dedicated user 'mysql'"
|
||||||
|
exec gosu mysql "$BASH_SOURCE" "$@"
|
||||||
|
fi
|
||||||
|
|
||||||
|
mysql_get_config() {
|
||||||
|
local conf="$1"; shift
|
||||||
|
mysqld --verbose --help 2>/dev/null \
|
||||||
|
| awk -v conf="$conf" '$1 == conf && /^[^ \t]/ { sub(/^[^ \t]+[ \t]+/, ""); print; exit }'
|
||||||
|
}
|
||||||
|
|
||||||
|
DATADIR="$(mysql_get_config 'datadir')"
|
||||||
|
SOCKET="$(mysql_get_config 'socket')"
|
||||||
|
|
||||||
|
echo "Starting temporary MariaDB server..."
|
||||||
|
|
||||||
|
mysqld --skip-networking --skip-grant-tables --socket="${SOCKET}" &
|
||||||
|
|
||||||
|
echo "Waiting for server startup"
|
||||||
|
for i in {30..0}; do
|
||||||
|
if mysql --protocol=socket -hlocalhost -uroot --socket="${SOCKET}" --database=mysql <<<'SELECT 1'; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
if [ "$i" = 0 ]; then
|
||||||
|
echo "Unable to start temporary server."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Upgrading instance (if necessary)..."
|
||||||
|
|
||||||
|
mariadb-upgrade --verbose --protocol=socket -hlocalhost -uroot --socket="${SOCKET}"
|
||||||
|
|
||||||
|
echo "Upgrade complete; Shutting down temporary MariaDB server..."
|
|
@ -0,0 +1,3 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
exec mysqladmin ping -h localhost
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
dockerize -template /etc/mysql/db.cnf.tmpl:/etc/mysql/conf.d/db.cnf
|
||||||
|
|
||||||
|
exec gosu mysql mysqld
|
|
@ -0,0 +1,20 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
source /bd_build/buildconfig
|
||||||
|
set -x
|
||||||
|
|
||||||
|
apt-get update
|
||||||
|
|
||||||
|
# Install common scripts
|
||||||
|
cp -rT /bd_build/mariadb/scripts/ /usr/local/bin
|
||||||
|
|
||||||
|
cp -rT /bd_build/mariadb/startup_scripts/. /etc/my_init.d/
|
||||||
|
|
||||||
|
cp -rT /bd_build/mariadb/service.minimal/. /etc/service.minimal/
|
||||||
|
|
||||||
|
# cp -rT /bd_build/mariadb/service.full/. /etc/service.full/
|
||||||
|
|
||||||
|
# Run service setup for all setup scripts
|
||||||
|
for f in /bd_build/mariadb/setup/*.sh; do
|
||||||
|
bash "$f" -H
|
||||||
|
done
|
|
@ -0,0 +1,14 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
source /bd_build/buildconfig
|
||||||
|
set -x
|
||||||
|
|
||||||
|
$minimal_apt_get_install tzdata
|
||||||
|
|
||||||
|
echo "1" >> /etc/container_environment/MARIADB_AUTO_UPGRADE
|
||||||
|
|
||||||
|
cp /bd_build/mariadb/mariadb/db.sql /docker-entrypoint-initdb.d/00-azuracast.sql
|
||||||
|
cp /bd_build/mariadb/mariadb/db.cnf.tmpl /etc/mysql/db.cnf.tmpl
|
||||||
|
|
||||||
|
mv /usr/local/bin/healthcheck.sh /usr/local/bin/db_healthcheck.sh
|
||||||
|
mv /usr/local/bin/docker-entrypoint.sh /usr/local/bin/db_entrypoint.sh
|
|
@ -0,0 +1,9 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# If the MariaDB host is anything but localhost, disable MariaDB on this container.
|
||||||
|
if [ "$MYSQL_HOST" != "localhost" ]; then
|
||||||
|
echo "MariaDB host is not localhost; disabling MariaDB..."
|
||||||
|
|
||||||
|
rm -rf /etc/service/mariadb
|
||||||
|
rm -rf /etc/service.minimal/mariadb
|
||||||
|
fi
|
|
@ -0,0 +1,52 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
if [ ! -f /etc/service/mariadb/run ]; then
|
||||||
|
echo "MariaDB disabled. Skipping DB initialization..."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
source /usr/local/bin/db_entrypoint.sh
|
||||||
|
|
||||||
|
set -- mysqld
|
||||||
|
|
||||||
|
mysql_note "Initial DB setup..."
|
||||||
|
|
||||||
|
mysql_check_config "$@"
|
||||||
|
# Load various environment variables
|
||||||
|
docker_setup_env "$@"
|
||||||
|
docker_create_db_directories
|
||||||
|
|
||||||
|
# If container is started as root user, restart as dedicated mysql user
|
||||||
|
if [ "$(id -u)" = "0" ]; then
|
||||||
|
mysql_note "Switching to dedicated user 'mysql'"
|
||||||
|
exec gosu mysql "${BASH_SOURCE[0]}" "$@"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# there's no database, so it needs to be initialized
|
||||||
|
if [ -z "$DATABASE_ALREADY_EXISTS" ]; then
|
||||||
|
docker_verify_minimum_env
|
||||||
|
|
||||||
|
# check dir permissions to reduce likelihood of half-initialized database
|
||||||
|
ls /docker-entrypoint-initdb.d/ > /dev/null
|
||||||
|
|
||||||
|
docker_init_database_dir "$@"
|
||||||
|
|
||||||
|
mysql_note "Starting temporary server"
|
||||||
|
docker_temp_server_start "$@"
|
||||||
|
mysql_note "Temporary server started."
|
||||||
|
|
||||||
|
docker_setup_db
|
||||||
|
docker_process_init_files /docker-entrypoint-initdb.d/*
|
||||||
|
|
||||||
|
mysql_note "Stopping temporary server"
|
||||||
|
docker_temp_server_stop
|
||||||
|
mysql_note "Temporary server stopped"
|
||||||
|
|
||||||
|
echo
|
||||||
|
mysql_note "MariaDB init process done. Ready for start up."
|
||||||
|
echo
|
||||||
|
# MDEV-27636 mariadb_upgrade --check-if-upgrade-is-needed cannot be run offline
|
||||||
|
#elif mysql_upgrade --check-if-upgrade-is-needed; then
|
||||||
|
elif _check_if_upgrade_is_needed; then
|
||||||
|
docker_mariadb_upgrade "$@"
|
||||||
|
fi
|
|
@ -0,0 +1,6 @@
|
||||||
|
save ""
|
||||||
|
|
||||||
|
appendonly no
|
||||||
|
|
||||||
|
maxmemory 128mb
|
||||||
|
maxmemory-policy volatile-lfu
|
|
@ -0,0 +1,3 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
exec gosu redis redis-server /etc/redis/redis.conf
|
|
@ -0,0 +1,20 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
source /bd_build/buildconfig
|
||||||
|
set -x
|
||||||
|
|
||||||
|
apt-get update
|
||||||
|
|
||||||
|
# Install common scripts
|
||||||
|
# cp -rT /bd_build/redis/scripts/ /usr/local/bin
|
||||||
|
|
||||||
|
cp -rT /bd_build/redis/startup_scripts/. /etc/my_init.d/
|
||||||
|
|
||||||
|
cp -rT /bd_build/redis/service.minimal/. /etc/service.minimal/
|
||||||
|
|
||||||
|
# cp -rT /bd_build/redis/service.full/. /etc/service.full/
|
||||||
|
|
||||||
|
# Run service setup for all setup scripts
|
||||||
|
for f in /bd_build/redis/setup/*.sh; do
|
||||||
|
bash "$f" -H
|
||||||
|
done
|
|
@ -0,0 +1,12 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
source /bd_build/buildconfig
|
||||||
|
set -x
|
||||||
|
|
||||||
|
add-apt-repository -y ppa:chris-lea/redis-server
|
||||||
|
apt-get update
|
||||||
|
|
||||||
|
$minimal_apt_get_install redis-server
|
||||||
|
|
||||||
|
cp /bd_build/redis/redis/redis.conf /etc/redis/redis.conf
|
||||||
|
chown redis:redis /etc/redis/redis.conf
|
|
@ -0,0 +1,17 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
bool() {
|
||||||
|
case "$1" in
|
||||||
|
Y* | y* | true | TRUE | 1) return 0 ;;
|
||||||
|
esac
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# If Redis is expressly disabled or the host is anything but localhost, disable Redis on this container.
|
||||||
|
ENABLE_REDIS=${ENABLE_REDIS:-false}
|
||||||
|
|
||||||
|
if [ "$REDIS_HOST" != "localhost" ] || [ bool "$ENABLE_REDIS" ]; then
|
||||||
|
echo "Redis is disabled or host is not localhost; disabling Redis..."
|
||||||
|
rm -rf /etc/service/redis
|
||||||
|
rm -rf /etc/service.minimal/redis
|
||||||
|
fi
|
|
@ -0,0 +1,26 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
set -x
|
||||||
|
|
||||||
|
opam init --disable-sandboxing -a --bare && opam switch create 4.13.1
|
||||||
|
|
||||||
|
# Pin specific commit of Liquidsoap
|
||||||
|
opam pin add --no-action liquidsoap https://github.com/savonet/liquidsoap.git#af311dc8ee57e3e7d3f637ea23af4096fd57820d
|
||||||
|
|
||||||
|
opam install -y ladspa.0.2.2 ffmpeg.1.1.1 ffmpeg-avutil.1.1.1 ffmpeg-avcodec.1.1.1 ffmpeg-avdevice.1.1.1 \
|
||||||
|
ffmpeg-av.1.1.1 ffmpeg-avfilter.1.1.1 ffmpeg-swresample.1.1.1 ffmpeg-swscale.1.1.1 frei0r.0.1.2 \
|
||||||
|
samplerate.0.1.6 taglib.0.3.9 mad.0.5.2 faad.0.5.0 fdkaac.0.3.2 lame.0.3.5 vorbis.0.8.0 cry.0.6.6 \
|
||||||
|
flac.0.3.0 opus.0.2.1 dtools.0.4.4 duppy.0.9.2 ocurl.0.9.2 ssl.0.5.10 \
|
||||||
|
liquidsoap
|
||||||
|
|
||||||
|
# Have Liquidsoap build its own chroot.
|
||||||
|
mkdir -p /tmp/liquidsoap
|
||||||
|
|
||||||
|
/var/azuracast/.opam/4.13.1/bin/liquidsoap /bd_build/liquidsoap/build_chroot.liq || true
|
||||||
|
|
||||||
|
# Clear entire OPAM directory
|
||||||
|
rm -rf /var/azuracast/.opam
|
||||||
|
|
||||||
|
cp -r /tmp/liquidsoap/var/azuracast/.opam /var/azuracast/.opam
|
||||||
|
rm -rf /tmp/liquidsoap
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
liquidsoap.chroot.make('/tmp/liquidsoap')
|
||||||
|
shutdown()
|
|
@ -0,0 +1,3 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
exec /usr/bin/supervisord -c /etc/supervisor/supervisord.conf
|
|
@ -0,0 +1,20 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
source /bd_build/buildconfig
|
||||||
|
set -x
|
||||||
|
|
||||||
|
apt-get update
|
||||||
|
|
||||||
|
# Install common scripts
|
||||||
|
# cp -rT /bd_build/stations/scripts/ /usr/local/bin
|
||||||
|
|
||||||
|
# cp -rT /bd_build/stations/startup_scripts/. /etc/my_init.d/
|
||||||
|
|
||||||
|
cp -rT /bd_build/stations/service.minimal/. /etc/service.minimal/
|
||||||
|
|
||||||
|
# cp -rT /bd_build/stations/service.full/. /etc/service.full/
|
||||||
|
|
||||||
|
# Run service setup for all setup scripts
|
||||||
|
for f in /bd_build/stations/setup/*.sh; do
|
||||||
|
bash "$f" -H
|
||||||
|
done
|
|
@ -0,0 +1,10 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
source /bd_build/buildconfig
|
||||||
|
set -x
|
||||||
|
|
||||||
|
# Only install Icecast deps (Icecast is handled by another container).
|
||||||
|
$minimal_apt_get_install libxml2 libxslt1-dev libvorbis-dev
|
||||||
|
|
||||||
|
# SSL self-signed cert generation
|
||||||
|
$minimal_apt_get_install openssl
|
|
@ -0,0 +1,40 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
source /bd_build/buildconfig
|
||||||
|
set -x
|
||||||
|
|
||||||
|
# Packages required by Liquidsoap
|
||||||
|
$minimal_apt_get_install libao-dev libasound2-dev libavcodec-dev libavdevice-dev libavfilter-dev libavformat-dev \
|
||||||
|
libavutil-dev libfaad-dev libfdk-aac-dev libflac-dev libfreetype-dev libgd-dev libjack-dev \
|
||||||
|
libjpeg-dev liblo-dev libmad0-dev libmagic-dev libmp3lame-dev libopus-dev libpng-dev libportaudio2 \
|
||||||
|
libpulse-dev libsamplerate0-dev libsdl2-dev libsdl2-ttf-dev libsdl2-image-dev libshine-dev libsoundtouch-dev libspeex-dev \
|
||||||
|
libsrt-dev libswresample-dev libswscale-dev libtag1-dev libtheora-dev libtiff-dev libx11-dev libxpm-dev bubblewrap ffmpeg
|
||||||
|
|
||||||
|
# Optional audio plugins
|
||||||
|
$minimal_apt_get_install frei0r-plugins-dev ladspa-sdk multimedia-audio-plugins swh-plugins tap-plugins lsp-plugins-ladspa
|
||||||
|
|
||||||
|
# Per-architecture LS installs
|
||||||
|
ARCHITECTURE=amd64
|
||||||
|
|
||||||
|
if [ "$(uname -m)" = "aarch64" ]; then
|
||||||
|
ARCHITECTURE=arm64
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Adding this comment to trigger an uncached re-pull of this deb file.
|
||||||
|
|
||||||
|
wget -O /tmp/liquidsoap.deb "https://github.com/savonet/liquidsoap/releases/download/v2.0.3/liquidsoap_2.0.3-ubuntu-focal-2_${ARCHITECTURE}.deb"
|
||||||
|
|
||||||
|
dpkg -i /tmp/liquidsoap.deb
|
||||||
|
apt-get install -y -f --no-install-recommends
|
||||||
|
rm -f /tmp/liquidsoap.deb
|
||||||
|
ln -s /usr/bin/liquidsoap /usr/local/bin/liquidsoap
|
||||||
|
|
||||||
|
# To do a pinned install, uncomment and customize below
|
||||||
|
# else
|
||||||
|
# $minimal_apt_get_install build-essential libssl-dev libcurl4-openssl-dev m4 ocaml opam autoconf automake
|
||||||
|
#
|
||||||
|
# sudo -u azuracast bash ../liquidsoap/build_as_azuracast.sh
|
||||||
|
# ln -s /var/azuracast/.opam/4.13.1/bin/liquidsoap /usr/local/bin/liquidsoap
|
||||||
|
# chmod a+x /usr/local/bin/liquidsoap
|
||||||
|
# apt-get purge -y build-essential libssl-dev libcurl4-openssl-dev m4 ocaml opam autoconf automake
|
||||||
|
# fi
|
|
@ -0,0 +1,12 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
source /bd_build/buildconfig
|
||||||
|
set -x
|
||||||
|
|
||||||
|
# $minimal_apt_get_install python3-minimal python3-pip
|
||||||
|
# pip3 install setuptools supervisor
|
||||||
|
|
||||||
|
$minimal_apt_get_install supervisor
|
||||||
|
|
||||||
|
# mkdir -p /etc/supervisor
|
||||||
|
cp /bd_build/stations/supervisor/supervisord.conf /etc/supervisor/supervisord.conf
|
|
@ -0,0 +1,25 @@
|
||||||
|
[unix_http_server]
|
||||||
|
file=/tmp/supervisor.sock ; (the path to the socket file)
|
||||||
|
|
||||||
|
[inet_http_server] ; inet (TCP) server disabled by default
|
||||||
|
port=127.0.0.1:9001 ; (ip_address:port specifier, *:port for all iface)
|
||||||
|
|
||||||
|
[supervisord]
|
||||||
|
user=root
|
||||||
|
logfile=/var/azuracast/www_tmp/supervisord.log ; (main log file;default $CWD/supervisord.log)
|
||||||
|
logfile_maxbytes=50MB ; (max main logfile bytes b4 rotation;default 50MB)
|
||||||
|
logfile_backups=10 ; (num of main logfile rotation backups;default 10)
|
||||||
|
loglevel=info ; (log level;default info; others: debug,warn,trace)
|
||||||
|
pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
|
||||||
|
nodaemon=true ; (start in foreground if true;default false)
|
||||||
|
minfds=1024 ; (min. avail startup file descriptors;default 1024)
|
||||||
|
minprocs=200 ; (min. avail process descriptors;default 200)
|
||||||
|
|
||||||
|
[rpcinterface:supervisor]
|
||||||
|
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
|
||||||
|
|
||||||
|
[supervisorctl]
|
||||||
|
serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL for a unix socket
|
||||||
|
|
||||||
|
[include]
|
||||||
|
files = /var/azuracast/stations/*/config/supervisord.conf conf.d/*
|
|
@ -1,11 +1,9 @@
|
||||||
{{if isTrue .Env.ENABLE_REDIS }}
|
{{if isTrue .Env.ENABLE_REDIS }}
|
||||||
upstream redis_server {
|
upstream redis_server {
|
||||||
nchan_redis_server "redis://redis:6379";
|
nchan_redis_server "redis://localhost:6379";
|
||||||
}
|
}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
resolver 127.0.0.11;
|
|
||||||
|
|
||||||
server {
|
server {
|
||||||
listen 9010;
|
listen 9010;
|
||||||
|
|
||||||
|
@ -130,7 +128,7 @@ server {
|
||||||
proxy_connect_timeout 60;
|
proxy_connect_timeout 60;
|
||||||
|
|
||||||
proxy_set_header Host localhost:$1;
|
proxy_set_header Host localhost:$1;
|
||||||
proxy_pass http://stations:$1/$3?$args;
|
proxy_pass http://127.0.0.1:$1/$3?$args;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Reverse proxy the Liquidsoap harbor inputs to allow for streaming.
|
# Reverse proxy the Liquidsoap harbor inputs to allow for streaming.
|
||||||
|
@ -140,11 +138,9 @@ server {
|
||||||
location ~ ^/radio/{{ .Env.NGINX_WEBDJ_PORTS }}(/?)(.*)$ {
|
location ~ ^/radio/{{ .Env.NGINX_WEBDJ_PORTS }}(/?)(.*)$ {
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
resolver 127.0.0.11;
|
|
||||||
|
|
||||||
include proxy_params;
|
include proxy_params;
|
||||||
|
|
||||||
proxy_pass http://stations:$1/$3;
|
proxy_pass http://127.0.0.1:$1/$3;
|
||||||
}
|
}
|
||||||
|
|
||||||
# pub/sub endpoints
|
# pub/sub endpoints
|
||||||
|
|
|
@ -15,6 +15,7 @@ pm.start_servers = 2
|
||||||
pm.min_spare_servers = 1
|
pm.min_spare_servers = 1
|
||||||
pm.max_spare_servers = 3
|
pm.max_spare_servers = 3
|
||||||
pm.max_requests = 100
|
pm.max_requests = 100
|
||||||
|
pm.status_path = /status
|
||||||
pm.process_idle_timeout = 60s
|
pm.process_idle_timeout = 60s
|
||||||
|
|
||||||
chdir = /
|
chdir = /
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
echo 'Spinning up Beanstalkd process...'
|
|
||||||
|
|
||||||
exec sudo -E -u azuracast beanstalkd -p 11300 -z 262140
|
|
|
@ -1,5 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
source /etc/php/.version
|
|
||||||
|
|
||||||
exec /usr/sbin/php-fpm${PHP_VERSION} -F --fpm-config /etc/php/${PHP_VERSION}/fpm/php-fpm.conf -c /etc/php/${PHP_VERSION}/fpm/
|
|
|
@ -1,3 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
exec sudo -E -u azuracast php /var/azuracast/www/bin/console azuracast:sync:nowplaying
|
|
|
@ -1,3 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
exec sudo -E -u azuracast php /var/azuracast/www/bin/console queue:process --worker-name=app_worker_0
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
if [ $(whoami) != 'azuracast' ]; then
|
||||||
|
echo 'This script must be run as the "azuracast" user. Rerunning...'
|
||||||
|
exec gosu azuracast azuracast_ci "$@"
|
||||||
|
fi
|
||||||
|
|
||||||
|
azuracast_install || exit 1
|
||||||
|
|
||||||
|
cd /var/azuracast/www
|
||||||
|
composer codeception-no-coverage
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
if [ `whoami` != 'azuracast' ]; then
|
if [ `whoami` != 'azuracast' ]; then
|
||||||
echo 'This script must be run as the "azuracast" user. Rerunning...'
|
echo 'This script must be run as the "azuracast" user. Rerunning...'
|
||||||
exec sudo -E -u azuracast azuracast_cli "$@"
|
exec gosu azuracast azuracast_cli "$@"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cd /var/azuracast/www
|
cd /var/azuracast/www
|
||||||
|
|
|
@ -9,7 +9,7 @@ bool() {
|
||||||
|
|
||||||
if [ $(whoami) != 'azuracast' ]; then
|
if [ $(whoami) != 'azuracast' ]; then
|
||||||
echo 'This script must be run as the "azuracast" user. Rerunning...'
|
echo 'This script must be run as the "azuracast" user. Rerunning...'
|
||||||
exec sudo -E -u azuracast azuracast_install "$@"
|
exec gosu azuracast azuracast_install "$@"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "AzuraCast Setup"
|
echo "AzuraCast Setup"
|
||||||
|
|
|
@ -9,7 +9,7 @@ bool() {
|
||||||
|
|
||||||
if [ $(whoami) != 'azuracast' ]; then
|
if [ $(whoami) != 'azuracast' ]; then
|
||||||
echo 'This script must be run as the "azuracast" user. Rerunning...'
|
echo 'This script must be run as the "azuracast" user. Rerunning...'
|
||||||
exec sudo -E -u azuracast azuracast_restore "$@"
|
exec gosu azuracast azuracast_restore "$@"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "AzuraCast Backup Restore"
|
echo "AzuraCast Backup Restore"
|
||||||
|
|
|
@ -2,4 +2,4 @@
|
||||||
|
|
||||||
source /etc/container_environment.sh
|
source /etc/container_environment.sh
|
||||||
|
|
||||||
exec sudo -E -u azuracast "$@" >/proc/1/fd/1 2>/proc/1/fd/2
|
exec gosu azuracast "$@" >/proc/1/fd/1 2>/proc/1/fd/2
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
exec /usr/sbin/tmpreaper 12h --protect '.tmpreaper' --verbose \
|
exec /usr/sbin/tmpreaper 12h --protect '.tmpreaper' --verbose \
|
||||||
|
/tmp \
|
||||||
/tmp/app_nginx_client \
|
/tmp/app_nginx_client \
|
||||||
/tmp/app_fastcgi_temp \
|
/tmp/app_fastcgi_temp \
|
||||||
|
/var/azuracast/stations/*/temp \
|
||||||
> /proc/1/fd/1 2> /proc/1/fd/2
|
> /proc/1/fd/1 2> /proc/1/fd/2
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
if [[ -f /var/azuracast/www/bin/uptime_wait ]]; then
|
gosu azuracast php /var/azuracast/www/bin/uptime_wait || exit 1
|
||||||
if ! php /var/azuracast/www/bin/uptime_wait; then
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
exec "$@"
|
exec "$@"
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
sv -w 45 check nginx || exit 1
|
||||||
|
|
||||||
# Acme loading script
|
# Acme loading script
|
||||||
# Uses code from:
|
# Uses code from:
|
||||||
# https://github.com/nginx-proxy/acme-companion/blob/main/app/letsencrypt_service
|
# https://github.com/nginx-proxy/acme-companion/blob/main/app/letsencrypt_service
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
echo 'Spinning up Beanstalkd process...'
|
||||||
|
|
||||||
|
exec gosu azuracast beanstalkd -p 11300 -z 262140
|
|
@ -1,8 +1,10 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
|
sv -w 30 check php-fpm || exit 1
|
||||||
|
|
||||||
# Touch cron files to fix 'NUMBER OF HARD LINKS > 1' issue. See https://github.com/phusion/baseimage-docker/issues/198
|
# Touch cron files to fix 'NUMBER OF HARD LINKS > 1' issue. See https://github.com/phusion/baseimage-docker/issues/198
|
||||||
touch -c /var/spool/cron/crontabs/*
|
touch -c /var/spool/cron/crontabs/*
|
||||||
touch -c /etc/crontab
|
touch -c /etc/crontab
|
||||||
touch -c /etc/cron.*/*
|
touch -c /etc/cron.*/*
|
||||||
|
|
||||||
exec /usr/sbin/cron -f
|
exec /usr/sbin/cron -f
|
|
@ -1,5 +1,7 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
sv -w 30 check php-fpm || exit 1
|
||||||
|
|
||||||
bool() {
|
bool() {
|
||||||
case "$1" in
|
case "$1" in
|
||||||
Y* | y* | true | TRUE | 1) return 0 ;;
|
Y* | y* | true | TRUE | 1) return 0 ;;
|
|
@ -0,0 +1,3 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
exec php-fpm-healthcheck
|
|
@ -0,0 +1,25 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
source /etc/container_environment.sh
|
||||||
|
|
||||||
|
if [ -f /etc/service/mariadb/run ]; then
|
||||||
|
sv -w 30 check mariadb || exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f /etc/service/redis/run ]; then
|
||||||
|
sv -w 30 check redis || exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Set up PHP config
|
||||||
|
dockerize -template "/etc/php/${PHP_VERSION}/fpm/05-azuracast.ini.tmpl:/etc/php/${PHP_VERSION}/fpm/conf.d/05-azuracast.ini" \
|
||||||
|
-template "/etc/php/${PHP_VERSION}/fpm/www.conf.tmpl:/etc/php/${PHP_VERSION}/fpm/pool.d/www.conf" \
|
||||||
|
cp /etc/php/${PHP_VERSION}/fpm/conf.d/05-azuracast.ini /etc/php/${PHP_VERSION}/cli/conf.d/05-azuracast.ini
|
||||||
|
|
||||||
|
# Wait for services to spin up.
|
||||||
|
gosu azuracast php /var/azuracast/www/bin/uptime_wait || exit 1
|
||||||
|
|
||||||
|
# Initialize before running FPM
|
||||||
|
gosu azuracast azuracast_cli azuracast:setup:initialize || exit 1
|
||||||
|
|
||||||
|
# Run PHP-FPM
|
||||||
|
exec /usr/sbin/php-fpm${PHP_VERSION} -F --fpm-config /etc/php/${PHP_VERSION}/fpm/php-fpm.conf -c /etc/php/${PHP_VERSION}/fpm/
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
sv -w 30 check php-fpm || exit 1
|
||||||
|
|
||||||
|
exec gosu azuracast php /var/azuracast/www/bin/console azuracast:sync:nowplaying
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
sv -w 30 check php-fpm || exit 1
|
||||||
|
|
||||||
|
exec gosu azuracast php /var/azuracast/www/bin/console queue:process --worker-name=app_worker_0
|
|
@ -3,24 +3,18 @@ set -e
|
||||||
source /bd_build/buildconfig
|
source /bd_build/buildconfig
|
||||||
set -x
|
set -x
|
||||||
|
|
||||||
|
apt-get update
|
||||||
|
|
||||||
# Install common scripts
|
# Install common scripts
|
||||||
cp -rT /bd_build/scripts/ /usr/local/bin
|
cp -rT /bd_build/web/scripts/ /usr/local/bin
|
||||||
chmod -R a+x /usr/local/bin
|
|
||||||
|
|
||||||
# Install runit
|
cp -rT /bd_build/web/startup_scripts/. /etc/my_init.d/
|
||||||
$minimal_apt_get_install runit
|
|
||||||
|
|
||||||
# Install runit scripts
|
# cp -rT /bd_build/web/service.minimal/. /etc/service.minimal/
|
||||||
cp -rT /bd_build/startup_scripts/. /etc/my_init.d/
|
|
||||||
cp -rT /bd_build/runit/. /etc/service/
|
|
||||||
|
|
||||||
chmod -R +x /etc/service
|
cp -rT /bd_build/web/service.full/. /etc/service.full/
|
||||||
chmod -R +x /etc/my_init.d
|
|
||||||
|
|
||||||
# Install scripts commonly used during setup.
|
|
||||||
$minimal_apt_get_install curl wget tar zip unzip git rsync tzdata gpg-agent openssh-client
|
|
||||||
|
|
||||||
# Run service setup for all setup scripts
|
# Run service setup for all setup scripts
|
||||||
for f in /bd_build/setup/*.sh; do
|
for f in /bd_build/web/setup/*.sh; do
|
||||||
bash "$f" -H
|
bash "$f" -H
|
||||||
done
|
done
|
||||||
|
|
|
@ -18,5 +18,5 @@ rm -f /etc/cron.daily/dpkg
|
||||||
rm -f /etc/cron.daily/password
|
rm -f /etc/cron.daily/password
|
||||||
rm -f /etc/cron.weekly/fstrim
|
rm -f /etc/cron.weekly/fstrim
|
||||||
|
|
||||||
cp -r /bd_build/cron/. /etc/cron.d/
|
cp -r /bd_build/web/cron/. /etc/cron.d/
|
||||||
chmod -R 600 /etc/cron.d/*
|
chmod -R 600 /etc/cron.d/*
|
||||||
|
|
|
@ -6,9 +6,9 @@ set -x
|
||||||
$minimal_apt_get_install nginx nginx-common nginx-extras openssl
|
$minimal_apt_get_install nginx nginx-common nginx-extras openssl
|
||||||
|
|
||||||
# Install nginx and configuration
|
# Install nginx and configuration
|
||||||
cp /bd_build/nginx/proxy_params.conf /etc/nginx/proxy_params
|
cp /bd_build/web/nginx/proxy_params.conf /etc/nginx/proxy_params
|
||||||
cp /bd_build/nginx/nginx.conf.tmpl /etc/nginx/nginx.conf.tmpl
|
cp /bd_build/web/nginx/nginx.conf.tmpl /etc/nginx/nginx.conf.tmpl
|
||||||
cp /bd_build/nginx/azuracast.conf.tmpl /etc/nginx/azuracast.conf.tmpl
|
cp /bd_build/web/nginx/azuracast.conf.tmpl /etc/nginx/azuracast.conf.tmpl
|
||||||
|
|
||||||
mkdir -p /etc/nginx/azuracast.conf.d/
|
mkdir -p /etc/nginx/azuracast.conf.d/
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,8 @@ set -x
|
||||||
|
|
||||||
PHP_VERSION=8.1
|
PHP_VERSION=8.1
|
||||||
|
|
||||||
|
echo "${PHP_VERSION}" >> /etc/container_environment/PHP_VERSION
|
||||||
|
|
||||||
add-apt-repository -y ppa:ondrej/php
|
add-apt-repository -y ppa:ondrej/php
|
||||||
apt-get update
|
apt-get update
|
||||||
|
|
||||||
|
@ -18,14 +20,19 @@ $minimal_apt_get_install php${PHP_VERSION}-fpm php${PHP_VERSION}-cli php${PHP_VE
|
||||||
mkdir -p /run/php
|
mkdir -p /run/php
|
||||||
touch /run/php/php${PHP_VERSION}-fpm.pid
|
touch /run/php/php${PHP_VERSION}-fpm.pid
|
||||||
|
|
||||||
echo "PHP_VERSION=${PHP_VERSION}" >>/etc/php/.version
|
cp /bd_build/web/php/php.ini.tmpl /etc/php/${PHP_VERSION}/fpm/05-azuracast.ini.tmpl
|
||||||
|
cp /bd_build/web/php/www.conf.tmpl /etc/php/${PHP_VERSION}/fpm/www.conf.tmpl
|
||||||
cp /bd_build/php/php.ini.tmpl /etc/php/${PHP_VERSION}/fpm/05-azuracast.ini.tmpl
|
|
||||||
cp /bd_build/php/www.conf.tmpl /etc/php/${PHP_VERSION}/fpm/www.conf.tmpl
|
|
||||||
|
|
||||||
# Install Composer
|
# Install Composer
|
||||||
curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin --filename=composer
|
curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin --filename=composer
|
||||||
|
|
||||||
|
# Download PHP-FPM healthcheck script
|
||||||
|
$minimal_apt_get_install libfcgi-bin
|
||||||
|
|
||||||
|
wget -O /usr/local/bin/php-fpm-healthcheck \
|
||||||
|
https://raw.githubusercontent.com/renatomefi/php-fpm-healthcheck/master/php-fpm-healthcheck \
|
||||||
|
&& chmod +x /usr/local/bin/php-fpm-healthcheck
|
||||||
|
|
||||||
# Install PHP SPX profiler
|
# Install PHP SPX profiler
|
||||||
$minimal_apt_get_install php${PHP_VERSION}-dev zlib1g-dev build-essential
|
$minimal_apt_get_install php${PHP_VERSION}-dev zlib1g-dev build-essential
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ $minimal_apt_get_install sftpgo
|
||||||
|
|
||||||
mkdir -p /var/azuracast/sftpgo/persist /var/azuracast/sftpgo/backups
|
mkdir -p /var/azuracast/sftpgo/persist /var/azuracast/sftpgo/backups
|
||||||
|
|
||||||
cp /bd_build/sftpgo/sftpgo.json /var/azuracast/sftpgo/sftpgo.json
|
cp /bd_build/web/sftpgo/sftpgo.json /var/azuracast/sftpgo/sftpgo.json
|
||||||
|
|
||||||
touch /var/azuracast/sftpgo/sftpgo.db
|
touch /var/azuracast/sftpgo/sftpgo.db
|
||||||
chown -R azuracast:azuracast /var/azuracast/sftpgo
|
chown -R azuracast:azuracast /var/azuracast/sftpgo
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Copy the php.ini template to its destination.
|
|
||||||
source /etc/php/.version
|
|
||||||
|
|
||||||
dockerize -template "/etc/php/${PHP_VERSION}/fpm/05-azuracast.ini.tmpl:/etc/php/${PHP_VERSION}/fpm/conf.d/05-azuracast.ini" \
|
|
||||||
-template "/etc/php/${PHP_VERSION}/fpm/www.conf.tmpl:/etc/php/${PHP_VERSION}/fpm/pool.d/www.conf" \
|
|
||||||
cp /etc/php/${PHP_VERSION}/fpm/conf.d/05-azuracast.ini /etc/php/${PHP_VERSION}/cli/conf.d/05-azuracast.ini
|
|
|
@ -1,5 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -ex
|
|
||||||
|
|
||||||
exec sudo -E -u azuracast azuracast_cli azuracast:setup:initialize
|
|
Loading…
Reference in New Issue