refactor: 拷贝和借鉴 sentry/onpremise 的思路重构部署脚本

This commit is contained in:
icyleaf
2021-08-12 18:56:20 +08:00
parent a20e93bc21
commit 5bd5398923
19 changed files with 589 additions and 516 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
rootfs/
caddy/
backups/
log/
.env
+2 -2
View File
@@ -2,8 +2,8 @@
## 依赖
- Docker 1.12.0+
- Docker Compose 1.9.0+
- Docker 20.10.0+
- Docker Compose 1.28.0+
## 部署
+18 -480
View File
@@ -4,483 +4,21 @@
#
# example: ./deploy
# example: ./deploy --skip-update
set -e
dc="docker-compose --no-ansi"
dcr="$dc run --rm"
log_file="zealot_install_log-`date +'%Y-%m-%d_%H-%M-%S'`.txt"
exec &> >(tee -a "$log_file")
SKIP_UPDATE="false"
if [ "$1" == '--skip-update' ]; then
SKIP_UPDATE="true"
fi
ZEALOT_ROOT=$(pwd)
EXAMPLE_ENV_FILE="${ZEALOT_ROOT}/config.env"
ENV_FILE=".env"
DOCKER_COMPOSE_FILE="docker-compose.yml"
HAS_DOCKERDOCKER_COMPOSE_FILE="false"
TEMPLATE_PATH="templates"
DOCKER_COMPOSE_TEMPLATE_PATH="${TEMPLATE_PATH}/docker-compose"
CADDY_TEMPLATE_FILE="${TEMPLATE_PATH}/Caddyfile"
ROOTFS_ETC_PATH="rootfs/etc"
CADDY_FILE="${ROOTFS_ETC_PATH}/Caddyfile"
CERTS_PATH="${ROOTFS_ETC_PATH}/certs"
DOCKER_CADDY_CERT_PATH="/etc/certs"
ZEALOT_TAG=nightly
ZEALOT_USE_SSL=false
ZEALOT_CLEAN_UP=false
##
## Cleanup
##
cleanup () {
if [ "$ZEALOT_CLEAN_UP" == "true" ]; then
return 0;
fi
echo ""
echo "== Cleaning up =="
$dc stop &> /dev/null
ZEALOT_CLEAN_UP=true
}
trap cleanup ERR INT TERM
##
## Configuring env file
##
configure_env_file () {
echo ""
echo "== Configuring $ENV_FILE file =="
if [ -f "$ENV_FILE" ]; then
echo "File already exists, skipped."
else
echo "Creating $ENV_FILE file"
cp -n "$EXAMPLE_ENV_FILE" "$ENV_FILE"
fi
}
##
## Download docker images
##
download_docker_images () {
echo ""
echo "== Pulling Docker images =="
$dc pull
echo "Docker images pulled."
}
##
## Generate secret key for zealot
##
generate_secret_key () {
echo ""
echo "== Generating secret key =="
HAS_SECRET_TOKEN=$(grep 'SECRET_TOKEN' $ENV_FILE | awk '{split($0,a,"="); print a[2]}')
if [ -z "$HAS_SECRET_TOKEN" ]; then
SECRET_TOKEN=$(docker run --rm redis:5-alpine ash -c 'head /dev/urandom | tr -dc A-Za-z0-9 | head -c 256; echo '' 2> /dev/null')
sed -i -e 's/^SECRET_TOKEN=.*$/SECRET_TOKEN='"$SECRET_TOKEN"'/' $ENV_FILE
clean_sed_temp_file $ENV_FILE
echo "Secret key written to $ENV_FILE"
else
echo "Secret key had been write, skipped"
fi
}
check_zealot_domain () {
echo ""
echo "== Set zealot domain =="
status=$(grep 'ZEALOT_DOMAIN' $ENV_FILE | awk '{print $1}')
domain=$(grep 'ZEALOT_DOMAIN' $ENV_FILE | awk '{split($0,a,"="); print a[2]}')
read_from_user=0
if [ -z "$domain" ]; then
read_from_user=1
echo "Input zealot domain, without http(s):// (eg, zealot.test)."
printf "ZEALOT_DOMAIN="
read domain
else
echo "Read zealot domain: ${domain}, skipped"
fi
if [ -z "$domain" ]; then
echo "Read ZEALOT_DOMAIN failed, skipped"
else
sed -i -e 's/^.*ZEALOT_DOMAIN=.*$/ZEALOT_DOMAIN='"$domain"'/' $ENV_FILE
clean_sed_temp_file $ENV_FILE
if [ "$read_from_user" == "1" ]; then
echo "Zealot domain written to $ENV_FILE"
fi
fi
}
detect_docker_compose_file () {
echo ""
echo "== Detect docker-compose.yml =="
if [ -f "$DOCKER_COMPOSE_FILE" ]; then
if [ -n "cat $DOCKER_COMPOSE_FILE | grep '# USE SSL:'" ]; then
HAS_DOCKERDOCKER_COMPOSE_FILE="true"
echo "${DOCKER_COMPOSE_FILE} file already exists, skipped generate."
fi
fi
}
##
## Start deploy flow
##
choose_deploy () {
echo ""
echo "== Configuring Deploy =="
printf "How do you deploy?\n\
Use [L]et's Encryt SSL (default)\n\
Use [S]elf-signed SSL\n\
Do [n]ot use SSL? \n"
read -n 1 action
echo ""
local SSL_NAME=letsencrypt
case "$action" in
L | l )
check_or_configure_letsencrypt_ssl;;
S | s )
check_or_generate_selfsigned_ssl;;
N | n )
enable_rails_serve_static_files;;
* )
;;
esac
if [ -z "$action" ]; then
check_or_configure_letsencrypt_ssl
fi
}
##
## Check or generate Caddyfile
##
check_or_generate_caddyfile () {
if [ -f "$CADDY_FILE" ]; then
echo "${CADDY_FILE} file already exists, skipped."
else
echo "Creating $CADDY_FILE file"
mkdir -p $ROOTFS_ETC_PATH
cp -n "$CADDY_TEMPLATE_FILE" "$CADDY_FILE"
fi
}
##
## Check or configure Let's Encrypt SSL
##
check_or_configure_letsencrypt_ssl () {
echo ""
echo "== Configuring Let's Encrypt SSL/TLS =="
echo "What is you email for let's encrypt?"
printf "ZEALOT_CERT_EMAIL="
read email
if [ -z "$email" ]; then
echo "Read ZEALOT_CERT_EMAIL failed, Quitting"
exit
else
sed -i -e 's/^.*ZEALOT_CERT_EMAIL=.*$/ZEALOT_CERT_EMAIL='"$email"'/' $ENV_FILE
clean_sed_temp_file $ENV_FILE
echo "Let's Encrypt email written to $ENV_FILE"
check_or_generate_caddyfile
sed -i -e 's/^.*tls .*$/ tls {$ZEALOT_CERT_EMAIL}/' $CADDY_FILE
clean_sed_temp_file $CADDY_FILE
echo "Let's Encrypt email written to $CADDY_FILE"
fi
ZEALOT_USE_SSL="letsencrypt"
}
##
## Check or Generate self signed SSL
##
check_or_generate_selfsigned_ssl () {
DOMAIN_NAME=$(grep 'ZEALOT_DOMAIN' $ENV_FILE | awk '{split($0,a,"="); print a[2]}')
echo ""
echo "== Configuring self signed SSL/TLS cert =="
echo "Generating self-signed cert for ${DOMAIN_NAME}"
CERT_NAME="${DOMAIN_NAME}.pem"
KEY_NAME="${DOMAIN_NAME}-key.pem"
CERT_FILE="${CERTS_PATH}/${CERT_NAME}"
KEY_FILE="${CERTS_PATH}/${KEY_NAME}"
mkdir -p "$(pwd)/$CERTS_PATH"
docker run --rm --name zealot-mkcert -v $(pwd)/$CERTS_PATH:/root/.local/share/mkcert \
icyleafcn/mkcert /bin/ash -c "mkcert -install && mkcert ${DOMAIN_NAME}" &> /dev/null
while true; do
if [ -f "$CERT_FILE" ] && [ -f "$KEY_FILE" ];then
sed -i -e 's/^.*ZEALOT_CERT=.*$/ZEALOT_CERT='"$CERT_NAME"'/' $ENV_FILE
sed -i -e 's/^.*ZEALOT_CERT_KEY=.*$/ZEALOT_CERT_KEY='"$KEY_NAME"'/' $ENV_FILE
clean_sed_temp_file $ENV_FILE
echo "Generated cert and key to $CERTS_PATH"
check_or_generate_caddyfile
local CADDY_CERTS_PATH=$(echo $DOCKER_CADDY_CERT_PATH | sed 's/\//\\\//g')
sed -i -e 's/^ tls .*$/ tls '"$CADDY_CERTS_PATH"'\/{$ZEALOT_CERT} '"$CADDY_CERTS_PATH"'\/{$ZEALOT_CERT_KEY}/' $CADDY_FILE
clean_sed_temp_file $CADDY_FILE
echo "Self-signed cert and key written to $CADDY_FILE"
break
fi
sleep 1
done
ZEALOT_USE_SSL="selfsigned"
}
##
## Enable rails serve static files
##
enable_rails_serve_static_files () {
SSL_NAME=false
echo ""
echo "== Enable Rails serve static files =="
sed -i -e 's/^# RAILS_SERVE_STATIC_FILES=.*$/RAILS_SERVE_STATIC_FILES=true/' $ENV_FILE
clean_sed_temp_file $ENV_FILE
echo "Written RAILS_SERVE_STATIC_FILES=true written to $ENV_FILE"
}
##
## Create docker volumes for zealot
##
create_docker_volumes () {
echo ""
echo "== Creating volumes for persistent storage =="
# always remove zealot-app volume to make sure use old zealot data
HAS_APP_VOLUME=$(docker volume ls | grep -v DRIVER | grep zealot-app | wc -l 2> /dev/null)
if [ -z "$HAS_APP_VOLUME" ]; then
docker volume rm zealot-app
fi
echo "Created $(docker volume create --name=zealot-data)."
echo "Created $(docker volume create --name=zealot-postgres)."
echo "Created $(docker volume create --name=zealot-redis)."
cat $DOCKER_COMPOSE_TEMPLATE_PATH/external-volumes.yml >> $DOCKER_COMPOSE_FILE
}
configure_local_docker_volumes() {
echo ""
echo "== Configuring docker local volumes =="
echo "Which path do you want to storage?"
printf "ZEALOT_PATH="
read zealot_path
if [ -z "$zealot_path" ]; then
echo "Read PATH failed, Quitting"
exit
else
mkdir -p "$zealot_path/redis"
mkdir -p "$zealot_path/zealot"
mkdir -p "$zealot_path/postgres"
echo "You path is: $zealot_path"
LOCAL_VOLUMES_FILE="$DOCKER_COMPOSE_TEMPLATE_PATH/local-volumes.yml"
escaped_zealot_path=$(echo $zealot_path | sed 's/\//\\\//g')
sed -i -e 's/\/tmp\/zealot/'"$escaped_zealot_path"'/g' $LOCAL_VOLUMES_FILE
clean_sed_temp_file $LOCAL_VOLUMES_FILE
echo "Local docker volumes configured to $zealot_path"
cat $DOCKER_COMPOSE_TEMPLATE_PATH/local-volumes.yml >> $DOCKER_COMPOSE_FILE
fi
}
choose_volumes () {
echo ""
echo "== Configuring Docker volumes =="
printf "Which way do you choose to storage zealot data?\n\
Use Docker [V]olumes (default)\n\
Use [L]ocal file system\n"
read -n 1 action
echo ""
local STORAGE=volumes
case "$action" in
V | v )
create_docker_volumes;;
L | l )
configure_local_docker_volumes;;
* )
;;
esac
if [ -z "$action" ]; then
create_docker_volumes
fi
}
##
## Check and install docker
##
check_and_install_docker () {
docker_path=`which docker.io || which docker`
if [ -z $docker_path ]; then
os_type=$(current_os)
if [ "$os_type" == "Darwin" ]; then
echo "Docker not installed. Click https://docs.docker.com/docker-for-mac/install/ manually, "
echo "after then hit enter to continue or Ctrl+C to exit"
read
else
read -p "Docker not installed. Enter to install from https://get.docker.com/ or Ctrl+C to exit"
curl https://get.docker.com/ | sh
fi
fi
docker_path=`which docker.io || which docker`
if [ -z $docker_path ]; then
echo "Docker install failed. Quitting."
exit
fi
}
##
## Check and install docker-compose
##
check_and_install_docker_compose () {
docker_compose_path=`which docker-compose`
if [ -z $docker_compose_path ]; then
read -p "Docker Compose not installed. Enter to install from https://docs.docker.com/compose/install/ or Ctrl+C to exit"
curl -L "https://github.com/docker/compose/releases/download/1.25.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
export PATH="/usr/local/bin/docker-compose:$PATH"
fi
docker_compose_path=`which docker-compose`
if [ -z $docker_compose_path ]; then
echo "Docker Compose install failed. Quitting."
exit
fi
}
##
## Generate Docker compose
##
generate_docker_compose () {
echo ""
echo "== Generating docker-compose.yml =="
echo "# Generated on $(date)" > $DOCKER_COMPOSE_FILE
echo "# USE SSL: ${ZEALOT_USE_SSL}" >> $DOCKER_COMPOSE_FILE
cat $DOCKER_COMPOSE_TEMPLATE_PATH/base.yml >> $DOCKER_COMPOSE_FILE
if [ "$ZEALOT_USE_SSL" == "false" ]; then
echo " ports:" >> $DOCKER_COMPOSE_FILE
echo ' - "3031:3000"' >> $DOCKER_COMPOSE_FILE
fi
if [ ! "$ZEALOT_USE_SSL" == "false" ]; then
cat $DOCKER_COMPOSE_TEMPLATE_PATH/cert.yml >> $DOCKER_COMPOSE_FILE
fi
choose_volumes
echo "Generated $DOCKER_COMPOSE_FILE"
}
# ##
# ## Set up database
# ##
# set_up_database () {
# echo ""
# echo "== Setting up database =="
# $dcr zealot bundle exec rake zealot:upgrade
# }
##
## Current OS name
##
current_os() {
echo `uname -s`
}
##
## Docker check
##
docker_check() {
check_and_install_docker
check_and_install_docker_compose
}
remove_old_containers() {
if [ -f "$DOCKER_COMPOSE_FILE" ]; then
echo ""
echo "== Remove older versions of zealot =="
# Clean up old stuff and ensure nothing is working while we install/update
$dc down --rmi local --remove-orphans
rm docker-compose.yml
fi
}
##
## Banner
##
print_banner () {
echo ' ______ _ _
|___ / | | | |
/ / ___ __ _| | ___ | |_
/ / / _ \/ _` | |/ _ \| __|
/ /_| __/ (_| | | (_) | |_
/_____\___|\__,_|_|\___/ \__|'
}
##
## Clean sed temp file (always -e as suffix) if exists
##
clean_sed_temp_file () {
local FILENAME=$1
if [ -f "${FILENAME}-e" ]; then
rm ${FILENAME}-e
fi
}
all_done () {
echo ""
echo "== All done =="
echo "Clean it up ..."
docker-compose down &> /dev/null
echo ""
echo "You're all done! Run the following command get Zealot running:"
echo ""
echo " [sudo] docker-compose up -d"
echo ""
}
###################################
# Init
###################################
print_banner
docker_check
remove_old_containers
configure_env_file
detect_docker_compose_file
if [ "$HAS_DOCKERDOCKER_COMPOSE_FILE" == "false" ]; then
check_zealot_domain
choose_deploy
generate_docker_compose
fi
if [ "$SKIP_UPDATE" == "false" ]; then
download_docker_images
fi
generate_secret_key
all_done
#
# Mostly of scripts fork from https://github.com/getsentry/onpremise
# Orginal License: https://github.com/getsentry/onpremise/blob/master/LICENSE
source "$(dirname $0)/scripts/function.sh"
source "scripts/load-cli-parser.sh"
source "scripts/error-handling.sh"
source "scripts/check-requirements.sh"
source "scripts/generate-env-file.sh"
source "scripts/generate-secret-key.sh"
source "scripts/generate-domain.sh"
source "scripts/configure-cert.sh"
source "scripts/generate-compose-file.sh"
source "scripts/configure-volumes.sh"
source "scripts/fetch-docker-images.sh"
source "scripts/turn-things-off.sh"
source "scripts/wrap-up.sh"
+86
View File
@@ -0,0 +1,86 @@
MIN_DOCKER_VERSION='20.10.0'
MIN_COMPOSE_VERSION='1.28.0'
CURRENT_OS=$(current_os)
DOCKER_VERSION=$(docker version --format '{{.Server.Version}}')
# Compare dot-separated strings - function below is inspired by https://stackoverflow.com/a/37939589/808368
function ver () { echo "$@" | awk -F. '{ printf("%d%03d%03d", $1,$2,$3); }'; }
##
## Check docker compose version (v1 and v2)
##
function get_docker_compose_version () {
local INFO=$($dc --version)
if [[ $INFO == *"docker-compose"* ]]; then
# docker-compose version 1.29.2, build 5becea4c
COMPOSE_VERSION=$(echo $INFO | sed 's/docker-compose version \(.\{1,\}\),.*/\1/')
else
# Docker Compose version v2.0.0-beta.6
COMPOSE_VERSION=$(echo $INFO | awk '{print $NF}' | sed 's/^v//' | sed 's/\(.\{1,\}\),.*/\1/')
fi
}
##
## Check and install docker
##
check_and_install_docker () {
docker_path=`which docker.io || which docker 2> /dev/null`
if [ -z $docker_path ]; then
if [ "$CURRENT_OS" == "Darwin" ]; then
echo "Docker not installed. Click https://docs.docker.com/docker-for-mac/install/ manually, "
echo "after then hit enter to continue or Ctrl+C to exit"
read
else
read -p "Docker not installed. Enter to install from https://get.docker.com/ or Ctrl+C to exit"
curl https://get.docker.com/ | sh
fi
fi
docker_path=`which docker.io || which docker 2> /dev/null`
if [ -z $docker_path ]; then
echo "Docker install failed. Quitting."
exit
fi
}
##
## Check and install docker-compose
##
check_and_install_docker_compose () {
docker_compose_path=`which docker-compose`
if [ -z $docker_compose_path ]; then
read -p "Docker Compose not installed. Enter to install from https://docs.docker.com/compose/install/ or Ctrl+C to exit"
curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
export PATH="/usr/local/bin/docker-compose:$PATH"
fi
docker_compose_path=`which docker-compose`
if [ -z $docker_compose_path ]; then
echo "Docker Compose install failed. Quitting."
exit
fi
}
echo "${_group}Checking requirements ..."
get_docker_compose_version
check_and_install_docker
check_and_install_docker_compose
if [[ "$(ver $DOCKER_VERSION)" -lt "$(ver $MIN_DOCKER_VERSION)" ]]; then
echo "FAIL: Expected minimum Docker version to be $MIN_DOCKER_VERSION but found $DOCKER_VERSION"
exit 1
fi
if [[ "$(ver $COMPOSE_VERSION)" -lt "$(ver $MIN_COMPOSE_VERSION)" ]]; then
echo "FAIL: Expected minimum docker-compose version to be $MIN_COMPOSE_VERSION but found $COMPOSE_VERSION"
exit 1
fi
echo "Current OS: `uname -sm`"
echo "Docker version: ${DOCKER_VERSION}"
echo "Docker Compose version: ${COMPOSE_VERSION}"
echo "${_endgroup}"
+133
View File
@@ -0,0 +1,133 @@
echo "${_group}Configuring cert file(s) ..."
CADDY_VOLUME_PATH="${CADDY_PATH}${CADDY_ROOTFS_PATH}"
CADDY_FILE="${CADDY_VOLUME_PATH}/${CADDYFILE_NAME}"
CERTS_PATH="${CADDY_VOLUME_PATH}/${CERTS_NAME}"
DOCKER_CADDY_FILE="${CADDY_ROOTFS_PATH}/${CADDYFILE_NAME}"
DOCKER_CERTS_PATH="${CADDY_ROOTFS_PATH}/${CERTS_NAME}"
##
## Check or generate Caddyfile
##
check_or_generate_caddyfile () {
mkdir -p $CADDY_VOLUME_PATH
mkdir -p $CERTS_PATH
if [ -f "$CADDY_FILE" ]; then
echo "${CADDY_FILE} file already exists, skipped."
else
echo "Creating $CADDY_FILE file"
cp -n "$TEMPLATE_CADDY_FILE" "$CADDY_FILE"
fi
}
##
## Check or configure Let's Encrypt SSL
##
check_or_configure_letsencrypt_ssl () {
echo "${_group}Configuring Let's Encrypt SSL/TLS ..."
echo "What is you email for let's encrypt?"
printf "ZEALOT_CERT_EMAIL="
read email
if [ -z "$email" ]; then
echo "Read ZEALOT_CERT_EMAIL failed, Quitting"
exit
else
sed -i -e 's/^.*ZEALOT_CERT_EMAIL=.*$/ZEALOT_CERT_EMAIL='"$email"'/' $ENV_FILE
clean_sed_temp_file $ENV_FILE
echo "Let's Encrypt email written to .env"
check_or_generate_caddyfile
fi
ZEALOT_USE_SSL="letsencrypt"
}
##
## Check or Generate self signed SSL
##
check_or_generate_selfsigned_ssl () {
DOMAIN_NAME=$(grep 'ZEALOT_DOMAIN' $ENV_FILE | awk '{split($0,a,"="); print a[2]}')
echo "${_group}Configuring self signed SSL/TLS cert ... ${DOMAIN_NAME}"
CERT_NAME="${DOMAIN_NAME}.pem"
KEY_NAME="${DOMAIN_NAME}-key.pem"
CERT_FILE="${CERTS_PATH}/${CERT_NAME}"
KEY_FILE="${CERTS_PATH}/${KEY_NAME}"
docker run --rm --name zealot-mkcert \
-v $(pwd)/$CERTS_PATH:/root/.local/share/mkcert \
icyleafcn/mkcert \
/bin/ash -c "mkcert -install && mkcert ${DOMAIN_NAME}" &> /dev/null
while true; do
if [ -f "$CERT_FILE" ] && [ -f "$KEY_FILE" ];then
sed -i -e 's/^.*ZEALOT_CERT=.*$/ZEALOT_CERT='"$CERT_NAME"'/' $ENV_FILE
sed -i -e 's/^.*ZEALOT_CERT_KEY=.*$/ZEALOT_CERT_KEY='"$KEY_NAME"'/' $ENV_FILE
clean_sed_temp_file $ENV_FILE
echo "Generated cert and key to $CERTS_PATH"
check_or_generate_caddyfile
if [ -z grep 'tls {$ZEALOT_CERT_EMAIL}' $CADDY_FILE ]; then
echo "CAN NOT read \$ZEALOT_CERT_EMAIL variable in $CADDY_FILE, abort"
exit
else
local TEMP_PATH=$(echo $DOCKER_CERTS_PATH | sed 's/\//\\\//g')
sed -i -e 's/{$ZEALOT_CERT_EMAIL}/'"$TEMP_PATH"'\/{$ZEALOT_CERT} '"$TEMP_PATH"'\/{$ZEALOT_CERT_KEY}/' $CADDY_FILE
clean_sed_temp_file $CADDY_FILE
echo "Self-signed cert and key written to $CADDY_FILE"
fi
break
fi
sleep 1
done
ZEALOT_USE_SSL="self-signed"
}
##
## Start deploy flow
##
choose_deploy () {
printf "How do you deploy?\n\
Use [L]et's Encryt SSL (default)\n\
Use [S]elf-signed SSL\n\
Do [n]ot use SSL? \n"
read -n 1 action
echo ""
local SSL_NAME=letsencrypt
case "$action" in
L | l )
check_or_configure_letsencrypt_ssl;;
S | s )
check_or_generate_selfsigned_ssl;;
* )
SSL_NAME=false
;;
esac
if [ -z "$action" ]; then
check_or_configure_letsencrypt_ssl
fi
echo "${_endgroup}"
}
if [ -f "$DOCKER_COMPOSE_FILE" ]; then
if [ -n "cat $DOCKER_COMPOSE_FILE | grep '# USE SSL:'" ]; then
HAS_DOCKERDOCKER_COMPOSE_FILE="true"
echo "Cert already configured, skipped"
else
echo "Detected docker-compose file AND its not writon by zealot, at your own risk!!!"
fi
fi
if [ "$HAS_DOCKERDOCKER_COMPOSE_FILE" == "false" ]; then
choose_deploy
else
echo "${_endgroup}"
fi
+81
View File
@@ -0,0 +1,81 @@
echo "${_group}Configuring Docker volumes ..."
##
## Create docker volumes for zealot
##
create_docker_volumes () {
# always remove zealot-app volume to make sure use old zealot data
local HAS_APP_VOLUME=$(docker volume ls | grep -v DRIVER | grep zealot-app | wc -l 2> /dev/null)
if [ -z "$HAS_APP_VOLUME" ]; then
docker volume rm zealot-app
fi
echo "Created $(docker volume create --name=zealot-uploads)."
echo "Created $(docker volume create --name=zealot-backup)."
echo "Created $(docker volume create --name=zealot-postgres)."
echo "Created $(docker volume create --name=zealot-redis)."
cat $TEMPLATE_DOCKER_COMPOSE_PATH/external-volumes.yml >> $DOCKER_COMPOSE_FILE
echo "Exteral volumes write to file: $DOCKER_COMPOSE_FILE"
}
configure_local_docker_volumes() {
echo "Which path do you want to storage?"
printf "ZEALOT_STORED_PATH="
read stored
if [ -z "$stored" ]; then
echo "Read ZEALOT_STORED_PATH failed, Quitting"
exit
else
mkdir -p "$stored/zealot/uploads"
mkdir -p "$stored/zealot/backup"
mkdir -p "$stored/redis"
mkdir -p "$stored/postgres"
local LOCAL_VOLUMES_FILE="$TEMPLATE_DOCKER_COMPOSE_PATH/local-volumes.yml"
local TEMP_VOLUMES_FILE="/tmp/local-volumes.yml"
cp $LOCAL_VOLUMES_FILE $TEMP_VOLUMES_FILE
escaped_zealot_path=$(echo $stored | sed 's/\//\\\//g')
sed -i -e 's/\/tmp/'"$escaped_zealot_path"'/g' $TEMP_VOLUMES_FILE
clean_sed_temp_file $TEMP_VOLUMES_FILE
cat $TEMP_VOLUMES_FILE >> $DOCKER_COMPOSE_FILE
rm $TEMP_VOLUMES_FILE
echo "Local volumes '$stored' write to file: $DOCKER_COMPOSE_FILE"
fi
}
choose_volumes () {
printf "Which way do you choose to storage zealot data?\n\
Use Docker [V]olumes (default)\n\
Use [L]ocal file system\n"
read -n 1 action
echo ""
local STORAGE=volumes
case "$action" in
V | v )
create_docker_volumes;;
L | l )
configure_local_docker_volumes;;
* )
;;
esac
if [ -z "$action" ]; then
create_docker_volumes
fi
}
VOLUMES_EXISTS=$(grep -E "^(\s+)zealot\-(\w+):" $DOCKER_COMPOSE_FILE || echo 0)
if [ $VOLUMES_EXISTS -eq 4 ]; then
echo "Volumes already exists, skipped"
else
choose_volumes
fi
echo "${_endgroup}"
+37
View File
@@ -0,0 +1,37 @@
echo "${_group}Setting up error handling ..."
# Courtesy of https://stackoverflow.com/a/2183063/90297
trap_with_arg() {
func="$1" ; shift
for sig ; do
trap "$func $sig "'$LINENO' "$sig"
done
}
ZEALOT_CLEAN_UP="${ZEALOT_CLEAN_UP:-"false"}"
cleanup () {
if [ "$ZEALOT_CLEAN_UP" == "false" ]; then
return 0;
fi
ZEALOT_CLEAN_UP=true
if [[ "$1" != "EXIT" ]]; then
echo ""
echo "An error occurred, caught SIG$1 on line $2";
if [[ -n "$MINIMIZE_DOWNTIME" ]]; then
echo "*NOT* cleaning up, to clean your environment run \"docker-compose stop\"."
else
echo "Cleaning up..."
fi
fi
if [[ -z "$MINIMIZE_DOWNTIME" ]]; then
$dc stop -t $STOP_TIMEOUT &> /dev/null
fi
}
trap_with_arg cleanup ERR INT TERM EXIT
echo "ZEALOT_CLEAN_UP=${ZEALOT_CLEAN_UP}"
echo "${_endgroup}"
+10
View File
@@ -0,0 +1,10 @@
echo "${_group}Fetching Docker images ..."
if [ "$SKIP_UPDATE" == "false" ]; then
$dc pull
echo "Docker images pulled"
else
echo "Skipped"
fi
echo "${_endgroup}"
+60
View File
@@ -0,0 +1,60 @@
set -euo pipefail
test "${DEBUG:-}" && set -x
log_file="zealot_install_log-`date +'%Y-%m-%d_%H-%M-%S'`.txt"
exec &> >(tee -a "$log_file")
MINIMIZE_DOWNTIME="${MINIMIZE_DOWNTIME:-}"
ZEALOT_TAG=nightly
ZEALOT_USE_SSL=false
ZEALOT_ROOT=$(dirname $0)
EXAMPLE_ENV_FILE="config.env"
ENV_FILE=".env"
DOCKER_COMPOSE_FILE="docker-compose.yml"
HAS_DOCKERDOCKER_COMPOSE_FILE="false"
TEMPLATE_PATH="templates"
TEMPLATE_DOCKER_COMPOSE_PATH="${TEMPLATE_PATH}/docker-compose"
TEMPLATE_CADDY_FILE="${TEMPLATE_PATH}/Caddyfile"
CADDY_PATH="caddy"
CADDY_ROOTFS_PATH="/etc/caddy"
CADDYFILE_NAME="Caddyfile"
CERTS_NAME="certs"
if [ "${GITHUB_ACTIONS:-}" = "true" ]; then
_group="::group::"
_endgroup="::endgroup::"
else
_group="▶ "
_endgroup=""
fi
dc="docker-compose --ansi never"
dcr="$dc run --rm"
##
## Current OS name
##
current_os() {
echo `uname -s`
}
##
## Clean sed temp file (always -e as suffix) if exists
##
clean_sed_temp_file () {
local FILENAME=$1
if [ -f "${FILENAME}-e" ]; then
rm ${FILENAME}-e
fi
}
# Increase the default 10 second SIGTERM timeout
# to ensure celery queues are properly drained
# between upgrades as task signatures may change across
# versions
STOP_TIMEOUT=60 # seconds
+20
View File
@@ -0,0 +1,20 @@
echo "${_group}Generating docker-compose.file ..."
if [ -f "$DOCKER_COMPOSE_FILE" ]; then
echo "File already exists, skipped"
else
echo "# Generated on $(date)" > $DOCKER_COMPOSE_FILE
echo "# USE SSL: ${ZEALOT_USE_SSL}" >> $DOCKER_COMPOSE_FILE
cat $TEMPLATE_DOCKER_COMPOSE_PATH/base.yml >> $DOCKER_COMPOSE_FILE
if [ "$ZEALOT_USE_SSL" == "false" ]; then
echo " ports:" >> $DOCKER_COMPOSE_FILE
echo ' - "80:80"' >> $DOCKER_COMPOSE_FILE
else
cat $TEMPLATE_DOCKER_COMPOSE_PATH/cert.yml >> $DOCKER_COMPOSE_FILE
fi
echo "Generated docker-compose.yml"
fi
echo "${_endgroup}"
+24
View File
@@ -0,0 +1,24 @@
echo "${_group}Generating domain ..."
DOMAIN_FROM_USER=0
DOMAIN=$(grep 'ZEALOT_DOMAIN' $ENV_FILE | awk '{split($0,a,"="); print a[2]}')
if [ -z "$DOMAIN" ]; then
DOMAIN_FROM_USER=1
echo "Input zealot domain, without http(s):// (eg, zealot.test)."
printf "ZEALOT_DOMAIN="
read DOMAIN
else
echo "Read zealot domain: ${DOMAIN}, skipped"
fi
if [ -z "$DOMAIN" ]; then
echo "Read ZEALOT_DOMAIN failed, skipped"
else
sed -i -e 's/^.*ZEALOT_DOMAIN=.*$/ZEALOT_DOMAIN='"$DOMAIN"'/' $ENV_FILE
clean_sed_temp_file $ENV_FILE
if [ "$DOMAIN_FROM_USER" == "1" ]; then
echo "Domain written to .env"
fi
fi
echo "${_endgroup}"
+10
View File
@@ -0,0 +1,10 @@
echo "${_group}Generating .env file ..."
if [ -f "$ENV_FILE" ]; then
echo "File already exists, skipped."
else
echo "Creating $ENV_FILE file"
cp -n "${EXAMPLE_ENV_FILE}" "${ENV_FILE}"
fi
echo "${_endgroup}"
+14
View File
@@ -0,0 +1,14 @@
echo "${_group}Generating secret key ..."
HAS_SECRET_TOKEN=$(grep 'SECRET_TOKEN' $ENV_FILE | awk '{split($0,a,"="); print a[2]}')
if [ -z "$HAS_SECRET_TOKEN" ]; then
SECRET_TOKEN=$(export LC_ALL=C; head /dev/urandom | tr -dc "a-z0-9@#%^&*(-_=+)" | head -c 50 | sed -e 's/[\/&]/\\&/g')
sed -i -e 's/^SECRET_TOKEN=.*$/SECRET_TOKEN='"'$SECRET_TOKEN'"'/' $ENV_FILE
clean_sed_temp_file $ENV_FILE
echo "Secret key written to .env"
else
echo "Secret key had been write, skipped"
fi
echo "${_endgroup}"
+44
View File
@@ -0,0 +1,44 @@
echo "${_group}Parsing command line ..."
MINIMIZE_DOWNTIME="${MINIMIZE_DOWNTIME:-}"
SKIP_UPDATE="${SKIP_UPDATE:-"false"}"
##
## Banner
##
print_banner () {
echo ' ______ _ _
|___ / | | | |
/ / ___ __ _| | ___ | |_
/ / / _ \/ _` | |/ _ \| __|
/ /_| __/ (_| | | (_) | |_
/_____\___|\__,_|_|\___/ \__|'
}
show_help() {
cat <<EOF
Usage: $0 [options]
Install Zealot with docker-compose.
Options:
-h, --help Show this message and exit.
--skip-update Skip docker-compose pull the images (default value: ${SKIP_UPDATE}).
--minimize-downtime EXPERIMENTAL: try to keep accepting events for as long as possible while upgrading.
This will disable cleanup on error, and might leave your installation in partially upgraded state.
This option might not reload all configuration, and is only meant for in-place upgrades.
EOF
}
while (( $# )); do
case "$1" in
-h | --help) show_help; exit;;
--skip-update) SKIP_UPDATE=1;;
--minimize-downtime) MINIMIZE_DOWNTIME=1;;
--) ;;
*) echo "Unexpected argument: $1. Use --help for usage information."; exit 1;;
esac
shift
done
print_banner
echo "${_endgroup}"
+10
View File
@@ -0,0 +1,10 @@
echo "${_group}Turning things off ..."
if [[ -n "$MINIMIZE_DOWNTIME" ]]; then
# Stop everything but proxy service
$dc rm -fsv $($dc config --services | grep -v -E '^(web)$')
else
$dc down -t $STOP_TIMEOUT --rmi local --remove-orphans
fi
echo "${_endgroup}"
+25
View File
@@ -0,0 +1,25 @@
if [[ "$MINIMIZE_DOWNTIME" ]]; then
echo "${_group}Waiting for Zealot to start ..."
# Start the whole setup, except proxy(caddy) service.
$dc up -d --remove-orphans $($dc config --services | grep -v -E '^(web)$')
$dc exec -T web caddy reload --config /etc/caddy/Caddyfile
docker run --rm --network="${COMPOSE_PROJECT_NAME}_default" redis:5-alpine ash \
-c 'while [[ "$(wget -T 1 -q -O- http://web:3000/_health/)" != "ok" ]]; do sleep 0.5; done'
# Make sure everything is up. This should only touch relay and nginx
$dc up -d
echo "${_endgroup}"
else
echo ""
echo "-----------------------------------------------------------------"
echo ""
echo "You're all done! Run the following command to get Zealot running:"
echo ""
echo " [sudo] docker-compose up -d"
echo ""
echo "-----------------------------------------------------------------"
echo ""
fi
+4 -23
View File
@@ -1,24 +1,5 @@
{$ZEALOT_DOMAIN}:80, {$ZEALOT_DOMAIN}:443 {
redir 301 {
if {scheme} is http
/ https://{host}{uri}
}
:443
log stdout
# ssl
tls {$ZEALOT_CERT_EMAIL}
# serve assets of rails
root /app/public
proxy / http://zealot:3000 {
except /assets /packs /uploads /config /favicon.ico /robots.txt
transparent
header_upstream X-Marotagem true
header_upstream Host {host}
header_upstream X-Real-IP {remote}
header_upstream X-Forwarded-For {remote}
}
}
tls {$ZEALOT_CERT_EMAIL}
log
reverse_proxy @static zealot
+7 -5
View File
@@ -1,7 +1,10 @@
version: "2.1"
version: "3.8"
x-restart-policy: &restart_policy
restart: unless-stopped
x-defaults: &defaults
restart: unless-stopped
<<: *restart_policy
image: ghcr.io/tryzealot/zealot:nightly
depends_on:
- redis
@@ -26,7 +29,7 @@ x-defaults: &defaults
services:
redis:
container_name: zealot-redis
<<: *restart_policy
image: redis:5-alpine
command: redis-server
volumes:
@@ -34,7 +37,7 @@ services:
healthcheck:
test: ["CMD", "redis-cli", "ping"]
postgres:
container_name: zealot-postgres
<<: *restart_policy
image: postgres:12-alpine
volumes:
- zealot-postgres:/var/lib/postgresql/data
@@ -44,4 +47,3 @@ services:
test: ["CMD", "pg_isready", "-U", "postgres"]
zealot:
<<: *defaults
container_name: zealot-zealot
+3 -5
View File
@@ -1,11 +1,9 @@
web:
container_name: zealot-web
image: abiosoft/caddy:1.0.3
image: caddy:2-alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./rootfs/etc/Caddyfile:/etc/Caddyfile
- ./rootfs/etc/certs:/etc/certs
- zealot-data:/app/public
- ./rootfs/etc/Caddyfile:/etc/Caddyfile:ro
- ./rootfs/etc/certs:/etc/certs:ro
env_file: .env