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.
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.
While optional, creating a dedicated network for your proxy and applications is a best practice. It keeps your containers organized and ensures they can communicate. If you haven't created one already, run this command:
docker network create nginx-proxyAfter creating the network, ensure the main nginx-proxy container is connected to it.
docker network connect nginx-proxy nginx-proxyNote: 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.
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 nginx-proxy \
--restart unless-stopped \
jrcs/letsencrypt-nginx-proxy-companionThis container is now running and waiting for you to launch applications that need an SSL certificate.
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.
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 "LETSENCRYPT_EMAIL=your-email@example.com" \
--network nginx-proxy \
nginxdemos/helloFor 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: - nginx-proxy environment: - VIRTUAL_HOST=app.yourdomain.com - VIRTUAL_PORT=80 - LETSENCRYPT_HOST=app.yourdomain.com - LETSENCRYPT_EMAIL=your-email@example.com networks: nginx-proxy: external: true
-
From the same directory, run your application:
docker-compose up -d
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.
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-letsencryptFor a real-time view, which is helpful when launching a new container, use the --follow or -f flag:
docker logs -f nginx-letsencryptLook 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.