Merge Docker Multi-site Setup into Core Setup

This commit merges the previous Docker Multi-site configuration into the core Docker Compose configuration for all installations.
This commit is contained in:
Buster "Silver Eagle" Neece 2020-05-19 00:01:13 -05:00
parent 77155fdac8
commit 0070dde26c
No known key found for this signature in database
GPG Key ID: 6D9E12FF03411F4E
12 changed files with 271 additions and 204 deletions

1
.gitignore vendored
View File

@ -38,6 +38,7 @@ tmp/cache/*---*
# Docker files
/docker-compose.yml
/docker-compose.override.yml
/.env
# Backups
/*.tar.gz

View File

@ -27,7 +27,7 @@ services:
env_file: azuracast.env
environment: &default-environment
LANG: ${LANG:-en_US.UTF-8}
AZURACAST_DC_REVISION: 7
AZURACAST_DC_REVISION: 8
AZURACAST_SFTP_PORT: ${AZURACAST_SFTP_PORT:-2022}
ports:
- '${AZURACAST_SFTP_PORT:-2022}:2022'
@ -54,12 +54,12 @@ services:
build:
context: ../docker-azuracast-db
ports:
- "127.0.0.1:3306:3306"
- "127.0.0.1:3306:3306"
volumes:
- db_data:/var/lib/mysql
env_file: azuracast.env
environment:
<< : *default-environment
<<: *default-environment
restart: always
logging: *default-logging
@ -77,7 +77,7 @@ services:
build:
context: ../docker-azuracast-redis
ports:
- "127.0.0.1:6379:6379"
- "127.0.0.1:6379:6379"
restart: always
logging: *default-logging
sysctls:
@ -91,26 +91,26 @@ services:
build:
context: ../docker-azuracast-radio
ports:
- '8000:8000'
- '8005:8005'
- '8006:8006'
- '8010:8010'
- '8015:8015'
- '8016:8016'
- '8020:8020'
- '8025:8025'
- '8026:8026'
- '8030:8030'
- '8035:8035'
- '8036:8036'
- '8040:8040'
- '8045:8045'
- '8046:8046'
- '8000:8000'
- '8005:8005'
- '8006:8006'
- '8010:8010'
- '8015:8015'
- '8016:8016'
- '8020:8020'
- '8025:8025'
- '8026:8026'
- '8030:8030'
- '8035:8035'
- '8036:8036'
- '8040:8040'
- '8045:8045'
- '8046:8046'
volumes:
- station_data:/var/azuracast/stations
- ./util/local_ssl:/etc/nginx/ssl:ro
- shoutcast2_install:/var/azuracast/servers/shoutcast2
- tmp_data:/var/azuracast/www_tmp
- station_data:/var/azuracast/stations
- ./util/local_ssl:/etc/nginx/ssl:ro
- shoutcast2_install:/var/azuracast/servers/shoutcast2
- tmp_data:/var/azuracast/www_tmp
init: true
restart: always
ulimits: *default-ulimits

View File

@ -1,42 +0,0 @@
version: '2.2'
services:
web:
environment:
# Update this to your default AzuraCast domain.
# DON'T FORGET TO UPDATE THE nginx_proxy SERVICE BELOW!
VIRTUAL_HOST: azuracast.local
# To enable automated LetsEncrypt certificates and renewal, uncomment the lines below
# and set the domain name to the same as the one above. You can also optionally provide
# an e-mail address for expiration notifications.
# LETSENCRYPT_HOST: azuracast.local
# LETSENCRYPT_EMAIL: your-email-address@example.com
nginx_proxy:
image: azuracast/azuracast_nginx_proxy:latest
ports:
- '80:80'
- '443:443'
volumes:
- letsencrypt:/etc/nginx/certs
- nginx_proxy_vhosts:/etc/nginx/vhost.d
- letsencrypt_html:/usr/share/nginx/html
- /var/run/docker.sock:/tmp/docker.sock:ro
environment:
# Update this to your default AzuraCast domain.
DEFAULT_HOST: azuracast.local
depends_on:
- web
restart: always
nginx_proxy_letsencrypt:
image: jrcs/letsencrypt-nginx-proxy-companion:latest
volumes_from:
- nginx_proxy
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
restart: always
volumes:
letsencrypt_html: {}
nginx_proxy_vhosts: {}

View File

@ -12,14 +12,38 @@
version: '2.2'
services:
nginx_proxy:
image: azuracast/azuracast_nginx_proxy:latest
ports:
- '${AZURACAST_HTTP_PORT:-80}:80'
- '${AZURACAST_HTTPS_PORT:-443}:443'
volumes:
- letsencrypt:/etc/nginx/certs
- nginx_proxy_vhosts:/etc/nginx/vhost.d
- letsencrypt_html:/usr/share/nginx/html
- /var/run/docker.sock:/tmp/docker.sock:ro
environment:
DEFAULT_HOST: ${LETSENCRYPT_HOST:-azuracast.local}
depends_on:
- web
restart: always
nginx_proxy_letsencrypt:
image: jrcs/letsencrypt-nginx-proxy-companion:latest
volumes_from:
- nginx_proxy
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
DEFAULT_EMAIL: ${LETSENCRYPT_EMAIL:-""}
restart: always
web:
container_name: azuracast_web
image: azuracast/azuracast_web_v2:latest
# Want to customize the HTTP/S ports? Follow the instructions here:
# https://www.azuracast.com/help/docker/#use-non-standard-ports
ports:
- '${AZURACAST_HTTP_PORT:-80}:80'
- '${AZURACAST_HTTPS_PORT:-443}:443'
- '${AZURACAST_SFTP_PORT:-2022}:2022'
depends_on:
- mariadb
@ -29,8 +53,11 @@ services:
env_file: azuracast.env
environment: &default-environment
LANG: ${LANG:-en_US.UTF-8}
AZURACAST_DC_REVISION: 7
AZURACAST_DC_REVISION: 8
AZURACAST_SFTP_PORT: ${AZURACAST_SFTP_PORT:-2022}
VIRTUAL_HOST: ${LETSENCRYPT_HOST:-azuracast.local}
LETSENCRYPT_HOST: ${LETSENCRYPT_HOST:-""}
LETSENCRYPT_EMAIL: ${LETSENCRYPT_EMAIL:-""}
volumes:
- letsencrypt:/etc/letsencrypt
- www_data:/var/azuracast/www
@ -242,9 +269,11 @@ services:
logging: *default-logging
volumes:
nginx_proxy_vhosts: {}
db_data: {}
influx_data: {}
letsencrypt: {}
letsencrypt_html: {}
shoutcast2_install: {}
geolite_install: {}
sftpgo_data: {}
@ -252,4 +281,4 @@ volumes:
tmp_data: {}
www_data: {}
redis_data: {}
backups: {}
backups: {}

View File

@ -9,4 +9,4 @@ services:
LANG: en_US.UTF-8
APPLICATION_ENV: "testing"
volumes:
- .:/var/azuracast/www
- .:/var/azuracast/www

239
docker.sh
View File

@ -1,4 +1,148 @@
#!/usr/bin/env bash
# shellcheck disable=SC2145,SC2178,SC2120,SC2162
# Functions to manage .env files
__dotenv=
__dotenv_file=
__dotenv_cmd=.env
.env() {
REPLY=()
[[ $__dotenv_file || ${1-} == -* ]] || .env.--file .env || return
if declare -F -- ".env.${1-}" >/dev/null; then
.env."$@"
return
fi
.env --help >&2
return 64
}
.env.-f() { .env.--file "$@"; }
.env.get() {
.env::arg "get requires a key" "$@" &&
[[ "$__dotenv" =~ ^(.*(^|$'\n'))([ ]*)"$1="(.*)$ ]] &&
REPLY=${BASH_REMATCH[4]%%$'\n'*} && REPLY=${REPLY%"${REPLY##*[![:space:]]}"}
}
.env.parse() {
local line key
while IFS= read -r line; do
line=${line#"${line%%[![:space:]]*}"} # trim leading whitespace
line=${line%"${line##*[![:space:]]}"} # trim trailing whitespace
if [[ ! "$line" || "$line" == '#'* ]]; then continue; fi
if (($#)); then
for key; do
if [[ $key == "${line%%=*}" ]]; then
REPLY+=("$line")
break
fi
done
else
REPLY+=("$line")
fi
done <<<"$__dotenv"
((${#REPLY[@]}))
}
.env.export() { ! .env.parse "$@" || export "${REPLY[@]}"; }
.env.set() {
.env::file load || return
local key saved=$__dotenv
while (($#)); do
key=${1#+}
key=${key%%=*}
if .env.get "$key"; then
REPLY=()
if [[ $1 == +* ]]; then
shift
continue # skip if already found
elif [[ $1 == *=* ]]; then
__dotenv=${BASH_REMATCH[1]}${BASH_REMATCH[3]}$1$'\n'${BASH_REMATCH[4]#*$'\n'}
else
__dotenv=${BASH_REMATCH[1]}${BASH_REMATCH[4]#*$'\n'}
continue # delete all occurrences
fi
elif [[ $1 == *=* ]]; then
__dotenv+="${1#+}"$'\n'
fi
shift
done
[[ $__dotenv == "$saved" ]] || .env::file save
}
.env.puts() { echo "${1-}" >>"$__dotenv_file" && __dotenv+="$1"$'\n'; }
.env.generate() {
.env::arg "key required for generate" "$@" || return
.env.get "$1" && return || REPLY=$("${@:2}") || return
.env::one "generate: ouptut of '${*:2}' has more than one line" "$REPLY" || return
.env.puts "$1=$REPLY"
}
.env.--file() {
.env::arg "filename required for --file" "$@" || return
__dotenv_file=$1
.env::file load || return
(($# < 2)) || .env "${@:2}"
}
.env::arg() { [[ "${2-}" ]] || {
echo "$__dotenv_cmd: $1" >&2
return 64
}; }
.env::one() { [[ "$2" != *$'\n'* ]] || .env::arg "$1"; }
.env::file() {
local REPLY=$__dotenv_file
case "$1" in
load)
__dotenv=
! [[ -f "$REPLY" ]] || __dotenv="$(<"$REPLY")"$'\n' || return
;;
save)
if [[ -L "$REPLY" ]] && declare -F -- realpath.resolved >/dev/null; then
realpath.resolved "$REPLY"
fi
{ [[ ! -f "$REPLY" ]] || cp -p "$REPLY" "$REPLY.bak"; } &&
printf %s "$__dotenv" >"$REPLY.bak" && mv "$REPLY.bak" "$REPLY"
;;
esac
}
.env.-h() { .env.--help "$@"; }
.env.--help() {
echo "Usage:
$__dotenv_cmd [-f|--file FILE] COMMAND [ARGS...]
$__dotenv_cmd -h|--help
Options:
-f, --file FILE Use a file other than .env
Read Commands:
get KEY Get raw value of KEY (or fail)
parse [KEY...] Get trimmed KEY=VALUE lines for named keys (or all)
export [KEY...] Export the named keys (or all) in shell format
Write Commands:
set [+]KEY[=VALUE]... Set or unset values (in-place w/.bak); + sets default
puts STRING Append STRING to the end of the file
generate KEY [CMD...] Set KEY to the output of CMD unless it already exists;
return the new or existing value."
}
__dotenv() {
set -eu
__dotenv_cmd=${0##*/}
.env.export() {
.env.parse "$@" || return 0
printf 'export %q\n' "${REPLY[@]}"
REPLY=()
}
.env "$@" || return $?
${REPLY[@]+printf '%s\n' "${REPLY[@]}"}
}
# This is a general-purpose function to ask Yes/No questions in Bash, either
# with or without a default answer. It keeps repeating the question until it
@ -39,6 +183,42 @@ ask() {
done
}
#
# Configure the ports used by AzuraCast.
# Usage: ./docker.sh setup_ports
#
setup_ports() {
AZURACAST_HTTP_PORT=80
read -p "Port to use for HTTP connections? [80]:" INPUT
AZURACAST_HTTP_PORT="${INPUT:-$AZURACAST_HTTP_PORT}"
AZURACAST_HTTPS_PORT=443
read -p "Port to use for HTTPS connections? [443]:" INPUT
AZURACAST_HTTPS_PORT="${INPUT:-$AZURACAST_HTTPS_PORT}"
AZURACAST_SFTP_PORT=2022
read -p "Port to use for SFTP connections? [2022]:" INPUT
AZURACAST_SFTP_PORT="${INPUT:-$AZURACAST_SFTP_PORT}"
.env --file .env put AZURACAST_HTTP_PORT="${AZURACAST_HTTP_PORT}" \
AZURACAST_HTTPS_PORT="${AZURACAST_HTTPS_PORT}" \
AZURACAST_SFTP_PORT="${AZURACAST_SFTP_PORT}"
}
#
# Configure the settings used by LetsEncrypt.
#
setup_letsencrypt() {
read -p "Domain name (example.com) or names (example.com,foo.bar) to use with LetsEncrypt:" INPUT
LETSENCRYPT_HOST="${INPUT:-""}"
read -p "Optional e-mail address for expiration updates:" INPUT
LETSENCRYPT_EMAIL="${INPUT:-""}"
.env --file .env put LETSENCRYPT_HOST="${LETSENCRYPT_HOST}" \
LETSENCRYPT_EMAIL="${LETSENCRYPT_EMAIL}"
}
#
# Run the initial installer of Docker and AzuraCast.
# Usage: ./docker.sh install
@ -96,7 +276,7 @@ install() {
if [[ ! -f .env ]]; then
echo "Writing default .env file..."
curl -fsSL https://raw.githubusercontent.com/AzuraCast/AzuraCast/master/.env -o .env
curl -fsSL https://raw.githubusercontent.com/AzuraCast/AzuraCast/master/sample.env -o .env
fi
if [[ ! -f azuracast.env ]]; then
@ -104,7 +284,10 @@ install() {
curl -fsSL https://raw.githubusercontent.com/AzuraCast/AzuraCast/master/azuracast.sample.env -o azuracast.env
# Generate a random password and replace the MariaDB password with it.
NEW_PASSWORD=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c"${1:-32}";echo);
NEW_PASSWORD=$(
tr </dev/urandom -dc _A-Z-a-z-0-9 | head -c"${1:-32}"
echo
)
sed -i "s/azur4c457/${NEW_PASSWORD}/g" azuracast.env
fi
@ -113,8 +296,16 @@ install() {
curl -fsSL https://raw.githubusercontent.com/AzuraCast/AzuraCast/master/docker-compose.sample.yml -o docker-compose.yml
fi
if ask "Customize AzuraCast ports?" N; then
setup_ports
fi
if ask "Set up LetsEncrypt?" N; then
setup_letsencrypt
fi
docker-compose pull
docker-compose run --user="azuracast" --rm web azuracast_install $*
docker-compose run --user="azuracast" --rm web azuracast_install "$@"
docker-compose up -d
exit
}
@ -161,10 +352,10 @@ update() {
docker volume rm azuracast_tmp_data
docker volume rm azuracast_redis_data
docker-compose run --user="azuracast" --rm web azuracast_update $*
docker-compose run --user="azuracast" --rm web azuracast_update "$@"
docker-compose up -d
docker rmi $(docker images | grep "none" | awk '/ / { print $3 }') 2>/dev/null
docker rmi "$(docker images | grep "none" | awk '/ / { print $3 }')" 2>/dev/null
echo "Update complete!"
exit
@ -211,9 +402,9 @@ backup() {
BACKUP_EXT="${BACKUP_FILENAME##*.}"
shift
MSYS_NO_PATHCONV=1 docker exec --user="azuracast" azuracast_web azuracast_cli azuracast:backup /tmp/cli_backup.${BACKUP_EXT} $*
docker cp azuracast_web:tmp/cli_backup.${BACKUP_EXT} ${BACKUP_PATH}
MSYS_NO_PATHCONV=1 docker exec --user="azuracast" azuracast_web rm -f /tmp/cli_backup.${BACKUP_EXT}
MSYS_NO_PATHCONV=1 docker exec --user="azuracast" azuracast_web azuracast_cli azuracast:backup "/tmp/cli_backup.${BACKUP_EXT}" "$@"
docker cp "azuracast_web:tmp/cli_backup.${BACKUP_EXT}" "${BACKUP_PATH}"
MSYS_NO_PATHCONV=1 docker exec --user="azuracast" azuracast_web rm -f "/tmp/cli_backup.${BACKUP_EXT}"
exit
}
@ -243,12 +434,13 @@ restore() {
docker-compose down -v
docker-compose pull
docker-compose up -d web
docker cp ${BACKUP_PATH} azuracast_web:tmp/cli_backup.${BACKUP_EXT}
MSYS_NO_PATHCONV=1 docker exec --user="azuracast" azuracast_web azuracast_restore /tmp/cli_backup.${BACKUP_EXT} $*
docker cp "${BACKUP_PATH}" "azuracast_web:tmp/cli_backup.${BACKUP_EXT}"
MSYS_NO_PATHCONV=1 docker exec --user="azuracast" azuracast_web azuracast_restore "/tmp/cli_backup.${BACKUP_EXT}" "$@"
docker-compose down
docker-compose up -d
fi
exit
}
@ -261,12 +453,12 @@ restore-legacy() {
APP_BASE_DIR=$(pwd)
BACKUP_PATH=${1:-"./backup.tar.gz"}
BACKUP_DIR=$(cd $(dirname "$BACKUP_PATH") && pwd)
BACKUP_DIR=$(cd "$(dirname "$BACKUP_PATH")" && pwd)
BACKUP_FILENAME=$(basename "$BACKUP_PATH")
cd $APP_BASE_DIR
cd "$APP_BASE_DIR"
if [ -f $BACKUP_PATH ]; then
if [ -f "$BACKUP_PATH" ]; then
docker-compose down
docker volume rm azuracast_db_data azuracast_influx_data azuracast_station_data
@ -274,11 +466,11 @@ restore-legacy() {
docker volume create azuracast_influx_data
docker volume create azuracast_station_data
docker run --rm -v $BACKUP_DIR:/backup \
docker run --rm -v "$BACKUP_DIR:/backup" \
-v azuracast_db_data:/azuracast/db \
-v azuracast_influx_data:/azuracast/influx \
-v azuracast_station_data:/azuracast/stations \
busybox tar zxvf /backup/$BACKUP_FILENAME
busybox tar zxvf "/backup/$BACKUP_FILENAME"
docker-compose up -d
else
@ -334,7 +526,7 @@ dev-phpstan() {
#
dev-codeception() {
docker-compose -f docker-compose.sample.yml -f docker-compose.testing.yml build web
docker-compose -f docker-compose.sample.yml -f docker-compose.testing.yml run --user="azuracast" --rm web composer codeception -- $*
docker-compose -f docker-compose.sample.yml -f docker-compose.testing.yml run --user="azuracast" --rm web composer codeception -- "$@"
}
#
@ -361,19 +553,14 @@ uninstall() {
#
# Create and link a LetsEncrypt SSL certificate.
# Usage: ./docker.sh letsencrypt-create domainname.example.com
# Usage: ./docker.sh letsencrypt-create
#
letsencrypt-create() {
docker-compose exec --user="azuracast" web letsencrypt_connect $*
exit
}
setup_letsencrypt
#
# Renew an existing LetsEncrypt SSL certificate
# Usage: ./docker.sh letsencrypt-renew
#
letsencrypt-renew() {
docker-compose exec --user="azuracast" web letsencrypt_renew $*
docker-compose stop web
docker-compose rm web
docker-compose up -d
exit
}

View File

@ -5,5 +5,4 @@
* * * * * root sleep 15; /usr/local/bin/cron_task azuracast_cli sync:run nowplaying
* * * * * root sleep 30; /usr/local/bin/cron_task azuracast_cli sync:run nowplaying
* * * * * root sleep 45; /usr/local/bin/cron_task azuracast_cli sync:run nowplaying
0 0 * * * root /usr/local/bin/cron_task letsencrypt_renew
30 */6 * * * root /usr/local/bin/temp_cleanup

View File

@ -1,4 +0,0 @@
#! /bin/bash
set -e
sudo kill -HUP `sudo cat /var/run/nginx.pid`

View File

@ -1,44 +0,0 @@
#!/usr/bin/env bash
if [ `whoami` != 'azuracast' ]; then
echo 'This script must be run as the "azuracast" user. Rerunning...'
sudo -E -u azuracast letsencrypt_connect $@
exit 1
fi
usage ()
{
echo 'Usage: letsencrypt_connect domainname.example.com'
exit
}
if [ "$#" -ne 1 ]
then
usage
fi
DOMAIN=$1
SSL_DIR="/etc/letsencrypt"
LETSENCRYPT_DIR="$SSL_DIR/live/$DOMAIN"
shift
certbot certonly --webroot -w /var/www/letsencrypt -d $DOMAIN $*
if [ -d $LETSENCRYPT_DIR ]; then
cd $SSL_DIR
rm ssl.crt ssl.key
ln -s live/$DOMAIN/fullchain.pem ssl.crt
ln -s live/$DOMAIN/privkey.pem ssl.key
echo 'Reloading nginx...'
sudo kill -HUP `sudo cat /var/run/nginx.pid`
echo 'Domain is ready to be served via LetsEncrypt!'
exit
else
echo "Domain name $DOMAIN is not set up with LetsEncrypt yet. Reverting to self-signed cert..."
letsencrypt_uninstall
exit 1
fi

View File

@ -1,9 +0,0 @@
#!/usr/bin/env sh
if [ `whoami` != 'azuracast' ]; then
echo 'This script must be run as the "azuracast" user. Rerunning...'
sudo -E -u azuracast letsencrypt_renew $@
exit 1
fi
certbot renew --webroot -w /var/www/letsencrypt $*

View File

@ -1,25 +0,0 @@
#!/usr/bin/env bash
if [ `whoami` != 'azuracast' ]; then
echo 'This script must be run as the "azuracast" user. Rerunning...'
sudo -E -u azuracast letsencrypt_uninstall $@
exit 1
fi
SSL_DIR="/etc/letsencrypt"
cd $SSL_DIR
rm ssl.crt ssl.key
openssl req -new -nodes -x509 -subj "/C=US/ST=Texas/L=Austin/O=IT/CN=localhost" \
-days 365 -extensions v3_ca \
-keyout $SSL_DIR/selfsigned.key \
-out $SSL_DIR/selfsigned.crt
ln -s selfsigned.key ssl.key
ln -s selfsigned.crt ssl.crt
sudo kill -HUP `sudo cat /var/run/nginx.pid`
echo "Self-signed certificate restored."
exit

View File

@ -1,25 +0,0 @@
#!/bin/bash
set -e
source /bd_build/buildconfig
set -x
# add-apt-repository -y ppa:certbot/certbot
# apt-get update
$minimal_apt_get_install certbot openssl
mkdir -p /var/www/letsencrypt /var/lib/letsencrypt /etc/letsencrypt/renewal-hooks/deploy /var/log/letsencrypt
chown -R azuracast:azuracast /var/www/letsencrypt /var/lib/letsencrypt /etc/letsencrypt /var/log/letsencrypt
# SSL self-signed cert generation
openssl req -new -nodes -x509 -subj "/C=US/ST=Texas/L=Austin/O=IT/CN=localhost" \
-days 365 -extensions v3_ca \
-keyout /etc/letsencrypt/selfsigned.key \
-out /etc/letsencrypt/selfsigned.crt
ln -s /etc/letsencrypt/selfsigned.key /etc/letsencrypt/ssl.key
ln -s /etc/letsencrypt/selfsigned.crt /etc/letsencrypt/ssl.crt
# Add nginx restart hook.
cp /bd_build/letsencrypt/01-reload-nginx.sh /etc/letsencrypt/renewal-hooks/deploy/01-reload-nginx.sh
chmod 755 /etc/letsencrypt/renewal-hooks/deploy/*