Persist uploads and auto-restore on startup
Zip uploads are extracted into {cwd}/data/modules/copy-to-backend/<relative target>
and then applied to the target path. On startup, restored content overlays the codebase when the feature is enabled.
Solo entrepreneurs waste time rebuilding Docker images or redeploying to platforms like Vercel. This brings HOT deployments—cutting iteration from minutes to seconds.
- Update assets (icons, downloadable files) instantly
- Tweak landing pages and docs (static pages) in seconds
Use npm run ci:copy-templates
to HOT deploy src/templates
. See the agent playbook at docs/static-pages/.agent.md
.
Quickstart
- Set
FEATURE_COPY_TO_BACKEND=1
in your environment. - Optionally set
FEATURE_COPY_TO_BACKEND_BEARER=yourtoken
to protect the endpoint. - (Optional) Set
COPY_TO_BACKEND_TARGET
default (e.g.,/app/assets
). - POST a zip file to
/api/modules/copy-to-backend/copy
with form fieldzip
. - Restart the container to verify persisted content restores on boot.
HOT deploy templates (static pages)
Deploy updated Handlebars/HTML under src/templates/
without rebuilding images:
npm run ci:copy-templates
- Copies updated templates into the running backend via the Copy-to-Backend module.
- Changes go live in seconds; ideal for landing pages and docs iterations.
- Rollback: switch your local git branch to a stable version and push again.
- For a deeper how-to, read
docs/static-pages/.agent.md
.
HOT deploy client (frontend)
Build and deploy the client bundle under client/dist/
to the running backend without rebuilding images:
npm run ci:copy-client-dist
- Runs
npm run build
inclient/
and uploads thedist/
output via Copy-to-Backend to/app/client/dist
. - Ideal for shipping UI changes quickly; just refresh the browser.
- Uses
scripts/dev/copy-to-backend-client-dist.ts
under the hood. - Pairs with the allowed target path
/app/client/dist
shown below. - Requires
FEATURE_COPY_TO_BACKEND
to be enabled (see Environment variables).
Multi-environment & interactive CLI
Use npm run ci:copy
to interactively deploy templates or the client bundle across environments. When FEATURE_COPY_TO_BACKEND_ENVS
is set, you can pick an environment; the CLI overrides COPY_TO_BACKEND_API_URL
and optionally FEATURE_COPY_TO_BACKEND_BEARER
for that run.
npm run ci:copy

Watch how multi-deployment CLI enables HOT deployment in just 4 seconds
- Define envs as
name|url
orname|url|bearer
, comma-separated. - Example:
staging|http://staging.local|secret,prod|https://api.example.com|secret2
- If not set, the CLI uses current
COPY_TO_BACKEND_API_URL
andFEATURE_COPY_TO_BACKEND_BEARER
.
Example: upload a ZIP
curl -X POST \
-H "Authorization: Bearer $FEATURE_COPY_TO_BACKEND_BEARER" \
-F "zip=@module.zip" \
-F "target=/app/assets" \
http://localhost:3000/api/modules/copy-to-backend/copy
If copyOnly=true
is provided, the raw ZIP is copied to the target. Otherwise, the ZIP is extracted to the persistence folder, then its files are applied to the target.
Allowed target paths
/app/assets
→ maps toassets/
/app/src/templates
→ maps tosrc/templates/
/app/client/dist
→ maps toclient/dist/
/app/dist
→ maps todist/
Targets are strictly validated for safety; unknown paths are rejected.
Docker persistence
Mount a named volume at /app/data
so uploads persist across restarts:
services:
app:
volumes:
- microsaas-data:/app/data
volumes:
microsaas-data:
Environment variables
FEATURE_COPY_TO_BACKEND
(required): enable feature and startup restore when set to1
ortrue
.FEATURE_COPY_TO_BACKEND_BEARER
(optional): bearer token for the upload endpoint.COPY_TO_BACKEND_TARGET
(optional): default target path (defaults to/app/assets
).COPY_TO_BACKEND_API_URL
(optional): override the API base URL for deployment scripts and the interactive CLI (e.g.,http://localhost:3000
).FEATURE_COPY_TO_BACKEND_ENVS
(optional): comma-separated environments for the CLI; each entry isname|url
orname|url|bearer
.
Security & operations
- Prefer using a bearer token outside local development.
- Restrict network access to the upload endpoint.
- Consider HTTPS/ingress auth in production.
- Startup restore is idempotent and overwrites files with persisted versions.