Skip to content

Updating docker-compose for production #1333

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 7, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 11 additions & 103 deletions deployment/docker-compose.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,9 @@ e.g. [Docker Hub](https://hub.docker.com/), [Google Container Registry](https://
would pull the pre-built images from the container registry. This maintains a separation of concerns between the build
environment and the production environment.

## Installing the Docker Compose Setup for Production
## Deploying for Production

If you are using the [API Platform Distribution](../distribution/index.md), we provide a [ready-to-deploy Docker Compose
setup for production](https://github.com/api-platform/docker-compose-prod), with (optional) [Let's Encrypt](https://letsencrypt.org/)
integration.

It is designed to be used as a companion to the distribution, and as such it needs to be placed inside a subdirectory at
the top level of the distribution project:

```console
wget -O - https://github.com/api-platform/docker-compose-prod/archive/master.tar.gz | tar -xzf - && mv docker-compose-prod-master docker-compose-prod
git add docker-compose-prod
```

Then commit the changes to your git repository. The `docker-compose-prod` directory should be checked in.
To build images for production, you have to use the `docker-compose.prod.yml` file with Docker Compose.

## Building and Pushing the Docker Images

Expand Down Expand Up @@ -57,14 +45,13 @@ These steps should be performed in a CI job (recommended) or on your development
2. Build the Docker images:

```shell
docker-compose -f docker-compose-prod/docker-compose.build.yml pull --ignore-pull-failures
docker-compose -f docker-compose-prod/docker-compose.build.yml build --pull
docker-compose -f docker-compose.yml -f docker-compose.prod.yml build --pull
```

3. Push the built images to the container registry:

```shell
docker-compose -f docker-compose-prod/docker-compose.build.yml push
docker-compose -f docker-compose.yml -f docker-compose.prod.yml push
```

## Pulling the Docker Images and Running the Services
Expand All @@ -77,100 +64,21 @@ These steps should be performed on the production server.
confused with `api/.env` which is used by the Symfony application). For example:

```shell
ADMIN_HOST=admin.example.com
ADMIN_IMAGE=registry.example.com/api-platform/admin
API_HOST=api.example.com
APP_SECRET=3c857494cfcc42c700dfb7a6
CLIENT_HOST=example.com,www.example.com
CLIENT_IMAGE=registry.example.com/api-platform/client
CORS_ALLOW_ORIGIN=^https://(?:\w+\.)?example\.com$
DATABASE_URL=postgres://api-platform:4e3bc2766fe81df300d56481@db/api
MERCURE_ALLOW_ANONYMOUS=0
MERCURE_CORS_ALLOWED_ORIGINS=https://example.com,https://admin.example.com
MERCURE_HOST=mercure.example.com
MERCURE_JWT_KEY=4121344212538417de3e2118
MERCURE_JWT_SECRET=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJtZXJjdXJlIjp7InN1YnNjcmliZSI6WyJmb28iLCJiYXIiXSwicHVibGlzaCI6WyJmb28iXX19.B0MuTRMPLrut4Nt3wxVvLtfWB_y189VEpWMlSmIQABQ
MERCURE_SUBSCRIBE_URL=https://mercure.example.com/hub
NGINX_IMAGE=registry.example.com/api-platform/nginx
PHP_IMAGE=registry.example.com/api-platform/php
POSTGRES_PASSWORD=4e3bc2766fe81df300d56481
REACT_APP_API_ENTRYPOINT=https://api.example.com
TRUSTED_HOSTS=^(?:localhost|api|api\.example\.com)$
VARNISH_IMAGE=registry.example.com/api-platform/varnish
SERVER_NAME=api.example.com
MERCURE_PUBLISHER_JWT_KEY=someKey
MERCURE_SUBSCRIBER_JWT_KEY=someKey
Copy link

@Antarian Antarian May 8, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be worth to mention, that you need also update docker-compose.yml file database section to use bind volume. Otherwise you are at risk to override all your production data.
Also environment variable SERVER_NAME set in docker compose.yml may be different in production.

Thinking if documentation is the place to inform to change these, or API-Platform 2.6 docker-compose needs more work to be production ready. Like moving DB volume setting and some variables (POSTGRES_PASSWORD) to environment or to .override and .prod respectively.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello,
I think that the Docker Compose configuration needs some work for the database indeed to be usable in production.
Are you willing to make a PR?

```

**Important**: Please make sure to change all the passwords, keys and secret values to your own.

2. Set up a redirect from e.g. `www.example.com` to `example.com`:

```shell
mkdir -p docker-compose-prod/docker/nginx-proxy/vhost.d
echo 'return 301 https://example.com$request_uri;' > docker-compose-prod/docker/nginx-proxy/vhost.d/www.example.com
```

**Note**: If you do not want such a redirect, or you want it to be the other way round, please adapt to suit your needs.

3. *(optional)* Set up the Let's Encrypt integration.

**Note**: If you are using Cloudflare, you might consider using their [free SSL/TLS encryption](https://www.cloudflare.com/ssl/)
setup as a simpler alternative. But if you would prefer to have full control, read on.

Make sure the environment variables required for the Let's Encrypt integration are set.

You could set the environment variables in the `.env` file at the top level of the distribution project (not to be
confused with `api/.env` which is used by the Symfony application). For example:

```shell
[email protected]
LEXICON_CLOUDFLARE_AUTH_TOKEN=9e06358f74cbce70602c22fc3279f0aee3077
[email protected]
```

**Note**: If you are not using [Cloudflare DNS](https://www.cloudflare.com/dns/), please see [the documentation on
how to pass the correct environment variables to Lexicon](https://github.com/adferrand/docker-letsencrypt-dns#configuring-dns-provider-and-authentication-to-dns-api).

Configure the (sub)domains for which you want certificate(s) to be issued for in `docker-compose-prod/docker/letsencrypt/domains.conf`.
For example, to request a wildcard certificate for `*.example.com` and `example.com`:

```shell
*.example.com example.com autorestart-containers=api-platform_nginx-proxy_1
```

**Note**: Replace the `api-platform` prefix in `api-platform_nginx-proxy_1` with your [Docker Compose project name
(it defaults to the project directory name)](https://docs.docker.com/compose/reference/envvars/#compose_project_name).

4. Pull the Docker images.

If you are **not** using the (optional) Let's Encrypt integration:
2. Pull the Docker images.

```console
docker-compose -f docker-compose-prod/docker-compose.yml pull
docker-compose -f docker-compose.yml -f docker-compose.prod.yml pull
```

If you are using the (optional) Let's Encrypt integration:
3. Bring up the services.

```console
docker-compose -f docker-compose-prod/docker-compose.yml -f docker-compose-prod/docker-compose.letsencrypt.yml pull
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
```

5. Bring up the services.

If you are **not** using the (optional) Let's Encrypt integration:

```console
docker-compose -f docker-compose-prod/docker-compose.yml up -d
```

If you are using the (optional) Let's Encrypt integration:

```console
docker-compose -f docker-compose-prod/docker-compose.yml -f docker-compose-prod/docker-compose.letsencrypt.yml up -d
```

## Running the Docker Compose Setup for Production Locally

Sometimes, you may need to run a production-like setup locally; for example, for [end-to-end testing](../distribution/testing.md#using-the-api-platform-distribution-for-end-to-end-testing)
or to troubleshoot problems which can only be reproduced with a production setup (e.g. Varnish errors or cache misses).

You may (re)use the same [Docker Compose setup for production](https://github.com/api-platform/docker-compose-prod) we
have [installed above](#installing-the-docker-compose-setup-for-production).