> ## Docker Compose setup guide

> Set up your software for testing in our Docker environment. Package your system, push images, and run your first test.

> Fetch the complete documentation index at: https://antithesis.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

---

This is a step-by-step guide to packaging your software, pushing it to the Antithesis registry, and running it in our Docker environment.

If you're a Docker user, follow this guide. If you're already running your software with Kubernetes, follow the [Kubernetes setup guide](/docs/getting_started/setup_guide/setup_k8s/) instead.

If you're trying to learn to use Antithesis, our [tutorials](/docs/getting_started/tutorials/) walk you through it.

## Before you do anything else

1. Make sure you have a container registry and credentials -- or [contact us](/docs/faq/poc_faq/) to request them.

2. Antithesis runs your software using Linux container images, much as Docker and Kubernetes do. So it's helpful to have some understanding of:
   - [Docker](https://docs.docker.com)
   - Your software's dependencies

3. Antithesis runs your system in a hermetic simulation environment -- meaning **no internet access** at all. Anything your system needs must either be packaged into the environment or mocked appropriately.

**Need help?**

If you run into trouble, or simply want to make sure your testing is as thorough as possible, our solutions engineering team would be happy to help -- email us at support@antithesis.com or [join our Discord](https://discord.com/invite/antithesis).

> **Note**

## Containerize your software

You'll package your software and its dependencies and upload them to the Antithesis registry. If you're already deploying with containers, read this tip, then jump to the next step.

> **Tip**

For example, DON'T do this:

```docker
FROM docker.io/ubuntu:24.04
COPY src/my_app /opt/my_app
CMD curl --fail https://example.com/data > /opt/data && /opt/my_app /opt/data
```

DO this instead:

```docker
FROM docker.io/ubuntu:24.04
COPY src/my_app /opt/my_app
RUN curl --fail https://example.com/data > /opt/data
CMD /opt/my_app /opt/data
```

If this is your first time containerizing software, here's a basic example to get you started:

Create a [Dockerfile](https://docs.docker.com/get-started/docker-concepts/building-images/writing-a-dockerfile/) in the root directory of your project to containerize it. Your structure might look like this:

```shell
my_project/
  src/
    my_app/
    ..
  Dockerfile
```

Build a Docker image for your software, compiled for x86-64 CPUs. Be sure to replace `<image-name>` and `<tag-name>` appropriately.

```shell
$ docker build --platform linux/amd64 . -t <image-name>:<tag-name>
```

> **Note**

## Containerize your dependencies

Since there's no internet access inside the Antithesis environment, all of your software's dependencies need to be deployed alongside it.

There are two ways to do this.

1. Deploy the actual service, just as you would in production.
2. Upload a mock of the service.

### Deploy the actual service

If the dependency is something you control, e.g. a local database node, follow [the previous step](#containerize-your-software) to build a container image. You'll upload it to the Antithesis registry along with your software.

For third-party services, many open-source tools (like Redis, Kafka, MongoDB, MySQL, etc.) are already hosted on public registries such as [Docker Hub](https://hub.docker.com/) or [Quay](https://quay.io/). If so, you can simply specify the registry and image when setting up [orchestration](#set-up-container-orchestration).

### Upload a mock

If a third-party dependency doesn't offer a public container image, you'll need a mock of the service. Many companies provide mocks in containerized form (e.g. Stripe provides [Stripe-mock](https://github.com/stripe/stripe-mock)), and third-party providers, e.g. [Localstack](https://www.localstack.cloud/), provide sophisticated pre-built mocks of common dependencies like AWS. Treat these like any other open-source, containerized dependency and specify the registry and image when setting up [orchestration](#set-up-container-orchestration).

[Handling external dependencies](/docs/reference/dependencies/) offers more details, and a list of commonly used mocks.

## Set up container orchestration

We expect you to deliver a container image that contains a specific directory structure of what to run. We call this the `config` image.

In this image, include:

- Any configuration files expected by the containers: license files, settings, environment variables file, or other resources.
- A container orchestration file, `docker-compose.yaml`.

The `docker-compose.yaml` file in this directory lists each of the services you want to have running, the container image that the service should be started from, any external volumes that should be mounted into that container, and other options.

Here's an example `docker-compose.yaml` which uses a `.env` file to declare environment variables. Docker compose offers [multiple ways to set environment variables](https://docs.docker.com/compose/how-tos/environment-variables/set-environment-variables/) within your containers.

```bash
# env variables
POSTGRES_ROOT_PASSWORD=your_root_password
POSTGRES_DATABASE_NAME=your_database_name
POSTGRES_USERNAME=your_user_name
POSTGRES_PASSWORD=your_user_password
```

```yaml
version: '3.0'

services:
  application1:
    container_name: application1
    hostname: application1
    image: mycompany/my_app_1:my_tag

  application2:
    container_name: application2
    hostname: application2
    image: mycompany/my_app_2:my_tag

  database:
    container_name: database
    hostname: database
    image: docker.io/library/postgres:17.2
    environment:
      POSTGRES_ROOT_PASSWORD: ${POSTGRES_ROOT_PASSWORD}
      POSTGRES_DATABASE: ${POSTGRES_DATABASE_NAME}
      POSTGRES_USER: ${POSTGRES_USERNAME}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - ./volumes/database:/usr/bin/database/data
```

> **Note**

> **Warning**

This is often the trickiest part of the process for users who don't already deploy software in containers. If you simply follow the example above, you should be on solid ground, but if you run into trouble, here are a few resources you might find helpful:

- [Official Docker Compose documentation](https://docs.docker.com/compose/)
- [Our Docker best practices guide](/docs/best_practices/docker_best_practices/)
- Or you can email us at support@antithesis.com

Here are the contents of our example `config` directory:

```shell
$ ls -a config/
.
..
docker-compose.yaml
license
```

### Test your setup locally

To test your container orchestration locally, from inside your config directory, run:

```shell
$ docker-compose up
```

This should produce a running system.

However, we want to test that this all still works **without any access to the internet**. If you're on a Linux machine, first enter a network namespace before running the command:

```shell
$ pwd
/home/user/config

$ unshare -n

[2] $ docker-compose up
...
[Lots of output]
...
```

If everything still comes up and works, and your services all find each other, then the hardest part is done!

When pushing your container images to our registry, you'll also send us the `config` image.

To build a `config` image, copy all configuration files and add them to a [scratch image](https://docs.docker.com/develop/develop-images/baseimages/#create-a-simple-parent-image-using-scratch).

```docker
FROM scratch
COPY docker-compose.yaml /docker-compose.yaml
```

Now you'll need to add a test template to make it go.

## Provide a basic test template

To test your system and find bugs, Antithesis needs to exercise your software. We do this using a test template -- code that makes your software do something. There's a lot you can do with test templates (see [Test composition](/docs/product/test_templates/) or [our tutorial on this](/docs/getting_started/tutorials/docker_compose/cluster-test/) for more), but to test your setup, you can use one of your existing integration tests.

To do this, use the following naming conventions to enable Antithesis to detect and run your test. These conventions should be followed exactly.

1. Create a directory called `/opt/antithesis/test/v1/quickstart` in any of your containers.

2. Paste an existing integration test into an executable named `singleton_driver_<your_test_name>.<extension>` in the directory you just created. Make sure your executable has an appropriate shebang in the first line, e.g. `#!/usr/bin/env bash`

Now you'll need to validate that your system can find the test template you just defined -- [details here](/docs/product/test_templates/testing_locally/). The easiest way to do this is to call `docker compose exec` on your test command and see if it runs.

```shell
$ docker compose exec <your_service_name> /opt/antithesis/test/v1/quickstart/singleton_driver_<your_test_name>
```

## Add a ready signal for fuzzing

Before running any tests, Antithesis initializes your software and its dependencies. Once your system is up and running, it should emit a `setup_complete` message to initiate testing.

> **Important**

> **Warning**

[Our SDKs](/docs/reference/sdk/) provide pre-built ways to emit this message. If you cannot use our SDKs, write the following [JSONL](https://jsonlines.org/) message to `$ANTITHESIS_OUTPUT_DIR/sdk.jsonl` -- in our environment, we'll ensure that this variable and the directory it points to always exist.

```json
{"antithesis_setup": { "status": "complete", "details": {"message": "Set up complete - ready for testing!" }}}
```

> **Note**

Now that you've added a test template and enabled your software to tell Antithesis to begin fault injection, you're ready to deploy to the Antithesis environment for testing!

## Push your images

When you become a customer, we configure a container registry for you and send you a credential file `$TENANT_NAME.key.json`.

To authenticate to your container registry, run the following command:

```shell
$ cat $TENANT_NAME.key.json | docker login -u _json_key https://us-central1-docker.pkg.dev --password-stdin
```

Now you're locally authenticated to the registry and can run all other Docker commands as normal.

Push your **custom** and **non-public** images (including your config image) to: `us-central1-docker.pkg.dev/molten-verve-216720/$TENANT_NAME-repository/`.

For example, if your local image is named `my_app`, you'd tag it as it's referenced in your `docker-compose.yaml` and push it as follows:

```shell
$ docker tag my_app:my_tag us-central1-docker.pkg.dev/molten-verve-216720/$TENANT_NAME-repository/my_app
$ docker push us-central1-docker.pkg.dev/molten-verve-216720/$TENANT_NAME-repository/my_app:my_tag
```

Images that are publicly available (e.g. `docker.io/library/postgres:17.2`) can be referenced directly in your config files, you do not need to copy them into the Antithesis registry.

## Run your first test

You can use this webhook endpoint to kick off a test run using the username and password we sent you when you became a customer.

```bash
curl --fail -u 'user:password' \
-X POST https://<tenant>.antithesis.com/api/v1/launch/basic_test \
-d '{"params": { "antithesis.description":"basic_test on main",
    "antithesis.duration":"30",
    "antithesis.config_image":"config_image_with_tag",
    "antithesis.images":"my_images_with_version_list",
    "antithesis.report.recipients":"foo@email.com;bar@email.com"
    } }'
```

- All container images mentioned in `docker-compose.yaml` will be automatically pulled into the testing environment.
- Images needed for setup but not mentioned in `docker-compose.yaml` should be passed in the `antithesis.images` parameter with an image name and tags/digests.  If it's public image, include a full path to the image (eg. `"antithesis.images":"docker.io/library/postgres:17.2"`).
- **Do not** pass the config image in `antithesis.images`; it should only be passed to `antithesis.config_image`.
- Consult the [endpoint reference](/docs/reference/webhook/test_webhook/#parameters) for more details.

> **Warning**

Since you're just learning the ropes here, we've set Antithesis up to test for 30 minutes, but once you're up and running you'll be able to specify a longer testing duration. You can also get results through other channels, e.g. via a [Slack or Discord integration](/docs/product/tooling_integrations/discord_slack/).

## Review the triage report

Within an hour, you'll receive an email with a link to a [triage report](/docs/product/reports/). We suggest you read about the triage report and test properties while you wait!

Congratulations -- you're now set up with Antithesis!

From here, we suggest:

- Reading the [Properties and Assertions](/docs/concepts/properties_assertions/overview/) section to understand some of the core concepts behind Antithesis testing.
- Trying the [Test Composer tutorial](/docs/getting_started/tutorials/docker_compose/cluster-test/) for a ground-up guide to iterating on your testing.
- Reading the [SDK docs](/docs/reference/sdk/) to integrate the relevant SDK with your code.

Later on, you'll probably also want to [configure your CI system](/docs/product/tooling_integrations/ci/) to automate the process of building your software and kicking off webhooks.
