@webjsdev/cli 0.10.1 → 0.10.3

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/bin/webjs.js CHANGED
@@ -148,17 +148,31 @@ async function main() {
148
148
  const { readdir } = await import('node:fs/promises');
149
149
  const testFiles = [];
150
150
 
151
- for (const dir of ['test/server', 'test/unit', 'test']) {
152
- const fullDir = join(cwd, dir);
153
- if (!existsSync(fullDir)) continue;
154
- const files = await readdir(fullDir);
155
- for (const f of files) {
156
- if (/\.test\.(js|ts|mjs|mts)$/.test(f)) {
157
- const full = join(fullDir, f);
151
+ // Walk test/ recursively so the documented feature-folder layout
152
+ // (test/<feature>/<name>.test.ts) is discovered, not just files
153
+ // sitting directly in test/. Two kinds are NOT run here:
154
+ // - **/browser/** → real-browser tests, owned by WTR below.
155
+ // - **/e2e/** → full-app boot, opt-in via WEBJS_E2E=1 (the
156
+ // documented "WEBJS_E2E=1 webjs test adds the
157
+ // e2e tests" semantics).
158
+ const runE2E = !!process.env.WEBJS_E2E;
159
+ const walk = async (dir, segments) => {
160
+ let entries;
161
+ try { entries = await readdir(dir, { withFileTypes: true }); }
162
+ catch { return; }
163
+ for (const ent of entries) {
164
+ if (ent.name === 'node_modules') continue;
165
+ const full = join(dir, ent.name);
166
+ if (ent.isDirectory()) {
167
+ if (ent.name === 'browser') continue;
168
+ if (ent.name === 'e2e' && !runE2E) continue;
169
+ await walk(full, [...segments, ent.name]);
170
+ } else if (/\.test\.(js|ts|mjs|mts)$/.test(ent.name)) {
158
171
  if (!testFiles.includes(full)) testFiles.push(full);
159
172
  }
160
173
  }
161
- }
174
+ };
175
+ await walk(join(cwd, 'test'), []);
162
176
 
163
177
  if (testFiles.length > 0) {
164
178
  console.log(`webjs test: running ${testFiles.length} server test file(s)…\n`);
package/lib/create.js CHANGED
@@ -392,7 +392,16 @@ export async function scaffoldApp(name, cwd, opts = {}) {
392
392
  '.cursorrules',
393
393
  '.github/copilot-instructions.md',
394
394
  '.github/pull_request_template.md',
395
+ // CI is the test gate (the pre-commit hook only blocks main). Runs
396
+ // webjs check + the unit / browser / e2e layers on every PR and push
397
+ // to main, mirroring the webjs framework's own CI.
398
+ '.github/workflows/ci.yml',
395
399
  '.editorconfig',
400
+ // Production / deploy scaffolding. `docker compose up --build` runs
401
+ // the app locally with the same Dockerfile production builds from.
402
+ 'Dockerfile',
403
+ 'compose.yaml',
404
+ '.dockerignore',
396
405
  ];
397
406
  for (const f of templateFiles) {
398
407
  const src = join(TEMPLATES, f);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webjsdev/cli",
3
- "version": "0.10.1",
3
+ "version": "0.10.3",
4
4
  "type": "module",
5
5
  "description": "webjs CLI - dev, start, create, db",
6
6
  "bin": {
@@ -0,0 +1,43 @@
1
+ .git
2
+ .github
3
+ node_modules
4
+ **/node_modules
5
+
6
+ # `.webjs/` is ignored EXCEPT for `.webjs/vendor/`, which holds the committed
7
+ # importmap manifest (and optionally downloaded bundle bytes) the server needs
8
+ # at boot without reaching api.jspm.io. DO NOT collapse to `**/.webjs`: parent
9
+ # exclusion blocks child negations and the vendor files would never ship.
10
+ .webjs/*
11
+ !.webjs/vendor/
12
+ !.webjs/vendor/**
13
+
14
+ dist
15
+ build
16
+ out
17
+ .cache
18
+
19
+ # Local env files. The container gets its env from compose / uncloud, not a
20
+ # committed file. Keep the example for reference.
21
+ .env
22
+ !.env.example
23
+
24
+ # Prisma local SQLite. Schema + migrations ship; the runtime volume owns the db.
25
+ dev.db
26
+ dev.db-journal
27
+ prisma/dev.db
28
+ prisma/dev.db-journal
29
+
30
+ # logs
31
+ *.log
32
+ npm-debug.log*
33
+
34
+ # editors / OS
35
+ .vscode
36
+ .idea
37
+ .DS_Store
38
+ Thumbs.db
39
+
40
+ # tests aren't needed in the production image
41
+ coverage/
42
+ test/
43
+ **/test/
@@ -0,0 +1,105 @@
1
+ name: CI
2
+
3
+ # The test gate for {{APP_NAME}}. Runs the full test pyramid on every PR
4
+ # into main and on every push to main. This is the gate the local
5
+ # pre-commit hook deliberately leaves out, so `git commit` stays fast and
6
+ # the test gate runs in one authoritative place a local --no-verify cannot
7
+ # skip. Same posture as the webjs framework's own CI.
8
+ #
9
+ # The four layers run as separate jobs so a failure names the layer that
10
+ # broke. Mark all four as required status checks in the branch-protection
11
+ # rule for main so a PR can only merge when every layer is green. Free on
12
+ # public repos (ubuntu-latest has unlimited Actions minutes).
13
+
14
+ on:
15
+ pull_request:
16
+ branches: [main]
17
+ push:
18
+ branches: [main]
19
+
20
+ # A newer push to the same branch cancels the older in-flight run.
21
+ concurrency:
22
+ group: ci-${{ github.ref }}
23
+ cancel-in-progress: true
24
+
25
+ jobs:
26
+ conventions:
27
+ name: Conventions (webjs check)
28
+ runs-on: ubuntu-latest
29
+ steps:
30
+ - uses: actions/checkout@v6
31
+ - uses: actions/setup-node@v6
32
+ with:
33
+ node-version: '24'
34
+ cache: npm
35
+ - run: npm ci
36
+ - run: npm run check
37
+
38
+ unit:
39
+ name: Unit + integration (node --test)
40
+ runs-on: ubuntu-latest
41
+ steps:
42
+ - uses: actions/checkout@v6
43
+ - uses: actions/setup-node@v6
44
+ with:
45
+ node-version: '24'
46
+ cache: npm
47
+ - run: npm ci
48
+ - run: npx prisma generate
49
+ - name: Apply migrations to the test database
50
+ run: npx prisma migrate deploy
51
+ env:
52
+ DATABASE_URL: file:./ci.db
53
+ # --server keeps this job to node:test (the browser layer is its own
54
+ # job below). Without WEBJS_E2E the e2e folders are skipped too.
55
+ - run: npm run test:server
56
+ env:
57
+ DATABASE_URL: file:./ci.db
58
+
59
+ browser:
60
+ name: Browser (web-test-runner / Playwright)
61
+ runs-on: ubuntu-latest
62
+ steps:
63
+ - uses: actions/checkout@v6
64
+ - uses: actions/setup-node@v6
65
+ with:
66
+ node-version: '24'
67
+ cache: npm
68
+ - run: npm ci
69
+ - run: npx prisma generate
70
+ - name: Install Playwright Chromium
71
+ run: npx playwright install --with-deps chromium
72
+ - run: npm run test:browser
73
+
74
+ e2e:
75
+ name: E2E (full app boot)
76
+ runs-on: ubuntu-latest
77
+ steps:
78
+ - uses: actions/checkout@v6
79
+ - uses: actions/setup-node@v6
80
+ with:
81
+ node-version: '24'
82
+ cache: npm
83
+ - run: npm ci
84
+ - run: npx prisma generate
85
+ - name: Apply migrations to the test database
86
+ run: npx prisma migrate deploy
87
+ env:
88
+ DATABASE_URL: file:./ci.db
89
+ # The scaffold's e2e test (test/hello/e2e/) drives a real browser
90
+ # via puppeteer-core, which is not a default dependency (the test
91
+ # skips when it is absent). Install it and Chromium so the e2e
92
+ # layer actually runs in CI rather than skipping silently.
93
+ - name: Install puppeteer-core + Chromium
94
+ run: |
95
+ npm install --no-save puppeteer-core
96
+ npx playwright install --with-deps chromium
97
+ - name: Resolve the Chromium binary path
98
+ run: echo "CHROMIUM_PATH=$(node -e "console.log(require('playwright-core').chromium.executablePath())")" >> "$GITHUB_ENV"
99
+ # --server with WEBJS_E2E=1 runs node:test including the e2e folders
100
+ # (the runner gates them on that env var) and skips the browser layer.
101
+ - name: Run e2e
102
+ env:
103
+ WEBJS_E2E: '1'
104
+ DATABASE_URL: file:./ci.db
105
+ run: npm run test:server
@@ -1,11 +1,16 @@
1
1
  #!/bin/bash
2
2
  #
3
- # pre-commit hook - blocks commits on main/master.
3
+ # pre-commit hook. Blocks commits on main/master.
4
4
  #
5
5
  # No AI agent, no editor, no human can commit to main directly.
6
6
  # Create a feature branch first. This is git-level enforcement.
7
7
  #
8
8
  # To bypass in emergencies: git commit --no-verify
9
+ #
10
+ # Tests and convention checks run in CI (.github/workflows/ci.yml), not
11
+ # here, so a commit stays fast and the test gate cannot be skipped by a
12
+ # local --no-verify. The CI workflow runs `webjs check` + `webjs test`
13
+ # on every push and pull request.
9
14
 
10
15
  BRANCH=$(git symbolic-ref --short HEAD 2>/dev/null)
11
16
 
@@ -21,53 +26,4 @@ if [ "$BRANCH" = "main" ] || [ "$BRANCH" = "master" ]; then
21
26
  exit 1
22
27
  fi
23
28
 
24
- # Require a test to accompany app-code changes. Tool-agnostic floor: a
25
- # commit that stages app code (app/, modules/, components/, lib/) with no
26
- # test (test/** or *.test.* / *.spec.*) is blocked. The full suite below
27
- # proves tests PASS; this proves a test was WRITTEN. Bypass for a genuine
28
- # non-code commit with WEBJS_NO_TEST_GATE=1, or --no-verify in emergencies.
29
- if [ "${WEBJS_NO_TEST_GATE:-}" != "1" ]; then
30
- STAGED=$(git diff --cached --name-only 2>/dev/null)
31
- APP_CODE=$(printf '%s\n' "$STAGED" | grep -E '^(app|modules|components|lib)/.*\.([mc]?[jt]sx?)$' || true)
32
- if [ -n "$APP_CODE" ]; then
33
- TESTS=$(printf '%s\n' "$STAGED" | grep -E '(^|/)test/|\.test\.[mc]?[jt]sx?$|\.spec\.[mc]?[jt]sx?$' || true)
34
- if [ -z "$TESTS" ]; then
35
- echo ""
36
- echo "ERROR: app code changed but no test is staged."
37
- echo "Every change ships with a test. Add or update the test that"
38
- echo "proves the new behaviour (a browser/e2e test for interactive"
39
- echo "or component code), then git add it."
40
- echo ""
41
- echo "Genuine non-code commit? WEBJS_NO_TEST_GATE=1 git commit ..."
42
- echo "Emergency bypass: git commit --no-verify"
43
- echo ""
44
- exit 1
45
- fi
46
- fi
47
- fi
48
-
49
- # webjs test + webjs check on every commit. Tool-agnostic enforcement:
50
- # fires regardless of which agent (Claude, Cursor, Antigravity, Copilot,
51
- # human) is making the commit. Skipped if the CLI is not yet installed
52
- # (fresh clone before npm install).
53
- if command -v webjs >/dev/null 2>&1 || [ -x "node_modules/.bin/webjs" ]; then
54
- echo "Running webjs test..."
55
- if ! npx --no-install webjs test; then
56
- echo ""
57
- echo "ERROR: webjs test failed. Fix tests before committing."
58
- echo "To bypass (emergencies only): git commit --no-verify"
59
- echo ""
60
- exit 1
61
- fi
62
-
63
- echo "Running webjs check..."
64
- if ! npx --no-install webjs check; then
65
- echo ""
66
- echo "ERROR: webjs check failed. Fix convention violations before committing."
67
- echo "To bypass (emergencies only): git commit --no-verify"
68
- echo ""
69
- exit 1
70
- fi
71
- fi
72
-
73
29
  exit 0
@@ -301,6 +301,16 @@ In Docker / Railway, prefer `npm start` (or `node node_modules/.bin/npm
301
301
  start`) as the CMD over `node ... webjs.js start ...`. The npm form
302
302
  fires `prestart`; the direct binary form skips it.
303
303
 
304
+ **Containerized deploy ships with the scaffold.** `Dockerfile`,
305
+ `compose.yaml`, and `.dockerignore` are scaffolded at the app root. The
306
+ Dockerfile pins `node:24-alpine` (the same Node major CI uses), installs
307
+ deps, runs `prisma generate`, and starts via `npm start` so `prestart`
308
+ applies migrations. Run it locally with `docker compose up --build` (the
309
+ app comes up on http://localhost:8080 against a SQLite file on a named
310
+ volume). For production, point `DATABASE_URL` at managed Postgres and set
311
+ `AUTH_SECRET`. The `.dockerignore` keeps the `.webjs/vendor/` importmap in
312
+ the image while excluding `node_modules`, tests, and local state.
313
+
304
314
  **Health and readiness probes.** Every webjs server answers two endpoints:
305
315
  `/__webjs/health` (liveness, 200 once the process is listening) and
306
316
  `/__webjs/ready` (readiness, 503 until the instance is fully warm, then 200).
@@ -308,12 +318,17 @@ Fully warm means the deterministic analysis AND the first vendor attempt have
308
318
  both completed, so the importmap and its build id are settled. Point your
309
319
  platform's readiness check at `/__webjs/ready` so it holds traffic off a
310
320
  not-yet-warmed instance instead of routing the first user request into the cold
311
- analysis or the brief window where the importmap is still resolving. On
312
- Railway, set `"healthcheckPath": "/__webjs/ready"` under `deploy` in
313
- `railway.json`. For dependency-aware
314
- readiness (gate on a live DB ping), add an optional `readiness.{js,ts}` at the
315
- app root that default-exports an async check; `/__webjs/ready` runs it once warm
316
- and reports 503 if it returns `false` or throws.
321
+ analysis or the brief window where the importmap is still resolving. The
322
+ scaffolded `Dockerfile` and `compose.yaml` already wire this up with a
323
+ `HEALTHCHECK` that probes `/__webjs/ready`, so any Docker-based deploy gets the
324
+ gate with no extra config. On a platform that reads its own config instead,
325
+ point its equivalent knob at the same path: Railway `"healthcheckPath":
326
+ "/__webjs/ready"`, Render `healthCheckPath: /__webjs/ready`, Fly a
327
+ `[[http_service.checks]]` on `/__webjs/ready`, or a Kubernetes `readinessProbe`
328
+ with `httpGet.path: /__webjs/ready`. For dependency-aware readiness (gate on a
329
+ live DB ping), add an optional `readiness.{js,ts}` at the app root that
330
+ default-exports an async check; `/__webjs/ready` runs it once warm and reports
331
+ 503 if it returns `false` or throws.
317
332
 
318
333
  Scripts:
319
334
 
@@ -889,9 +904,11 @@ composition, so a nested shell ends up dropped by the HTML parser.
889
904
  action called from the client needs a browser test
890
905
  (`webjs test --browser`) asserting the behaviour in a real browser. A
891
906
  commit that stages app code (`app/`, `modules/`, `components/`, `lib/`)
892
- with no test is blocked by `.claude/hooks/require-tests-with-src.sh`
893
- and the `.hooks/pre-commit` floor (bypass a genuine non-code commit
894
- with `WEBJS_NO_TEST_GATE=1`).
907
+ with no test is blocked for Claude Code by
908
+ `.claude/hooks/require-tests-with-src.sh`. The test suite itself runs in
909
+ CI (`.github/workflows/ci.yml`), not in the pre-commit hook, so `git
910
+ commit` stays fast and the gate cannot be skipped with a local
911
+ `--no-verify`.
895
912
  3. Commit and push **per logical unit**, not at the end. A logical unit is one
896
913
  feature, one fix, one rename, one doc rewrite. If you have 5+ unstaged files
897
914
  spanning different concerns, commit the current group before continuing.
@@ -907,9 +924,10 @@ composition, so a nested shell ends up dropped by the HTML parser.
907
924
  | Antigravity (Google) | text rule only (post-write hooks not yet exposed) | `.agents/rules/workflow.md` |
908
925
  | GitHub Copilot | text rule only (no hooks API) | `.github/copilot-instructions.md` |
909
926
 
910
- Tool-agnostic fallback: `.hooks/pre-commit` runs `webjs test` + `webjs check`
911
- on every commit, regardless of which agent (or human) made it. No AI
912
- attribution trailers in commit messages.
927
+ The `.hooks/pre-commit` hook blocks commits to main and nothing else;
928
+ `webjs test` + `webjs check` run in CI (`.github/workflows/ci.yml`) on
929
+ every PR and push to main, regardless of which agent (or human) made
930
+ the commit. No AI attribution trailers in commit messages.
913
931
  4. Run the **pre-merge self-review loop** before signaling the PR is
914
932
  ready. After committing the work, trigger a fresh-context review
915
933
  pass (a new chat / composer tab / subagent / Cascade thread
@@ -451,14 +451,14 @@ test/
451
451
  - `webjs test --browser` (or `npx wtr`) runs the browser tests.
452
452
  - `WEBJS_E2E=1 webjs test` adds the e2e tests.
453
453
 
454
- **Every change ships with a test, enforced at commit time.** A commit
455
- that stages app code (`app/`, `modules/`, `components/`, `lib/`) without
456
- staging a test is blocked by `.claude/hooks/require-tests-with-src.sh`
457
- (Claude Code) and the universal `.hooks/pre-commit` (any agent or human).
454
+ **Every change ships with a test.** For Claude Code, a commit that
455
+ stages app code (`app/`, `modules/`, `components/`, `lib/`) without
456
+ staging a test is blocked by `.claude/hooks/require-tests-with-src.sh`.
458
457
  A unit test alone is not enough for interactive or component code: add
459
- the browser test that asserts the rendered/hydrated behaviour. Bypass a
460
- genuine non-code commit with `WEBJS_NO_TEST_GATE=1`, or `--no-verify` in
461
- an emergency.
458
+ the browser test that asserts the rendered/hydrated behaviour. The test
459
+ suite itself runs in CI (`.github/workflows/ci.yml`) on every PR and
460
+ push to main, not in the local pre-commit hook, so `git commit` stays
461
+ fast and the gate cannot be skipped with a local `--no-verify`.
462
462
 
463
463
  ### Choosing a feature folder
464
464
 
@@ -1003,10 +1003,19 @@ This project enforces a git workflow via agent-specific config files
1003
1003
  Other agents enforce this via `.cursorrules`, `.agents/rules/workflow.md`,
1004
1004
  `.github/copilot-instructions.md`.
1005
1005
 
1006
- **Pre-commit checks:**
1007
- - `webjs test` must pass
1008
- - `webjs check` must pass
1009
- - No unrelated files in the commit
1006
+ **Pre-commit hook (`.hooks/pre-commit`):**
1007
+ - Blocks commits to `main` / `master`. Nothing else runs locally, so
1008
+ `git commit` stays fast. Keeping commits to one logical unit (no
1009
+ unrelated files) is your discipline plus the `nudge-uncommitted`
1010
+ hooks, not something this hook enforces.
1011
+
1012
+ **CI gate (`.github/workflows/ci.yml`), on every PR and push to main:**
1013
+ - `webjs check` (conventions) must pass
1014
+ - `webjs test` (unit + integration), the browser layer, and the e2e
1015
+ layer must pass
1016
+ - Mark these as required status checks in the branch-protection rule for
1017
+ main so a PR can only merge when the gate is green. The gate lives in
1018
+ CI, where a local `--no-verify` cannot skip it.
1010
1019
 
1011
1020
  ---
1012
1021
 
@@ -0,0 +1,49 @@
1
+ # Production image for the {{APP_NAME}} webjs app.
2
+ #
3
+ # Works with a plain `docker build` / `docker compose up`, and is the same
4
+ # artifact the webdeploy hosting tool (ubicloud + uncloud) builds and ships.
5
+ #
6
+ # webjs serves .ts directly via Node's built-in type-stripping, so there is
7
+ # NO JavaScript build step. **Node 24+ is REQUIRED**: on older Node the runtime
8
+ # falls back to esbuild, whose class-declaration transform breaks webjs's SSR
9
+ # walker for multi-class component files. Do not lower this base image
10
+ # below 24 (the same version the CI workflow and the framework pin).
11
+ FROM node:24-alpine
12
+
13
+ # openssl + ca-certificates are required by Prisma's query engine at runtime.
14
+ RUN apk add --no-cache openssl ca-certificates
15
+
16
+ WORKDIR /app
17
+
18
+ # Install deps first so this layer is cached unless the manifests change.
19
+ # package-lock.json is optional (it's absent when the app was scaffolded with
20
+ # --no-install); the glob keeps the COPY working with or without it.
21
+ COPY package.json package-lock.json* ./
22
+ RUN npm install --no-audit --no-fund
23
+
24
+ # App source. node_modules and local state are excluded via .dockerignore.
25
+ COPY . .
26
+
27
+ # Generate the Prisma client at build time (every scaffold ships a
28
+ # prisma/schema.prisma). If you remove Prisma from the app, delete this line.
29
+ RUN npx prisma generate
30
+
31
+ ENV NODE_ENV=production
32
+ # webjs start reads $PORT (default 8080). compose / uncloud / Railway set it.
33
+ ENV PORT=8080
34
+ EXPOSE 8080
35
+
36
+ # Platform-neutral readiness gate. webjs answers /__webjs/ready with 503 until
37
+ # the instance is fully warm (analysis + first vendor attempt), then 200. This
38
+ # HEALTHCHECK is honoured by Docker, compose, and most Docker-based platforms,
39
+ # so the gate works the same everywhere instead of needing a per-platform file.
40
+ # The probe is dependency-free (Node 24's built-in fetch, no curl/wget). For
41
+ # platforms that read their own config, point the equivalent knob at the same
42
+ # path (Railway healthcheckPath, Render healthCheckPath, Fly [checks], k8s
43
+ # readinessProbe); see AGENTS.md "Health and readiness probes".
44
+ HEALTHCHECK --interval=15s --timeout=3s --start-period=40s --retries=5 \
45
+ CMD ["node", "-e", "fetch('http://127.0.0.1:'+(process.env.PORT||8080)+'/__webjs/ready').then(r=>process.exit(r.ok?0:1),()=>process.exit(1))"]
46
+
47
+ # `npm start` runs `prestart: prisma migrate deploy` (idempotent, a no-op when
48
+ # there are no migrations yet) and then `webjs start`, which serves on $PORT.
49
+ CMD ["npm", "start"]
@@ -0,0 +1,36 @@
1
+ # {{APP_NAME}} local parity with production, using the same Dockerfile, one service.
2
+ #
3
+ # docker compose up --build → http://localhost:8080
4
+ #
5
+ # In production the webdeploy tool (ubicloud + uncloud) provisions a managed
6
+ # Postgres and injects DATABASE_URL + AUTH_SECRET for you. Locally this uses
7
+ # the scaffold's SQLite file on a named volume so data survives `compose down`.
8
+ services:
9
+ app:
10
+ build: .
11
+ ports:
12
+ - "8080:8080"
13
+ environment:
14
+ PORT: 8080
15
+ # SQLite on a volume for local dev. For production, point DATABASE_URL at
16
+ # your managed Postgres and switch prisma/schema.prisma's provider to
17
+ # "postgresql".
18
+ DATABASE_URL: file:/data/dev.db
19
+ # Generate: node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
20
+ AUTH_SECRET: ${AUTH_SECRET:-change-me-please-at-least-32-characters!}
21
+ # Uncomment to back cache / sessions / rate-limiting / pub-sub with Redis
22
+ # instead of the in-memory defaults.
23
+ # REDIS_URL: redis://redis:6379
24
+ volumes:
25
+ - app-data:/data
26
+ # Readiness gate: hold the service "starting" until /__webjs/ready returns
27
+ # 200 (fully warm). Same probe as the Dockerfile HEALTHCHECK; dependency-free.
28
+ healthcheck:
29
+ test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:'+(process.env.PORT||8080)+'/__webjs/ready').then(r=>process.exit(r.ok?0:1),()=>process.exit(1))"]
30
+ interval: 15s
31
+ timeout: 3s
32
+ start_period: 40s
33
+ retries: 5
34
+
35
+ volumes:
36
+ app-data: