Skip to content

Inspect an upload and save a project plan

DeploymentsImpreza documentationRead as Markdown ↗

Inspect a retained project archive before creating an app. The plan records the source version, its SHA256, selected project folder, findings and available build options. Choose a build option, save the server and runtime configuration for review, then confirm that saved deployment.

Git inspection

Inspect a pinned Git commit through the portal, REST or local MCP 0.34.0+. Retained uploads remain supported.

Inspection accepts either context_id or git_url with a complete 40-character git_commit. In My Apps, choose Git commit over HTTPS in the inspection form. For a private repository, supply git_username and git_token; the token is used only for the fetch and is not saved in the plan or deployment. Use the same fields with impreza_plan_project or POST /v1/platform/deployments/custom/plans.

{
  "git_url": "https://github.com/OWNER/PROJECT.git",
  "git_commit": "0123456789abcdef0123456789abcdef01234567",
  "project_dir": "."
}

Review source.origin.url, source.origin.commit and source.sha256 before selecting a build option. The exact captured archive is retained under the account upload quota. Preparing and applying the plan use those captured bytes, not a moving branch and not a second repository fetch. To change the source, inspect a new commit.

Only public-network HTTPS origins on port 443 are supported. Redirects, URL credentials and submodules are refused. No checkout, project hooks, dependency installation or application code runs during inspection. Git archive attributes can exclude files, and Git LFS objects are not materialized. Existing archive limits still apply, including rejection of links. Each Git command has a 60-second timeout, resource limits and bounded output. Errors include UNSAFE_GIT_SOURCE, GIT_INSPECTION_FAILED, UNSUPPORTED_GIT_SOURCE and SOURCE_UNAVAILABLE; quota and ownership checks still apply. Successful inspection is not proof that the application builds.

npm workspaces

Use npm_workspace in project inspection and custom deployments through the portal, REST or local MCP 0.34.0+.

For an npm monorepo, set project_dir to the folder containing the root package.json and matching package-lock.json, then select a declared workspace such as apps/web. Leave the field absent for an independent package. A saved plan fixes both fields. Previews and redeploys inherit the saved selection.

{"context_id":"ctx_...","project_dir":".","npm_workspace":"apps/web"}

