Porter has a hierarchical configuration system that loads configuration values in the following precedence order:

  • Flags (highest)
  • Environment Variables
  • Config File (lowest)

You may set a default value for a configuration value in the config file, override it with an environment variable, and then override both for a particular command with a flag.


Nearly all of Porter’s configuration, except global configuration such as secret accounts, storage accounts, or telemetry, are configurable by flags. Use the porter help command to view available flags.

Environment Variables

Flags have corresponding environment variables that you can use so that you don’t need to manually set the flag every time. The flag will default to the value of the environment variable, when defined. Global configuration settings can also be specified with an environment variable. For example, the experimental config file setting maps to PORTER_EXPERIMENTAL, and accepts a comma-separated list of values.

--flag maps to the environment variable of PORTER_FLAG. Dashes in the flag name are represented as underscores in the environment variable name. So --another-flag maps to the environment variable PORTER_ANOTHER_FLAG

For example, you can set PORTER_OUTPUT=json and then all subsequent porter commands will act as though the --output=json flag was passed.

Config File

Porter’s configuration file is located in the PORTER_HOME directory, by default ~/.porter/. The file name should be config.FILE_EXTENSION, where the file extension can be json, toml, yaml, or hcl. For example, If you defined the configuration in YAML, the file is named config.yaml.

Do not embed sensitive data in the configuration file. Instead, use templates to inject environment variables or secrets in the configuration file. Environment variables are specified with ${env.NAME}, where name is case-sensitive. Secrets are specified with ${secret.KEY} and case sensitivity depends upon the secrets plugin used.

Below is an example configuration file in TOML:

# ~/.porter/config.toml

# Set the default namespace
namespace = "dev"

# Include debug logs
debug = true

# Include debug logs from the plugins
debug-plugins = true

# Default command output to JSON
output = "json"

# Allow all bundles access to the Docker Host
allow-docker-host-access = true

# Enable experimental features
experimental = ["flagA", "flagB"]

# Use Docker buildkit to build the bundle
build-driver = "buildkit"

# Use the storage configuration named devdb
default-storage = "devdb"

# When default-storage is not set, use the mongodb-docker plugin.
# This mode does not support additional configuration for the plugin.
# If the plugin requires configuration, use default-storage and define
# the configuration in the storage section.
default-storage-plugin = "mongodb-docker"

# Use the secrets configuration named mysecrets
default-secrets = "mysecrets"

# When default-secrets is not set, use the kubernetes.secret plugin.
# This mode does not support additional configuration for the plugin.
# If the plugin requires configuration, use default-secrets and define
# the configuration in the secrets section.
default-secrets-plugin = "kubernetes.secret"

# Defines storage accounts
  # The storage account name
  name = "devdb"

  # The plugin used to access the storage account
  plugin = "mongodb"

  # Additional configuration for storage account
  # These values vary depending on the plugin used
    # The mongodb connection string
    url = "${secret.porter-db-connection-string}"
    # Timeout for database queries
    timeout = 300

# Define secret store accounts
  # The secret store name
  name = "mysecrets"
  # The plugin used to access the secret store account
  plugin = "azure.keyvault"

  # Additional configuration for secret store account
  # These values vary depending on the plugin used
    # The name of the secret vault
    vault = "topsecret"
    # The subscription where the vault is defined
    subscription-id = "${env.AZURE_SUBSCRIPTION_ID}"

# Log command output to a file in PORTER_HOME/logs/
  # Log command output to a file
  log-to-file = true

  # When structured is true, the logs printed to the console 
  # include a timestamp and log level
  structured = false

  # Sets the log level for what is written to the file
  # Allowed values: debug, info, warn, error
  level = "info"

# Send trace and log data to an Open Telemetry collector
  # Enable trace collection
  enabled = true

  # Send telemetry via the grpc protocol
  # Allowed values: http/protobuf, grpc
  protocol = "grpc"

  # The Open Telemetry collector endpoint
  endpoint = ""

  # Specify if the collector endpoint is secured with TLS
  insecure = true

  # Specify a certificate to connect to the collector endpoint
  certificate = "/home/me/some-cert.pem"

  # The compression type used when communicating with the collector endpoint
  compression = "gzip"
  # The timeout enforced when communicating with the collector endpoint
  timeout = "3s"

  # The timeout enforced when establishing a connection with the collector endpoint
  start-timeout = "100ms"

  # Used for testing that porter is emitting spans without setting up an open telemetry collector
  redirect-to-file = false

  # Additional headers to send to the open telemetry collector
    environment = "dev"
    owner = "myusername"

Experimental Feature Flags

Porter sometimes uses feature flags to release new functionality for users to evaluate, without affecting the stability of Porter. You can enable an experimental feature by:

  • Using the experimental global flag --experimental flagA,flagB. The value is a comma-separated list of strings.
  • Setting the PORTER_EXPERIMENTAL environment variable like so PORTER_EXPERIMENTAL=flagA,flagB. The value is a comma-separated list of strings.
  • Setting the experimental field in the configuration file like so experimental = [“flagA”,“flagB”]. The value is an array of strings.

