azuracast
This commit is contained in:
parent
d5da608c79
commit
761d106d08
9
srv/azuracast/.env
Normal file
9
srv/azuracast/.env
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
COMPOSE_PROJECT_NAME=azuracast
|
||||||
|
|
||||||
|
AZURACAST_HTTP_PORT=80
|
||||||
|
AZURACAST_HTTPS_PORT=443
|
||||||
|
|
||||||
|
AZURACAST_SFTP_PORT=2022
|
||||||
|
AZURACAST_VERSION=latest
|
||||||
|
LETSENCRYPT_HOST=ac.accroc.radio
|
||||||
|
LETSENCRYPT_EMAIL=
|
112
srv/azuracast/azuracast.env
Normal file
112
srv/azuracast/azuracast.env
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
#
|
||||||
|
# AzuraCast Customization
|
||||||
|
#
|
||||||
|
|
||||||
|
# The application environment.
|
||||||
|
# Valid options: production, development, testing
|
||||||
|
APPLICATION_ENV=production
|
||||||
|
|
||||||
|
# Manually modify the logging level.
|
||||||
|
# This allows you to log debug-level errors temporarily (for problem-solving) or reduce
|
||||||
|
# the volume of logs that are produced by your installation, without needing to modify
|
||||||
|
# whether your installation is a production or development instance.
|
||||||
|
# Valid options: debug, info, notice, warning, error, critical, alert, emergency
|
||||||
|
# LOG_LEVEL=notice
|
||||||
|
|
||||||
|
# Enable certain advanced features inside the web interface, including
|
||||||
|
# advanced playlist coniguration, station port assignment, changing base
|
||||||
|
# media directory, and other functionality that should only be used by
|
||||||
|
# users who are comfortable with advanced functionality.
|
||||||
|
#
|
||||||
|
# Disclaimer: If this is enabled, you are responsible for fixing any errors
|
||||||
|
# that are caused by your misuse of advanced features! In many cases, the easiest
|
||||||
|
# fix is to revert your own changes.
|
||||||
|
#
|
||||||
|
# Valid options: true, false
|
||||||
|
ENABLE_ADVANCED_FEATURES=false
|
||||||
|
|
||||||
|
# Enable the composer "merge" functionality to combine the main application's
|
||||||
|
# composer.json file with any plugins' composer files.
|
||||||
|
# This can have performance implications, so you should only use it if
|
||||||
|
# you use one or more plugins with their own Composer dependencies.
|
||||||
|
# Valid options: true, false
|
||||||
|
COMPOSER_PLUGIN_MODE=false
|
||||||
|
|
||||||
|
# The minimum port number to use when automatically assigning ports to a station.
|
||||||
|
# By default, this matches the first forwarded port on the "stations" container.
|
||||||
|
# You can modify this variable if your station port range is different.
|
||||||
|
# Be sure to also forward the necessary ports via `docker-compose.yml`
|
||||||
|
# (and nginx, if you want to use the built-in port-80/443 proxy)!
|
||||||
|
AUTO_ASSIGN_PORT_MIN=8000
|
||||||
|
|
||||||
|
# The maximum port number to use when automatically assigning ports to a station.
|
||||||
|
# See AUTO_ASSIGN_PORT_MIN.
|
||||||
|
AUTO_ASSIGN_PORT_MAX=8499
|
||||||
|
|
||||||
|
#
|
||||||
|
# Database Configuration
|
||||||
|
# --
|
||||||
|
# Once the database has been installed, DO NOT CHANGE these values!
|
||||||
|
#
|
||||||
|
|
||||||
|
# The host to connect to. Leave this as the default value unless you're connecting
|
||||||
|
# to an external database server.
|
||||||
|
# Default: mariadb
|
||||||
|
MYSQL_HOST=mariadb
|
||||||
|
|
||||||
|
# The port to connect to. Leave this as the default value unless you're connecting
|
||||||
|
# to an external database server.
|
||||||
|
# Default: 3306
|
||||||
|
MYSQL_PORT=3306
|
||||||
|
|
||||||
|
# The username AzuraCast will use to connect to the database.
|
||||||
|
# Default: azuracast
|
||||||
|
MYSQL_USER=azuracast
|
||||||
|
|
||||||
|
# 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
|
||||||
|
# an internal password used by the service itself.
|
||||||
|
# Default: 0000000000000000000000000
|
||||||
|
MYSQL_PASSWORD=00000000000000000000000000
|
||||||
|
|
||||||
|
# The name of the AzuraCast database.
|
||||||
|
# Default: azuracast
|
||||||
|
MYSQL_DATABASE=azuracast
|
||||||
|
|
||||||
|
# Automatically generate a random root password upon the first database spin-up.
|
||||||
|
# This password will be visible in the mariadb container's logs.
|
||||||
|
# Default: yes
|
||||||
|
MYSQL_RANDOM_ROOT_PASSWORD=yes
|
||||||
|
|
||||||
|
# Log slower queries for the purpose of diagnosing issues. Only turn this on when
|
||||||
|
# you need to, by uncommenting this and switching it to 1.
|
||||||
|
# To read the slow query log once enabled, run:
|
||||||
|
# docker-compose exec mariadb slow_queries
|
||||||
|
# Default: 0
|
||||||
|
MYSQL_SLOW_QUERY_LOG=0
|
||||||
|
|
||||||
|
#
|
||||||
|
# Advanced Configuration
|
||||||
|
#
|
||||||
|
|
||||||
|
# Override the IP/hostname to use when negotiating inbound FTP Passive Mode (PASV) connections.
|
||||||
|
# The system will attempt to automatically detect this, so you often don't need to change it.
|
||||||
|
# FTP_PASV_IP=localhost
|
||||||
|
|
||||||
|
# PHP's maximum POST body size and max upload filesize.
|
||||||
|
# PHP_MAX_FILE_SIZE=25M
|
||||||
|
|
||||||
|
# PHP's maximum memory limit.
|
||||||
|
# PHP_MEMORY_LIMIT=128M
|
||||||
|
|
||||||
|
# PHP's maximum script execution time (in seconds).
|
||||||
|
# PHP_MAX_EXECUTION_TIME=30
|
||||||
|
|
||||||
|
# Maximum number of PHP-FPM worker processes to spawn.
|
||||||
|
# PHP_FPM_MAX_CHILDREN=5
|
||||||
|
|
||||||
|
# Create additional media sync worker processes.
|
||||||
|
# This setting can be used to increase the performance of the media sync process
|
||||||
|
# by creating additional worker processes to consume messages
|
||||||
|
# Default: 0
|
||||||
|
# ADDITIONAL_MEDIA_SYNC_WORKER_COUNT=0
|
6
srv/azuracast/docker-compose.override.yml
Normal file
6
srv/azuracast/docker-compose.override.yml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
version: '2.2'
|
||||||
|
|
||||||
|
services:
|
||||||
|
stations:
|
||||||
|
volumes:
|
||||||
|
- /srv/azuracast/media/musica-default.mp3:/usr/local/share/icecast/web/error.mp3
|
294
srv/azuracast/docker-compose.yml
Normal file
294
srv/azuracast/docker-compose.yml
Normal file
|
@ -0,0 +1,294 @@
|
||||||
|
#
|
||||||
|
# AzuraCast Docker Compose Configuration File
|
||||||
|
#
|
||||||
|
# When updating, you will be prompted to replace this file with a new
|
||||||
|
# version; you should do this whenever possible to take advantage of
|
||||||
|
# new updates.
|
||||||
|
#
|
||||||
|
# If you need to customize this file, you can create a new file named:
|
||||||
|
# docker-compose.override.yml
|
||||||
|
# with any changes you need to make.
|
||||||
|
#
|
||||||
|
version: '2.2'
|
||||||
|
|
||||||
|
services:
|
||||||
|
nginx_proxy:
|
||||||
|
image: "azuracast/azuracast_nginx_proxy:${AZURACAST_VERSION:-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}
|
||||||
|
networks:
|
||||||
|
- frontend
|
||||||
|
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}
|
||||||
|
networks:
|
||||||
|
- frontend
|
||||||
|
restart: always
|
||||||
|
|
||||||
|
web:
|
||||||
|
container_name: azuracast_web
|
||||||
|
image: "azuracast/azuracast_web_v2:${AZURACAST_VERSION:-latest}"
|
||||||
|
# Want to customize the HTTP/S ports? Follow the instructions here:
|
||||||
|
# https://www.azuracast.com/help/docker/#use-non-standard-ports
|
||||||
|
ports:
|
||||||
|
- '${AZURACAST_SFTP_PORT:-2022}:2022'
|
||||||
|
depends_on:
|
||||||
|
- mariadb
|
||||||
|
- stations
|
||||||
|
- redis
|
||||||
|
env_file: azuracast.env
|
||||||
|
environment:
|
||||||
|
LANG: ${LANG:-en_US.UTF-8}
|
||||||
|
AZURACAST_DC_REVISION: 11
|
||||||
|
AZURACAST_VERSION: ${AZURACAST_VERSION:-latest}
|
||||||
|
AZURACAST_SFTP_PORT: ${AZURACAST_SFTP_PORT:-2022}
|
||||||
|
VIRTUAL_HOST: ${LETSENCRYPT_HOST:-azuracast.local}
|
||||||
|
LETSENCRYPT_HOST: ${LETSENCRYPT_HOST}
|
||||||
|
LETSENCRYPT_EMAIL: ${LETSENCRYPT_EMAIL}
|
||||||
|
volumes:
|
||||||
|
- letsencrypt:/etc/nginx/certs:ro
|
||||||
|
- www_vendor:/var/azuracast/www/vendor
|
||||||
|
- 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: always
|
||||||
|
ulimits: &default-ulimits
|
||||||
|
nofile:
|
||||||
|
soft: 65536
|
||||||
|
hard: 65536
|
||||||
|
logging: &default-logging
|
||||||
|
options:
|
||||||
|
max-size: "1m"
|
||||||
|
max-file: "5"
|
||||||
|
|
||||||
|
mariadb:
|
||||||
|
image: "azuracast/azuracast_db:${AZURACAST_VERSION:-latest}"
|
||||||
|
volumes:
|
||||||
|
- db_data:/var/lib/mysql
|
||||||
|
env_file: azuracast.env
|
||||||
|
networks:
|
||||||
|
- backend
|
||||||
|
restart: always
|
||||||
|
logging: *default-logging
|
||||||
|
|
||||||
|
redis:
|
||||||
|
image: "azuracast/azuracast_redis:${AZURACAST_VERSION:-latest}"
|
||||||
|
sysctls:
|
||||||
|
net.core.somaxconn: 1024
|
||||||
|
volumes:
|
||||||
|
- redis_data:/data
|
||||||
|
networks:
|
||||||
|
- backend
|
||||||
|
restart: always
|
||||||
|
logging: *default-logging
|
||||||
|
|
||||||
|
stations:
|
||||||
|
container_name: azuracast_stations
|
||||||
|
image: "azuracast/azuracast_radio:${AZURACAST_VERSION:-latest}"
|
||||||
|
ports:
|
||||||
|
# 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.
|
||||||
|
# For instructions, see:
|
||||||
|
# https://www.azuracast.com/help/docker/#expand-the-docker-radio-station-port-range
|
||||||
|
- '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'
|
||||||
|
- '8050:8050'
|
||||||
|
- '8055:8055'
|
||||||
|
- '8056:8056'
|
||||||
|
- '8060:8060'
|
||||||
|
- '8065:8065'
|
||||||
|
- '8066:8066'
|
||||||
|
- '8070:8070'
|
||||||
|
- '8075:8075'
|
||||||
|
- '8076:8076'
|
||||||
|
- '8090:8090'
|
||||||
|
- '8095:8095'
|
||||||
|
- '8096:8096'
|
||||||
|
- '8100:8100'
|
||||||
|
- '8105:8105'
|
||||||
|
- '8106:8106'
|
||||||
|
- '8110:8110'
|
||||||
|
- '8115:8115'
|
||||||
|
- '8116:8116'
|
||||||
|
- '8120:8120'
|
||||||
|
- '8125:8125'
|
||||||
|
- '8126:8126'
|
||||||
|
- '8130:8130'
|
||||||
|
- '8135:8135'
|
||||||
|
- '8136:8136'
|
||||||
|
- '8140:8140'
|
||||||
|
- '8145:8145'
|
||||||
|
- '8146:8146'
|
||||||
|
- '8150:8150'
|
||||||
|
- '8155:8155'
|
||||||
|
- '8156:8156'
|
||||||
|
- '8160:8160'
|
||||||
|
- '8165:8165'
|
||||||
|
- '8166:8166'
|
||||||
|
- '8170:8170'
|
||||||
|
- '8175:8175'
|
||||||
|
- '8176:8176'
|
||||||
|
- '8180:8180'
|
||||||
|
- '8185:8185'
|
||||||
|
- '8186:8186'
|
||||||
|
- '8190:8190'
|
||||||
|
- '8195:8195'
|
||||||
|
- '8196:8196'
|
||||||
|
- '8200:8200'
|
||||||
|
- '8205:8205'
|
||||||
|
- '8206:8206'
|
||||||
|
- '8210:8210'
|
||||||
|
- '8215:8215'
|
||||||
|
- '8216:8216'
|
||||||
|
- '8220:8220'
|
||||||
|
- '8225:8225'
|
||||||
|
- '8226:8226'
|
||||||
|
- '8230:8230'
|
||||||
|
- '8235:8235'
|
||||||
|
- '8236:8236'
|
||||||
|
- '8240:8240'
|
||||||
|
- '8245:8245'
|
||||||
|
- '8246:8246'
|
||||||
|
- '8250:8250'
|
||||||
|
- '8255:8255'
|
||||||
|
- '8256:8256'
|
||||||
|
- '8260:8260'
|
||||||
|
- '8265:8265'
|
||||||
|
- '8266:8266'
|
||||||
|
- '8270:8270'
|
||||||
|
- '8275:8275'
|
||||||
|
- '8276:8276'
|
||||||
|
- '8280:8280'
|
||||||
|
- '8285:8285'
|
||||||
|
- '8286:8286'
|
||||||
|
- '8290:8290'
|
||||||
|
- '8295:8295'
|
||||||
|
- '8296:8296'
|
||||||
|
- '8300:8300'
|
||||||
|
- '8305:8305'
|
||||||
|
- '8306:8306'
|
||||||
|
- '8310:8310'
|
||||||
|
- '8315:8315'
|
||||||
|
- '8316:8316'
|
||||||
|
- '8320:8320'
|
||||||
|
- '8325:8325'
|
||||||
|
- '8326:8326'
|
||||||
|
- '8330:8330'
|
||||||
|
- '8335:8335'
|
||||||
|
- '8336:8336'
|
||||||
|
- '8340:8340'
|
||||||
|
- '8345:8345'
|
||||||
|
- '8346:8346'
|
||||||
|
- '8350:8350'
|
||||||
|
- '8355:8355'
|
||||||
|
- '8356:8356'
|
||||||
|
- '8360:8360'
|
||||||
|
- '8365:8365'
|
||||||
|
- '8366:8366'
|
||||||
|
- '8370:8370'
|
||||||
|
- '8375:8375'
|
||||||
|
- '8376:8376'
|
||||||
|
- '8380:8380'
|
||||||
|
- '8385:8385'
|
||||||
|
- '8386:8386'
|
||||||
|
- '8390:8390'
|
||||||
|
- '8395:8395'
|
||||||
|
- '8396:8396'
|
||||||
|
- '8400:8400'
|
||||||
|
- '8405:8405'
|
||||||
|
- '8406:8406'
|
||||||
|
- '8410:8410'
|
||||||
|
- '8415:8415'
|
||||||
|
- '8416:8416'
|
||||||
|
- '8420:8420'
|
||||||
|
- '8425:8425'
|
||||||
|
- '8426:8426'
|
||||||
|
- '8430:8430'
|
||||||
|
- '8435:8435'
|
||||||
|
- '8436:8436'
|
||||||
|
- '8440:8440'
|
||||||
|
- '8445:8445'
|
||||||
|
- '8446:8446'
|
||||||
|
- '8450:8450'
|
||||||
|
- '8455:8455'
|
||||||
|
- '8456:8456'
|
||||||
|
- '8460:8460'
|
||||||
|
- '8465:8465'
|
||||||
|
- '8466:8466'
|
||||||
|
- '8470:8470'
|
||||||
|
- '8475:8475'
|
||||||
|
- '8476:8476'
|
||||||
|
- '8480:8480'
|
||||||
|
- '8485:8485'
|
||||||
|
- '8486:8486'
|
||||||
|
- '8490:8490'
|
||||||
|
- '8495:8495'
|
||||||
|
- '8496:8496'
|
||||||
|
volumes:
|
||||||
|
- station_data:/var/azuracast/stations
|
||||||
|
- shoutcast2_install:/var/azuracast/servers/shoutcast2
|
||||||
|
- letsencrypt:/etc/nginx/certs:ro
|
||||||
|
- tmp_data:/var/azuracast/www_tmp
|
||||||
|
networks:
|
||||||
|
- frontend
|
||||||
|
- backend
|
||||||
|
init: true
|
||||||
|
restart: always
|
||||||
|
ulimits: *default-ulimits
|
||||||
|
logging: *default-logging
|
||||||
|
|
||||||
|
networks:
|
||||||
|
frontend:
|
||||||
|
driver: bridge
|
||||||
|
backend:
|
||||||
|
driver: bridge
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
nginx_proxy_vhosts: { }
|
||||||
|
db_data: { }
|
||||||
|
letsencrypt: { }
|
||||||
|
letsencrypt_html: { }
|
||||||
|
shoutcast2_install: { }
|
||||||
|
geolite_install: { }
|
||||||
|
sftpgo_data: { }
|
||||||
|
station_data: { }
|
||||||
|
www_vendor: { }
|
||||||
|
tmp_data: { }
|
||||||
|
redis_data: { }
|
||||||
|
backups: { }
|
586
srv/azuracast/docker.sh
Executable file
586
srv/azuracast/docker.sh
Executable file
|
@ -0,0 +1,586 @@
|
||||||
|
#!/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
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
# 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
|
||||||
|
# gets a valid answer.
|
||||||
|
ask() {
|
||||||
|
# https://djm.me/ask
|
||||||
|
local prompt default reply
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
|
||||||
|
if [[ "${2:-}" == "Y" ]]; then
|
||||||
|
prompt="Y/n"
|
||||||
|
default=Y
|
||||||
|
elif [[ "${2:-}" == "N" ]]; then
|
||||||
|
prompt="y/N"
|
||||||
|
default=N
|
||||||
|
else
|
||||||
|
prompt="y/n"
|
||||||
|
default=
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Ask the question (not using "read -p" as it uses stderr not stdout)
|
||||||
|
echo -n "$1 [$prompt] "
|
||||||
|
|
||||||
|
read reply
|
||||||
|
|
||||||
|
# Default?
|
||||||
|
if [[ -z "$reply" ]]; then
|
||||||
|
reply=${default}
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if the reply is valid
|
||||||
|
case "$reply" in
|
||||||
|
Y* | y*) return 0 ;;
|
||||||
|
N* | n*) return 1 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# Generate a prompt to set an environment file value.
|
||||||
|
envfile-set() {
|
||||||
|
local VALUE INPUT
|
||||||
|
|
||||||
|
.env --file .env
|
||||||
|
|
||||||
|
.env get "$1"
|
||||||
|
VALUE=${REPLY:-$2}
|
||||||
|
|
||||||
|
echo -n "$3 [$VALUE]: "
|
||||||
|
read INPUT
|
||||||
|
|
||||||
|
VALUE=${INPUT:-$VALUE}
|
||||||
|
|
||||||
|
.env set "${1}=${VALUE}"
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Configure the ports used by AzuraCast.
|
||||||
|
#
|
||||||
|
setup-ports() {
|
||||||
|
envfile-set "AZURACAST_HTTP_PORT" "80" "Port to use for HTTP connections"
|
||||||
|
envfile-set "AZURACAST_HTTPS_PORT" "443" "Port to use for HTTPS connections"
|
||||||
|
envfile-set "AZURACAST_SFTP_PORT" "2022" "Port to use for SFTP connections"
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Configure the settings used by LetsEncrypt.
|
||||||
|
#
|
||||||
|
setup-letsencrypt() {
|
||||||
|
envfile-set "LETSENCRYPT_HOST" "" "Domain name (example.com) or names (example.com,foo.bar) to use with LetsEncrypt"
|
||||||
|
envfile-set "LETSENCRYPT_EMAIL" "" "Optional e-mail address for expiration updates"
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Configure release mode settings.
|
||||||
|
#
|
||||||
|
setup-release() {
|
||||||
|
local AZURACAST_VERSION="latest"
|
||||||
|
if ask "Prefer stable release versions of AzuraCast?" N; then
|
||||||
|
AZURACAST_VERSION="stable"
|
||||||
|
fi
|
||||||
|
|
||||||
|
.env --file .env set AZURACAST_VERSION=${AZURACAST_VERSION}
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Run the initial installer of Docker and AzuraCast.
|
||||||
|
# Usage: ./docker.sh install
|
||||||
|
#
|
||||||
|
install() {
|
||||||
|
if [[ ! $(command -v curl) ]]; then
|
||||||
|
echo "cURL does not appear to be installed."
|
||||||
|
echo "Install curl using your host's package manager,"
|
||||||
|
echo "then continue installing using this script."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $(command -v docker) && $(docker --version) ]]; then
|
||||||
|
echo "Docker is already installed! Continuing..."
|
||||||
|
else
|
||||||
|
if ask "Docker does not appear to be installed. Install Docker now?" Y; then
|
||||||
|
curl -fsSL get.docker.com -o get-docker.sh
|
||||||
|
sh get-docker.sh
|
||||||
|
rm get-docker.sh
|
||||||
|
|
||||||
|
if [[ $EUID -ne 0 ]]; then
|
||||||
|
sudo usermod -aG docker "$(whoami)"
|
||||||
|
|
||||||
|
echo "You must log out or restart to apply necessary Docker permissions changes."
|
||||||
|
echo "Restart, then continue installing using this script."
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $(command -v docker-compose) && $(docker-compose --version) ]]; then
|
||||||
|
echo "Docker Compose is already installed! Continuing..."
|
||||||
|
else
|
||||||
|
if ask "Docker Compose does not appear to be installed. Install Docker Compose now?" Y; then
|
||||||
|
local COMPOSE_VERSION=1.25.3
|
||||||
|
|
||||||
|
if [[ $EUID -ne 0 ]]; then
|
||||||
|
if [[ ! $(command -v sudo) ]]; then
|
||||||
|
echo "Sudo does not appear to be installed."
|
||||||
|
echo "Install sudo using your host's package manager,"
|
||||||
|
echo "then continue installing using this script."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
sudo sh -c "curl -fsSL https://github.com/docker/compose/releases/download/${COMPOSE_VERSION}/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose"
|
||||||
|
sudo chmod +x /usr/local/bin/docker-compose
|
||||||
|
sudo sh -c "curl -fsSL https://raw.githubusercontent.com/docker/compose/${COMPOSE_VERSION}/contrib/completion/bash/docker-compose -o /etc/bash_completion.d/docker-compose"
|
||||||
|
else
|
||||||
|
curl -fsSL https://github.com/docker/compose/releases/download/${COMPOSE_VERSION}/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
|
||||||
|
chmod +x /usr/local/bin/docker-compose
|
||||||
|
curl -fsSL https://raw.githubusercontent.com/docker/compose/${COMPOSE_VERSION}/contrib/completion/bash/docker-compose -o /etc/bash_completion.d/docker-compose
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -f .env ]]; then
|
||||||
|
echo "Writing default .env file..."
|
||||||
|
curl -fsSL https://raw.githubusercontent.com/AzuraCast/AzuraCast/master/sample.env -o .env
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -f azuracast.env ]]; then
|
||||||
|
echo "Creating default AzuraCast settings file..."
|
||||||
|
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.
|
||||||
|
local NEW_PASSWORD
|
||||||
|
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
|
||||||
|
|
||||||
|
setup-release
|
||||||
|
|
||||||
|
if [[ ! -f docker-compose.yml ]]; then
|
||||||
|
echo "Retrieving default docker-compose.yml file..."
|
||||||
|
|
||||||
|
.env --file .env get AZURACAST_VERSION
|
||||||
|
local AZURACAST_VERSION
|
||||||
|
AZURACAST_VERSION="${REPLY:-latest}"
|
||||||
|
|
||||||
|
if [[ $AZURACAST_VERSION == "stable" ]]; then
|
||||||
|
curl -fsSL https://raw.githubusercontent.com/AzuraCast/AzuraCast/stable/docker-compose.sample.yml -o docker-compose.yml
|
||||||
|
else
|
||||||
|
curl -fsSL https://raw.githubusercontent.com/AzuraCast/AzuraCast/master/docker-compose.sample.yml -o docker-compose.yml
|
||||||
|
fi
|
||||||
|
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 --rm --user="azuracast" web azuracast_install "$@"
|
||||||
|
docker-compose up -d
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Update the Docker images and codebase.
|
||||||
|
# Usage: ./docker.sh update
|
||||||
|
#
|
||||||
|
update() {
|
||||||
|
if ask "Please make sure your AzuraCast installation is backed up before updating. Continue?" Y; then
|
||||||
|
# Check for a new Docker Utility Script.
|
||||||
|
curl -fsSL https://raw.githubusercontent.com/AzuraCast/AzuraCast/master/docker.sh -o docker.new.sh
|
||||||
|
|
||||||
|
local UTILITY_FILES_MATCH
|
||||||
|
UTILITY_FILES_MATCH="$(
|
||||||
|
cmp --silent docker.sh docker.new.sh
|
||||||
|
echo $?
|
||||||
|
)"
|
||||||
|
local UPDATE_UTILITY=0
|
||||||
|
|
||||||
|
if [[ ${UTILITY_FILES_MATCH} -ne 0 ]]; then
|
||||||
|
if ask "The Docker Utility Script has changed since your version. Update to latest version?" Y; then
|
||||||
|
UPDATE_UTILITY=1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ${UPDATE_UTILITY} -ne 0 ]]; then
|
||||||
|
mv docker.new.sh docker.sh
|
||||||
|
chmod a+x docker.sh
|
||||||
|
|
||||||
|
echo "A new Docker Utility Script has been downloaded."
|
||||||
|
echo "Please re-run the update process to continue."
|
||||||
|
exit
|
||||||
|
else
|
||||||
|
rm docker.new.sh
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -f azuracast.env ]]; then
|
||||||
|
curl -fsSL https://raw.githubusercontent.com/AzuraCast/AzuraCast/master/azuracast.sample.env -o azuracast.env
|
||||||
|
echo "Default environment file loaded."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Migrate previous release settings to new environment variable.
|
||||||
|
.env --file azuracast.env get PREFER_RELEASE_BUILDS
|
||||||
|
|
||||||
|
local PREFER_RELEASE_BUILDS
|
||||||
|
PREFER_RELEASE_BUILDS="${REPLY:-false}"
|
||||||
|
|
||||||
|
if [[ $PREFER_RELEASE_BUILDS == "true" ]]; then
|
||||||
|
.env --file .env set AZURACAST_VERSION=stable
|
||||||
|
fi
|
||||||
|
|
||||||
|
.env --file azuracast.env set PREFER_RELEASE_BUILDS
|
||||||
|
|
||||||
|
# Check for new Docker Compose file
|
||||||
|
.env --file .env get AZURACAST_VERSION
|
||||||
|
local AZURACAST_VERSION
|
||||||
|
AZURACAST_VERSION="${REPLY:-latest}"
|
||||||
|
|
||||||
|
if [[ $AZURACAST_VERSION == "stable" ]]; then
|
||||||
|
curl -fsSL https://raw.githubusercontent.com/AzuraCast/AzuraCast/stable/docker-compose.sample.yml -o docker-compose.new.yml
|
||||||
|
else
|
||||||
|
curl -fsSL https://raw.githubusercontent.com/AzuraCast/AzuraCast/master/docker-compose.sample.yml -o docker-compose.new.yml
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check for updated Docker Compose config.
|
||||||
|
local COMPOSE_FILES_MATCH
|
||||||
|
COMPOSE_FILES_MATCH="$(
|
||||||
|
cmp --silent docker-compose.yml docker-compose.new.yml
|
||||||
|
echo $?
|
||||||
|
)"
|
||||||
|
local UPDATE_COMPOSE=0
|
||||||
|
|
||||||
|
if [[ ${COMPOSE_FILES_MATCH} -ne 0 ]]; then
|
||||||
|
if ask "The docker-compose.yml file has changed since your version. Overwrite? This will overwrite any customizations you made to this file?" Y; then
|
||||||
|
UPDATE_COMPOSE=1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ${UPDATE_COMPOSE} -ne 0 ]]; then
|
||||||
|
docker-compose -f docker-compose.new.yml pull
|
||||||
|
docker-compose down
|
||||||
|
|
||||||
|
cp docker-compose.yml docker-compose.backup.yml
|
||||||
|
mv docker-compose.new.yml docker-compose.yml
|
||||||
|
else
|
||||||
|
rm docker-compose.new.yml
|
||||||
|
|
||||||
|
docker-compose pull
|
||||||
|
docker-compose down
|
||||||
|
fi
|
||||||
|
|
||||||
|
docker volume rm azuracast_www_vendor
|
||||||
|
docker volume rm azuracast_tmp_data
|
||||||
|
docker volume rm azuracast_redis_data
|
||||||
|
|
||||||
|
docker-compose run --rm --user="azuracast" web azuracast_update "$@"
|
||||||
|
docker-compose up -d
|
||||||
|
|
||||||
|
docker system prune -f
|
||||||
|
|
||||||
|
echo "Update complete!"
|
||||||
|
fi
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Update this Docker utility script.
|
||||||
|
# Usage: ./docker.sh update-self
|
||||||
|
#
|
||||||
|
update-self() {
|
||||||
|
curl -fsSL https://raw.githubusercontent.com/AzuraCast/AzuraCast/master/docker.sh -o docker.sh
|
||||||
|
chmod a+x docker.sh
|
||||||
|
|
||||||
|
echo "New Docker utility script downloaded."
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Run a CLI command inside the Docker container.
|
||||||
|
# Usage: ./docker.sh cli [command]
|
||||||
|
#
|
||||||
|
cli() {
|
||||||
|
docker-compose run --rm --user="azuracast" web azuracast_cli "$@"
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Enter the bash terminal of the running web container.
|
||||||
|
# Usage: ./docker.sh bash
|
||||||
|
#
|
||||||
|
bash() {
|
||||||
|
docker-compose exec --user="azuracast" web bash
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Back up the Docker volumes to a .tar.gz file.
|
||||||
|
# Usage:
|
||||||
|
# ./docker.sh backup [/custom/backup/dir/custombackupname.zip]
|
||||||
|
#
|
||||||
|
backup() {
|
||||||
|
BACKUP_PATH=${1:-"./backup.tar.gz"}
|
||||||
|
BACKUP_FILENAME=$(basename -- "$BACKUP_PATH")
|
||||||
|
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}"
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Restore an AzuraCast backup into Docker.
|
||||||
|
# Usage:
|
||||||
|
# ./docker.sh restore [/custom/backup/dir/custombackupname.zip]
|
||||||
|
#
|
||||||
|
restore() {
|
||||||
|
BACKUP_PATH=${1:-"./backup.tar.gz"}
|
||||||
|
BACKUP_FILENAME=$(basename -- "$BACKUP_PATH")
|
||||||
|
BACKUP_EXT="${BACKUP_FILENAME##*.}"
|
||||||
|
shift
|
||||||
|
|
||||||
|
if [[ ! -f .env ]] || [[ ! -f azuracast.env ]]; then
|
||||||
|
echo "AzuraCast hasn't been installed yet on this server."
|
||||||
|
echo "You should run './docker.sh install' first before restoring."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -f ${BACKUP_PATH} ]]; then
|
||||||
|
echo "File '${BACKUP_PATH}' does not exist. Nothing to restore."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ask "Restoring will remove any existing AzuraCast installation data, replacing it with your backup. Continue?" Y; then
|
||||||
|
docker-compose down -v
|
||||||
|
docker-compose pull
|
||||||
|
|
||||||
|
# Run the web task to allow for a full system spin-up
|
||||||
|
docker-compose run --rm --user=azuracast web azuracast_cli cache:clear
|
||||||
|
|
||||||
|
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-compose down
|
||||||
|
docker-compose up -d
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Restore the Docker volumes from a legacy backup format .tar.gz file.
|
||||||
|
# Usage:
|
||||||
|
# ./docker.sh restore [/custom/backup/dir/custombackupname.tar.gz]
|
||||||
|
#
|
||||||
|
restore-legacy() {
|
||||||
|
local APP_BASE_DIR BACKUP_PATH BACKUP_DIR BACKUP_FILENAME
|
||||||
|
|
||||||
|
APP_BASE_DIR=$(pwd)
|
||||||
|
|
||||||
|
BACKUP_PATH=${1:-"./backup.tar.gz"}
|
||||||
|
BACKUP_DIR=$(cd "$(dirname "$BACKUP_PATH")" && pwd)
|
||||||
|
BACKUP_FILENAME=$(basename "$BACKUP_PATH")
|
||||||
|
|
||||||
|
cd "$APP_BASE_DIR" || exit
|
||||||
|
|
||||||
|
if [ -f "$BACKUP_PATH" ]; then
|
||||||
|
docker-compose down
|
||||||
|
|
||||||
|
docker volume rm azuracast_db_data azuracast_station_data
|
||||||
|
docker volume create azuracast_db_data
|
||||||
|
docker volume create azuracast_station_data
|
||||||
|
|
||||||
|
docker run --rm -v "$BACKUP_DIR:/backup" \
|
||||||
|
-v azuracast_db_data:/azuracast/db \
|
||||||
|
-v azuracast_station_data:/azuracast/stations \
|
||||||
|
busybox tar zxvf "/backup/$BACKUP_FILENAME"
|
||||||
|
|
||||||
|
docker-compose up -d
|
||||||
|
else
|
||||||
|
echo "File $BACKUP_PATH does not exist in this directory. Nothing to restore."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# DEVELOPER TOOL:
|
||||||
|
# Access the static console as a developer.
|
||||||
|
# Usage: ./docker.sh static [static_container_command]
|
||||||
|
#
|
||||||
|
static() {
|
||||||
|
cd frontend || exit
|
||||||
|
docker-compose build
|
||||||
|
docker-compose run --rm frontend "$@"
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Stop all Docker containers and remove related volumes.
|
||||||
|
# Usage: ./docker.sh uninstall
|
||||||
|
#
|
||||||
|
uninstall() {
|
||||||
|
if ask "This operation is destructive and will wipe your existing Docker containers. Continue?" N; then
|
||||||
|
|
||||||
|
docker-compose down -v
|
||||||
|
docker-compose rm -f
|
||||||
|
docker volume prune -f
|
||||||
|
|
||||||
|
echo "All AzuraCast Docker containers and volumes were removed."
|
||||||
|
echo "To remove *all* Docker containers and volumes, run:"
|
||||||
|
echo " docker stop \$(docker ps -a -q)"
|
||||||
|
echo " docker rm \$(docker ps -a -q)"
|
||||||
|
echo " docker volume prune -f"
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Create and link a LetsEncrypt SSL certificate.
|
||||||
|
# Usage: ./docker.sh letsencrypt-create
|
||||||
|
#
|
||||||
|
letsencrypt-create() {
|
||||||
|
setup-letsencrypt
|
||||||
|
|
||||||
|
docker-compose stop web
|
||||||
|
docker-compose rm -f web
|
||||||
|
docker-compose up -d
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Utility script to facilitate switching ports.
|
||||||
|
# Usage: ./docker.sh change-ports
|
||||||
|
#
|
||||||
|
change-ports() {
|
||||||
|
setup-ports
|
||||||
|
|
||||||
|
docker-compose down
|
||||||
|
docker-compose up -d
|
||||||
|
}
|
||||||
|
|
||||||
|
"$@"
|
Loading…
Reference in New Issue
Block a user