Skip to content

Commit 72ac359

Browse files
authored
Merge pull request #1452 from api-platform/fix/docker-compose
fix: deployment with Docker Compose
2 parents 108157e + 8b47d07 commit 72ac359

File tree

5 files changed

+75
-69
lines changed

5 files changed

+75
-69
lines changed

deployment/docker-compose.md

Lines changed: 60 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,84 +1,88 @@
11
# Deploying with Docker Compose
22

3-
While [Docker Compose](https://docs.docker.com/compose/) is mainly known and used in a development environment, it [can
4-
actually be used in production too](https://docs.docker.com/compose/production/). This is especially suitable for prototyping
3+
While [Docker Compose](https://docs.docker.com/compose/) is mainly known and used in a development environment, it [can be used in production too](https://docs.docker.com/compose/production/). This is especially suitable for prototyping
54
or small-scale deployments, where the robustness (and the associated complexity) of [Kubernetes](kubernetes.md) is not
65
required.
76

8-
It is recommended that you build the Docker images in a [CI (continuous integration)](https://en.wikipedia.org/wiki/Continuous_integration)
9-
job, or failing which, on your development machine. The built images should then be pushed to a [container registry](https://docs.docker.com/registry/introduction/),
10-
e.g. [Docker Hub](https://hub.docker.com/), [Google Container Registry](https://cloud.google.com/container-registry/),
11-
[GitLab Container Registry](https://docs.gitlab.com/ee/user/packages/container_registry/). On the production server, you
12-
would pull the pre-built images from the container registry. This maintains a separation of concerns between the build
13-
environment and the production environment.
7+
API Platform provides Docker images and a Docker Compose definition optimized for production usage.
8+
In this tutorial, we will learn how to deploy our Symfony application on a single server using Docker Compose.
149

15-
## Deploying for Production
10+
Note: this tutorial has been adapted from [the Symfony Docker documentation](https://github.com/dunglas/symfony-docker/blob/main/docs/production.md).
1611

17-
To build images for production, you have to use the `docker-compose.prod.yml` file with Docker Compose.
12+
## Preparing a Server
1813

19-
## Building and Pushing the Docker Images
14+
To deploy your application in production, you need a server.
15+
In this tutorial, we will use a virtual machine provided by DigitalOcean, but any Linux server can work.
16+
If you already have a Linux server with Docker Compose installed, you can skip straight to [the next section](#configuring-a-domain-name).
2017

21-
These steps should be performed in a CI job (recommended) or on your development machine.
18+
Otherwise, use [this affiliate link](https://m.do.co/c/5d8aabe3ab80) to get $100 of free credit, create an account, then click on "Create a Droplet".
19+
Then, click on the "Marketplace" tab under the "Choose an image" section and search for the app named "Docker".
20+
This will provision an Ubuntu server with the latest versions of Docker and Docker Compose already installed!
2221

23-
1. Make sure the environment variables required for the build are set.
22+
For test purposes, the cheapest plan will be enough. For real production usage, you'll probably want to pick a plan in the "general purpose" section that will fit your needs.
2423

25-
If you are building the images in a CI job, these environment variables should be set as part of your CI job's environment.
24+
![Deploying a Symfony app on DigitalOcean with Docker Compose](digitalocean-droplet.png)
2625

27-
If you are building on your development machine, you could set the environment variables in the `.env` file at the
28-
top level of the distribution project (not to be confused with `api/.env` which is used by the Symfony application).
29-
For example:
26+
You can keep the defaults for other settings or tweak them according to your needs.
27+
Don't forget to add your SSH key or to create a password, then press the "Finalize and create" button.
3028

31-
```shell
32-
ADMIN_IMAGE=registry.example.com/api-platform/admin
33-
CLIENT_IMAGE=registry.example.com/api-platform/client
34-
NGINX_IMAGE=registry.example.com/api-platform/nginx
35-
PHP_IMAGE=registry.example.com/api-platform/php
36-
REACT_APP_API_ENTRYPOINT=https://api.example.com
37-
VARNISH_IMAGE=registry.example.com/api-platform/varnish
38-
```
29+
Then, wait a few seconds while your Droplet is provisioning.
30+
When your Droplet is ready, use SSH to connect:
3931

40-
**Note**: `REACT_APP_API_ENTRYPOINT` must be an exact match of the target domain name where your API will be accessed
41-
from, since its value is [embedded during build time](https://create-react-app.dev/docs/adding-custom-environment-variables).
42-
See [this discussion for possible workarounds](https://github.com/facebook/create-react-app/issues/2353) if this limitation
43-
is unacceptable for your project.
32+
```console
33+
ssh root@<droplet-ip>
34+
```
4435

45-
2. Build the Docker images:
36+
## Configuring a Domain Name
4637

47-
```shell
48-
docker-compose -f docker-compose.yml -f docker-compose.prod.yml build --pull
49-
```
38+
In most cases, you'll want to associate a domain name with your website.
39+
If you don't own a domain name yet, you'll have to buy one through a registrar.
40+
Use [this affiliate link](https://gandi.link/f/93650337) to redeem a 20% discount at Gandi.net.
5041

51-
3. Push the built images to the container registry:
42+
Then create a DNS record of type `A` for your domain name pointing to the IP address of your server.
5243

53-
```shell
54-
docker-compose -f docker-compose.yml -f docker-compose.prod.yml push
55-
```
44+
Example:
5645

57-
## Pulling the Docker Images and Running the Services
46+
```dns
47+
your-domain-name.example.com. IN A 207.154.233.113
48+
````
5849
59-
These steps should be performed on the production server.
50+
Example in Gandi's UI:
6051
61-
1. Make sure the environment variables required are set.
52+
![Creating a DNS record at Gandi.net](gandi-dns.png)
6253
63-
You could set the environment variables in the `.env` file at the top level of the distribution project (not to be
64-
confused with `api/.env` which is used by the Symfony application). For example:
54+
Note: Let's Encrypt, the service used by default by API Platform to automatically generate a TLS certificate, doesn't support using bare IP addresses.
55+
Using a domain name is mandatory to use Let's Encrypt.
6556
66-
```shell
67-
SERVER_NAME=api.example.com
68-
MERCURE_PUBLISHER_JWT_KEY=someKey
69-
MERCURE_SUBSCRIBER_JWT_KEY=someKey
70-
```
57+
## Deploying
7158
72-
**Important**: Please make sure to change all the passwords, keys and secret values to your own.
59+
Copy your project on the server using `git clone`, `scp` or any other tool that may fit your needs.
60+
If you use GitHub, you may want to use [a deploy key](https://docs.github.com/en/developers/overview/managing-deploy-keys#deploy-keys).
61+
Deploy keys are also [supported by GitLab](https://docs.gitlab.com/ee/user/project/deploy_keys/).
7362
74-
2. Pull the Docker images.
63+
Example with Git:
7564
76-
```console
77-
docker-compose -f docker-compose.yml -f docker-compose.prod.yml pull
78-
```
65+
```console
66+
git clone git@github.com:<username>/<project-name>.git
67+
```
7968

80-
3. Bring up the services.
69+
Go into the directory containing your project (`<project-name>`), and start the app in production mode:
8170

82-
```console
83-
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
84-
```
71+
```console
72+
SERVER_NAME=your-domain-name.example.com \
73+
APP_SECRET=ChangeMe \
74+
POSTGRES_PASSWORD=ChangeMe \
75+
CADDY_MERCURE_JWT_SECRET=ChangeMe \
76+
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
77+
```
78+
79+
Be sure to replace `your-domain-name.example.com` with your actual domain name and to set the values of `APP_SECRET`, `CADDY_MERCURE_JWT_SECRET` to cryptographically secure random values.
80+
81+
Your server is up and running, and a Let's Encrypt HTTPS certificate has been automatically generated for you.
82+
Go to `https://your-domain-name.example.com` and enjoy!
83+
84+
## Deploying on Multiple Nodes
85+
86+
If you want to deploy your app on a cluster of machines, we recommend using [Kubernetes](kubernetes.md).
87+
You can use [Docker Swarm](https://docs.docker.com/engine/swarm/stack-deploy/),
88+
which is compatible with the provided Compose files.
248 KB
Loading

deployment/images/gandi-dns.png

139 KB
Loading

deployment/index.md

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
# Deploying API Platform Applications
22

3-
API Platform apps are super easy to deploy in production on most cloud providers thanks to the native integration with
4-
[Kubernetes](kubernetes.md).
3+
API Platform apps are super easy to deploy in production thanks to the [Docker Compose definetion](docker-compose.md) and to the [Kubernetes chart](kubernetes.md) we provide.
54

6-
The server part of API Platform is basically a standard Symfony application, which you can also easily [deploy on your
7-
own servers](http://symfony.com/doc/current/deployment.html). Documentation for deploying on various container [orchestration](https://en.wikipedia.org/wiki/Orchestration_(computing))
8-
tools and PaaS (Platform as a Service) are also available:
5+
We strongly recommend using Kubernetes or Docker Compose to deploy your apps.
96

10-
* [Deploying to a Kubernetes Cluster](kubernetes.md)
11-
* [Deploying with Docker Compose](docker-compose.md)
12-
* [Deploying on Heroku](heroku.md)
13-
* [Deploying on Platform.sh](https://platform.sh/blog/deploy-api-platform-on-platformsh)
7+
If you want to play with a local Kubernetes cluster, read [how to deploy an API Platform project on Minikube](minikube.md).
148

15-
The clients are [Create React App](https://create-react-app.dev/) skeletons. You can deploy them in a wink
16-
on any static website hosting service (including [Netlify](https://www.netlify.com/), [Firebase Hosting](https://firebase.google.com/docs/hosting/),
17-
[GitHub Pages](https://pages.github.com/), or [Amazon S3](https://docs.aws.amazon.com/en_us/AmazonS3/latest/dev/WebsiteHosting.html)
18-
by following [the relevant documentation](https://create-react-app.dev/docs/deployment/).
9+
If you don't want to use Docker, keep in mind that the server application of API Platform is a standard Symfony project,
10+
while the Progressive Web Application is a standard Next.js project:
1911

2012
<p align="center" class="symfonycasts"><a href="https://symfonycasts.com/screencast/ansistrano?cid=apip"><img src="../distribution/images/symfonycasts-player.png" alt="JWT screencast"><br>Watch the Animated Deployment with Ansistrano screencast</a></p>
13+
14+
* [Deploying the Symfony application](https://symfony.com/doc/current/deployment.html)
15+
* [Deployin the Next.js application](https://nextjs.org/docs/deployment)
16+
17+
Alternatively, you may want to deploy API Platform on a PaaS (Platform as a Service):
18+
19+
* [Deploying the server application of API Platform on Heroku](heroku.md)
20+
* [Deploying API Platform on Platform.sh (outdated)](https://platform.sh/blog/deploy-api-platform-on-platformsh)

deployment/kubernetes.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ and [Amazon Web Services](https://aws.amazon.com/eks/) provide managed Kubernete
77
[The official API Platform distribution](../distribution/index.md) contains a built-in [Helm](https://helm.sh/) (the k8s
88
package manager) chart to deploy in a wink on any of these platforms.
99

10+
If you want to deploy API Platform on a local Kubernetes cluster, check out [our Minikube tutorial](minikube.md)!
11+
1012
## Preparing Your Cluster and Your Local Machine
1113

1214
1. Create a Kubernetes cluster on your preferred Cloud provider or install Kubernetes locally on your servers

0 commit comments

Comments
 (0)