3a8fb09bcf
Provision server / provision (push) Successful in 6s
- configure.sh generates .env files from .env.keys + bws - deploy.sh detects build: services and runs docker compose build - new-service.sh prints .env.keys instructions - clean up .gitignore
98 lines
2.8 KiB
Bash
Executable File
98 lines
2.8 KiB
Bash
Executable File
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
CMD="${SSH_ORIGINAL_COMMAND:-${1:-}}"
|
|
|
|
if [[ "$CMD" =~ ^cert-[a-zA-Z0-9._-]+$ ]]; then
|
|
APP="${CMD#cert-}"
|
|
|
|
# Write temporary HTTP-only config so nginx can serve ACME challenges
|
|
cat > "/opt/hantim/docker/nginx/conf.d/$APP.conf" <<NGINXCONF
|
|
server {
|
|
listen 80;
|
|
listen [::]:80;
|
|
server_name $APP www.$APP;
|
|
|
|
location /.well-known/acme-challenge/ {
|
|
root /var/www/certbot;
|
|
}
|
|
|
|
location / {
|
|
return 444;
|
|
}
|
|
}
|
|
NGINXCONF
|
|
|
|
docker exec nginx nginx -t && docker exec nginx nginx -s reload
|
|
certbot certonly --webroot -w /opt/hantim/docker/nginx/certbot/www \
|
|
--non-interactive --agree-tos --register-unsafely-without-email \
|
|
--cert-name "$APP" -d "$APP" -d "www.$APP"
|
|
rm -f "/opt/hantim/docker/nginx/conf.d/$APP.conf"
|
|
echo "Certificate issued for $APP"
|
|
exit 0
|
|
fi
|
|
|
|
if [ "$CMD" = "provision" ]; then
|
|
cd /opt/hantim
|
|
git pull
|
|
bash scripts/configure.sh
|
|
exit 0
|
|
fi
|
|
|
|
if ! [[ "$CMD" =~ ^deploy-[a-zA-Z0-9._-]+$ ]]; then
|
|
echo "Unknown command: $CMD"
|
|
exit 1
|
|
fi
|
|
|
|
APP="${CMD#deploy-}"
|
|
cd /opt/hantim
|
|
git pull
|
|
cd "docker/$APP"
|
|
if grep -q '^\s*build:' compose.yml 2>/dev/null; then
|
|
docker compose build
|
|
else
|
|
if ! docker compose pull; then
|
|
echo "Image not yet available for $APP — skipping. It will deploy when the app repo is first pushed."
|
|
exit 0
|
|
fi
|
|
fi
|
|
|
|
if [ "$APP" = "nginx" ]; then
|
|
# Issue certs for any new domains (brief nginx downtime while certbot binds port 80)
|
|
missing_certs=false
|
|
for conf in /opt/hantim/docker/nginx/conf.d/*.conf; do
|
|
cert_name=$(basename "$conf" .conf)
|
|
if [ ! -d "/etc/letsencrypt/live/$cert_name" ]; then
|
|
missing_certs=true
|
|
break
|
|
fi
|
|
done
|
|
if [ "$missing_certs" = true ]; then
|
|
docker stop nginx 2>/dev/null || true
|
|
trap 'docker start nginx 2>/dev/null || true' EXIT
|
|
for conf in /opt/hantim/docker/nginx/conf.d/*.conf; do
|
|
cert_name=$(basename "$conf" .conf)
|
|
if [ ! -d "/etc/letsencrypt/live/$cert_name" ]; then
|
|
domains=$(grep -oP 'server_name\s+\K[^;]+' "$conf" | tr ' ' '\n' | sort -u)
|
|
domain_args=""
|
|
for d in $domains; do
|
|
domain_args="$domain_args -d $d"
|
|
done
|
|
echo "Issuing cert for $cert_name..."
|
|
certbot certonly --standalone --non-interactive --agree-tos \
|
|
--register-unsafely-without-email --cert-name "$cert_name" $domain_args
|
|
fi
|
|
done
|
|
trap - EXIT
|
|
fi
|
|
# Test config before applying — a bad config would take down all sites
|
|
docker compose run --rm -T nginx nginx -t
|
|
fi
|
|
|
|
docker compose down --remove-orphans
|
|
docker compose up -d
|
|
|
|
if [ "$APP" = "nginx" ]; then
|
|
docker exec nginx nginx -s reload
|
|
fi
|