This guide shows you how to run any custom Docker container on your FlyWP server and secure it with a free, auto-renewing Let’s Encrypt SSL certificate. The setup uses the server’s existing nginx-proxy to automatically handle traffic routing and SSL termination.
Prerequisites:
- A server managed by FlyWP.
- A user account with permissions to run Docker commands or sudo permission (default fly user).
- A domain (e.g.,
app.yourdomain.com) with its DNS A record pointing to your server’s public IP address.
How It Works 💡
This setup relies on two key containers working together:
nginx-proxy: This container (already running on your server) acts as a reverse proxy. It detects new containers on its network and uses their environment variables to automatically create the necessary NGINX configuration to route traffic to them. The key variables are:VIRTUAL_HOST: The domain name for your application.VIRTUAL_PORT: The internal port your application listens on inside its container.
letsencrypt-nginx-proxy-companion: This is a helper container you’ll add. It works withnginx-proxyto handle SSL. It watches for containers with specific variables and automatically obtains and renews SSL certificates for them. The key variables are:LETSENCRYPT_HOST: The domain to secure with SSL (should matchVIRTUAL_HOST).LETSENCRYPT_EMAIL: Your email, used for certificate registration and renewal notices.
Step 1: Create a Shared Docker Network (Recommended)
While optional, creating a dedicated network for your proxy and applications is a best practice. It keeps your containers organised and ensures they can communicate. If you haven’t created one already, run this command:
docker network create proxy-network
After creating the network, ensure the main nginx-proxy container is connected to it.
docker network connect proxy-network nginx-proxy
Note: This command might return an error if the container is already on the network; this is safe to ignore. You can also use FlyWP’s existing proxy network. Replace every mention of nginx-proxy network with site-network.
Step 2: Deploy the Let’s Encrypt Companion (One-Time Setup)
Next, deploy the Let’s Encrypt companion container. You only need to do this once per server. This container will manage certificates for all your future applications.
docker run -d \
--name nginx-letsencrypt \
--restart unless-stopped \
--volumes-from nginx-proxy \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
-v /etc/acme.sh:/etc/acme.sh \
--network proxy-network \
--restart unless-stopped \
jrcs/letsencrypt-nginx-proxy-companion
This container is now running and waiting for you to launch applications that need an SSL certificate.
Step 3: Deploy Your Application with SSL 🚀
You can now deploy your application. The nginx-proxy container will auto-detect everything from the environment variables you set. As long as your DNS is set properly, SSL will be activated automatically. Here’s how to do it using both docker run and docker-compose.
Here we will be using a simple hello-world Docker container.
Using docker run
This is a direct command to run a container. Stop and remove any old version of your app container first (docker stop my-app && docker rm my-app).
docker run -d \
--name my-custom-app \
--restart unless-stopped \
-e "VIRTUAL_HOST=app.yourdomain.com" \
-e "VIRTUAL_PORT=80" \
-e "LETSENCRYPT_HOST=app.yourdomain.com" \
-e "[email protected]" \
--network proxy-network \
nginxdemos/hello
Using docker-compose
For more complex applications, docker-compose is the recommended method.
- Create a file named
docker-compose.yml:
version: "3.7"
services:
my-custom-app:
image: nginxdemos/hello
container_name: my-custom-app
restart: unless-stopped
networks:
- proxy-network
environment:
- VIRTUAL_HOST=app.yourdomain.com
- VIRTUAL_PORT=80
- LETSENCRYPT_HOST=app.yourdomain.com
- [email protected]
networks:
proxy-network:
external: true
- From the same directory, run your application:
docker compose up -d
Success! ✅
That’s it! As long as your DNS settings are correct, the companion container will obtain a certificate and nginx-proxy will begin routing traffic for https://app.yourdomain.com to your new container, with SSL fully enabled. The certificate will automatically renew when needed.
Troubleshooting: In Case of Errors 🔍
If your site is not working as expected or the SSL certificate isn’t activated, the first and most important step is to check the logs of the Let’s Encrypt companion container.
To view the logs, run this command on your server:
docker logs nginx-letsencrypt
For a real-time view, which is helpful when launching a new container, use the --follow or -f flag:
docker logs -f nginx-letsencrypt
Look for messages related to your domain name. The logs are very descriptive and will almost always tell you the exact cause of the problem, such as:
- DNS problems: The log will state that it couldn’t verify your domain because its A record does not point to your server’s IP address.
- Rate limits: Let’s Encrypt has limits on how often you can request a certificate. The log will mention if you’ve been temporarily blocked.
- Connection issues: A timeout error could indicate a firewall is blocking port 80, which Let’s Encrypt requires for validation.