Build Drivers

The build-drivers experimental feature flag is no longer active. Build drivers are enabled by default and the only available driver is buildkit.

The docker driver uses the local Docker host to build a bundle image, and run it in a container. To use a remote Docker host, set the following environment variables:

  • DOCKER_HOST (required)
  • DOCKER_TLS_VERIFY (optional)
  • DOCKER_CERTS_PATH (optional)

Structured Logs

The structured-logs experimental feature flag is no longer active. Use the trace and logs configuration sections below to configure how logs and telemetry should be collected.


Porter can be configured to write a logfile for each command.

The following log settings are available:

Setting Environment Variable Description
logs.log-to-file PORTER_LOGS_LOG_TO_FILE Specifies if a logfile should be written for each command.
logs.structured PORTER_LOGS_STRUCTURED Specifies if the logs printed to the console should include a timestamp and log level
logs.level PORTER_LOGS_LEVEL Filters the logs to the specified level and higher. The log level controls both the logs written to file, and the logs output to the console when porter is run. Allowed values are: debug, info, warn, error.


Porter supports the OpenTelemetry specification for exporting trace data.

Porter automatically uses the standard OpenTelemetry environment variables to configure the trace exporter.

Setting Environment Variable Description
telemetry.enabled PORTER_TELEMETRY_ENABLED Enables telemetry collection. Defaults to false.
The protocol used to connect with the telemetry server. Either grpc or http/protobuf. Defaults to http/protobuf.
The endpoint where traces should be sent. Defaults
If true, TLS is not used, which is useful for local development and self-signed certificates.
Path to the PEM formatted certificate to use with the endpoint.
Supported values are: gzip. Defaults to no compression.
A timeout to use with the telemetry server, in Go duration format. For example, 30s or 1m.
A map of key/value pairs that should be sent as headers to the telemetry server.

Below is a sample Porter configuration file that demonstrates how to set each of the telemetry settings:

  enabled = true
  protocol = "grpc"
  endpoint = ""
  insecure = true
  certificate = "/home/me/some-cert.pem"
  compression = "gzip"
  timeout = "3s"
  start-timeout = "100ms"

    environment = "dev"
    owner = "me"

Common Configuration Settings

Some configuration settings are applicable to many of Porter’s commands and to save time you may want to set these values in the configuration file or with environment variables.


--namespace specifies the current namespace. It is set with the PORTER_NAMESPACE environment variable.

namespace = "dev"


--debug is a flag that is understood not only by the porter client but also the runtime and most mixins. They may use it to print additional information that may be useful when you think you may have found a bug, when you want to know what commands they are executing, or when you need really verbose output to send to the developers. It is set with the PORTER_DEBUG environment variable.

debug = true

Debug Plugins

--debug-plugins controls if logs related to communication between porter and its plugins should be printed when debugging. This can be very verbose, so it is not turned on by default when debug is true. It is set with the PORTER_DEBUG_PLUGINS environment variable.

debug-plugins = true


--output controls the format of the command output printed by porter. It is set with the PORTER_OUTPUT environment variable. Each command supports a different set of allowed outputs though usually there is some combination of: plaintext, json, and yaml.

output = "json"

Allow Docker Host Access

--allow-docker-host-access controls whether the local Docker daemon or host should be made available to executing bundles. It is set with the PORTER_ALLOW_DOCKER_HOST_ACCESS environment variable.

This flag is available for the following commands: install, upgrade, invoke, and uninstall. When this value is set to true, bundles are executed in a privileged container with the docker socket mounted. This allows you to use Docker from within your bundle, such as docker push, docker-compose, or docker-in-docker.

🚨 There are security implications to enabling access! You should trust any bundles that you execute with this setting enabled as it gives them elevated access to the host machine.

⚠️️ This configuration setting is only available when you are in an environment that provides access to the local docker daemon. Therefore, it does not work with the Azure Cloud Shell driver.

Schema Check

The schema-check configuration file setting controls Porter’s behavior when the schemaVersion of a resource does not match Porter’s supported version. By default, Porter requires that a resource’s schemaVersion field exactly matches the supported version. In some cases, such as when migrating to a new version of Porter, it may be helpful to use a less strict version comparison. Allowed values are:

  • exact - Default behavior. Require that the schemaVersion on the resource exactly match Porter’s supported version. If it doesn’t match, the command will fail.
  • minor - Require that the MAJOR.MINOR portion of the schemaVersion on the resource match Porter’s supported version. For example, a bundle with a schemaVersion of 1.2.3 would work even though the supported version is 1.2.5.
  • major - Require that the MAJOR portion of the schemaVersion on the resource match Porter’s supported version. For example, a bundle with a schemaVersion of 1.2.3 would work even though the supported version is 1.3.0.
  • none - Only print a warning when the schemaVersion does not exactly match the supported version.

Porter can only guarantee correct parsing of the file when the schemaVersion exactly matches. Depending on what has changed between schema versions, you can make a judgement call on if those changes are relevant to your situation.