Docker best practices
Antithesis runs your system in our testing environment using the configurations in your docker-compose.yaml
file. For an overview of the process, please check out our setup guide.
Here are some best practices we suggest you follow to get the most out of your testing.
There’s an example docker-compose.yaml
file below with explanatory comments.
Dos
Set container names for all of your services
If you don’t set one, Antithesis generates a container name that may be of the form
antithesis-<service-name>-<number>
.
Use the same name for container and host names
It’s ideal to use the same name for
container_name
andhostname
. In the report, logging output will be listed under thehostname
and if nohostname
is supplied, it’ll be inferred, possibly from thecontainer_name
.
Configure service healthchecks
Docker can perform healthchecks, with timeouts and retries, on your services. Using this attribute is really convenient when configuring a system with dependencies – when one service depends on another service to be healthy before being started itself.
Configure the order of service startup and shutdown
Configure the
depends_on
attribute for services that have dependencies on other services.
Don’ts
Don’t change the default logging driver
If you specify a custom logging driver, Antithesis will generate logs as normal, but won’t display them in the debugging artifacts we send you.
Don’t use underscores in hostname
Per the standards for DNS domain names, underscores are not included in the permissible characters. Using underscores in the
hostname
can create issues in hostname resolution.
Don’t configure an internal network
If you do specify
internal: true
, your system will not be able to connect to the Antithesis network.
Don’t set a pull policy
Antithesis pulls all the container images before spinning up your system because there’s no internet access inside the testing environment. So, if you set a pull policy for your services that tries to pull images from a registry, it will fail.
Example docker-compose file
Here’s a docker-compose.yaml
with comments highlighting the above the points:
version: '3.8'
services:
etcd0:
image: 'docker.io/bitnami/etcd:3.5'
# Don't set a pull policy that forces to pull the image from a registry
# pull_policy: always
container_name: etcd0 # Set the container name
hostname: etcd0 # Use the same name for container_name and hostname and don't use _ in the hostname
environment:
ETCD_NAME: "etcd0"
ETCD_INITIAL_ADVERTISE_PEER_URLS: "http://etcd0:2380"
ETCD_LISTEN_PEER_URLS: "http://0.0.0.0:2380"
ETCD_LISTEN_CLIENT_URLS: "http://0.0.0.0:2379"
ETCD_ADVERTISE_CLIENT_URLS: "http://etcd0.etcd:2379"
ETCD_INITIAL_CLUSTER_TOKEN: "etcd-cluster-1"
ETCD_INITIAL_CLUSTER: "etcd0=http://etcd0:2380,etcd1=http://etcd1:2380,etcd2=http://etcd2:2380"
ETCD_INITIAL_CLUSTER_STATE: "new"
ALLOW_NONE_AUTHENTICATION: "yes"
healthcheck: # Configure Docker provided healthchecks for your services
test: ["CMD", "etcdctl", "endpoint", "health"]
interval: 5s
timeout: 5s
retries: 3
# Don't configure an internal network
# networks:
# - etcd-example
etcd1:
image: 'docker.io/bitnami/etcd:3.5'
container_name: etcd1 # Set the container name
hostname: etcd1 # Use the same value for container_name and hostname and don't use _ in the hostname
environment:
ETCD_NAME: "etcd1"
ETCD_INITIAL_ADVERTISE_PEER_URLS: "http://etcd1:2380"
ETCD_LISTEN_PEER_URLS: "http://0.0.0.0:2380"
ETCD_LISTEN_CLIENT_URLS: "http://0.0.0.0:2379"
ETCD_ADVERTISE_CLIENT_URLS: "http://etcd1.etcd:2379"
ETCD_INITIAL_CLUSTER_TOKEN: "etcd-cluster-1"
ETCD_INITIAL_CLUSTER: "etcd0=http://etcd0:2380,etcd1=http://etcd1:2380,etcd2=http://etcd2:2380"
ETCD_INITIAL_CLUSTER_STATE: "new"
ALLOW_NONE_AUTHENTICATION: "yes"
healthcheck:
test: ["CMD", "etcdctl", "endpoint", "health"]
interval: 5s
timeout: 5s
retries: 3
# Don't configure an internal network
# networks:
# - etcd-example
etcd2:
image: 'docker.io/bitnami/etcd:3.5'
container_name: etcd2 # Set the container name
hostname: etcd2 # Use the same value for container_name and hostname and don't use _ in the hostname
environment:
ETCD_NAME: "etcd2"
ETCD_INITIAL_ADVERTISE_PEER_URLS: "http://etcd2:2380"
ETCD_LISTEN_PEER_URLS: "http://0.0.0.0:2380"
ETCD_LISTEN_CLIENT_URLS: "http://0.0.0.0:2379"
ETCD_ADVERTISE_CLIENT_URLS: "http://etcd2.etcd:2379"
ETCD_INITIAL_CLUSTER_TOKEN: "etcd-cluster-1"
ETCD_INITIAL_CLUSTER: "etcd0=http://etcd0:2380,etcd1=http://etcd1:2380,etcd2=http://etcd2:2380"
ETCD_INITIAL_CLUSTER_STATE: "new"
ALLOW_NONE_AUTHENTICATION: "yes"
healthcheck:
test: ["CMD", "etcdctl", "endpoint", "health"]
interval: 5s
timeout: 5s
retries: 3
# Don't configure an internal network
# networks:
# - etcd-example
health-checker:
image: 'etcd-tutorial-health-checker:tutorial'
container_name: health-checker # Set the container name
# No hostname set because it will not be connected by any other services and this service will exit after publishing a setup_complete message
# hostname: health-checker
depends_on: # Docker will not start health-checker service until etcd0, etcd1, and etcd2 are marked as healthy
etcd0:
condition: service_healthy
etcd1:
condition: service_healthy
etcd2:
condition: service_healthy
entrypoint: ['/entrypoint.py']
# Don't configure an internal network
# networks:
# - etcd-example
client1:
image: 'etcd-tutorial-client:tutorial'
container_name: client1 # Set the container name
hostname: client1 # Use the same name for container_name and hostname and don't use _ in the hostname
entrypoint: "sleep infinity"
# Don't change the default logging driver as Antithesis relies on it. If you do specify a custom logging driver, Antithesis will generate logs as normal, but not display them in the debugging artifacts we send you.
# logging:
# driver: "local"
# Don't configure an internal network
# networks:
# - etcd-example
client2:
image: 'etcd-tutorial-client:tutorial'
container_name: client2 # Set the container name
hostname: client2 # Use the same name for container_name and hostname and don't use _ in the hostname
entrypoint: "sleep infinity"
# Don't configure an internal network
# networks:
# - etcd-example
# Don't configure an internal network. This prevents your system from connecting to the Antithesis network.
# networks:
# etcd-example:
# internal: true