This repo demonstrates how to use a single Traefik Docker container as a reverse proxy for multiple projects, each with different domains. Instead of manually installing and configuring a reverse proxy for a server, you can deploy this pre-configured Traefik container and easily add as many projects with as many domains as you need.
root/
├── traefik/
│ ├── docker-compose.yml
├── project-1/
│ ├── docker-compose.yml
├── project-2/
│ ├── docker-compose.yml
├── README.md
└── ... (additional projects)
Before getting started, ensure you have the following installed on your system:
- Docker - How to install Docker (version 20.10.0 or higher)
- Docker Compose - How to install Docker Compose (version 1.27.0 or higher)
- Git - How to Install Git on Ubuntu
- A registered domain name pointed to your server's IP address - What are DNS Records? - What is a DNS A Record?
- Open ports
80and443on your server - How to Open a Port on a Linux Server Using UFW?
Follow these steps to set up the Traefik reverse proxy and deploy multiple projects.
git clone https://github.com/sesto-dev/one-traefik-multiple-projects.gitTraefik and the projects need to communicate over a shared Docker network.
docker network create traefik-publicSet up the necessary environment variables for Traefik and each project.
cd one-traefik-multiple-projects/traefikCreate a .env file inside the traefik directory:
cp .env.example .env
nano .envEdit the .env file to set your domain and other necessary variables.
USERNAME=your_admin_username
PASSWORD=your_admin_password
DOMAIN=yourdomain.com
ACME_EMAIL=youremail@domain.comNote: To generate and set the hashed password in one command for Traefik's HTTP Basic Auth, you can use the following command:
export HASHED_PASSWORD=$(openssl passwd -apr1 $PASSWORD)Then spin up your Traefik container:
docker compose up -dFor each project, create a .env file based on the provided examples and enter the DOMAIN for that project.
cd ../project-1
cp .env.example .env
nano .env`DOMAIN=project1.yourdomain.comThen spin up the project container:
docker compose up -dRepeat for project-2.
Open your browser and navigate to the domains you've configured. You should see the projects running correctly. You can also visit Traefik's dashboard at https://traefik.yourdomain.com.
This section provides a comprehensive guide for deploying your Traefik setup with Cloudflare DNS in a production environment.
The repository includes production-ready configuration files:
traefik/.env.production: Contains production domain and Cloudflare credentialsportfolio/.env.production: Contains production domaindeploy-production.sh: Automates the deployment processgenerate-password.sh: Helper script to generate secure passwords
Before deploying to production, make sure to:
Replace yourdomain.com in both .env.production files with your actual domain:
# In traefik/.env.production and portfolio/.env.production
DOMAIN=yourdomain.comGenerate a new hashed password for the Traefik dashboard:
# Using the provided script
./generate-password.sh
# Or directly with OpenSSL
openssl passwd -apr1 your_secure_passwordUpdate the HASHED_PASSWORD in traefik/.env.production with the generated hash.
Ensure your Cloudflare API key or DNS API token is correct in traefik/.env.production:
CLOUDFLARE_EMAIL=your-cloudflare-email@example.com
CLOUDFLARE_API_KEY=your-global-api-key
# OR
# CLOUDFLARE_DNS_API_TOKEN=your-dns-api-token- Create an A record for your root domain (e.g.,
yourdomain.com) pointing to your server's IP - Create an A record for the Traefik subdomain (e.g.,
traefik.yourdomain.com) pointing to the same IP - Set the proxy status to "DNS only" (gray cloud) initially until certificates are issued
- Set SSL/TLS mode to "Full (Strict)" for maximum security
- Enable "Always Use HTTPS" in the SSL/TLS section
- Set minimum TLS version to TLS 1.2 or 1.3
Ensure Docker and Docker Compose are installed on your production server.
If you're using Google Artifact Registry for your container images:
curl https://sdk.cloud.google.com | bash
gcloud initCopy the entire multi-project-setup directory to your production server.
chmod +x deploy-production.sh./deploy-production.shThe script will:
- Create the traefik-public network if it doesn't exist
- Optionally generate a new password
- Copy production environment files
- Authenticate with Google Artifact Registry
- Start Traefik and your services
- Check if containers are running:
docker ps - Check Traefik logs:
docker logs traefik-traefik-1 - Verify certificate issuance in the logs
Once certificates are issued, you can change the proxy status to "Proxied" (orange cloud) for additional protection.
Regularly check Traefik logs for any errors or issues:
docker logs traefik-traefik-1Periodically backup the traefik/certificates directory which contains your Let's Encrypt certificates.
If you encounter issues with certificate issuance:
- Check Traefik logs for any DNS challenge errors
- Verify Cloudflare API credentials
- Ensure DNS records are properly configured
If you see an error like:
ERR The ACME resolve is skipped from the resolvers list error="unable to get ACME account: permissions 644 for /certificates/acme.json are too open, please use 600"
This is because Let's Encrypt requires strict permissions on the certificate storage file. The configuration has been updated to automatically set the correct permissions, but if you still encounter this issue:
-
Stop the Traefik container:
cd traefik docker-compose down -
Create or fix permissions on the acme.json file:
touch ./certificates/acme.json chmod 600 ./certificates/acme.json
-
Restart Traefik:
docker-compose up -d
If you have issues pulling your private image:
gcloud auth login
gcloud auth configure-docker asia-southeast2-docker.pkg.dev- Ensure ports 80 and 443 are open on your server's firewall
- Check that the traefik-public network exists:
docker network ls
For local development:
- Use the
.envfiles (not.env.production) - Set
DOMAIN=localhostin both.envfiles - The configuration will automatically use HTTP only for local development
When developing locally with custom domains like localhost and traefik.localhost, you need to ensure your hosts file is properly configured:
-
Open your hosts file with administrator privileges:
- Windows:
C:\Windows\System32\drivers\etc\hosts - Mac/Linux:
/etc/hosts
- Windows:
-
Add these entries to your hosts file:
127.0.0.1 localhost 127.0.0.1 traefik.localhost -
Save the file and restart your browser
If you encounter a 404 error when accessing your domain:
- Verify your hosts file has the correct entries
- Ensure your
.envfiles are using UTF-8 encoding without BOM - Check that the
DOMAINvariable is set tolocalhostin both.envfiles - Restart your containers:
cd traefik && docker-compose down && docker-compose up -d cd ../portfolio && docker-compose down && docker-compose up -d
If you're having issues with the Google Artifact Registry authentication for local development, temporarily use the nginx:alpine image in your portfolio/docker-compose.yaml:
# For production, use your private image
# image: asia-southeast2-docker.pkg.dev/mamenesia/images/portfolio:release
# Temporarily using nginx:alpine for local development
image: nginx:alpineThis setup allows you to develop locally without needing to obtain SSL certificates for localhost domains or authenticate with Google Artifact Registry.
