What is Antithesis? How we’re different Problems we solve Security approach Demo Fintech Customer stories Working with Antithesis Contact us Backstory Leadership Careers Brand

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 and hostname. In the report, logging output will be listed under the hostname and if no hostname is supplied, it’ll be inferred, possibly from the container_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
  • Introduction
  • How Antithesis Works
  • Tutorial
  • Testing with Antithesis
  • Build and run an etcd cluster
  • Meet the Test Composer
  • User manual
  • Setup guide
  • Properties and Assertions
  • Properties in Antithesis
  • Assertions in Antithesis
  • Sometimes Assertions
  • Properties to Test For
  • Test Composer
  • Test Composer Basics
  • Test Composer Reference
  • Principles of Test Composition
  • Checking Test Templates Locally
  • Webhooks
  • Launching a test
  • Retrieving logs
  • Launching a debugging session
  • Webhook API
  • Reports
  • The triage report
  • Findings
  • Environment
  • Utilization
  • Properties
  • The bug report
  • Context, Instance, & Logs
  • Bug likelihood over time
  • Statistical debug information
  • Multiverse debugging
  • Overview
  • Exploring the multiverse
  • Querying with event sets
  • The Environment and its utilities
  • Using the Antithesis Notebook
  • Cookbook
  • The Environment and Multiverse
  • The Antithesis Environment
  • Fault Injection
  • CPUID
  • Reference
  • Handling External Dependencies
  • SDK reference
  • Go
  • Tutorial
  • Instrumentor
  • Assert (reference)
  • Lifecycle (reference)
  • Random (reference)
  • Java
  • Tutorial
  • Instrumentation
  • Assert (reference)
  • Lifecycle (reference)
  • Random (reference)
  • C
  • C++
  • Tutorial
  • C/C++ Instrumentation
  • Assert (reference)
  • Lifecycle (reference)
  • Random (reference)
  • JavaScript
  • Python
  • Tutorial
  • Assert (reference)
  • Lifecycle (reference)
  • Random (reference)
  • Rust
  • Tutorial
  • Instrumentation
  • Assert (reference)
  • Lifecycle (reference)
  • Random (reference)
  • .NET
  • Languages not listed above
  • Assert (reference)
  • Lifecycle (reference)
  • Tooling integrations
  • CI integration
  • Discord and Slack integrations
  • Configuring Antithesis
  • Instrumentation
  • User management
  • Sizing your deployment
  • Best practices
  • Docker best practices
  • Is Antithesis working?
  • Optimizing for Antithesis
  • Finding more bugs
  • FAQ
  • About Antithesis POCs
  • Release notes
  • Release notes