The root must declare an array of workspace paths. Exact paths and whole-segment wildcards, such as packages/*, are supported; recursive globs, negation and object declarations are refused. npm installs from the root lockfile, builds workspaces with scripts in declaration order, and starts the selected app with npm start --workspace=apps/web. Put shared packages before their consumers. This is not automatic dependency-order scheduling. Root build/start scripts are not run.

For node_npm_static, static_output_dir is relative to the selected workspace; only its generated site is copied into the web-server image. The combined workspace/output path must fit the existing five-segment, 120-character limit. Node server images retain the npm root and sibling packages. Do not place unrelated secrets in the source. Existing exclusions and symlink refusals apply. Public build variables reach workspace build scripts only; they are never a credential channel.

Inspection checks the selected package and root lockfile without running code. Undeclared selections produce npm_workspace_not_declared and no npm build option. Builds also recheck workspace membership. Missing paths, invalid lockfiles or failed shared builds fail the deployment; verify the operation result and health of the serving release. For standalone pnpm/Yarn projects and private registries, use the respective settings below.

Pinned pnpm and Yarn

Local MCP 0.34.0+ supports node_package_manager for standalone Node server/static recipes in the portal, REST and MCP. Omit it to retain npm. Use an exact pin such as pnpm@10.26.1 or yarn@4.9.2, also declared identically in the selected folder's package.json. Supported major families are pnpm 10–12 and Yarn 4; ranges, tags, classic Yarn and manager URLs are rejected.

Keep pnpm-lock.yaml or yarn.lock beside that package file. Inspection infers the pin without executing code; saved plans preserve it. Creation requires deploy scope. Installation uses a frozen/immutable lockfile and verifies its bytes after installation. Node server recipes remove development dependencies before startup; static recipes copy only the configured output into Nginx. Node 24 and the selected manager's dependency/build-script rules apply.

Pinned pnpm/Yarn recipes support standalone projects only: do not combine the field with npm_workspace, package workspaces or pnpm-workspace.yaml. Yarn uses the node-modules linker; source .yarnrc, .yarnrc.yml, .yarn and PnP files are excluded. Custom plugins, patched dependencies and additional manager configuration require a reviewed Dockerfile. Verify the deployment result and application health; an accepted plan is not proof that dependencies or scripts will build.

For private registries, the recipes accept build_secrets.npmrc with pnpm, or build_secrets.yarnrc containing Yarn YAML configuration. Yarn mounts it at /app/.yarnrc.yml for installation only; pnpm receives its temporary npm configuration file. Other secrets remain build-script-only. Use registry-host-scoped credentials, an agent with build-secrets-v1, and the explicit rotation workflow below. These settings require trusted project code and are never inherited automatically by previews.

Build credentials

Build credentials require agent 0.6.11+ advertising build-secrets-v1 and local MCP 0.34.0+ when using the local connector. Unsupported agents refuse the deployment before receiving the command.

Supply build_secrets as a JSON object when creating a Dockerfile/npm deployment or preparing a saved plan. In My Apps, use Build secrets. Each name starts with a letter and contains only ASCII letters, digits or underscores (64 characters maximum). Up to 16 nonempty UTF-8 values, 64 KiB each and 256 KiB total; no NUL characters. Do not use Public build variables for credentials.

The control plane encrypts values separately, bound to account, agent and app. Reviews and deployment reads show only build_secret_names. The assigned agent obtains values only for its active, authorized preparation operation. Manifests and queued jobs contain names and temporary file references, not values. Files are private to the agent state and removed after build completion or a handled failure. An interrupted operation still needs recovery verification before it can be declared clean.

For generated npm recipes, the name npmrc supplies an npm configuration file during dependency installation only. Scope registry tokens to their registry host. Other names are mounted under /run/secrets/NAME during build scripts only. They do not become runtime environment variables. For a custom Dockerfile, request each secret explicitly:

RUN --mount=type=secret,id=PackageToken,required=true \
    your-build-command --token-file /run/secrets/PackageToken

Build output is withheld when credentials are mounted. These builds bypass cached layers so replacement credentials are checked on the next build. Use trusted source and dependencies: a script can deliberately copy credentials into an image or send them over the network. Secret mounts do not prevent that. Avoid embedding values in commands or generated artifacts. Automatic previews do not inherit build credentials; create a separately reviewed preview app with explicitly scoped test credentials.

To replace expiring credentials, open the app card's Build credentials, or call impreza_rotate_build_secrets with deployment_id and build_secrets. REST uses POST /v1/platform/deployments/custom/{id}/build-secrets with deploy scope. Supply exactly the current names. Rotation is refused while an operation is pending/running, does not return values and does not redeploy. Start a redeploy explicitly when ready. Changing mount names requires a new reviewed deployment.

Verify the operation result, application response and health. Credential delivery failures fail before replacement. Generated Python/PHP recipes do not yet accept these fields.

From My Apps

  1. Open the custom-app form and upload a source version. Remove credentials and local dependencies before uploading.
  2. Expand Inspect an upload and save a plan. Choose the archive and project folder (. by default). A Dockerfile path is relative to the archive root. The PHP public folder is relative to the project folder. Python needs an explicit production start command.
  3. Select Inspect and save plan. Review the detected folders, findings and build options. Missing or invalid lockfiles block npm/Composer recipes; a missing PHP public index.php also blocks that recipe. A valid JSON lockfile is not proof that it matches the dependency declaration.
  4. Choose an available option. The form fixes source and build settings to that plan. Review the app name, server, container port, domain, runtime variables, volumes and startup health policy before submitting.
  5. Select Review and save deployment. Read the immutable configuration in Review saved deployments, then select Confirm and deploy. Preparation creates no app or DNS record. A retry of the same saved deployment returns its original receipt.
  6. Use Load saved plans to resume an inspection, or Load saved deployments to resume a final configuration review. Clear the selected plan to edit source/build settings manually, or inspect again to save different settings. A new upload is required to change source bytes.

A source inspection plan can offer several build options. A prepared deployment fixes one option and its runtime configuration. Changes in the form require a new review; they do not alter a saved configuration. To update an existing app, use its normal redeploy workflow.

Review once, apply safely

A prepared deployment records the source, recipe, project folder, start command or public folder, server, proposed domain, environment values, CPU/memory limits, container port, volumes and startup policy. It stores the generated recipe and checks the effective configuration again before applying. Environment values are encrypted in the saved record; review/list responses show their names only. Values reach the existing deployment configuration when applied. Never put credentials in names, domains or start commands.

Review the returned execution_id and configuration_digest with the configuration. Applying accepts those identifiers only; settings cannot be overridden. The app, queue job and acceptance receipt are committed together. Concurrent requests use the same receipt, or return a conflict while the first request finishes. After a lost response, retry the same identifiers. A committed receipt remains valid for replay after expiry, rule changes or app removal and never creates another job. Acceptance means queued, not healthy: inspect the app status and logs.

Before the first acceptance, expiry, changed rules, altered source bytes, an unavailable agent, a changed server IP or changed effective settings require revalidation or a fresh preparation. A failed transaction leaves no new app/job. A prepared deployment cannot restart a failed deployment; use the normal app workflow. Preparing a second record creates a separate intention, so reuse the original identifier when retrying.

At most 20 pending prepared deployments per account; each expires no later than its source plan and within 24 hours. Expired pending records are removed when the account prepares again. The encrypted preparation copy is removed on acceptance; the existing deployment still holds its runtime environment. Accepted receipts are retained. ready_for_review reflects the saved record, not live capacity or source availability.

Preparation reserves no capacity, domain, host port or build slot. A managed hostname can be proposed without creating DNS; it must still be available at apply. App IDs, host ports and onion addresses are allocated at execution. DNS is external to the database transaction: an interrupted attempt can leave a DNS record, even if no app/job committed. This flow does not pin external dependencies/images, promote artifacts or guarantee a successful build.

From MCP

Local MCP requires 0.32.0+ for the prepare/apply flow (source inspection remains available in 0.31.0+). Hosted MCP uses existing account uploads and cannot read local folders. Both transports expose the same plan and deployment rules.

  1. Upload with impreza_upload_context in local MCP, or use an existing retained context_id from impreza_list_contexts.
  2. Call impreza_plan_project with context_id and optional project_dir, dockerfile_path, start_command and php_document_root.
  3. Read the findings and analysis.deployment_options. No options means the selected paths/configuration have no supported candidate. Reinspect after correcting the source or settings.
  4. After customer review, call impreza_prepare_project_deployment with plan_id, the zero-based option_index, name and agent_id, plus runtime settings. Do not resend source or build settings.
  5. Review the returned configuration, then call impreza_apply_project_deployment with only execution_id and configuration_digest. Use impreza_list_prepared_deployments to list records or retrieve one execution ID.
  6. Inspect the deployment status, logs and readiness. impreza_list_project_plans lists the latest 20 plans or retrieves one plan_id.
// Inspect an already uploaded Python project
{"context_id":"ctx_...","project_dir":"apps/api",
 "start_command":"exec uvicorn app:app --host 0.0.0.0 --port 8000"}

// Save configuration for review with impreza_prepare_project_deployment
{"plan_id":"plan_...","option_index":0,"name":"my-api",
 "agent_id":"agt_...","target_port":8000,
 "healthcheck_path":"/ready","require_healthy_start":true}

// After review: impreza_apply_project_deployment
{"execution_id":"pdep_...","configuration_digest":"returned digest"}

Start commands and plan findings are public application configuration within your account; never put credentials in them. Supply runtime secrets through the dedicated environment variables when preparing, deploying or editing an app.

REST and lifecycle

  • POST /v1/platform/deployments/custom/plans: create an inspection plan, deploy scope, HTTP 201.
  • GET /v1/platform/deployments/custom/plans: latest 20 account plans, read scope.
  • GET /v1/platform/deployments/custom/plans/{plan_id}: retrieve one plan, read scope.
  • POST /v1/platform/deployments/custom/plans/{plan_id}/prepare-deployment: save final configuration, deploy scope, HTTP 201.
  • GET /v1/platform/deployments/custom/prepared and /{execution_id}: list/retrieve prepared deployments, read scope.
  • POST /v1/platform/deployments/custom/prepared/{execution_id}/apply: apply with configuration_digest, deploy scope; HTTP 201 on first acceptance, 200 on replay. Returns receipt with deployment/command IDs and replayed.
  • POST /v1/platform/deployments/custom/plans/{plan_id}/deploy: compatible direct creation from an option, deploy scope, HTTP 201. This older endpoint and impreza_deploy_project_plan remain reusable and are not idempotent. Use prepare/apply for safe retries.

A plan contains plan_id, status, creation/expiry timestamps, source (context ID, SHA256, size), inspection_revision, project_dir, an inventory summary and analysis. It does not return archive contents or storage paths. App metadata includes project_plan provenance for the creation request; it does not certify the currently running release after later redeploys or recovery.

Plans expire after at most 24 hours, earlier if the unused source expires. At most 20 unexpired plans are stored per account. Expired records are removed when that account creates another plan. The list can include expired records until then. A plan does not extend upload retention: deleting or losing the source makes it unavailable. Another account's plan returns 404. Resource-confined MCP credentials cannot access account plans.

needs_review means the saved plan can be considered, not that its build will succeed. expired, stale (inspection rules changed), or source_unavailable requires a fresh inspection. Execution rechecks expiry, rules, actual source SHA256 and account ownership. It also requires an online target heartbeat within 90 seconds, rejects an explicitly requested memory limit above reported total memory, and runs normal deployment ownership, domain and agent capability checks. These checks do not reserve free memory, CPU, domains or build slots.

Preparation and the older direct-deploy endpoint accept option_index, name, agent_id, domain, vars, cpus, memory_mb, target_port, volumes, onion, build_secrets, healthcheck_path, require_healthy_start and startup_timeout_seconds. Other fields are refused. Recipe defaults apply where omitted. Static plans use the standard dist output with SPA fallback; custom static output/routing or public build variables need the normal custom-deploy flow.

Inspection boundaries

The inspector streams one gzip-compressed ustar/POSIX pax archive, with at most 256 MiB expanded data, 10,000 entries and ten seconds of processing. It rejects unsafe paths, duplicate entries, file/directory conflicts, links, devices, sparse files, GNU long-name records and unsupported pax attributes. Standard directory entries and safe pax paths are supported. If necessary, repack as ustar or POSIX pax without links or extended attributes.

It inventories paths and reads only the selected package.json, requirements.txt, composer.json and Dockerfile (32 KiB each), plus selected npm/Composer lockfiles (2 MiB each). Up to 50 candidate project folders are returned. Common sensitive filenames produce a finding, not a secret scan. No project code is executed and no archive is extracted.

Source SHA256 fixes uploaded bytes. Inspection can capture a pinned Git commit but does not analyze arbitrary source code, resolve dependencies, prove lockfile consistency, interpret ignore rules, pin external images/packages, discover all required environment variables or certify startup. Build options are candidates under the existing recipe limits. The source inspection plan alone does not freeze runtime settings; the optional prepared deployment does. Use deployment history and startup checks to verify the resulting app.