Introduction
When building containerized applications with Docker Compose, the docker-compose.yaml file serves as the blueprint for defining services, networks, and volumes. A valid Compose file must adhere to both the YAML language specification and Docker Compose's schema. A malformed file can lead to startup failures or misconfigurations in Terraform Enterprise.
This article provides best practices for writing a valid docker-compose.yaml file, highlights common mistakes, and explains how to resolve them.
Prerequisites
This guide is intended for users who are:
- Migrating Terraform Enterprise from a Replicated installation to a Flexible Deployment Options (FDO) Docker deployment.
- Deploying Terraform Enterprise using FDO Docker.
- Familiar with the YAML data serialization language.
Best Practices for docker-compose.yaml
Follow Core YAML Syntax
YAML is sensitive to indentation and whitespace. Follow these fundamental rules:
- Indentation: Use spaces, not tabs. A consistent two-space indentation is the standard.
-
Key-Value Pairs: Separate keys and values with a colon and a space (
key: value). -
Lists: Denote list items with a dash and a space (
- item). -
Special Characters: If a value contains special characters (
: {} [] , & * # ? | - < > = ! % @ \), enclose it in quotes. -
Forcing Strings: To ensure a numeric value is treated as a string, enclose it in quotes (e.g.,
"10"). -
Escape Characters: Use single quotes (
'...') to prevent the interpretation of escape characters like\n.
Use Correct Quoting and Escaping
Properly escaping characters like backslashes (\) and dollar signs ($) is critical for passing literal values to the container.
| Goal |
docker-compose.yaml Syntax |
Result in Container | Notes |
|---|---|---|---|
Literal backslash \
|
'C:\Users\myuser' or "C:\\Users\\myuser"
|
C:\Users\myuser |
Single quotes are often simpler. |
Literal dollar sign $
|
mysecret$$key |
mysecret$key |
Double $$ escapes the dollar sign. |
| Reference environment variable |
$VAR_NAME or ${VAR_NAME}
|
Substituted at runtime | Docker Compose substitutes the variable. |
Pass literal $VAR_NAME
|
$$VAR_NAME or '$VAR_NAME'
|
$VAR_NAME |
Use $$ or single quotes to prevent substitution. |
Use the Correct Environment Variable Format
For the environment section, use the YAML mapping (key-value) style, not the list style. The mapping style correctly handles special characters and complex values.
-
Recommended (Mapping Style):
environment: TFE_HOSTNAME: "tfe.example.com" TFE_DATABASE_PASSWORD: 'MyP@ssw0rd$$2025\\Secure!'
-
Not Recommended (List Style):
## Avoid this format, as it can cause parsing issues with special characters. environment: - TFE_HOSTNAME=tfe.example.com - TFE_DATABASE_PASSWORD=MyP@ssw0rd$$2025\Secure!
Example Configuration
This example demonstrates a correctly structured docker-compose.yaml file. For complete, working examples, refer to the official documentation for Mounted Disk, External Services, and Active-Active modes.
name: terraform-enterprise
services:
tfe:
## Replace with a valid image tag, which requires a 'v' prefix (e.g., v202507-1).
image: images.releases.hashicorp.com/hashicorp/terraform-enterprise:v202507-1
## Use the recommended mapping style for environment variables.
environment:
## Double quotes are safe for most values.
TFE_HOSTNAME: "usingdoublequotes.tfe.io"
## Single quotes prevent shell interpretation of $, \, or !.
## The literal value passed to the container will be: MyP@ssw0rd$2025\Secure!
TFE_DATABASE_PASSWORD: 'MyP@ssw0rd$$2025\Secure!'
## Use the list format for ports.
ports:
- "80:80"
- "443:443"Common Issues and Symptoms
A malformed docker-compose.yaml file can cause startup checks to fail, often with timeout errors in the logs.
terraform-enterprise: check failed: name=upgrade duration=1m30.000494959s err="timeout: context deadline exceeded" terraform-enterprise: the following startup checks failed: checks=["database", "upgrade"] terraform-enterprise: startup: error="startup checks failed" INFO waiting for fluent-bit, logwatch, terraform-enterprise to die
Common causes include:
- Using
KEY=VALUEsyntax instead of the correct YAMLKEY: VALUEformat. - Improper quoting or escaping of special characters like
$and\.
Recommended Solutions
If you suspect your docker-compose.yaml is causing issues, use one of the following approaches to correct it.
Option 1: Refine an Exported Configuration
This approach is useful when migrating from a Replicated installation.
-
Export your current application configuration into a file.
$ docker exec -it terraform-enterprise tfectl app-config --format docker > docker-compose.yaml
- Create a new, clean
docker-compose.yamlfile using a standard HashiCorp example as a base: - Copy only the necessary, non-default settings from your exported file into the new file. Refer to the Terraform Enterprise Configuration Reference to identify default values that you can omit.
Option 2: Build from a Standard Template
Rebuilding your configuration from scratch is the most reliable way to ensure a valid file.
- Start with a fresh
docker-compose.yamlfile based on one of the official examples linked in Option 1. - Add your custom configuration settings one by one, referring to the Terraform Enterprise Configuration Reference to ensure you use the correct keys and value formats.
- Validate your syntax and indentation carefully as you build the file.