Skip to content

Latest commit

 

History

History
108 lines (74 loc) · 4.73 KB

production.md

File metadata and controls

108 lines (74 loc) · 4.73 KB

Deploying in Production

Symfony Docker provides Docker images, and a Docker Compose definition optimized for production usage. In this tutorial, we will learn how to deploy our Symfony application on a single server using Docker Compose.

Preparing a Server

To deploy your application in production, you need a server. In this tutorial we will use a virtual machine provided by DigitalOcean, but any Linux server can work. If you already have a Linux server with Docker Compose installed, you can skip straight to the next section.

Otherwise, use this affiliate link to get $100 of free credit, create an account, then click on "Create a Droplet". Then, click on the "Marketplace" tab under the "Choose an image" section and search for the app named "Docker". This will provision an Ubuntu server with the latest versions of Docker and Docker Compose already installed!

For test purposes, cheapest plans will be enough, even though you might want at least 2GB of RAM to execute Docker Compose for the first time. For real production usage, you'll probably want to pick a plan in the "general purpose" section that will fit your needs.

Deploying a Symfony app on DigitalOcean with Docker Compose

You can keep the defaults for other settings, or tweak them according to your needs. Don't forget to add your SSH key or to create a password then press the "Finalize and create" button.

Then, wait a few seconds while your Droplet is provisioning. When your Droplet is ready, use SSH to connect:

ssh root@<droplet-ip>

Configuring a Domain Name

In most cases, you'll want to associate a domain name to your website. If you don't own a domain name yet, you'll have to buy one through a registrar.

Then create a DNS record of type A for your domain name pointing to the IP address of your server.

Example:

your-domain-name.example.com.  IN  A     207.154.233.113

Note

Let's Encrypt, the service used by default by Symfony Docker to automatically generate a TLS certificate doesn't support using bare IP addresses. Using a domain name is mandatory to use Let's Encrypt.

Deploying

Copy your project on the server using git clone, scp or any other tool that may fit your need. If you use GitHub, you may want to use a deploy key. Deploy keys are also supported by GitLab.

Example with Git:

git clone git@github.com:<username>/<project-name>.git

Go into the directory containing your project (<project-name>), and start the app in production mode:

SERVER_NAME=your-domain-name.example.com \
APP_SECRET=ChangeMe \
CADDY_MERCURE_JWT_SECRET=ChangeThisMercureHubJWTSecretKey \
docker compose -f compose.yaml -f compose.prod.yaml up -d --wait

Be sure to replace your-domain-name.example.com by your actual domain name and to set the values of APP_SECRET, CADDY_MERCURE_JWT_SECRET to cryptographically secure random values.

Your server is up and running, and a HTTPS certificate has been automatically generated for you. Go to https://your-domain-name.example.com and enjoy!

Note

The worker mode of FrankenPHP is enabled by default in prod. To disabled it, add the env var FRANKENPHP_CONFIG as empty to the compose.prod.yaml file.

Caution

Docker can have a cache layer, make sure you have the right build for each deployment or rebuild your project with --no-cache option to avoid cache issue

Disabling HTTPS

Alternatively, if you don't want to expose an HTTPS server but only an HTTP one, run the following command:

SERVER_NAME=:80 \
APP_SECRET=ChangeMe \
CADDY_MERCURE_JWT_SECRET=ChangeThisMercureHubJWTSecretKey \
docker compose -f compose.yaml -f compose.prod.yaml up -d --wait

Deploying on Multiple Nodes

If you want to deploy your app on a cluster of machines, you can use Docker Swarm, which is compatible with the provided Compose files. To deploy on Kubernetes, take a look at the Helm chart provided with API Platform, which can be easily adapted for use with Symfony Docker.

Passing local environment variables to containers

By default, .env.local and .env.*.local files are excluded from production images. If you want to pass them to your containers, you can use the env_file attribute:

# compose.prod.yml

services:
    php:
        env_file:
            - .env.prod.local
        # ...