Skip to content

Instantly share code, notes, and snippets.

@ma-04
Last active August 7, 2025 07:54
Show Gist options
  • Select an option

  • Save ma-04/52db1a5f65d781d8b04d0ad4cbd5d753 to your computer and use it in GitHub Desktop.

Select an option

Save ma-04/52db1a5f65d781d8b04d0ad4cbd5d753 to your computer and use it in GitHub Desktop.

FlyWP: Setting Up a Custom Docker Container with SSL

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:

  1. 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.
  2. letsencrypt-nginx-proxy-companion: This is a helper container you'll add. It works with nginx-proxy to 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 match VIRTUAL_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 organized and ensures they can communicate. If you haven't created one already, run this command:

docker network create nginx-proxy

After creating the network, ensure the main nginx-proxy container is connected to it.

docker network connect nginx-proxy 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 nginx-proxy \
  --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.

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 "LETSENCRYPT_EMAIL=your-email@example.com" \
  --network nginx-proxy \
  nginxdemos/hello

Using docker-compose

For more complex applications, docker-compose is the recommended method.

  1. 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
  2. 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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment