# Build & deploy pipeline export const languages = [ { name: "Node.js", link: "/nodejs/how-to/build-pipeline" }, { name: "PHP", link: "/php/how-to/build-pipeline" }, { name: "Python", link: "/python/how-to/build-pipeline" }, { name: "Go", link: "/go/how-to/build-pipeline" }, { name: ".NET", link: "/dotnet/how-to/build-pipeline" }, { name: "Rust", link: "/rust/how-to/build-pipeline" }, { name: "Java", link: "/java/how-to/build-pipeline" }, { name: "Elixir", link: "/elixir/how-to/build-pipeline" }, { name: "Deno", link: "/deno/how-to/build-pipeline" }, { name: "Bun", link: "/bun/how-to/build-pipeline" }, { name: "Gleam", link: "/gleam/how-to/build-pipeline" }, { name: "Nginx", link: "/nginx/how-to/build-pipeline" } ] export const customizeBuild = [ { name: "Node.js", link: "/nodejs/how-to/build-process#build-environment" }, { name: "PHP", link: "/php/how-to/build-process#build-environment" }, { name: "Python", link: "/python/how-to/build-process#build-environment" }, { name: "Go", link: "/go/how-to/build-process#build-environment" }, { name: ".NET", link: "/dotnet/how-to/build-process#build-environment" }, { name: "Rust", link: "/rust/how-to/build-process#build-environment" }, { name: "Java", link: "/java/how-to/build-process#build-environment" }, { name: "Elixir", link: "/elixir/how-to/build-process#build-environment" }, { name: "Deno", link: "/deno/how-to/build-process#build-environment" }, { name: "Bun", link: "/bun/how-to/build-process#build-environment" }, { name: "Gleam", link: "/gleam/how-to/build-process#build-environment" }, { name: "Nginx", link: "/nginx/how-to/build-process#build-environment" } ] export const customizeRuntime = [ { name: "Node.js", link: "/nodejs/how-to/customize-runtime" }, { name: "PHP", link: "/php/how-to/customize-runtime" }, { name: "Python", link: "/python/how-to/customize-runtime" }, { name: "Go", link: "/go/how-to/customize-runtime" }, { name: ".NET", link: "/dotnet/how-to/customize-runtime" }, { name: "Rust", link: "/rust/how-to/customize-runtime" }, { name: "Java", link: "/java/how-to/customize-runtime" }, { name: "Elixir", link: "/elixir/how-to/customize-runtime" }, { name: "Deno", link: "/deno/how-to/customize-runtime" }, { name: "Bun", link: "/bun/how-to/customize-runtime" }, { name: "Gleam", link: "/gleam/how-to/customize-runtime" }, { name: "Nginx", link: "/nginx/how-to/customize-runtime" } ] ## Configure the pipeline Zerops provides a customizable build and runtime environment for your application. Start by adding a [zerops.yaml](/zerops-yaml/specification) file to the **root of your repository** and modify it to fit your application. Here is a basic example for a Node.js application: ```yaml zerops: - setup: api build: base: nodejs@20 buildCommands: - npm i - npm run build deployFiles: ./dist cache: node_modules run: base: nodejs@20 start: npm start ``` The zerops.yaml in your repository tells Zerops how to build and deploy your application. When the build & deploy pipeline triggers for the Node.js service named `api`, Zerops will: 1. Create a build environment with Node.js v.20 preinstalled 2. Run build commands: `npm i`, `npm run build` 3. Create a runtime environment with Node.js v.20 preinstalled 4. Deploy the built artifact from the `./dist` folder to runtime containers 5. Cache the `./node_modules` folder for faster subsequent builds 6. Start your application using `npm start` Learn more about `zerops.yaml` parameters for your runtime: ## Trigger the pipeline ### Continuous deployment Set up automatic builds triggered by Git events. You can establish continuous deployment in two ways: * **New Service:** Create a new runtime service and connect it to your GitHub or GitLab repository during the service creation process. * **Existing Services:** Go to the service detail and choose **Pipelines & CI/CD settings** from the left menu. Click **Connect with a GitHub repository** or **Connect with a GitLab repository** to link your repository. Once connected, Zerops will automatically build and deploy your application with each push to the selected branch or when you create a new tag. ### On-demand deployment Trigger builds and deployments manually when needed using either the CLI or GUI. #### Using Zerops CLI - **Build and deploy:** `zcli service push` - Uploads code and triggers the full pipeline - **Deploy only:** `zcli service deploy` - Skips build, deploys pre-built artifacts See [CLI commands documentation](/references/zcli/commands#service-operations) for all parameters. #### Using Zerops GUI In **Pipelines & CI/CD settings** section of your service detail: - **Re-deploy last pipeline** - With optional secret env variable updates - **Trigger new pipeline** - From git repo or with custom configuration #### Using import YAML Add `buildFromGit: ` to your service configuration for one-time build during import. See [import documentation](/references/import#service-basic-configuration). ## Build phase Zerops starts a temporary build container and executes these steps: 1. **Install build environment** - Sets up the runtime and tools 2. **Download source code** - From [GitHub ↗](https://www.github.com), [GitLab ↗](https://www.gitlab.com) or via [Zerops CLI](/references/cli) 3. **Customize environment** - Runs optional preparation commands 4. **Execute build commands** - Compiles and packages your application 5. **Upload artifacts** - Stores build output in internal Zerops storage 6. **Cache files** - Optionally [caches](/features/build-cache) selected files for faster future builds Zerops automatically deletes the build container after the build finishes or fails. ### Build hardware resources All runtime services use the same hardware resources for build containers:
HW resource Minimum Maximum
CPU cores 1 5
RAM 8 GB 8 GB
Disk 1 GB 100 GB
Build containers start with minimum resources and scale vertically up to maximum capacity as needed. :::info Build container resources are not charged. Build costs are covered by the standard Zerops [project fee](https://zerops.io/#pricing). ::: ### Build time limit The entire build pipeline has a **1 hour** time limit. After 1 hour, Zerops terminates the build pipeline and deletes the build container. ### Customize the build environment All runtime services start with a default build environment based on the [build.base](/zerops-yaml/specification#base-) attribute in `zerops.yaml`. Install additional packages or tools by adding [build.prepareCommands](/zerops-yaml/specification#preparecommands-) to your configuration. Learn more about customizing build environments: ## Runtime prepare phase (optional) When your application requires additional system packages, libraries, or tools in the runtime environment, Zerops allows you to build a custom runtime image. This optional phase occurs after the build phase and before deployment. ### When to use custom runtime images Build custom runtime images when you need: - System packages or libraries for runtime operations (e.g., `sudo apk add imagemagick` for image processing) - Library dependencies for interpreted languages or dynamically linked binaries - System-level tools or utilities your application requires - Customized base operating system or additional software layers ### Configuration Configure custom runtime images in your `zerops.yml` file using these fields: #### `run.os` + `run.base` Specify the operating system and base packages for your custom runtime image: ```yaml run: os: alpine # or ubuntu base: nodejs@20 # specify your runtime and version ``` #### `run.prepareCommands` Define commands that customize your runtime image. These commands run inside a fresh base container: ```yaml run: prepareCommands: - sudo apk add --no-cache imagemagick - sudo apt-get update && apt-get install -y some-package # for Ubuntu ``` Zerops creates the custom runtime image from this container after all commands complete successfully. #### `build.addToRunPrepare` Copy specific files from the build phase to the runtime prepare phase. This is useful when you need source files during runtime preparation: ```yaml build: addToRunPrepare: - package.json - requirements.txt - config/runtime-setup.sh ``` These files are packed immediately after `build.buildCommands` finish and become available during the runtime prepare phase. ### How it works When you trigger the first deploy with defined [run.prepareCommands](/zerops-yaml/specification#preparecommands--1), Zerops: 1. **Creates prepare container** - Based on `run.os` and `run.base` 2. **Copies build files** - Files specified in [build.addToRunPrepare](/zerops-yaml/specification#addtorunprepare-) (if any) 3. **Runs prepare commands** - Executes [run.prepareCommands](/zerops-yaml/specification#preparecommands--1) in order 4. **Creates runtime image** - Builds custom runtime image from the prepared container 5. **Uses for deployment** - Deploys your application using this custom runtime image ### Custom runtime image caching Zerops caches custom runtime images to optimize deployment times. The runtime prepare phase is skipped and cached images are reused when: - It is not the first deployment of your service - None of these `zerops.yaml` fields changed since the last deployment: - `run.os` or `run.base` - `run.prepareCommands` - `build.addToRunPrepare` - File contents specified in `build.addToRunPrepare` remain unchanged - The custom runtime image cache hasn't been manually invalidated #### Manual cache invalidation To invalidate the custom runtime image cache, go to your service detail in the Zerops GUI, choose **Pipelines & CI/CD settings** section from the left menu, and click on the button under **Pipeline #**. Then click on the **Clear runtime prepare image** button. Learn more about building custom runtime images: :::warning Do not include your application code in the custom runtime image, as your built application code is deployed automatically into fresh containers. Shared storage mounts are also not available during the runtime prepare phase. ::: ## Deploy phase ### Application artifacts After the [build phase](#build-phase) completes, Zerops stores the application artifact in internal storage and deletes the build container. For [manual deployments](#manual-deploy-using-zerops-cli) using Zerops CLI, the application artifact is also uploaded to internal storage. Zerops uses the stored artifact to deploy identical versions of your application whenever a new container starts: - During new application version deployments - When applications [scale horizontally](/features/scaling#horizontal-scaling-runtime-services-linux-containers-and-docker) - When runtime containers fail and new containers start automatically ### First deploy For initial deployments, Zerops starts one or more runtime containers based on your service [auto scaling settings](/features/scaling). Zerops executes these steps for each new container: 1. **Install runtime environment** - Sets up the runtime (or uses a custom runtime image if configured) 2. **Download application artifact** - Retrieves build output from internal storage 3. **Run initialization** - Executes optional [init commands](/zerops-yaml/specification#initcommands-) 4. **Start application** - Launches your app using the [start command](/zerops-yaml/specification#startcommands-) 5. **Check readiness** - Waits for [readiness check](/zerops-yaml/specification#readinesscheck-) to succeed (if configured) 6. **Activate container** - Container becomes active and receives incoming requests Services with multiple containers deploy in parallel. :::info If your application needs initialization in each runtime container, add [init commands](/zerops-yaml/specification#initcommands-) to `zerops.yaml`. ::: :::caution Do not use `initCommands` for runtime environment customization. See [how to build custom runtime images](#runtime-prepare-phase-optional). ::: ### Subsequent deploys For applications with existing running versions, Zerops starts new containers matching the count of existing containers. Zerops executes the same steps as the first deployment for each new container. Your service briefly contains both new and old versions during this process. Old containers are then removed from the project balancer to stop receiving new requests. The processes inside old containers terminate and Zerops gradually deletes all old containers. ### Readiness checks If your application is not ready to handle requests immediately after starting via the [start command](/zerops-yaml/specification#startcommands-), configure a [readiness check](/zerops-yaml/specification#readinesscheck-) in your `zerops.yaml`. When readiness checks are defined, Zerops: 1. **Starts your application** 2. **Performs readiness check** 3. **Waits and retries** - If check fails, waits 5 seconds and repeats step 2 4. **Activates container** - If check succeeds, marks container as active Runtime containers with pending readiness checks do not receive incoming requests - only active containers handle traffic. If readiness checks fail for 5 minutes, Zerops marks the container as failed, deletes it, creates a new container, and repeats the deployment process. **Readiness check types:** - `httpGet` - Succeeds when URL returns HTTP `2xx` status (5-second timeout, follows `3xx` redirects) - `exec.command` - Succeeds when command returns status code 0 (5-second timeout) Read the [runtime log](/nodejs/how-to/logs#runtime-log) to troubleshoot failed readiness checks. ## Manual deploy using Zerops CLI Start deploy-only pipelines using the [Zerops CLI](/references/cli). The [`zcli service deploy`](/references/zcli/commands#deploy) command uploads and deploys your application in Zerops. Use this when you have your own build process. For building applications in Zerops, use [continuous](#continuous-deployment) or [on-demand](#on-demand-deployment) deployment instead. ```sh Usage: zcli service deploy pathToFileOrDir [flags] Flags: --archive-file-path string If set, zCLI creates a tar.gz archive with the application code in the required path relative to the working directory. By default, no archive is created. --deploy-git-folder Sets a custom path to the zerops.yaml file relative to the working directory. By default zCLI looks for zerops.yaml in the working directory. -h, --help the service deploy command. --project-id string If you have access to more than one project, you must specify the project ID for which the command is to be executed. --service-id string If you have access to more than one service, you must specify the service ID for which the command is to be executed. --version-name string Adds a custom version name. Automatically filled if the VERSIONNAME environment variable exists. --working-dir string Sets a custom working directory. Default working directory is the current directory. (default "./") --zerops-yaml-path string Sets a custom path to the zerops.yaml file relative to the working directory. By default zCLI looks for zerops.yaml in the working directory. ``` `pathToFileOrDir` defines paths to directories and/or files relative to the working directory. The working directory defaults to the current directory and can be changed using the `--working-dir` flag. Place `zerops.yaml` in the working directory. :::info You can modify the deploy pipeline anytime by updating the `zerops.yaml` in your working directory. ::: ## Manage builds and deployments ### Cancel running build When you need to cancel an incorrect running build, use the Zerops GUI. Go to the service detail, open the running processes list, and click **Open pipeline detail**. Then click **Cancel build**. :::caution Build cancellation is only available before the build pipeline finishes. Once the build completes, deployment cannot be cancelled. ::: ### Application versions Zerops keeps the 10 most recent versions of your application in internal storage. Access the application versions list in Zerops GUI by going to service detail and choosing the **Pipelines & CI/CD settings** section from the left menu. The active version is highlighted - click the button below to show all archived versions. Access pipeline details from the additional menu. Pipeline details contain: - Pipeline configuration (`zerops.yaml`) used for the selected version - Build log (if available) - Prepare runtime log (if available) You can download the build artifact for selected versions or manually delete inactive versions. ### Restore an archived version Restore archived versions by choosing **Activate** from the additional menu. Zerops will deploy the selected version and archive the currently active version. Environment variables restore to their state from the last moment when the selected version was active.