Skip to content

Deploy from ZIP

Upload a ZIP archive, then deploy with the returned upload URL.

Deploy an existing app directly from its source folder. StackMachine automatically detects the language and framework, installs dependencies, and builds the app for you. You do not need to build locally or set install/build/start commands.

Include source files, dependency manifests (such as package.json, requirements.txt, or pyproject.toml), lockfiles, and framework configuration at the ZIP root. Exclude dependencies and generated output so StackMachine builds a fresh version from source.

Use the client from Client setup. For Node.js, install zip-a-folder with npm install zip-a-folder and use Node.js 24.12 or newer. Python uses the built-in zipfile module and needs no extra archive package.

ZIP your source folder

Replace ./my-app with your project folder. These examples automatically exclude node_modules, .git, dist, other build output, virtual environments, and local .env files at every level. They preserve source, manifests, lockfiles, and configuration such as .gitignore and .python-version. The ZIP contains the folder contents directly, without an enclosing my-app directory.

zip-project.mjszip_project.py
import { zip } from "zip-a-folder";

const excludedDirs = [
  "node_modules", ".git", "dist", "build", ".next",
  ".venv", "venv", "__pycache__", "target",
];

// Keep the ZIP outside the source folder. Archive its contents at the root.
await zip("./my-app", "app.zip", {
  exclude: [
    ...excludedDirs.flatMap((name) => [`**/${name}`, `**/${name}/**`]),
    "**/.env*",
    "**/.DS_Store",
  ],
});
import os
from pathlib import Path
from zipfile import ZIP_DEFLATED, ZipFile

source = Path("./my-app")
excluded_dirs = {
    "node_modules", ".git", "dist", "build", ".next",
    ".venv", "venv", "__pycache__", "target",
}

# Keep the ZIP outside the source folder. Archive its contents at the root.
with ZipFile("app.zip", "w", compression=ZIP_DEFLATED) as archive:
    for root, dirs, files in os.walk(source):
        dirs[:] = [name for name in dirs if name not in excluded_dirs]
        for name in files:
            path = Path(root) / name
            if name.startswith(".env") or name == ".DS_Store" or path.is_symlink():
                continue
            archive.write(path, arcname=path.relative_to(source).as_posix())

Upload the ZIP

Upload the app.zip created above. Save the returned uploadUrl / upload_url for the next step.

deployFromZip.jsdeploy_app.py
import { readFileSync } from "node:fs";

const archive = new Blob([readFileSync("app.zip")]);
const uploadUrl = await client.files.upload(archive, {
  onProgress: ({ percent }) => console.log("Upload %:", percent * 100),
});
// Should return: "https://storage.example.com/upload/abc123..."
console.log(uploadUrl);
from pathlib import Path

upload_url = client.files.upload(
    Path("app.zip"),
    on_progress=lambda p: print("Upload %:", p.percent * 100),
)
# Should return: "https://storage.example.com/upload/abc123..."
print(upload_url)

Start a deployment

Pass uploadUrl / upload_url on deployments.create along with appName / app_name and owner. Replace owner with your workspace name. StackMachine detects and builds the uploaded source automatically; you get a buildId and QUEUED status immediately.

deployFromZip.jsdeploy_app.py
const deployment = await client.deployments.create({
  appName: "my-zip-app",
  owner: "stackmachine",
  uploadUrl,
});
// Should return: {
console.log(deployment.buildId, deployment.status);
deployment = client.deployments.create(
    app_name="my-zip-app",
    owner="stackmachine",
    upload_url=upload_url,
)
# Should return: {
print(deployment.build_id, deployment.status)

Wait for the build

Call wait() on the deployment from step 3. Use onProgress / on_progress for build logs; the resolved app version includes the live URL.

deployFromZip.jsdeploy_app.py
const appVersion = await deployment.wait({
  onProgress: ({ kind, message }) => console.log(kind, message),
});
// Should return: {
console.log(appVersion.app.url);
app_version = deployment.wait(on_progress=lambda e: print(e.kind, e.message))
# Should return: {
print(app_version.app.url)

Source: stackmachine/sdks examples.

Navigation

Type to search…

↑↓ navigate↵ selectEsc close