-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathdeploy-prod.sh
More file actions
executable file
·133 lines (113 loc) · 4.12 KB
/
Copy pathdeploy-prod.sh
File metadata and controls
executable file
·133 lines (113 loc) · 4.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#!/usr/bin/env bash
set -euo pipefail
# deploy-prod.sh
# Deploy the application in SSL (production) mode as described in README.md
# Usage: DOMAIN=your.domain EMAIL=you@example.com DATA_WEBSERVER_PATH=/path DATA_PATH=/path ./deploy-prod.sh
print_usage() {
cat <<EOF
Usage: $0 [--external-port PORT] [--no-sudo]
Environment variables required when using SSL:
DATA_WEBSERVER_PATH Path to webserver data (required)
DATA_PATH Path to MIP follow-up clusters (required, may be empty directory)
DOMAIN Domain name for TLS certificate (required when USE_SSL=1)
EMAIL Email for certbot (required when USE_SSL=1)
Optional environment variables:
EXTERNAL_PORT External port (defaults to 8081)
USE_SSL Set to 1 to enable SSL (defaults to 1)
This script will build frontend artifacts, ensure TLS certificates exist (attempts certbot if missing), and start the docker compose stack.
EOF
}
# Defaults
: "${EXTERNAL_PORT:=8081}"
: "${USE_SSL:=1}"
# Parse args
USE_SUDO=1
while [[ $# -gt 0 ]]; do
case "$1" in
--external-port)
EXTERNAL_PORT="$2"; shift 2;;
--no-sudo)
USE_SUDO=0; shift;;
-h|--help)
print_usage; exit 0;;
*)
echo "Unknown arg: $1" >&2; print_usage; exit 2;;
esac
done
if [[ -z "${DATA_WEBSERVER_PATH-}" ]]; then
echo "ERROR: DATA_WEBSERVER_PATH is not set." >&2
print_usage
exit 2
fi
if [[ -z "${DATA_PATH-}" ]]; then
echo "ERROR: DATA_PATH is not set." >&2
print_usage
exit 2
fi
if [[ "$USE_SSL" -ne 0 ]]; then
if [[ -z "${DOMAIN-}" ]]; then
echo "ERROR: DOMAIN must be set when USE_SSL=1." >&2
print_usage
exit 2
fi
if [[ -z "${EMAIL-}" ]]; then
echo "ERROR: EMAIL must be set when USE_SSL=1." >&2
print_usage
exit 2
fi
fi
echo "Deploying in SSL (production) mode"
echo " DATA_WEBSERVER_PATH=$DATA_WEBSERVER_PATH"
echo " DATA_PATH=$DATA_PATH"
echo " EXTERNAL_PORT=$EXTERNAL_PORT"
echo " USE_SSL=$USE_SSL"
if [[ "$USE_SSL" -ne 0 ]]; then
echo " DOMAIN=$DOMAIN"
echo " EMAIL=$EMAIL"
fi
# Build frontend
echo "\n==> Building frontend..."
if [[ -d frontend ]]; then
if [[ -f frontend/yarn.lock ]]; then
echo "Using yarn to install and build frontend"
(cd frontend && yarn install --frozen-lockfile || yarn install)
(cd frontend && yarn build)
else
echo "Using npm to install and build frontend"
(cd frontend && npm ci)
(cd frontend && npm run build)
fi
else
echo "Warning: frontend directory not found; skipping frontend build." >&2
fi
# Prepare docker compose commands
if [[ $USE_SUDO -eq 1 && $(id -u) -ne 0 ]]; then
SUDO_CMD=(sudo --preserve-env=DATA_PATH,DATA_WEBSERVER_PATH,EXTERNAL_PORT,USE_SSL,DOMAIN,EMAIL)
else
SUDO_CMD=()
fi
echo "\n==> Stopping any existing docker compose stack (if running)"
${SUDO_CMD[@]} docker compose down || true
echo "\n==> Starting docker compose (building images)"
${SUDO_CMD[@]} docker compose up --build -d
# Ensure there's a root cron job to check certificate expiration hourly
# The job runs `is-certificate-expired.sh` and, if it returns "1", tries
# to renew the certificate using certbot and restarts nginx on success.
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CRON_JOB_CMD="[ -x \"$REPO_ROOT/is-certificate-expired.sh\" ] && \"$REPO_ROOT/is-certificate-expired.sh\" \"$LOCAL_DOMAIN\" $EXTERNAL_PORT | grep -q '^1$' && certbot certonly --webroot -w \"$REPO_ROOT/certbot/www\" -d \"$DOMAIN\" --email \"$EMAIL\" --agree-tos --no-eff-email --force-renewal --deploy-hook 'sudo docker compose restart nginx' --cert-name \"$DOMAIN\" >/dev/null 2>&1"
CRON_LINE="0 * * * * $CRON_JOB_CMD"
echo "\n==> Ensuring hourly cron job for certificate renewal (root crontab)"
TMP_CRON_FILE="$(mktemp)"
# Dump existing root crontab (if any) into tmp file
${SUDO_CMD[@]} bash -c "crontab -l -u root 2>/dev/null || true" > "$TMP_CRON_FILE"
if grep -Fxq "$CRON_LINE" "$TMP_CRON_FILE"; then
echo "Cron job already present; skipping."
else
echo "Adding cron job to root crontab."
echo "$CRON_LINE" >> "$TMP_CRON_FILE"
${SUDO_CMD[@]} crontab -u root "$TMP_CRON_FILE"
fi
rm -f "$TMP_CRON_FILE"
echo "\nDeployment finished.\n"
echo "Check services with: docker compose ps"
echo "If you used sudo, use: sudo docker compose ps"