This document describes the Uffizzi Compose file that is used to define and preview multi-container applications on the Uffizzi platform. Based on Docker Compose, a Uffizzi Compose file is a structured YAML format that provides Uffizzi with configuration details needed to preview an application. Uffizzi Compose utilizes the Docker Compose custom extension field, x-uffizzi, to specify configuration options used by Uffizzi. This means that all Uffizzi Compose files are valid Docker Compose v3.9 files; however, the reverse is not necessarily true since Uffizzi only supports a subset of the full Docker Compose specification. This document describes all parameters that are supported by Uffizzi Compose and which are required or optional.
The Uffizzi Compose file is a YAML file defining services (required), configs, secrets, volumes, and x-uffizzi elements such as ingress (required). Other Compose top-level elements networks and version are not currently supported by Uffizzi. As a YAML file, a Uffizzi Compose should comply with the YAML Specification. It is recommended to name your Uffizzi Compose file docker-compose.uffizzi.yml (Note: You can use either the .yml or .yaml extension). At a minimum, a Uffizzi Compose file must include services and ingress (a sub-level element of x-uffizzi). Services are the containers that make up your application, and ingress tells Uffizzi which container should receive incoming HTTPS traffic. Ingress requires a service and port number that the service is listening on.
Docker Compose supports vendor-specific extensions for platforms like Uffizzi to supplement the Compose specification with parameters that are specific to that vendor's platform. For example, the Uffizzi extension, x-uffizzi, tells Uffizzi which service should receive incoming HTTP traffic:
x-uffizzi:
ingress:
service: web
port: 8080
The example above is valid Docker Compose syntax because the docker-compose CLI ignores any field prefixed with x-. This allows users to still run docker-compose config on a Uffizzi Compose file to check for valid Docker Compose format.
Info
The x- extension prefix works for both top-level and sub-level definitions within a compose file.
As with Docker Compose, a Service is an abstract definition of a computing resource within an application that can be combined with other components. Services are deployed as containers on Uffizzi. A valid services definition is required for a Uffizzi Compose file.
Ingress exposes HTTPS routes from outside your preview environment to your application services. Ingress requires a service and port number as parameters. A valid ingress definition is required for a Uffizzi Compose file.
Configs allow you to add configuration files to your applications. Configs are only supported in Uffizzi CI. If you use a different CI provider, you should use env_file. Config files are expected to be in the same git repository as your compose file. All file paths are relative from the root of the current repository. Configs are optional for Uffizzi Compose files.
Secrets provide a mechanism for supplying sensitive environment varialbes (such as passwords, secret keys, access tokens, etc.) to your application services. The environment variables are defined as name/value pairs and are injected at runtime. Secrets are optional for Uffizzi Compose files.
Volumes provide a way to persist data used by contaienrs in a given Uffizzi environment. Volumes will persist for the lifetime of a Uffizzi environment, and they are destroyed when the environment is destroyed. Uffizzi supports both empty volumes and host (i.e. non-empty) volumes. Empty volumes can be either named or anonymous. Host volumes are mounted from a host mount path.
This is an example Docker Compose file for Uffizzi CI. If you are using a different CI provider, see the Getting Started guide for building a Docker Compose template.
docker-compose.uffizzi.yml
# Uffizzi extensionx-uffizzi:ingress:# requiredservice:loadbalancerport:8080continuous_previews:deploy_preview_when_pull_request_is_opened:truedelete_preview_when_pull_request_is_closed:trueshare_to_github:true# Vote applicaitonservices:redis:image:redis:latestpostgres:image:postgres:9.6secrets:-pg_user-pg_passwordworker:build:.# defaults to ./Dockerfiledeploy:resources:limits:memory:250Mresult:build:context:https://github.com/UffizziCloud/example-voting-result#maindockerfile:Dockerfileenvironment:PORT:8088vote:build:context:https://github.com/UffizziCloud/example-voting-vote# defaults to "Default branch" as set in GitHub (usually main/master)dockerfile:Dockerfiledeploy:resources:limits:memory:250Menvironment:PORT:8888loadbalancer:image:nginx:latestconfigs:-source:nginx-vote-conftarget:/etc/nginx/conf.d/vote.conf# Loadbalancer configurationconfigs:nginx-vote-conf:file:./vote.conf# Postgres credentialssecrets:pg_user:external:true# indicates value is external to this repositoryname:"POSTGRES_USER"# i.e., value should be added in the Uffizzi Dashboardpg_password:external:true# indicates value is external to this repositoryname:"POSTGRES_PASSWORD"# i.e., value should be added in the Uffizzi Dashboard
Ingress exposes HTTPS routes from outside your preview environment to your application services. Ingress requires a service and port number as parameters. A valid ingress definition is required for a Uffizzi Compose file.
This section contains example configurations supported by an ingress definition.
Continuous Previews (CP) are an automation-enabled best practice that encourages cross-functional teams to continuously collaborate during the development process by providing feedback on features that are still in progress. With CP, git topic branches are previewed using on-demand test environments before they are merged into a downstream branch. Continuous Previews settings are optional for Uffizzi Compose.
When specified, the continuous previews policies are globally scoped, i.e. the policies apply to all services in the compose file. This behavior can be overrided with the service-level x-uffizzi-continuous-previews option).
This section contains example configurations supported by a continuous_previews definition.
This option is for Uffizzi CI only. If you are using a different CI provider, see the Getting Started guide for building a Docker Compose template.
Possible values: true, false
Uffizzi will setup webhooks on your git repositories to watch for open pull requests (PR). If a PR is opened, Uffizzi will build the commit and deploy a new preview.
This option is for Uffizzi CI only. If you are using a different CI provider, see the Getting Started guide for building a Docker Compose template.
Possible values: true, false
Should be used with deploy_preview_when_pull_request_is_opened.
Uffizzi will setup webhooks on your git repositories to watch for closed pull requests (PR). If a PR is closed, Uffizzi will destroy the preview associated with the corresponding commit.
Uffizzi will preview all images tagged with uffizzi_request_# where # is a pull request number. This is useful if you want Uffizzi to only preview images built from pull requests. To enable this behavior, set deploy_preview_when_image_tag_is_created: false, then configure your build system or CI/CD tool to tag images generated from pull requests with the uffizzi_request_# tag.
If delete_preview_when_pull_request_is_closed is also specified, Uffizzi will delete the preview based on whichever event (timeout or closed PR) happens first.
Configuration options that are applied at build time. In each example below, the default build context is Dockerfile, unless otherwise specified.
build can be specified either as a string containing a path to the build context:
services:webapp:build:./dir
Here the build context is implied to be Dockerfile (i.e. Uffizzi expects that ./dir/Dockerfile exists).
Or, a build can be an object with the path specified with context. The path can be local (i.e., within the same file system or repository as the Uffizzi Compose file):
Scope of build-args In your Dockerfile, if you specify ARG before the FROM instruction, ARG is not available in the build instructions under FROM. If you need an argument to be available in both places, also specify it under the FROM instruction. Refer to the understand how ARGS and FROM interact section in the documentation for usage details.
configs is only supported in Uffizzi CI. If you use an external CI provider, such as GitHub Actions, GitLab CI, or CircleCI, it is recommended that you pass configuration files using env_file instead. In this example, an environment variable LOKI_CONFIG is stored by your CI provider:
The short syntax variant only specifies the config name. This grants the container access to the config and mounts it at / within the container. The source name and destination mountpoint are both set to the config name.
The following example uses the short syntax to grant the redis service access to the my_config resource. The value of my_config is set to the contents of the file ./my_config.txt.
Auto deploys updates to an existing preview—either a new commit in the git repository or the deployed tag is updated. If this parameter is missing, Uffizzi will auto-deploy updates to repositories or images by default.
x-uffizzi-auto-deploy-updates is only supported in Uffizzi CI. If you use an external CI provider, such as GitHub Actions, GitLab CI, or CircleCI, deployment updates should be configured by your provider's event triggers. For example, in GitHub Actions this can be defined with push, pull_request and types:
Setting entrypoint both overrides any default entrypoint set on the service’s image with the ENTRYPOINT Dockerfile instruction, and clears out any default command on the image - meaning that if there’s a CMD instruction in the Dockerfile, it is ignored.
Add environment variables as an array. Any boolean values (true, false, yes, no) need to be enclosed in quotes to ensure they are not converted to True or False by the YML parser.
Healthchecks let Uffizzi know when to restart a container. For example, a healthcheck could catch a deadlock, where an application is running, but unable to make progress. Restarting a container in such a state can help to make the application more available despite bugs.
When a healthcheck fails, Uffizzi will try retries times before giving up. Giving up means restarting the container. Defaults to 3. Minimum value is 1.
Specify the image to start the container from, as repository:tag. If no tag is specified, default is latest. If no registry is specified, default is hub.docker.com.
services:cache:image:redis:latest# Defaults to hub.docker.com
Uffizzi CI supports major cloud registries, as noted below. If you use an external CI provider with Uffizzi, such as GitHub Actions, GitLab CI, CircleCI, etc., you can deploy images from any registry that implements the generic Docker Registry HTTP API V2 protocol, including:
If you use Uffizzi CI, you must first add your registry credentials in the Uffizzi UI (Settings > Integrations). You do not need to provide Docker Hub credentials to pull public images from hub.docker.com.
Grant access to secrets on a per-service basis using the per-service secrets configuration. Uffizzi Compose currently supports the secrets short syntax only.
Important
secrets are only supported in Uffizzi CI. If you use an external CI provider, such as GitHub Actions, GitLab CI, or CircleCI, it is recommended that you pass secrets using environment instead.
Secrets are name/value pairs that provide a mechanism for securing and sharing environment variables across all services in a stack. The secret name/value pairs must be added in the Uffizzi Dashboard (UI).
In the following example, pg_user and pg_password are references to secrets invoked in the top-level secrets key. POSTGRES_USER and POSTGRES_PASSWORD are the names of secrets that have been added in the Uffizzi Dashboard. Their respective values are injected into the db service container once the stack is deployed.
Secrets should be stored as secrets using your external CI provider's interface abd referenced in your compose file using the environment element with variable substitution. In the following example, PG_USER and PG_PASSWORD are stored using GitHub Actions secrets and referenced using variable substitution in a Docker Compose template.
volumes defines mount host paths or named volumes, specified as sub-options to a service.
If the mount is a host path and only used by a single service, it may be declared as part of the service definition instead of the top-level volumes key.
To reuse a volume across multiple services, a named volume must be declared in the top-level volumes key.
This example shows a named volume (share_db) being used by the web service, and a bind mount defined for a single service
The short syntax uses the generic [SOURCE:]TARGET[:MODE] format, where SOURCE can be either a host path or volume name. TARGET is the container path where the volume is mounted. Standard modes are ro for read-only and rw for read-write (default).
volumes:# Anonymous volume. Just specify a path and let Uffizzi create a volume-/var/lib/mysql# Anonymous volume with read-only access-/var/lib/mysql:ro# Named volume-data_volume:/var/lib/mysql# Named volume with read-only access-shared_db:/var/lib/mysql:ro# Host volume -./db/mysql:/var/lib/mysql# Host volume with read-only access-./db/mysql:/var/lib/mysql:ro
The long form syntax allows the configuration of additional fields that can’t be expressed in the short form.
source: the source of the mount, a path on the host for a bind mount, or the name of a volume defined in the top-level volumes key. Not applicable for a tmpfs mount. target: the path in the container where the volume is mounted read_only: flag to set the volume as read-only
An option for specifying continuous previews policies per service. This option overrides global continuous_previews policies for the service where it is specified.
In this example, a preview will be triggered when a new tag is created for frontend but not for backend. This is because the continuous previews policies are set to false within the backend service definition, which overrides the global policies. The frontend service definition contains no such override, so continuous previews will still be enabled for frontend.
Uffizzi will setup webhooks on your git repositories to watch for open pull requests (PR). If a PR is opened, Uffizzi will build the commit and deploy a new preview.
This parameter can be used as a standalone option:
In this example, a preview will not be deployed when a pull request is opened on the example/foo repository because deploy_preview_when_pull_request_is_open : false overrides the global setting. However, an open pull request on example/bar repository will still trigger a new preview.
Should be used with deploy_preview_when_pull_request_is_opened.
Uffizzi will setup webhooks on your git repositories to watch for closed pull requests (PR). If a PR is closed, Uffizzi will destroy the preview associated with the corresponding commit.
This parameter can be used as a standalone option:
In this example, foo will not be deleted when the pull request is closed because delete_preview_when_pull_request_is_closed : false overrides the global setting.
Uffizzi will preview all images tagged with uffizzi_request_# where # is a pull request number. This is useful if you want Uffizzi to only preview images built from pull requests. To enable this behavior, set deploy_preview_when_image_tag_is_created: false, then configure your build system or CI/CD tool to tag images generated from pull requests with the uffizzi_request_# tag.
The top-level configs declaration defines configs that can be granted to the services in this stack. The source of the config is a file (external source is currently not supported).
configs is only supported in Uffizzi CI. If you use an external CI provider, such as GitHub Actions, GitLab CI, or CircleCI, it is recommended that you pass configuration files using env_file instead. In this example, an environment variable LOKI_CONFIG is stored by your CI provider:
A top-level reference to secrets that can be granted to the services in a stack.
Important
Top-level secrets is only supported in Uffizzi CI. If you use an external CI provider, such as GitHub Actions, GitLab CI, or CircleCI, it is recommended that you pass secrets using environment instead.
Secrets are name/value pairs that provide a mechanism for securing and sharing environment variables across all services defined in the compose file. The source of the secret must be added in the Uffizzi Dashboard and invoked with external and secret name. If the external secret does not exist, you will see a secret-not-found error message in the Uffizzi Dashboard.
external: Indicates that the secret object (a name/value pair) is declared in the Uffizzi Dashboard (UI). Value must be true.
name: The name of the secret object in Uffizzi.
In the following example, POSTGRES_USER and POSTGRES_PASSWORD are the names of secrets that have been added in the Uffizzi Dashboard. Their respective values are available to the db service once the stack is deployed.
Secrets should be stored as secrets using your external CI provider's interface and referenced in your compose file using the environment element with variable substitution. In the following example, PG_USER and PG_PASSWORD are stored using GitHub Actions secrets and referenced using variable substitution in a Docker Compose template.
While it is possible to declare volumes on the fly as part of the service declaration, this section allows you to create named volumes that can be reused across multiple services.
Here’s an example of a two-service setup where a database’s data directory is shared with another service as a volume so that it can be periodically backed up: