# Docker Compose

This walkthrough will show you two methods of using CloudTruth to pass environment variables to a Docker container with Docker Compose. The first method uses an environment file and the second method uses the CloudTruth run command.

* Method 1: [Docker Compose Environment File](#docker-compose-environment-file)
  * Good for injecting environment variables into a container
* Method 2: [Docker Compose with CloudTruth Run](#docker-compose-with-cloudtruth-run)
  * Good for injecting environment variables into a container
* [#method-3-docker-compose-with-init-container](#method-3-docker-compose-with-init-container "mention")
  * Good for rendering templates as files in a container

## Prerequisites

* Working knowledge of Docker and Docker-Compose.
* You have created one or more [CloudTruth Parameters](https://docs.cloudtruth.com/configuration-management/parameters/parameter-management/managing-parameters).
* You have created a [CloudTruth API token](https://docs.cloudtruth.com/configuration-management/integrations/..#api-tokens).

## Method 1: Docker Compose Environment File

You can also use CloudTruth Parameters with Docker Compose by using [`env_file`](https://docs.docker.com/compose/environment-variables/#the-env_file-configuration-option) and creating an Environment file with CloudTruth CLI `cloudtruth parameter export docker`.

Inside your Docker folder create an environment file with the CloudTruth CLI.

```
 cloudtruth --project MyFirstProject parameter export docker > dotenv
```

Create a `Dockerfile` with the following contents.

```
FROM alpine
CMD ["printenv"]
```

With the Dockerfile that you created above, create a new container image called `cloudtruth`

```
docker build -t cloudtruth .
```

Create a `docker-compose.yml` and copy the following snippet. The `env_file` specified will import all environment variables to use with Docker compose.

```
services:
  app:
    build: .
    image: cloudtruth
    container_name: ct-test
    env_file:
      - dotenv
```

Issuing the following command will build the Docker container and issue the `printenv` command which will display all of the parameters passed in the dotenv file that are now sourced and available to use within your Docker environment.

```
docker-compose up
```

You'll see an output to the terminal with your parameters, similar to the output below.

```
Creating ct-test ... done
Attaching to ct-test
ct-test | PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ct-test | HOSTNAME=16569452923f
ct-test | FLASK_APP=flaskdemo.py
ct-test | FLASK_DEBUG=True
ct-test | FLASK_ENV=development
ct-test | FLASK_MESSAGE=Configuration Management for Default
ct-test | FLASK_RUN_HOST=0.0.0.0
ct-test | FLASK_RUN_PORT=3000
ct-test | HOME=/root
ct-test exited with code 0
```

####

#### Passing variables using the --env-flag file

Alternatively, the created `dotenv` file can be passed to Docker-Compose with the `--env-file` flag. This allows you to [set specific variables](https://docs.docker.com/compose/environment-variables/#set-environment-variables-in-containers) for your app in `docker-compose.yml`.

```
services:
  app:
    build: .
    image: cloudtruth
    container_name: ct-test
    environment: 
      - FLASK_ENV    
```

Now you pass the `--env-file` where only the specified variables are displayed.

```
docker-compose --env-file dotenv up
```

```
Starting ct-test ... done
Attaching to ct-test
ct-test | PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ct-test | HOSTNAME=ac37b482be46
ct-test | FLASK_ENV=development
ct-test | HOME=/root
ct-test exited with code 0 
```

## Method 2: Docker Compose with CloudTruth Run

This method will use the cloudtruth CLI to add CloudTruth parameters to the environment docker-compose runs in, allowing you to inject the values into the services controlled by docker-compose.

Create a `Dockerfile` with the following contents.

```
FROM alpine
CMD ["printenv"]
```

The `docker-compose.yml` allows you to [set specific variables](https://docs.docker.com/compose/environment-variables/#set-environment-variables-in-containers) for your app. For example, you can create variables/parameters for a Flask app, which are created in CloudTruth.

```
services:
  app:
    build: .
    image: cloudtruth
    container_name: ct-test
    environment: 
      - FLASK_ENV
      - FLASK_APP
      - FLASK_RUN_PORT 
```

Now execute `docker-compose up` with the `cloudtruth run` command which will pass your CloudTruth parameters to Docker compose and display the variables selected.

```
cloudtruth --project MyFirstProject run -- docker-compose up 
Starting ct-test ... done
Attaching to ct-test
ct-test | PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ct-test | HOSTNAME=4ac024aae550
ct-test | FLASK_ENV=development
ct-test | FLASK_APP=flaskdemo.py
ct-test | FLASK_RUN_PORT=3000
ct-test | HOME=/root
ct-test exited with code 0
```

## Method 3: Docker Compose with init container

This method will use the CloudTruth init (sidecar) container to render templates into a volume(s) shared with the target services in your docker-compose file.

Source code for the CloudTruth init container: <https://github.com/cloudtruth/templates>

This example injects a simple static HTML page into an nginx container. The static HTML page is stored as a template in CloudTruth.

### Add a target to the template

The init container will scan the specified project and environment for all templates with a special comment on the first line that specifies the file to render the template to. It must be on the first line and it looks like this:

```
#~ target: /usr/share/nginx/html/index.html
```

For this example, CloudTruth created a template named \`DEMO\_PAGE\` in project "MyFirstProject", but feel free to change the project name based on your use case. The template references the automatic parameter "cloudtruth.environment", which will insert the name of the environment the template was pulled from.

You'll notice that the template has the special comment as the first line: \`#\~ target: ...\`. The init container will find this template and render it to "/usr/share/nginx/html/index.html".

Here is the template:

```
#~ target: /usr/share/nginx/html/index.html
<!DOCTYPE html>
<html>
<head>
    <title>{{ cloudtruth.environment }}</title>
</head>
<body>
<p>This is the {{ cloudtruth.environment }} web page.</p>
</body>
</html>
```

### Create docker-compose file

This example uses the public nginx container image, but you can replace this with your own container image.

Create a docker-compose.yml file or use one you already have. There are three important pieces to note, that make this whole solution work:

1. Include the `cloudtruth/templates` image as a service in the docker-compose file. You will see that listed as the web\_init service in the example file below.
2. One or more named volumes shared between the target container (web) and the init container (web\_init). In this case, we use the "static-content" named volume. Be sure to mount the named volumes to the same location in both the init container and the target container.
3. Add the \`depends\_on\` stanza to the container you want to inject the template into. The target container (web) should depend on the CloudTruth init container (web\_init)

The full docker-compose.yml file for this example:

```
---
services:
  web_init:
    container_name: ctdemo-init
    environment:
      - CLOUDTRUTH_API_KEY=${CLOUDTRUTH_API_KEY}
      - CLOUDTRUTH_ENVIRONMENT=${CLOUDTRUTH_ENVIRONMENT:-production}
      - CLOUDTRUTH_PROJECT=${CLOUDTRUTH_PROJECT:-default}
    image: cloudtruth/templates
    volumes:
      - static-content:/usr/share/nginx/html
  web:
    container_name: ctdemo
    depends_on:
      web_init:
        condition: service_completed_successfully
    image: nginx:1.20-alpine
    ports:
      - "8585:80"
    volumes:
      - static-content:/usr/share/nginx/html

volumes:
  static-content:
```

### Run docker-compose up

You will need to set a few environment variables for this exercise:

* \`CLOUDTRUTH\_API\_KEY\` = your APi-Key
* \`CLOUDTRUTH\_PROJECT\` = the project you want to render templates from
* \`CLOUDTRUTH\_ENVIRONMENT\` = the environment you want to use values from to render into the template

Now run docker-compose:

```
docker-compose up
```

### Verify the results

After a few seconds, the nginx container should be running with the web page hosted at <http://localhost:8585>

In this case, I ran with \`CLOUDTRUTH\_ENVIRONMENT=production\` and can see that reflected in the web page:

![](https://2952342643-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MGjN2Xg1mE8iTvg49dw%2Fuploads%2Fgit-blob-58f53792d8bbe349987e024dabb90da87463c418%2Finit-container-demo-screenshot.png?alt=media)
