vela 0.15.2 → 0.15.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +34 -5
- package/dist/bin.js +3427 -3176
- package/dist/bin.js.map +4 -4
- package/package.json +2 -2
- package/templates/minimal/_env.example +7 -0
- package/templates/server/apply.sh +37 -3
- package/templates/server/lib.sh +20 -3
- package/templates/server/systemd/vela-pb@.service +8 -0
- package/templates/server/systemd/vela-web@.service +8 -0
- package/templates/static/_env.example +2 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vela",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A CLI for creating and updating SvelteKit projects",
|
|
6
6
|
"license": "MIT",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"package-manager-detector": "^1.8.0",
|
|
51
51
|
"picocolors": "^1.1.1",
|
|
52
52
|
"pocketbase": "^0.28.0",
|
|
53
|
-
"pocketbase-server": "^0.40.5-beta.
|
|
53
|
+
"pocketbase-server": "^0.40.5-beta.5",
|
|
54
54
|
"stripe": "^22.6.2",
|
|
55
55
|
"sv": "~1.0.1",
|
|
56
56
|
"svelte": "^5.56.10",
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# What this app reads from its environment. Copy to .env for development; on a
|
|
2
|
+
# server, `vela env set KEY -t <target>`. Values here are examples, not defaults.
|
|
3
|
+
|
|
4
|
+
# PocketBase superuser the app authenticates as. `vela create` writes these to
|
|
5
|
+
# .env; a deploy creates its own on the server the first time.
|
|
6
|
+
POCKETBASE_SUPERUSER_EMAIL=admin@example.com
|
|
7
|
+
POCKETBASE_SUPERUSER_PASSWORD=change-me
|
|
@@ -36,7 +36,9 @@ require_release_id "$RELEASE"
|
|
|
36
36
|
|
|
37
37
|
APP_NAME=$INSTANCE
|
|
38
38
|
APP_ID=$INSTANCE
|
|
39
|
+
SITE_NAME=""
|
|
39
40
|
ENV_TAG=prod
|
|
41
|
+
PREVIEW=0
|
|
40
42
|
DOMAIN=""
|
|
41
43
|
MANAGED=""
|
|
42
44
|
HEALTH_PATH=/
|
|
@@ -54,6 +56,8 @@ while [ $# -gt 0 ]; do
|
|
|
54
56
|
--name) APP_NAME=$2; shift 2 ;;
|
|
55
57
|
--app-id) APP_ID=$2; shift 2 ;;
|
|
56
58
|
--env) ENV_TAG=$2; shift 2 ;;
|
|
59
|
+
--site-name) SITE_NAME=$2; shift 2 ;;
|
|
60
|
+
--preview) PREVIEW=$2; shift 2 ;;
|
|
57
61
|
--domain) DOMAIN=$2; shift 2 ;;
|
|
58
62
|
--managed) MANAGED=$2; shift 2 ;;
|
|
59
63
|
--health-path) HEALTH_PATH=$2; shift 2 ;;
|
|
@@ -183,10 +187,22 @@ else
|
|
|
183
187
|
PRIMARY_URL="http://127.0.0.1:$WEB_PORT"
|
|
184
188
|
fi
|
|
185
189
|
|
|
186
|
-
#
|
|
187
|
-
#
|
|
190
|
+
# The instance's own env layer is managed only by `vela env`. Nothing here
|
|
191
|
+
# reads or rewrites it; the file is created so a first `vela env list` has
|
|
192
|
+
# something to read.
|
|
188
193
|
[ -f "$ETC/env" ] || { : > "$ETC/env"; chmod 0600 "$ETC/env"; chown root:root "$ETC/env"; }
|
|
189
194
|
|
|
195
|
+
# The shared layers - app-wide, and one for every preview - live under
|
|
196
|
+
# /etc/vela/scopes, and the units are templates on the instance name alone, so
|
|
197
|
+
# they reach those layers through fixed-name symlinks written here. A link to a
|
|
198
|
+
# layer nobody has written yet dangles, which systemd skips like a missing file.
|
|
199
|
+
link_scope "$APP_ID" all "$ETC"
|
|
200
|
+
if [ "$PREVIEW" = "1" ]; then
|
|
201
|
+
link_scope "$APP_ID" preview "$ETC"
|
|
202
|
+
else
|
|
203
|
+
rm -f "$ETC/scope.preview.env" "$ETC/scope.preview.public.env"
|
|
204
|
+
fi
|
|
205
|
+
|
|
190
206
|
runtime_tmp=$(mktemp "$ETC/.runtime.XXXXXX")
|
|
191
207
|
{
|
|
192
208
|
printf '# Generated by vela on each deploy. Edit /etc/vela/apps/%s/env instead.\n' "$INSTANCE"
|
|
@@ -194,6 +210,12 @@ runtime_tmp=$(mktemp "$ETC/.runtime.XXXXXX")
|
|
|
194
210
|
printf 'HOST=127.0.0.1\n'
|
|
195
211
|
printf 'PORT=%s\n' "$WEB_PORT"
|
|
196
212
|
runtime_origin_lines "$DOMAIN" "$PRIMARY_URL"
|
|
213
|
+
# Caddy is the only thing that reaches the app, so without these
|
|
214
|
+
# `getClientAddress()` is always 127.0.0.1. Caddy replaces any
|
|
215
|
+
# X-Forwarded-For a client sends with the address it saw (or, on a managed
|
|
216
|
+
# route, the one the Worker reports), so the last entry is the visitor.
|
|
217
|
+
printf 'ADDRESS_HEADER=x-forwarded-for\n'
|
|
218
|
+
printf 'XFF_DEPTH=1\n'
|
|
197
219
|
# Only an instance with a PocketBase gets pointed at one: a URL to a port
|
|
198
220
|
# nothing listens on is not a setting, it is a trap. Kept for one more
|
|
199
221
|
# deploy when the backend is being removed, so that a failed deploy can put
|
|
@@ -203,6 +225,10 @@ runtime_tmp=$(mktemp "$ETC/.runtime.XXXXXX")
|
|
|
203
225
|
printf 'POCKETBASE_URL=http://127.0.0.1:%s\n' "$PB_PORT"
|
|
204
226
|
fi
|
|
205
227
|
printf 'VELA_DATA_DIR=%s\n' "$APP_DATA_DIR"
|
|
228
|
+
# PocketBase names the app in its emails after APP_NAME, and links them to
|
|
229
|
+
# ORIGIN (above) unless APP_URL says otherwise. The name is the one
|
|
230
|
+
# src/lib/site.ts declares, so it is set from code on every deploy.
|
|
231
|
+
[ -z "$SITE_NAME" ] || printf 'APP_NAME=%s\n' "$SITE_NAME"
|
|
206
232
|
printf 'VELA_APP_ID=%s\n' "$APP_ID"
|
|
207
233
|
printf 'VELA_APP_NAME=%s\n' "$APP_NAME"
|
|
208
234
|
printf 'VELA_ENV=%s\n' "$ENV_TAG"
|
|
@@ -401,6 +427,13 @@ if [ -n "$LINK_NAME" ]; then
|
|
|
401
427
|
|| rm -f "$link_tmp" || true
|
|
402
428
|
fi
|
|
403
429
|
|
|
430
|
+
# The units come from the same upload as this script, so a server provisioned
|
|
431
|
+
# by an older CLI gets the current ones on its next deploy rather than running
|
|
432
|
+
# the old env file list against new layers nothing reads.
|
|
433
|
+
for unit in vela-web@.service vela-pb@.service; do
|
|
434
|
+
cmp -s "$SCRIPT_DIR/systemd/$unit" "/etc/systemd/system/$unit" \
|
|
435
|
+
|| install -m 0644 "$SCRIPT_DIR/systemd/$unit" "/etc/systemd/system/$unit"
|
|
436
|
+
done
|
|
404
437
|
systemctl daemon-reload
|
|
405
438
|
|
|
406
439
|
if [ "$BACKEND" = "1" ]; then
|
|
@@ -456,7 +489,8 @@ state_merge "$INSTANCE" "$(jq -c -n \
|
|
|
456
489
|
--arg health "$HEALTH_PATH" --arg pb "$PB_VERSION" \
|
|
457
490
|
--arg sha "$GIT_SHA" --arg at "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
|
|
458
491
|
--argjson web "$WEB_PORT" --argjson pbport "$PB_PORT" --argjson backend "$BACKEND" \
|
|
459
|
-
|
|
492
|
+
--argjson preview "$PREVIEW" \
|
|
493
|
+
'{appId: $app, name: $name, env: $env, instance: $instance, preview: ($preview == 1),
|
|
460
494
|
activeRelease: $release, previousRelease: $previous, domain: $domain,
|
|
461
495
|
managed: $managed, url: $url,
|
|
462
496
|
healthCheckPath: $health, pocketbaseVersion: $pb, gitSha: $sha,
|
package/templates/server/lib.sh
CHANGED
|
@@ -10,6 +10,19 @@ VELA_PORT_RANGE=${VELA_PORT_RANGE:-900}
|
|
|
10
10
|
|
|
11
11
|
app_dir() { printf '%s/apps/%s' "$VELA_ROOT" "$1"; }
|
|
12
12
|
etc_dir() { printf '%s/apps/%s' "$VELA_ETC" "$1"; }
|
|
13
|
+
# scope_dir <app-id> <all|preview> - an env layer shared by several instances.
|
|
14
|
+
# Its own tree because the production instance is named after the app id, so
|
|
15
|
+
# /etc/vela/apps/<app-id> is production's directory, not the app's.
|
|
16
|
+
scope_dir() { printf '%s/scopes/%s/%s' "$VELA_ETC" "$1" "$2"; }
|
|
17
|
+
# link_scope <app-id> <all|preview> <etc-dir> - point an instance's fixed-name
|
|
18
|
+
# scope.<layer>.env and scope.<layer>.public.env at that layer's files.
|
|
19
|
+
# `-n` replaces an existing link rather than following it; the targets are files,
|
|
20
|
+
# so there is never a directory for a plain `ln -sf` to descend into.
|
|
21
|
+
link_scope() {
|
|
22
|
+
local dir; dir=$(scope_dir "$1" "$2")
|
|
23
|
+
ln -sfn "$dir/env" "$3/scope.$2.env"
|
|
24
|
+
ln -sfn "$dir/env.public" "$3/scope.$2.public.env"
|
|
25
|
+
}
|
|
13
26
|
state_file() { printf '%s/apps/%s/state.json' "$VELA_ROOT" "$1"; }
|
|
14
27
|
|
|
15
28
|
log() { printf ' %s\n' "$*" >&2; }
|
|
@@ -227,13 +240,17 @@ unit_active() { systemctl is-active --quiet "$1"; }
|
|
|
227
240
|
# A fourth argument is the public host to ask as, the way Caddy would. An app
|
|
228
241
|
# serving several hosts has no pinned origin and tells its sites apart by
|
|
229
242
|
# `Host`; asked as 127.0.0.1 it may rightly answer that it serves no such site.
|
|
243
|
+
#
|
|
244
|
+
# X-Forwarded-For always, as Caddy would send it: the app reads the client
|
|
245
|
+
# address from it (ADDRESS_HEADER), and adapter-node throws from
|
|
246
|
+
# `getClientAddress()` on a request without one.
|
|
230
247
|
wait_for_http() {
|
|
231
248
|
local url=$1 attempts=${2:-60} delay=${3:-0.5} host=${4:-} code
|
|
232
249
|
local i=0
|
|
233
|
-
local -a as=()
|
|
234
|
-
[ -z "$host" ] || as
|
|
250
|
+
local -a as=(-H 'X-Forwarded-For: 127.0.0.1')
|
|
251
|
+
[ -z "$host" ] || as+=(-H "Host: $host" -H 'X-Forwarded-Proto: https')
|
|
235
252
|
while [ "$i" -lt "$attempts" ]; do
|
|
236
|
-
code=$(curl -sS -o /dev/null -w '%{http_code}' --max-time 5
|
|
253
|
+
code=$(curl -sS -o /dev/null -w '%{http_code}' --max-time 5 "${as[@]}" "$url" 2>/dev/null || echo 000)
|
|
237
254
|
case "$code" in
|
|
238
255
|
2*|3*|401|403) return 0 ;;
|
|
239
256
|
esac
|
|
@@ -10,7 +10,15 @@ User=vela
|
|
|
10
10
|
Group=vela
|
|
11
11
|
WorkingDirectory=/var/lib/vela/apps/%i
|
|
12
12
|
|
|
13
|
+
# Three layers, each secret and public, then what vela derives. Later wins.
|
|
14
|
+
# The scope.* names are symlinks apply.sh writes into the app-wide and preview
|
|
15
|
+
# layers under /etc/vela/scopes; a layer that does not exist is skipped.
|
|
16
|
+
EnvironmentFile=-/etc/vela/apps/%i/scope.all.env
|
|
17
|
+
EnvironmentFile=-/etc/vela/apps/%i/scope.all.public.env
|
|
18
|
+
EnvironmentFile=-/etc/vela/apps/%i/scope.preview.env
|
|
19
|
+
EnvironmentFile=-/etc/vela/apps/%i/scope.preview.public.env
|
|
13
20
|
EnvironmentFile=-/etc/vela/apps/%i/env
|
|
21
|
+
EnvironmentFile=-/etc/vela/apps/%i/env.public
|
|
14
22
|
EnvironmentFile=/etc/vela/apps/%i/runtime.env
|
|
15
23
|
|
|
16
24
|
ExecStart=/var/lib/vela/apps/%i/bin/pocketbase \
|
|
@@ -12,7 +12,15 @@ WorkingDirectory=/var/lib/vela/apps/%i/current
|
|
|
12
12
|
|
|
13
13
|
# Production secrets first, vela-generated runtime settings second, so PORT and
|
|
14
14
|
# POCKETBASE_URL always match what the server actually assigned.
|
|
15
|
+
# Three layers, each secret and public, then what vela derives. Later wins.
|
|
16
|
+
# The scope.* names are symlinks apply.sh writes into the app-wide and preview
|
|
17
|
+
# layers under /etc/vela/scopes; a layer that does not exist is skipped.
|
|
18
|
+
EnvironmentFile=-/etc/vela/apps/%i/scope.all.env
|
|
19
|
+
EnvironmentFile=-/etc/vela/apps/%i/scope.all.public.env
|
|
20
|
+
EnvironmentFile=-/etc/vela/apps/%i/scope.preview.env
|
|
21
|
+
EnvironmentFile=-/etc/vela/apps/%i/scope.preview.public.env
|
|
15
22
|
EnvironmentFile=-/etc/vela/apps/%i/env
|
|
23
|
+
EnvironmentFile=-/etc/vela/apps/%i/env.public
|
|
16
24
|
EnvironmentFile=/etc/vela/apps/%i/runtime.env
|
|
17
25
|
|
|
18
26
|
ExecStart=/usr/bin/node /var/lib/vela/apps/%i/current/build/index.js
|