Delivery format
ZIP or GitHub snapshot layout for Python and Node.js Worker and Web apps.
Delivery source format
Submit delivery as a ZIP upload or a GitHub snapshot (repo + branch/tag via the Velcio GitHub App). Layout rules and the 25 MB size limit are the same either way. Do not include a Dockerfile; Velcio generates the container build.
GitHub import is a one-time snapshot of the chosen ref at submit (or revision submit). It is not continuous deploy. Connect the App under Developer profile before importing private repos. After the buyer accepts, they download the delivery ZIP from Velcio; they do not get clone access to your GitHub repo. How to connect and submit: Developer workflow.
Choose Python or Node.js when you submit. That runtime is locked for the project's delivery builds.
At submit, choose process mode (required; there is no default):
- Worker: long-running process with no public URL.
- Web: HTTP app with a public URL on
https://{slug}.velcio.app. Use Web if the app needs inbound webhooks or any public HTTP endpoint. See Web delivery format for thePORTcontract.
Not sure which to pick? See Choosing Worker or Web for examples.
Maximum archive size: 25 MB.
Python layout
my-bot.zip
├── main.py # exactly one main.py anywhere in the tree
└── requirements.txt # OR pyproject.toml (see below)
Rules
- Use a supported Python version (3.11, 3.12, or 3.13) selected at delivery submit.
- Provide a dependency manifest at the project root:
requirements.txt, orpyproject.tomlwith PEP 621[project].dependencies. If both are present,requirements.txtwins. Poetry-only layouts are not supported. - Include exactly one
main.pyin the ZIP. Velcio rejects archives with zero or multiplemain.pyfiles and lists the paths when ambiguous. - Ignored paths:
__pycache__,.git, andnode_modulesare not searched. - Entry command:
main.pyat the project root runs aspython main.pybot/main.pyruns aspython -m bot.main- Other locations run as
python -m ...when parent directories form a package (__init__.pyon the path), otherwisepython path/to/main.py
Node.js layout
my-bot.zip
├── package.json
└── index.js # or src/index.js, bot/index.js, or package.json "main"
Rules
- Use a supported Node.js version (20 or 22 LTS) selected at delivery submit.
package.jsonis required at the project root.- Include
package-lock.jsonwhen possible for reproducible installs. - Entry file must be
index.js,src/index.js,bot/index.js, or a safe relative path inpackage.jsonmain(must exist inside the ZIP; no.., absolute paths, or control characters).
Web apps: PORT and health
When process mode is Web, Velcio sets PORT=8080 and proxies public HTTPS only to that port. Your app must listen on 0.0.0.0 using env PORT (do not hardcode 8000 or 3000) and implement GET /healthz with HTTP 2xx (Velcio does not add this route). Wrong port → public 502. Missing route → 404 on /healthz. Details: Web delivery format.
Common rules (all runtimes)
- No user-supplied Dockerfiles.
- No unsafe archive paths (
..or absolute paths). - Dependencies install during Velcio's build; keep archives lean.
- Never put secret values in the ZIP. Declare required env var names in Velcio (for example
OPENAI_API_KEY). The buyer sets values in Production secrets. Velcio writes a build.dockerignorethat excludes.env*(including.env.example) from the image; do not rely on shipping env files in the archive. - Rights transfer on acceptance. When the buyer accepts your delivery or a revision, you assign full ownership of that submitted code to the buyer. Do not reuse delivered code for other clients or projects unless the buyer agrees separately outside Velcio.
Required environment variables
Developers declare which production env vars the buyer must configure:
- Open Required environment variables on the project page while work is
in_progress. - Add any keys your app reads from the environment. Apps that need a database often use
DATABASE_URL(use quick-add if suggested). - Save the list early so the buyer can set values before you submit delivery.
- Confirm the same list when you submit (ZIP upload or GitHub snapshot).
Velcio blocks deploy until every declared required key has a buyer-provided value.
Failed builds and verification
If validation or build fails, deployment status becomes failed and the project returns to in_progress. Submit a corrected ZIP or GitHub snapshot, or use Retry deploy / Rebuild on the project page.
After a successful deploy, the project stays submitted while the developer verifies logs and behaviour. Buyer review starts only when the developer confirms delivery.