mirror of
https://github.com/kellymichels/zscripts-token-savers
synced 2026-10-07 07:18:18 +00:00
* fix(zdeploy): build docker stacks that come from a Dockerfile Mirrors the fix in the private scripts repo; the code is identical in both, only the config differs. The docker kind ran `docker compose pull` then `docker compose up -d`. That is right for a stack of published images and wrong for one built from a Dockerfile in the tree, where there is nothing to pull. `up -d` builds only when the image is MISSING, so the first deploy works and every one after it uploads the new code, starts the old image, and reports success. A project opts into building with deploy.build, which runs `docker compose build --pull` so the base image is refreshed at the same time. Stacks that pull are unaffected. The example config documents the flag on the docker project, next to the existing note about startApp, because the failure is silent and nobody goes looking for a setting they do not know exists. CHECKSUMS.txt regenerated, since two covered scripts changed. 286 tests pass, 1 skipped. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * fix(checksums): hash the scripts as git checks them out, not as a tool wrote them CI failed on the two files this branch touches while the same suite passed here. The manifest was right about the wrong bytes. .gitattributes pins *.ps1 to eol=crlf, and its comment says why: it makes these files byte-identical on every platform, which is what lets CHECKSUMS.txt hold one hash per file rather than one per OS. The edit that added Get-DockerImageStep was applied by a script that wrote LF, so the working copy stopped matching the pin. zchecksums then faithfully recorded the LF hashes, and every checkout that honours .gitattributes - including CI - disagreed. Nothing was wrong with the committed content: git normalises on the way in, so the objects were always correct. Only the local working copy and the manifest taken from it were off. Re-materialised both files through git so they carry the endings the attribute pins, then regenerated the manifest from those. 286 tests pass, 1 skipped. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
134 lines
5.0 KiB
JSON
134 lines
5.0 KiB
JSON
{
|
|
"_comment": "Copy this file to zconfig.json and fill in your values. zconfig.json is gitignored \u2014 never commit it.",
|
|
"ec2": {
|
|
"ip": "YOUR_SERVER_IP",
|
|
"user": "YOUR_SSH_USER",
|
|
"pemKey": "C:\\Users\\YourUser\\.ssh\\YourKey.pem",
|
|
"stackRoot": "/home/YOUR_SSH_USER/stack"
|
|
},
|
|
"paths": {
|
|
"temp": "C:\\YourRoot\\temp",
|
|
"backupsLocal": "C:\\YourRoot\\backups\\projects",
|
|
"backupsEc2": "C:\\YourRoot\\backups\\ec2",
|
|
"scriptsRoot": "C:\\YourRoot\\zscripts",
|
|
"oneDriveBackups": ""
|
|
},
|
|
"projects": {
|
|
"_comment": "Rename these keys to your own project names \u2014 the key IS the command argument: zstart pyapp, zdeploy viteapp, zbackup nextapp. Add as many projects as you like. Keys starting with _ are ignored.",
|
|
"pyapp": {
|
|
"label": "My Python App",
|
|
"kind": "python",
|
|
"localRoot": "C:\\YourRoot\\pyapp",
|
|
"startModule": "pyapp.main",
|
|
"_startApp_note": "ASGI/FastAPI app? Use \"startApp\": \"app.main:app\" instead of startModule (runs uvicorn --port <dev> --reload).",
|
|
"install": "-e .",
|
|
"ports": {
|
|
"dev": 8080
|
|
},
|
|
"domain": "pyapp.yourdomain.com",
|
|
"start": {
|
|
"_comment": "Optional zstart pre-steps: gitPull runs 'git pull --ff-only' first; env sets variables for the server process.",
|
|
"gitPull": true,
|
|
"env": {
|
|
"MYAPP_DEBUG": "1"
|
|
}
|
|
},
|
|
"db": {
|
|
"user": "pyapp_user",
|
|
"name": "pyapp_db"
|
|
},
|
|
"remote": {
|
|
"path": "/home/YOUR_SSH_USER/stack/pyapp",
|
|
"composeDir": "/home/YOUR_SSH_USER/stack/pyapp/docker",
|
|
"appService": "app"
|
|
},
|
|
"verify": {
|
|
"_comment": "Optional post-deploy build check. Two ways to reach the app, both ON the server rather than through the public proxy - which answers from whichever vhost matches the Host header, so a container with no public route gets another site's version back. Use port+expect when the app publishes a host port; use viaProxy+upstream when it does not, or when its version endpoint is deliberately not public.",
|
|
"port": 8080,
|
|
"path": "/health",
|
|
"expect": "\"status\":\"ok\"",
|
|
"viaProxy": "edge_proxy_container",
|
|
"upstream": "app_container:80",
|
|
"_viaProxy_note": "Runs: docker exec <viaProxy> curl -s http://<upstream><path>. Reads the build from inside the shared docker network, and exercises the real HTTP path - so it proves the app is serving, not just that its database knows a version. Omit both keys to keep the previous behaviour."
|
|
},
|
|
"deploy": {
|
|
"zipName": "PyAppDeploy.zip",
|
|
"gitPull": true,
|
|
"tagOnDeploy": false,
|
|
"exclude": [
|
|
"docs"
|
|
],
|
|
"_comment": "preserve: server-side files/dirs in the project dir that deploys must never delete (.env* files are always preserved)",
|
|
"preserve": [
|
|
"keys",
|
|
"seed-data"
|
|
]
|
|
}
|
|
},
|
|
"viteapp": {
|
|
"label": "My Vite Site",
|
|
"kind": "vite",
|
|
"localRoot": "C:\\YourRoot\\viteapp",
|
|
"ports": {
|
|
"dev": 5173
|
|
},
|
|
"domain": "www.yourdomain.com",
|
|
"remote": {
|
|
"path": "/home/YOUR_SSH_USER/stack/viteapp",
|
|
"containerName": "viteapp"
|
|
},
|
|
"deploy": {
|
|
"zipName": "ViteAppDeploy.zip"
|
|
}
|
|
},
|
|
"nextapp": {
|
|
"label": "My Next.js App",
|
|
"kind": "nextjs",
|
|
"localRoot": "C:\\YourRoot\\nextapp",
|
|
"ports": {
|
|
"dev": 4173,
|
|
"prod": 3000
|
|
},
|
|
"domain": "app.yourdomain.com",
|
|
"db": {
|
|
"user": "nextapp_user",
|
|
"name": "nextapp_db"
|
|
},
|
|
"migrations": "prisma",
|
|
"remote": {
|
|
"path": "/home/YOUR_SSH_USER/stack/nextapp",
|
|
"appService": "web"
|
|
},
|
|
"verify": {
|
|
"_comment": "Optional: after deploy, curl this ON the server (localhost:port+path). Add it when compose publishes the app to 127.0.0.1 only, as it usually does behind the edge proxy \u2014 probing the public IP on that port can never answer. Redirects are followed, so a Next.js '/' that 307s to '/login' still verifies. Takes precedence over the domain check.",
|
|
"port": 3000,
|
|
"path": "/",
|
|
"expect": ""
|
|
},
|
|
"deploy": {
|
|
"zipName": "NextAppDeploy.zip"
|
|
}
|
|
},
|
|
"edge": {
|
|
"label": "Edge Nginx Proxy",
|
|
"kind": "edge",
|
|
"localRoot": "C:\\YourRoot\\edge",
|
|
"proxyContainer": "edge_proxy",
|
|
"certsSource": "",
|
|
"remote": {
|
|
"path": "/home/YOUR_SSH_USER/stack/edge"
|
|
}
|
|
},
|
|
"analytics": {
|
|
"label": "Analytics (any docker compose app)",
|
|
"kind": "docker",
|
|
"_build_note": "Images pulled from a registry need nothing here. If the image is BUILT from a Dockerfile in this tree, add \"deploy\": { \"build\": true } \u2014 without it a redeploy uploads the new code and restarts the OLD image, and reports success.",
|
|
"localRoot": "C:\\YourRoot\\analytics",
|
|
"domain": "analytics.yourdomain.com",
|
|
"remote": {
|
|
"path": "/home/YOUR_SSH_USER/stack/analytics"
|
|
}
|
|
}
|
|
}
|
|
}
|