Add web container Docker code to this repo; tie image to code version.
This commit is contained in:
parent
5bf69298b4
commit
153f7a8ec7
|
@ -0,0 +1,17 @@
|
|||
# Files in the root directory
|
||||
/*
|
||||
/.*
|
||||
|
||||
!/composer.json
|
||||
!/composer.lock
|
||||
|
||||
# Git/GitHub internal directories
|
||||
/.git
|
||||
/.github
|
||||
|
||||
# Non-code folders
|
||||
/frontend
|
||||
/resources
|
||||
!/resources/locale/compiled
|
||||
/util
|
||||
!/util/docker/web
|
|
@ -0,0 +1,84 @@
|
|||
# SFTPGo build stage
|
||||
FROM golang:stretch as sftpgo
|
||||
LABEL maintainer="nicola.murino@gmail.com"
|
||||
|
||||
RUN go get -d github.com/drakkan/sftpgo
|
||||
WORKDIR /go/src/github.com/drakkan/sftpgo
|
||||
|
||||
ARG build_commit="8e604f888a3a3c324500ba261cd1789ee8d80f0d"
|
||||
|
||||
# uncomment the next line to get the latest stable version instead of the latest git
|
||||
# RUN git checkout `git rev-list --tags --max-count=1`
|
||||
RUN go build -i -ldflags "-s -w -X github.com/drakkan/sftpgo/utils.commit=`git describe --always --dirty` -X github.com/drakkan/sftpgo/utils.date=`date -u +%FT%TZ`" -o sftpgo
|
||||
|
||||
#
|
||||
# Main build stage
|
||||
#
|
||||
FROM ubuntu:bionic
|
||||
|
||||
ENV TZ="UTC"
|
||||
|
||||
# Run base build process
|
||||
COPY ./util/docker/web/ /bd_build
|
||||
|
||||
COPY --from=sftpgo /go/src/github.com/drakkan/sftpgo/sftpgo /usr/local/sbin/sftpgo
|
||||
|
||||
RUN chmod a+x /bd_build/*.sh \
|
||||
&& /bd_build/prepare.sh \
|
||||
&& /bd_build/add_user.sh \
|
||||
&& /bd_build/setup.sh \
|
||||
&& /bd_build/cleanup.sh \
|
||||
&& rm -rf /bd_build
|
||||
|
||||
#
|
||||
# START Operations as `azuracast` user
|
||||
#
|
||||
USER azuracast
|
||||
|
||||
WORKDIR /var/azuracast/www
|
||||
|
||||
# Add code
|
||||
COPY --chown=azuracast:azuracast ./composer.json ./composer.lock ./
|
||||
RUN composer install \
|
||||
--ignore-platform-reqs \
|
||||
--no-ansi \
|
||||
--no-autoloader \
|
||||
--no-interaction \
|
||||
--no-scripts
|
||||
|
||||
# We need to copy our whole application so that we can generate the autoload file inside the vendor folder.
|
||||
COPY --chown=azuracast:azuracast . .
|
||||
|
||||
RUN composer dump-autoload --optimize --classmap-authoritative \
|
||||
&& touch /var/azuracast/.docker
|
||||
|
||||
VOLUME ["/var/azuracast/www", "/var/azuracast/backups", "/etc/letsencrypt", "/var/azuracast/sftpgo/persist"]
|
||||
|
||||
#
|
||||
# END Operations as `azuracast` user
|
||||
#
|
||||
USER root
|
||||
|
||||
EXPOSE 80 443 2022
|
||||
|
||||
# Nginx Proxy environment variables.
|
||||
ENV VIRTUAL_HOST="azuracast.local" \
|
||||
HTTPS_METHOD="noredirect"
|
||||
|
||||
# Sensible default environment variables.
|
||||
ENV APPLICATION_ENV="production" \
|
||||
MYSQL_HOST="mariadb" \
|
||||
MYSQL_PORT=3306 \
|
||||
MYSQL_USER="azuracast" \
|
||||
MYSQL_PASSWORD="azur4c457" \
|
||||
MYSQL_DATABASE="azuracast" \
|
||||
PREFER_RELEASE_BUILDS="false" \
|
||||
COMPOSER_PLUGIN_MODE="false" \
|
||||
ADDITIONAL_MEDIA_SYNC_WORKER_COUNT=0
|
||||
|
||||
# Entrypoint and default command
|
||||
ENTRYPOINT ["dockerize",\
|
||||
"-wait","tcp://mariadb:3306",\
|
||||
"-wait","tcp://influxdb:8086",\
|
||||
"-timeout","40s"]
|
||||
CMD ["/usr/local/bin/my_init"]
|
|
@ -18,7 +18,7 @@ services:
|
|||
web:
|
||||
image: azuracast/azuracast_web_v2:latest
|
||||
build:
|
||||
context: ../docker-azuracast-web-v2
|
||||
context: .
|
||||
depends_on:
|
||||
- mariadb
|
||||
- influxdb
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
source /bd_build/buildconfig
|
||||
set -x
|
||||
|
||||
$minimal_apt_get_install sudo
|
||||
|
||||
adduser --home /var/azuracast --disabled-password --gecos "" azuracast
|
||||
|
||||
usermod -aG docker_env azuracast
|
||||
usermod -aG www-data azuracast
|
||||
|
||||
mkdir -p /var/azuracast/www /var/azuracast/backups /var/azuracast/www_tmp /var/azuracast/geoip
|
||||
|
||||
chown -R azuracast:azuracast /var/azuracast
|
||||
chmod -R 777 /var/azuracast/www_tmp
|
||||
|
||||
echo 'azuracast ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers
|
|
@ -0,0 +1,4 @@
|
|||
export LC_ALL=C
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
minimal_apt_get_install='apt-get install -y --no-install-recommends'
|
|
@ -0,0 +1,9 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
source /bd_build/buildconfig
|
||||
set -x
|
||||
|
||||
apt-get clean
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
rm -rf /tmp/tmp*
|
|
@ -0,0 +1,9 @@
|
|||
0 * * * * root /usr/local/bin/cron_task azuracast_cli sync:run long
|
||||
*/5 * * * * root /usr/local/bin/cron_task azuracast_cli sync:run medium
|
||||
* * * * * root /usr/local/bin/cron_task azuracast_cli sync:run short
|
||||
* * * * * root /usr/local/bin/cron_task azuracast_cli sync:run nowplaying
|
||||
* * * * * 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
|
|
@ -0,0 +1,4 @@
|
|||
#! /bin/bash
|
||||
set -e
|
||||
|
||||
sudo kill -HUP `sudo cat /var/run/nginx.pid`
|
|
@ -0,0 +1,155 @@
|
|||
upstream redis_server {
|
||||
nchan_redis_server "redis://redis:6379";
|
||||
}
|
||||
|
||||
server {
|
||||
listen 9010;
|
||||
|
||||
location ~ /pub/(\w+)$ {
|
||||
nchan_publisher;
|
||||
nchan_redis_pass redis_server;
|
||||
|
||||
nchan_channel_group "azuracast_nowplaying";
|
||||
nchan_channel_id $1;
|
||||
|
||||
nchan_message_buffer_length 1;
|
||||
nchan_message_timeout 16s;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
listen 443 default_server http2 ssl;
|
||||
|
||||
ssl_certificate /etc/letsencrypt/ssl.crt;
|
||||
ssl_certificate_key /etc/letsencrypt/ssl.key;
|
||||
|
||||
ssl_protocols TLSv1.2;
|
||||
ssl_prefer_server_ciphers on;
|
||||
ssl_dhparam /etc/nginx/dhparam.pem;
|
||||
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
|
||||
ssl_ecdh_curve secp521r1:secp384r1:prime256v1;
|
||||
ssl_session_timeout 10m;
|
||||
ssl_session_cache shared:SSL:10m;
|
||||
ssl_session_tickets off;
|
||||
|
||||
root /var/azuracast/www/web;
|
||||
index index.php;
|
||||
|
||||
server_name localhost;
|
||||
|
||||
add_header X-XSS-Protection 1;
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header X-Robots-Tag none;
|
||||
add_header Referrer-Policy no-referrer-when-downgrade;
|
||||
|
||||
# LetsEncrypt handling
|
||||
location /.well-known/acme-challenge/ {
|
||||
root /var/www/letsencrypt;
|
||||
try_files $uri =404;
|
||||
}
|
||||
|
||||
# Serve a static version of the nowplaying data for non-PHP-blocking delivery.
|
||||
location /api/nowplaying_static {
|
||||
expires 10s;
|
||||
add_header Access-Control-Allow-Origin *;
|
||||
|
||||
alias /var/azuracast/www_tmp/nowplaying;
|
||||
try_files $uri =404;
|
||||
}
|
||||
|
||||
# Default clean URL routing
|
||||
location / {
|
||||
try_files $uri @clean_url;
|
||||
}
|
||||
|
||||
location @clean_url {
|
||||
rewrite ^(.*)$ /index.php last;
|
||||
}
|
||||
|
||||
# Set up caching for static assets.
|
||||
location /static {
|
||||
add_header Access-Control-Allow-Origin *;
|
||||
}
|
||||
|
||||
location /static/dist {
|
||||
expires 365d;
|
||||
}
|
||||
|
||||
location ~ ^/index\.php(/|$) {
|
||||
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||
|
||||
# NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
|
||||
fastcgi_pass localhost:9000;
|
||||
fastcgi_index index.php;
|
||||
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
|
||||
fastcgi_param DOCUMENT_ROOT $realpath_root;
|
||||
include fastcgi_params;
|
||||
|
||||
fastcgi_read_timeout 1800;
|
||||
fastcgi_buffering off;
|
||||
|
||||
internal;
|
||||
}
|
||||
|
||||
# Return 404 for all other php files not matching the front controller
|
||||
location ~ \.php$ {
|
||||
return 404;
|
||||
}
|
||||
|
||||
# Reverse proxy all possible radio listening ports (8000, 8010...8480, 8490)
|
||||
location ~ ^/radio/(8[0-9][0-9]0)(/?)(.*)$ {
|
||||
resolver 127.0.0.11;
|
||||
|
||||
proxy_buffering off;
|
||||
proxy_ignore_client_abort off;
|
||||
proxy_intercept_errors on;
|
||||
proxy_next_upstream error timeout invalid_header;
|
||||
proxy_redirect off;
|
||||
proxy_connect_timeout 60;
|
||||
proxy_send_timeout 21600;
|
||||
proxy_read_timeout 21600;
|
||||
|
||||
proxy_set_header Host localhost:$1;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Real-IP $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
|
||||
proxy_pass http://stations:$1/$3?$args;
|
||||
}
|
||||
|
||||
# Reverse proxy the Liquidsoap harbor inputs to allow for streaming.
|
||||
location ~ ^/radio/(8[0-9][0-9]5)(/?)(.*)$ {
|
||||
resolver 127.0.0.11;
|
||||
|
||||
proxy_buffering off;
|
||||
proxy_ignore_client_abort off;
|
||||
proxy_send_timeout 21600;
|
||||
proxy_read_timeout 21600;
|
||||
|
||||
proxy_pass http://stations:$1/;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "Upgrade";
|
||||
}
|
||||
|
||||
# pub/sub endpoints
|
||||
location ~ /api/live/nowplaying/(\w+)$ {
|
||||
nchan_access_control_allow_origin "*";
|
||||
|
||||
nchan_subscriber;
|
||||
nchan_redis_pass redis_server;
|
||||
|
||||
nchan_channel_group "azuracast_nowplaying";
|
||||
nchan_channel_id "$1";
|
||||
nchan_channel_id_split_delimiter ",";
|
||||
|
||||
nchan_subscriber_first_message -1;
|
||||
}
|
||||
|
||||
# deny access to .htaccess files, if Apache's document root
|
||||
# concurs with nginx's one
|
||||
location ~ /\.ht {
|
||||
deny all;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
user azuracast;
|
||||
worker_processes auto;
|
||||
|
||||
error_log /dev/stderr warn;
|
||||
pid /var/run/nginx.pid;
|
||||
|
||||
include /etc/nginx/modules-enabled/*.conf;
|
||||
|
||||
events {
|
||||
worker_connections 4096;
|
||||
}
|
||||
|
||||
http {
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||
|
||||
access_log off;
|
||||
|
||||
server_tokens off;
|
||||
|
||||
sendfile off;
|
||||
#tcp_nopush on;
|
||||
|
||||
keepalive_timeout 65;
|
||||
|
||||
#gzip on;
|
||||
|
||||
client_max_body_size 50M;
|
||||
client_body_temp_path /tmp/azuracast_nginx_client 1 1;
|
||||
|
||||
fastcgi_temp_path /tmp/azuracast_fastcgi_temp 1 1;
|
||||
|
||||
proxy_max_temp_file_size 0;
|
||||
|
||||
include /etc/nginx/conf.d/*.conf;
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
# AzuraCast custom PHP specifications
|
||||
|
||||
[php]
|
||||
post_max_size={{ default .Env.PHP_MAX_FILE_SIZE "50M" }}
|
||||
upload_max_filesize={{ default .Env.PHP_MAX_FILE_SIZE "50M" }}
|
||||
memory_limit={{ default .Env.PHP_MEMORY_LIMIT "256M" }}
|
||||
max_execution_time={{ default .Env.PHP_MAX_EXECUTION_TIME "30" }}
|
||||
|
||||
[opcache]
|
||||
opcache.enable=1
|
||||
opcache.enable_cli=1
|
||||
|
||||
{{if eq .Env.APPLICATION_ENV "production"}}
|
||||
opcache.revalidate_freq={{ default .Env.PHP_OPCACHE_REVALIDATE_FREQUENCY "60" }}
|
||||
{{end}}
|
|
@ -0,0 +1,24 @@
|
|||
[global]
|
||||
|
||||
error_log = syslog
|
||||
daemonize = no
|
||||
|
||||
[www]
|
||||
user = azuracast
|
||||
group = azuracast
|
||||
|
||||
listen = 0.0.0.0:9000
|
||||
|
||||
pm = ondemand
|
||||
pm.max_children = {{ default .Env.PHP_FPM_MAX_CHILDREN "5" }}
|
||||
pm.start_servers = 2
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
pm.max_requests = 100
|
||||
pm.process_idle_timeout = 60s
|
||||
|
||||
chdir = /
|
||||
|
||||
clear_env=No
|
||||
catch_workers_output = yes
|
||||
decorate_workers_output = no
|
|
@ -0,0 +1,70 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
source /bd_build/buildconfig
|
||||
set -x
|
||||
|
||||
## Prevent initramfs updates from trying to run grub and lilo.
|
||||
## https://journal.paul.querna.org/articles/2013/10/15/docker-ubuntu-on-rackspace/
|
||||
## http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=594189
|
||||
export INITRD=no
|
||||
mkdir -p /etc/container_environment
|
||||
echo -n no > /etc/container_environment/INITRD
|
||||
|
||||
# Add default timezone.
|
||||
echo "UTC" > /etc/timezone
|
||||
|
||||
# Avoid ERROR: invoke-rc.d: policy-rc.d denied execution of start.
|
||||
sed -i "s/^exit 101$/exit 0/" /usr/sbin/policy-rc.d
|
||||
|
||||
## Enable Ubuntu Universe, Multiverse, and deb-src for main.
|
||||
sed -i 's/^#\s*\(deb.*main restricted\)$/\1/g' /etc/apt/sources.list
|
||||
sed -i 's/^#\s*\(deb.*universe\)$/\1/g' /etc/apt/sources.list
|
||||
sed -i 's/^#\s*\(deb.*multiverse\)$/\1/g' /etc/apt/sources.list
|
||||
apt-get update
|
||||
|
||||
## Fix some issues with APT packages.
|
||||
## See https://github.com/dotcloud/docker/issues/1024
|
||||
dpkg-divert --local --rename --add /sbin/initctl
|
||||
ln -sf /bin/true /sbin/initctl
|
||||
|
||||
## Replace the 'ischroot' tool to make it always return true.
|
||||
## Prevent initscripts updates from breaking /dev/shm.
|
||||
## https://journal.paul.querna.org/articles/2013/10/15/docker-ubuntu-on-rackspace/
|
||||
## https://bugs.launchpad.net/launchpad/+bug/974584
|
||||
dpkg-divert --local --rename --add /usr/bin/ischroot
|
||||
ln -sf /bin/true /usr/bin/ischroot
|
||||
|
||||
# apt-utils fix for Ubuntu 16.04
|
||||
$minimal_apt_get_install apt-utils
|
||||
|
||||
## Install HTTPS support for APT.
|
||||
$minimal_apt_get_install apt-transport-https ca-certificates
|
||||
|
||||
## Install add-apt-repository
|
||||
$minimal_apt_get_install software-properties-common
|
||||
|
||||
## Upgrade all packages.
|
||||
apt-get dist-upgrade -y --no-install-recommends -o Dpkg::Options::="--force-confold"
|
||||
|
||||
## Fix locale.
|
||||
$minimal_apt_get_install language-pack-en
|
||||
|
||||
locale-gen en_US
|
||||
update-locale LANG=en_US.UTF-8 LC_CTYPE=en_US.UTF-8
|
||||
|
||||
echo -n en_US.UTF-8 > /etc/container_environment/LANG
|
||||
echo -n en_US.UTF-8 > /etc/container_environment/LC_CTYPE
|
||||
|
||||
# Make init folders
|
||||
mkdir -p /etc/my_init.d
|
||||
mkdir -p /etc/my_init.pre_shutdown.d
|
||||
mkdir -p /etc/my_init.post_shutdown.d
|
||||
mkdir -p /etc/container_environment
|
||||
touch /etc/container_environment.sh
|
||||
touch /etc/container_environment.json
|
||||
chmod 700 /etc/container_environment
|
||||
|
||||
groupadd -g 8377 docker_env
|
||||
chown :docker_env /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/
|
|
@ -0,0 +1,8 @@
|
|||
#!/bin/sh
|
||||
|
||||
# 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 /etc/crontab
|
||||
touch -c /etc/cron.*/*
|
||||
|
||||
exec /usr/sbin/cron -f
|
|
@ -0,0 +1,3 @@
|
|||
#!/bin/bash
|
||||
|
||||
nginx -g "daemon off;"
|
|
@ -0,0 +1,3 @@
|
|||
#!/bin/bash
|
||||
|
||||
/usr/sbin/php-fpm7.4 -F --fpm-config /etc/php/7.4/fpm/php-fpm.conf -c /etc/php/7.4/fpm/
|
|
@ -0,0 +1,3 @@
|
|||
#!/bin/bash
|
||||
|
||||
sudo -E -u azuracast php /var/azuracast/www/util/cli.php queue:process 300
|
|
@ -0,0 +1,7 @@
|
|||
#!/bin/bash
|
||||
|
||||
echo 'Spinning up SFTP process...'
|
||||
|
||||
cd /var/azuracast/sftpgo
|
||||
|
||||
sudo -E -u azuracast sftpgo --config-dir=/var/azuracast/sftpgo serve > /proc/1/fd/1 2> /proc/1/fd/2
|
|
@ -0,0 +1,10 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
if [ `whoami` != 'azuracast' ]; then
|
||||
echo 'This script must be run as the "azuracast" user. Rerunning...'
|
||||
sudo -E -u azuracast azuracast_cli "$@"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd /var/azuracast/www
|
||||
php bin/console "$@"
|
|
@ -0,0 +1,72 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
bool() {
|
||||
case "$1" in
|
||||
Y*|y*|true|TRUE|1) return 0 ;;
|
||||
esac
|
||||
return 1
|
||||
}
|
||||
|
||||
if [ `whoami` != 'azuracast' ]; then
|
||||
echo 'This script must be run as the "azuracast" user. Rerunning...'
|
||||
sudo -E -u azuracast azuracast_install $@
|
||||
exit 1
|
||||
fi
|
||||
|
||||
update_mode=0
|
||||
release_update=0
|
||||
original_args=$*
|
||||
|
||||
while [[ "$1" =~ ^- && ! "$1" == "--" ]]; do case $1 in
|
||||
--update )
|
||||
update_mode=1
|
||||
;;
|
||||
|
||||
-r | --release )
|
||||
release_update=1
|
||||
;;
|
||||
esac; shift; done
|
||||
if [[ "$1" == '--' ]]; then shift; fi
|
||||
|
||||
if bool "$PREFER_RELEASE_BUILDS"; then
|
||||
release_update=1
|
||||
fi
|
||||
|
||||
if [ $update_mode = 1 ]; then
|
||||
echo "Updating AzuraCast..."
|
||||
else
|
||||
echo "Installing AzuraCast..."
|
||||
fi
|
||||
|
||||
APPLICATION_ENV="${APPLICATION_ENV:-production}"
|
||||
echo "(Environment: $APPLICATION_ENV)"
|
||||
|
||||
if [ $APPLICATION_ENV = "production" ]; then
|
||||
if [ $release_update = 1 ]; then
|
||||
COMPOSER_VERSION=${1:-"^0.9.5"}
|
||||
composer create-project azuracast/azuracast /var/azuracast/new $COMPOSER_VERSION --prefer-dist --no-install
|
||||
|
||||
rsync -a -v -q /var/azuracast/new/ /var/azuracast/www
|
||||
rm -rf /var/azuracast/new
|
||||
|
||||
if bool "$COMPOSER_PLUGIN_MODE"; then
|
||||
composer update --lock --no-dev --optimize-autoloader
|
||||
else
|
||||
composer install --no-dev --optimize-autoloader
|
||||
fi
|
||||
else
|
||||
if bool "$COMPOSER_PLUGIN_MODE"; then
|
||||
composer update --lock --no-dev --optimize-autoloader
|
||||
fi
|
||||
fi
|
||||
else
|
||||
if [ $APPLICATION_ENV = "testing" ]; then
|
||||
sudo mkdir -p vendor
|
||||
sudo chmod -R 0744 vendor
|
||||
sudo chown -R azuracast:azuracast vendor
|
||||
fi
|
||||
|
||||
composer install
|
||||
fi
|
||||
|
||||
azuracast_cli azuracast:setup ${original_args}
|
|
@ -0,0 +1,3 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
mv ${1}/* /var/azuracast/stations/
|
|
@ -0,0 +1,54 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
bool() {
|
||||
case "$1" in
|
||||
Y*|y*|true|TRUE|1) return 0 ;;
|
||||
esac
|
||||
return 1
|
||||
}
|
||||
|
||||
if [ `whoami` != 'azuracast' ]; then
|
||||
echo 'This script must be run as the "azuracast" user. Rerunning...'
|
||||
sudo -E -u azuracast azuracast_restore $@
|
||||
exit 1
|
||||
fi
|
||||
|
||||
release_update=0
|
||||
original_args=$*
|
||||
|
||||
while [[ "$1" =~ ^- && ! "$1" == "--" ]]; do case $1 in
|
||||
-r | --release )
|
||||
release_update=1
|
||||
;;
|
||||
esac; shift; done
|
||||
if [[ "$1" == '--' ]]; then shift; fi
|
||||
|
||||
if bool "$PREFER_RELEASE_BUILDS"; then
|
||||
release_update=1
|
||||
fi
|
||||
|
||||
echo "Restoring AzuraCast..."
|
||||
|
||||
APPLICATION_ENV="${APPLICATION_ENV:-production}"
|
||||
echo "(Environment: $APPLICATION_ENV)"
|
||||
|
||||
if [ $APPLICATION_ENV = "production" ]; then
|
||||
if [ $release_update = 1 ]; then
|
||||
composer create-project azuracast/azuracast /var/azuracast/new ^0.9.5 --prefer-dist --no-install
|
||||
else
|
||||
composer create-project azuracast/azuracast /var/azuracast/new dev-master --prefer-source --keep-vcs --no-install
|
||||
fi
|
||||
|
||||
rsync -a -v -q /var/azuracast/new/ /var/azuracast/www
|
||||
rm -rf /var/azuracast/new
|
||||
|
||||
if bool "$COMPOSER_PLUGIN_MODE"; then
|
||||
composer update --lock --no-dev --optimize-autoloader
|
||||
else
|
||||
composer install --no-dev --optimize-autoloader
|
||||
fi
|
||||
else
|
||||
composer install
|
||||
fi
|
||||
|
||||
azuracast_cli azuracast:restore ${original_args}
|
|
@ -0,0 +1,5 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
source /etc/container_environment.sh
|
||||
|
||||
azuracast_cli azuracast:internal:sftp-auth "$@"
|
|
@ -0,0 +1,5 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
source /etc/container_environment.sh
|
||||
|
||||
azuracast_cli azuracast:internal:sftp-upload "$@"
|
|
@ -0,0 +1,3 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
azuracast_install --update $*
|
|
@ -0,0 +1,5 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
source /etc/container_environment.sh
|
||||
|
||||
sudo -E -u azuracast $@ > /proc/1/fd/1 2> /proc/1/fd/2
|
|
@ -0,0 +1,44 @@
|
|||
#!/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
|
|
@ -0,0 +1,9 @@
|
|||
#!/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 $*
|
|
@ -0,0 +1,25 @@
|
|||
#!/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
|
|
@ -0,0 +1,420 @@
|
|||
#!/usr/bin/python3 -u
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import argparse
|
||||
import errno
|
||||
import json
|
||||
import os
|
||||
import os.path
|
||||
import re
|
||||
import signal
|
||||
import stat
|
||||
import sys
|
||||
import time
|
||||
|
||||
ENV_INIT_DIRECTORY = os.environ.get('ENV_INIT_DIRECTORY', '/etc/my_init.d')
|
||||
|
||||
KILL_PROCESS_TIMEOUT = int(os.environ.get('KILL_PROCESS_TIMEOUT', 30))
|
||||
KILL_ALL_PROCESSES_TIMEOUT = int(os.environ.get('KILL_ALL_PROCESSES_TIMEOUT', 30))
|
||||
|
||||
LOG_LEVEL_ERROR = 1
|
||||
LOG_LEVEL_WARN = 1
|
||||
LOG_LEVEL_INFO = 2
|
||||
LOG_LEVEL_DEBUG = 3
|
||||
|
||||
SHENV_NAME_WHITELIST_REGEX = re.compile('\W')
|
||||
|
||||
log_level = None
|
||||
|
||||
terminated_child_processes = {}
|
||||
|
||||
_find_unsafe = re.compile(r'[^\w@%+=:,./-]').search
|
||||
|
||||
|
||||
class AlarmException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def error(message):
|
||||
if log_level >= LOG_LEVEL_ERROR:
|
||||
sys.stderr.write("*** %s\n" % message)
|
||||
|
||||
|
||||
def warn(message):
|
||||
if log_level >= LOG_LEVEL_WARN:
|
||||
sys.stderr.write("*** %s\n" % message)
|
||||
|
||||
|
||||
def info(message):
|
||||
if log_level >= LOG_LEVEL_INFO:
|
||||
sys.stderr.write("*** %s\n" % message)
|
||||
|
||||
|
||||
def debug(message):
|
||||
if log_level >= LOG_LEVEL_DEBUG:
|
||||
sys.stderr.write("*** %s\n" % message)
|
||||
|
||||
|
||||
def ignore_signals_and_raise_keyboard_interrupt(signame):
|
||||
signal.signal(signal.SIGTERM, signal.SIG_IGN)
|
||||
signal.signal(signal.SIGINT, signal.SIG_IGN)
|
||||
raise KeyboardInterrupt(signame)
|
||||
|
||||
|
||||
def raise_alarm_exception():
|
||||
raise AlarmException('Alarm')
|
||||
|
||||
|
||||
def listdir(path):
|
||||
try:
|
||||
result = os.stat(path)
|
||||
except OSError:
|
||||
return []
|
||||
if stat.S_ISDIR(result.st_mode):
|
||||
return sorted(os.listdir(path))
|
||||
else:
|
||||
return []
|
||||
|
||||
|
||||
def is_exe(path):
|
||||
try:
|
||||
return os.path.isfile(path) and os.access(path, os.X_OK)
|
||||
except OSError:
|
||||
return False
|
||||
|
||||
|
||||
def import_envvars(clear_existing_environment=True, override_existing_environment=True):
|
||||
if not os.path.exists("/etc/container_environment"):
|
||||
return
|
||||
new_env = {}
|
||||
for envfile in listdir("/etc/container_environment"):
|
||||
name = os.path.basename(envfile)
|
||||
with open("/etc/container_environment/" + envfile, "r") as f:
|
||||
# Text files often end with a trailing newline, which we
|
||||
# don't want to include in the env variable value. See
|
||||
# https://github.com/phusion/baseimage-docker/pull/49
|
||||
value = re.sub('\n\Z', '', f.read())
|
||||
new_env[name] = value
|
||||
if clear_existing_environment:
|
||||
os.environ.clear()
|
||||
for name, value in new_env.items():
|
||||
if override_existing_environment or name not in os.environ:
|
||||
os.environ[name] = value
|
||||
|
||||
|
||||
def export_envvars(to_dir=True):
|
||||
if not os.path.exists("/etc/container_environment"):
|
||||
return
|
||||
shell_dump = ""
|
||||
for name, value in os.environ.items():
|
||||
if name in ['HOME', 'USER', 'GROUP', 'UID', 'GID', 'SHELL']:
|
||||
continue
|
||||
if to_dir:
|
||||
with open("/etc/container_environment/" + name, "w") as f:
|
||||
f.write(value)
|
||||
shell_dump += "export " + sanitize_shenvname(name) + "=" + shquote(value) + "\n"
|
||||
with open("/etc/container_environment.sh", "w") as f:
|
||||
f.write(shell_dump)
|
||||
with open("/etc/container_environment.json", "w") as f:
|
||||
f.write(json.dumps(dict(os.environ)))
|
||||
|
||||
|
||||
def shquote(s):
|
||||
"""Return a shell-escaped version of the string *s*."""
|
||||
if not s:
|
||||
return "''"
|
||||
if _find_unsafe(s) is None:
|
||||
return s
|
||||
|
||||
# use single quotes, and put single quotes into double quotes
|
||||
# the string $'b is then quoted as '$'"'"'b'
|
||||
return "'" + s.replace("'", "'\"'\"'") + "'"
|
||||
|
||||
|
||||
def sanitize_shenvname(s):
|
||||
"""Return string with [0-9a-zA-Z_] characters"""
|
||||
return re.sub(SHENV_NAME_WHITELIST_REGEX, "_", s)
|
||||
|
||||
|
||||
# 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
|
||||
# processes that have terminated).
|
||||
|
||||
def waitpid_reap_other_children(pid):
|
||||
global terminated_child_processes
|
||||
|
||||
status = terminated_child_processes.get(pid)
|
||||
if status:
|
||||
# A previous call to waitpid_reap_other_children(),
|
||||
# with an argument not equal to the current argument,
|
||||
# already waited for this process. Return the status
|
||||
# that was obtained back then.
|
||||
del terminated_child_processes[pid]
|
||||
return status
|
||||
|
||||
done = False
|
||||
status = None
|
||||
while not done:
|
||||
try:
|
||||
# https://github.com/phusion/baseimage-docker/issues/151#issuecomment-92660569
|
||||
this_pid, status = os.waitpid(pid, os.WNOHANG)
|
||||
if this_pid == 0:
|
||||
this_pid, status = os.waitpid(-1, 0)
|
||||
if this_pid == pid:
|
||||
done = True
|
||||
else:
|
||||
# Save status for later.
|
||||
terminated_child_processes[this_pid] = status
|
||||
except OSError as e:
|
||||
if e.errno == errno.ECHILD or e.errno == errno.ESRCH:
|
||||
return None
|
||||
else:
|
||||
raise
|
||||
return status
|
||||
|
||||
|
||||
def stop_child_process(name, pid, signo=signal.SIGTERM, time_limit=KILL_PROCESS_TIMEOUT):
|
||||
info("Shutting down %s (PID %d)..." % (name, pid))
|
||||
try:
|
||||
os.kill(pid, signo)
|
||||
except OSError:
|
||||
pass
|
||||
signal.alarm(time_limit)
|
||||
try:
|
||||
try:
|
||||
waitpid_reap_other_children(pid)
|
||||
except OSError:
|
||||
pass
|
||||
except AlarmException:
|
||||
warn("%s (PID %d) did not shut down in time. Forcing it to exit." % (name, pid))
|
||||
try:
|
||||
os.kill(pid, signal.SIGKILL)
|
||||
except OSError:
|
||||
pass
|
||||
try:
|
||||
waitpid_reap_other_children(pid)
|
||||
except OSError:
|
||||
pass
|
||||
finally:
|
||||
signal.alarm(0)
|
||||
|
||||
|
||||
def run_command_killable(*argv):
|
||||
filename = argv[0]
|
||||
status = None
|
||||
pid = os.spawnvp(os.P_NOWAIT, filename, argv)
|
||||
try:
|
||||
status = waitpid_reap_other_children(pid)
|
||||
except BaseException:
|
||||
warn("An error occurred. Aborting.")
|
||||
stop_child_process(filename, pid)
|
||||
raise
|
||||
if status != 0:
|
||||
if status is None:
|
||||
error("%s exited with unknown status\n" % filename)
|
||||
else:
|
||||
error("%s failed with status %d\n" % (filename, os.WEXITSTATUS(status)))
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def run_command_killable_and_import_envvars(*argv):
|
||||
run_command_killable(*argv)
|
||||
import_envvars()
|
||||
export_envvars(False)
|
||||
|
||||
|
||||
def kill_all_processes(time_limit):
|
||||
info("Killing all processes...")
|
||||
try:
|
||||
os.kill(-1, signal.SIGTERM)
|
||||
except OSError:
|
||||
pass
|
||||
signal.alarm(time_limit)
|
||||
try:
|
||||
# Wait until no more child processes exist.
|
||||
done = False
|
||||
while not done:
|
||||
try:
|
||||
os.waitpid(-1, 0)
|
||||
except OSError as e:
|
||||
if e.errno == errno.ECHILD:
|
||||
done = True
|
||||
else:
|
||||
raise
|
||||
except AlarmException:
|
||||
warn("Not all processes have exited in time. Forcing them to exit.")
|
||||
try:
|
||||
os.kill(-1, signal.SIGKILL)
|
||||
except OSError:
|
||||
pass
|
||||
finally:
|
||||
signal.alarm(0)
|
||||
|
||||
|
||||
def run_startup_files():
|
||||
# Run ENV_INIT_DIRECTORY/*
|
||||
for name in listdir(ENV_INIT_DIRECTORY):
|
||||
filename = os.path.join(ENV_INIT_DIRECTORY, name)
|
||||
if is_exe(filename):
|
||||
info("Running %s..." % filename)
|
||||
run_command_killable_and_import_envvars(filename)
|
||||
|
||||
# Run /etc/rc.local.
|
||||
if is_exe("/etc/rc.local"):
|
||||
info("Running /etc/rc.local...")
|
||||
run_command_killable_and_import_envvars("/etc/rc.local")
|
||||
|
||||
|
||||
def run_pre_shutdown_scripts():
|
||||
debug("Running pre-shutdown scripts...")
|
||||
|
||||
# Run /etc/my_init.pre_shutdown.d/*
|
||||
for name in listdir("/etc/my_init.pre_shutdown.d"):
|
||||
filename = "/etc/my_init.pre_shutdown.d/" + name
|
||||
if is_exe(filename):
|
||||
info("Running %s..." % filename)
|
||||
run_command_killable(filename)
|
||||
|
||||
|
||||
def run_post_shutdown_scripts():
|
||||
debug("Running post-shutdown scripts...")
|
||||
|
||||
# Run /etc/my_init.post_shutdown.d/*
|
||||
for name in listdir("/etc/my_init.post_shutdown.d"):
|
||||
filename = "/etc/my_init.post_shutdown.d/" + name
|
||||
if is_exe(filename):
|
||||
info("Running %s..." % filename)
|
||||
run_command_killable(filename)
|
||||
|
||||
|
||||
def start_runit():
|
||||
info("Booting runit daemon...")
|
||||
pid = os.spawnl(os.P_NOWAIT, "/usr/bin/runsvdir", "/usr/bin/runsvdir",
|
||||
"-P", "/etc/service")
|
||||
info("Runit started as PID %d" % pid)
|
||||
return pid
|
||||
|
||||
|
||||
def wait_for_runit_or_interrupt(pid):
|
||||
status = waitpid_reap_other_children(pid)
|
||||
return (True, status)
|
||||
|
||||
|
||||
def shutdown_runit_services(quiet=False):
|
||||
if not quiet:
|
||||
debug("Begin shutting down runit services...")
|
||||
os.system("/usr/bin/sv -w %d force-stop /etc/service/* > /dev/null" % KILL_PROCESS_TIMEOUT)
|
||||
|
||||
|
||||
def wait_for_runit_services():
|
||||
debug("Waiting for runit services to exit...")
|
||||
done = False
|
||||
while not done:
|
||||
done = os.system("/usr/bin/sv status /etc/service/* | grep -q '^run:'") != 0
|
||||
if not done:
|
||||
time.sleep(0.1)
|
||||
# According to https://github.com/phusion/baseimage-docker/issues/315
|
||||
# there is a bug or race condition in Runit, causing it
|
||||
# not to shutdown services that are already being started.
|
||||
# So during shutdown we repeatedly instruct Runit to shutdown
|
||||
# services.
|
||||
shutdown_runit_services(True)
|
||||
|
||||
|
||||
def install_insecure_key():
|
||||
info("Installing insecure SSH key for user root")
|
||||
run_command_killable("/usr/sbin/enable_insecure_key")
|
||||
|
||||
|
||||
def main(args):
|
||||
import_envvars(False, False)
|
||||
export_envvars()
|
||||
|
||||
if args.enable_insecure_key:
|
||||
install_insecure_key()
|
||||
|
||||
if not args.skip_startup_files:
|
||||
run_startup_files()
|
||||
|
||||
runit_exited = False
|
||||
exit_code = None
|
||||
|
||||
if not args.skip_runit:
|
||||
runit_pid = start_runit()
|
||||
try:
|
||||
exit_status = None
|
||||
if len(args.main_command) == 0:
|
||||
runit_exited, exit_code = wait_for_runit_or_interrupt(runit_pid)
|
||||
if runit_exited:
|
||||
if exit_code is None:
|
||||
info("Runit exited with unknown status")
|
||||
exit_status = 1
|
||||
else:
|
||||
exit_status = os.WEXITSTATUS(exit_code)
|
||||
info("Runit exited with status %d" % exit_status)
|
||||
else:
|
||||
info("Running %s..." % " ".join(args.main_command))
|
||||
pid = os.spawnvp(os.P_NOWAIT, args.main_command[0], args.main_command)
|
||||
try:
|
||||
exit_code = waitpid_reap_other_children(pid)
|
||||
if exit_code is None:
|
||||
info("%s exited with unknown status." % args.main_command[0])
|
||||
exit_status = 1
|
||||
else:
|
||||
exit_status = os.WEXITSTATUS(exit_code)
|
||||
info("%s exited with status %d." % (args.main_command[0], exit_status))
|
||||
except KeyboardInterrupt:
|
||||
stop_child_process(args.main_command[0], pid)
|
||||
raise
|
||||
except BaseException:
|
||||
warn("An error occurred. Aborting.")
|
||||
stop_child_process(args.main_command[0], pid)
|
||||
raise
|
||||
sys.exit(exit_status)
|
||||
finally:
|
||||
if not args.skip_runit:
|
||||
run_pre_shutdown_scripts()
|
||||
shutdown_runit_services()
|
||||
if not runit_exited:
|
||||
stop_child_process("runit daemon", runit_pid)
|
||||
wait_for_runit_services()
|
||||
run_post_shutdown_scripts()
|
||||
|
||||
# Parse options.
|
||||
parser = argparse.ArgumentParser(description='Initialize the system.')
|
||||
parser.add_argument('main_command', metavar='MAIN_COMMAND', type=str, nargs='*',
|
||||
help='The main command to run. (default: runit)')
|
||||
parser.add_argument('--enable-insecure-key', dest='enable_insecure_key',
|
||||
action='store_const', const=True, default=False,
|
||||
help='Install the insecure SSH key')
|
||||
parser.add_argument('--skip-startup-files', dest='skip_startup_files',
|
||||
action='store_const', const=True, default=False,
|
||||
help='Skip running /etc/my_init.d/* and /etc/rc.local')
|
||||
parser.add_argument('--skip-runit', dest='skip_runit',
|
||||
action='store_const', const=True, default=False,
|
||||
help='Do not run runit services')
|
||||
parser.add_argument('--no-kill-all-on-exit', dest='kill_all_on_exit',
|
||||
action='store_const', const=False, default=True,
|
||||
help='Don\'t kill all processes on the system upon exiting')
|
||||
parser.add_argument('--quiet', dest='log_level',
|
||||
action='store_const', const=LOG_LEVEL_WARN, default=LOG_LEVEL_INFO,
|
||||
help='Only print warnings and errors')
|
||||
args = parser.parse_args()
|
||||
log_level = args.log_level
|
||||
|
||||
if args.skip_runit and len(args.main_command) == 0:
|
||||
error("When --skip-runit is given, you must also pass a main command.")
|
||||
sys.exit(1)
|
||||
|
||||
# Run main function.
|
||||
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.SIGALRM, lambda signum, frame: raise_alarm_exception())
|
||||
try:
|
||||
main(args)
|
||||
except KeyboardInterrupt:
|
||||
warn("Init system aborted.")
|
||||
exit(2)
|
||||
finally:
|
||||
if args.kill_all_on_exit:
|
||||
kill_all_processes(KILL_ALL_PROCESSES_TIMEOUT)
|
|
@ -0,0 +1,6 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
/usr/sbin/tmpreaper 12h --protect '.tmpreaper' --verbose \
|
||||
/tmp/azuracast_nginx_client \
|
||||
/tmp/azuracast_fastcgi_temp \
|
||||
> /proc/1/fd/1 2> /proc/1/fd/2
|
|
@ -0,0 +1,26 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
source /bd_build/buildconfig
|
||||
set -x
|
||||
|
||||
# Install common scripts
|
||||
cp -rT /bd_build/scripts/ /usr/local/bin
|
||||
chmod -R a+x /usr/local/bin
|
||||
|
||||
# Install runit
|
||||
$minimal_apt_get_install runit
|
||||
|
||||
# Install runit scripts
|
||||
cp -rT /bd_build/startup_scripts/. /etc/my_init.d/
|
||||
cp -rT /bd_build/runit/. /etc/service/
|
||||
|
||||
chmod -R +x /etc/service
|
||||
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
|
||||
for f in /bd_build/setup/*.sh; do
|
||||
bash "$f" -H
|
||||
done
|
|
@ -0,0 +1,26 @@
|
|||
#!/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 /etc/letsencrypt/renewal-hooks/deploy/01-reload-nginx
|
||||
chmod a+x /etc/letsencrypt/renewal-hooks/deploy/*
|
|
@ -0,0 +1,24 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
source /bd_build/buildconfig
|
||||
set -x
|
||||
|
||||
$minimal_apt_get_install cron
|
||||
|
||||
service cron stop
|
||||
|
||||
chmod 600 /etc/crontab
|
||||
|
||||
# Fix cron issues in 0.9.19, see also #345: https://github.com/phusion/baseimage-docker/issues/345
|
||||
sed -i 's/^\s*session\s\+required\s\+pam_loginuid.so/# &/' /etc/pam.d/cron
|
||||
|
||||
## Remove useless cron entries.
|
||||
# Checks for lost+found and scans for mtab.
|
||||
rm -f /etc/cron.daily/standard
|
||||
rm -f /etc/cron.daily/upstart
|
||||
rm -f /etc/cron.daily/dpkg
|
||||
rm -f /etc/cron.daily/password
|
||||
rm -f /etc/cron.weekly/fstrim
|
||||
|
||||
cp -r /bd_build/cron/. /etc/cron.d/
|
||||
chmod -R 600 /etc/cron.d/*
|
|
@ -0,0 +1,13 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
source /bd_build/buildconfig
|
||||
set -x
|
||||
|
||||
DOCKERIZE_VERSION="v0.6.1"
|
||||
|
||||
cd /tmp
|
||||
|
||||
wget --quiet https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz
|
||||
|
||||
tar -C /usr/local/bin -xzvf dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz
|
||||
rm dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz
|
|
@ -0,0 +1,11 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
source /bd_build/buildconfig
|
||||
set -x
|
||||
|
||||
wget -qO- https://repos.influxdata.com/influxdb.key | apt-key add -
|
||||
echo "deb https://repos.influxdata.com/ubuntu bionic stable" | tee /etc/apt/sources.list.d/influxdb.list
|
||||
|
||||
apt-get update
|
||||
|
||||
$minimal_apt_get_install influxdb
|
|
@ -0,0 +1,19 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
source /bd_build/buildconfig
|
||||
set -x
|
||||
|
||||
$minimal_apt_get_install nginx nginx-common nginx-extras
|
||||
|
||||
# Install nginx and configuration
|
||||
cp /bd_build/nginx/nginx.conf /etc/nginx/nginx.conf
|
||||
cp /bd_build/nginx/azuracast.conf /etc/nginx/conf.d/azuracast.conf
|
||||
|
||||
# Create nginx temp dirs
|
||||
mkdir -p /tmp/azuracast_nginx_client /tmp/azuracast_fastcgi_temp
|
||||
touch /tmp/azuracast_nginx_client/.tmpreaper
|
||||
touch /tmp/azuracast_fastcgi_temp/.tmpreaper
|
||||
chmod -R 777 /tmp/azuracast_*
|
||||
|
||||
# Generate the dhparam.pem file (takes a long time)
|
||||
openssl dhparam -dsaparam -out /etc/nginx/dhparam.pem 4096
|
|
@ -0,0 +1,22 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
source /bd_build/buildconfig
|
||||
set -x
|
||||
|
||||
add-apt-repository -y ppa:ondrej/php
|
||||
apt-get update
|
||||
|
||||
$minimal_apt_get_install php7.4-fpm php7.4-cli php7.4-gd \
|
||||
php7.4-curl php7.4-xml php7.4-zip php7.4-bcmath \
|
||||
php7.4-mysqlnd php7.4-mbstring php7.4-intl php7.4-redis \
|
||||
mariadb-client
|
||||
|
||||
# Copy PHP configuration
|
||||
mkdir -p /run/php
|
||||
touch /run/php/php7.4-fpm.pid
|
||||
|
||||
cp /bd_build/php/php.ini.tmpl /etc/php/7.4/fpm/05-azuracast.ini.tmpl
|
||||
cp /bd_build/php/www.conf.tmpl /etc/php/7.4/fpm/www.conf.tmpl
|
||||
|
||||
# Install Composer
|
||||
curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin --filename=composer
|
|
@ -0,0 +1,11 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
source /bd_build/buildconfig
|
||||
set -x
|
||||
|
||||
mkdir -p /var/azuracast/sftpgo/persist /var/azuracast/sftpgo/backups
|
||||
|
||||
cp /bd_build/sftpgo/sftpgo.json /var/azuracast/sftpgo/sftpgo.json
|
||||
|
||||
touch /var/azuracast/sftpgo/sftpgo.db
|
||||
chown -R azuracast:azuracast /var/azuracast/sftpgo
|
|
@ -0,0 +1,6 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
source /bd_build/buildconfig
|
||||
set -x
|
||||
|
||||
$minimal_apt_get_install tmpreaper
|
|
@ -0,0 +1,33 @@
|
|||
{
|
||||
"sftpd": {
|
||||
"bind_port": 2022,
|
||||
"bind_address": "",
|
||||
"idle_timeout": 15,
|
||||
"max_auth_tries": 0,
|
||||
"umask": "0022",
|
||||
"banner": "",
|
||||
"upload_mode": 1,
|
||||
"actions": {
|
||||
"execute_on": ["upload"],
|
||||
"command": "/usr/local/bin/azuracast_sftp_upload"
|
||||
},
|
||||
"keys": [
|
||||
{"private_key": "persist/id_rsa"}
|
||||
],
|
||||
"enable_scp": true
|
||||
},
|
||||
"data_provider": {
|
||||
"driver": "bolt",
|
||||
"name": "sftpgo.db",
|
||||
"users_base_dir": "/var/azuracast/stations",
|
||||
"external_auth_program": "/usr/local/bin/azuracast_sftp_auth",
|
||||
"external_auth_scope": 0
|
||||
},
|
||||
"httpd": {
|
||||
"bind_port": 0,
|
||||
"bind_address": "",
|
||||
"templates_path": "templates",
|
||||
"static_files_path": "static",
|
||||
"backups_path": "backups"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Copy the php.ini template to its destination.
|
||||
dockerize -template "/etc/php/7.4/fpm/05-azuracast.ini.tmpl:/etc/php/7.4/fpm/conf.d/05-azuracast.ini" -template "/etc/php/7.4/fpm/www.conf.tmpl:/etc/php/7.4/fpm/pool.d/www.conf" cp /etc/php/7.4/fpm/conf.d/05-azuracast.ini /etc/php/7.4/cli/conf.d/05-azuracast.ini
|
|
@ -0,0 +1,12 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Duplicate php-worker runit script based on environment variable
|
||||
|
||||
echo "Adding $ADDITIONAL_MEDIA_SYNC_WORKER_COUNT additional workers"
|
||||
|
||||
for ((WORKER_NUMBER=1; WORKER_NUMBER<=$ADDITIONAL_MEDIA_SYNC_WORKER_COUNT; WORKER_NUMBER++)); do
|
||||
echo "Adding worker $WORKER_NUMBER..."
|
||||
cp -r /etc/service/php-worker /etc/service/php-worker-"$WORKER_NUMBER"
|
||||
done
|
||||
|
||||
echo "Done"
|
|
@ -0,0 +1,7 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [[ ! -f /var/azuracast/sftpgo/persist/id_rsa ]]; then
|
||||
ssh-keygen -t rsa -b 4096 -f /var/azuracast/sftpgo/persist/id_rsa -q -N ""
|
||||
fi
|
||||
|
||||
chown -R azuracast:azuracast /var/azuracast/sftpgo/persist
|
Loading…
Reference in New Issue