-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdeploy.sh
More file actions
187 lines (171 loc) · 9.15 KB
/
Copy pathdeploy.sh
File metadata and controls
187 lines (171 loc) · 9.15 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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
#!/usr/bin/env bash
# ============================================================================
# PSP Router — Deploy Script
# ============================================================================
# Deploys code + config to OpenResty and the nginx proxy snippet.
# Does NOT modify any existing Nginx config files directly.
#
# Usage:
# sudo bash deploy.sh # deploy to default paths
# sudo bash deploy.sh /custom/path # deploy to a custom OpenResty prefix
#
# NOTE on the custom prefix: dist/conf/nginx.conf hardcodes
# lua_package_path "/usr/local/openresty/nginx/lua/?.lua;;"
# so a custom prefix still loads Lua from the default location. Edit that line
# to match your prefix before deploying, or the router will run the wrong code
# (or fail to find its modules at all).
# ============================================================================
set -euo pipefail
OPENRESTY_BIN="/usr/local/openresty/bin/openresty"
DEPLOY_TARGET="${1:-/usr/local/openresty/nginx}"
SNIPPET_DIR="/etc/nginx/snippets"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
DIST_DIR="${SCRIPT_DIR}/dist"
if [ ! -d "${DIST_DIR}" ]; then
echo "ERROR: dist/ directory not found at ${DIST_DIR}" >&2
exit 1
fi
# ── Deploy OpenResty code + config ──────────────────────────────────────────
# A custom prefix is an empty directory: rsync will not create the parents, and
# OpenResty needs logs/ plus the mime.types that nginx.conf includes. The
# default prefix already has all of these, so this is a no-op there.
mkdir -p "${DEPLOY_TARGET}/conf/conf.d" "${DEPLOY_TARGET}/lua" "${DEPLOY_TARGET}/logs"
if [ ! -f "${DEPLOY_TARGET}/conf/mime.types" ] \
&& [ -f /usr/local/openresty/nginx/conf/mime.types ]; then
cp /usr/local/openresty/nginx/conf/mime.types "${DEPLOY_TARGET}/conf/mime.types"
fi
echo "Deploying OpenResty files to ${DEPLOY_TARGET} ..."
# resolver.conf is excluded because it is managed at runtime by the admin
# Settings UI. Without this exclude, every deploy silently reverts the DNS
# resolver to whatever is committed in the repo — which breaks cloud routing on
# any deployment that uses an internal resolver. It is seeded below if absent.
rsync -av --checksum \
--exclude "resolver.conf" \
"${DIST_DIR}/conf/" "${DEPLOY_TARGET}/conf/"
rsync -av --checksum \
--exclude "cloud_routes.json" \
--exclude "routes.json" \
--exclude "psp_rules.json" \
--exclude "settings.json" \
--exclude "admin_credentials.json" \
"${DIST_DIR}/lua/" "${DEPLOY_TARGET}/lua/"
# ── Ensure resolver.conf exists and is writable ──────────────────────────
# Managed at runtime by the admin Settings UI and excluded from the rsync above,
# so seed it on first deploy only — psp-router.conf includes it unconditionally
# and nginx refuses to start if it is missing.
RESOLVER_FILE="${DEPLOY_TARGET}/conf/resolver.conf"
if [ ! -f "${RESOLVER_FILE}" ]; then
cp "${DIST_DIR}/conf/resolver.conf" "${RESOLVER_FILE}"
echo "Created ${RESOLVER_FILE} from repo defaults"
echo " -> Set a resolver your server can actually reach at /admin/settings"
echo " (only cloud routes use it; stage/local resolve via /etc/hosts)."
fi
chmod 666 "${RESOLVER_FILE}"
# ── Ensure JSON data files exist and are writable ─────────────────────────
# These files are managed on the server (via admin UI).
# deploy.sh never overwrites them — only creates if missing.
CORE_DIR="${DEPLOY_TARGET}/lua/psp_handlers/core"
for JSON_FILE in cloud_routes.json routes.json psp_rules.json; do
if [ ! -f "${CORE_DIR}/${JSON_FILE}" ]; then
echo '{}' > "${CORE_DIR}/${JSON_FILE}"
fi
chmod 666 "${CORE_DIR}/${JSON_FILE}"
done
# Settings file — seed from the repo copy on first deploy.
# Seeding an EMPTY pattern list here would leave the router matching nothing
# while every health check still passes, so prefer the repo copy which ships
# working example patterns. settings.json is rsync-excluded above, so this is
# the only thing that ever puts it on the server.
SETTINGS_FILE="${CORE_DIR}/settings.json"
REPO_SETTINGS="${DIST_DIR}/lua/psp_handlers/core/settings.json"
if [ ! -f "${SETTINGS_FILE}" ]; then
if [ -f "${REPO_SETTINGS}" ]; then
cp "${REPO_SETTINGS}" "${SETTINGS_FILE}"
echo "Created ${SETTINGS_FILE} from repo defaults"
echo " -> These URI patterns are EXAMPLES. Review them at /admin/settings"
echo " so they match the callback URLs your PSPs actually call."
else
echo '{"patterns":[]}' > "${SETTINGS_FILE}"
echo "WARNING: Created ${SETTINGS_FILE} with an EMPTY pattern list."
echo " -> The router will match nothing until you add URI patterns"
echo " at /admin/settings."
fi
fi
chmod 666 "${SETTINGS_FILE}"
# ── Ensure admin credentials file exists ──────────────────────────────────
# Server-only file, NOT in git. Only created on first deploy.
# Default password: changeme (MD5: 4cb9c8a8048fd02294477fcb1a41191a)
# To reset: sudo /usr/local/openresty/bin/resty -e 'print(ngx.md5("newpass"))'
# (the package does not put `resty` on PATH — use the absolute path,
# or: printf '%s' 'newpass' | md5sum)
# then edit admin_credentials.json and reload OpenResty
CREDS_FILE="${CORE_DIR}/admin_credentials.json"
if [ ! -f "${CREDS_FILE}" ]; then
echo '{"user":"admin","pass_hash":"4cb9c8a8048fd02294477fcb1a41191a"}' > "${CREDS_FILE}"
chmod 644 "${CREDS_FILE}"
echo "Created ${CREDS_FILE} with default credentials (admin/changeme)"
echo "IMPORTANT: Change the password — see instructions above."
fi
# ── Allow auto-reload from admin UI ─────────────────────────────────────────
# The worker process runs as non-root and cannot signal the master directly.
# This sudoers entry lets the worker run `sudo openresty -s reload` without
# a password prompt — the only command allowed is the specific reload.
SUDOERS_FILE="/etc/sudoers.d/psp-router-reload"
mkdir -p /etc/sudoers.d
echo "ALL ALL=(root) NOPASSWD: ${OPENRESTY_BIN} -s reload" > "${SUDOERS_FILE}"
chmod 440 "${SUDOERS_FILE}"
# ── Deploy nginx proxy snippet ──────────────────────────────────────────────
echo "Deploying nginx snippet to ${SNIPPET_DIR} ..."
mkdir -p "${SNIPPET_DIR}"
cp "${DIST_DIR}/snippets/psp-router-proxy.conf" "${SNIPPET_DIR}/psp-router.conf"
# ── Test and start/reload OpenResty ─────────────────────────────────────────
# Pass the prefix explicitly. Without -p, OpenResty always reads its compiled-in
# default prefix, so a custom DEPLOY_TARGET would have files copied into it that
# are then never tested, loaded or reloaded — the deploy would look successful
# while running entirely different config.
# OpenResty will not start without its logs/ dir, and a custom prefix has none.
mkdir -p "${DEPLOY_TARGET}/logs"
if [ "${DEPLOY_TARGET}" != "/usr/local/openresty/nginx" ]; then
LPP=$(grep -o 'lua_package_path "[^"]*"' "${DEPLOY_TARGET}/conf/nginx.conf" 2>/dev/null || true)
case "${LPP}" in
*"${DEPLOY_TARGET}"*) ;;
*) echo "WARNING: nginx.conf has ${LPP:-no lua_package_path}," >&2
echo " which does not point at ${DEPLOY_TARGET}/lua." >&2
echo " Lua modules will load from the default prefix." >&2 ;;
esac
fi
echo "Testing OpenResty config ..."
${OPENRESTY_BIN} -p "${DEPLOY_TARGET}" -t
# Detect a running master by its PID file, not `pgrep -f openresty`: that
# pattern matches any command line containing the word — an editor, a tail on
# the log, even this script's own path — and a false positive sends us down the
# reload branch, which fails and leaves OpenResty down.
PID_FILE="${DEPLOY_TARGET}/logs/nginx.pid"
RUNNING=0
if [ -f "${PID_FILE}" ] && kill -0 "$(cat "${PID_FILE}" 2>/dev/null)" 2>/dev/null; then
RUNNING=1
fi
if [ "${RUNNING}" -eq 1 ]; then
echo "Reloading OpenResty ..."
if ${OPENRESTY_BIN} -p "${DEPLOY_TARGET}" -s reload; then
echo "Deploy complete — OpenResty reloaded."
else
echo "ERROR: reload FAILED — the running master is still serving the OLD config." >&2
echo " Check: ${OPENRESTY_BIN} -p ${DEPLOY_TARGET} -t" >&2
exit 1
fi
else
echo "Starting OpenResty ..."
if ${OPENRESTY_BIN} -p "${DEPLOY_TARGET}"; then
echo "Deploy complete — OpenResty started."
else
echo "ERROR: OpenResty failed to start." >&2
exit 1
fi
fi
# ── Reminder ────────────────────────────────────────────────────────────────
echo ""
echo "NOTE: To enable routing, ensure your App nginx config includes:"
echo " include /etc/nginx/snippets/psp-router.conf;"
echo ""
echo "Then reload nginx: nginx -s reload"