Self-hosting apps with Coolify and Traefik v3? Want a firewall to protect your apps from bad bots, abuse, and attacks? This guide shows how to install and configure CrowdSec on Coolify with Traefik v3 using the CrowdSec Traefik bouncer plugin.
This setup protects HTTP and HTTPS applications behind Coolify’s Traefik reverse proxy. It does not protect SSH, arbitrary host ports, or the entire Ubuntu host. If you need to secure the entire Coolify server with CrowdSec, nftables and Traefik, use the separate full-server guide.
Production-tested September 2026
This walkthrough was tested with Coolify 4.3.18, Traefik 3.7.13, CrowdSec 1.8.1, and the CrowdSec Traefik plugin 1.7.1. These are the versions tested for this guide, not a guarantee that they remain the latest releases.
The useful part of this CrowdSec Coolify setup is that one global Traefik middleware can protect every website on the server. You do not need to add separate labels to every application.
What is CrowdSec?
CrowdSec is a free, open-source security engine that analyses logs, detects suspicious behaviour, creates malicious-IP decisions, and shares threat intelligence with the community. It is useful for detecting scanners, bots, probing, and other repeated abusive behaviour before those clients reach your applications.
Basic CrowdSec remediation is primarily behaviour-based IP protection. It is not automatically a request-level WAF, and this base setup does not inspect every request for XSS or SQL injection.
What you’ll need
- Coolify self-hosted on a Linux server
- Traefik v3 running as your reverse proxy, installed by Coolify
- Docker and Docker Compose
- Root access or sudo
- A working Coolify installation; if you have not finished that step, start with the Coolify configuration and first project guide
Coolify manages its Traefik proxy. The main proxy compose file is /data/coolify/proxy/docker-compose.yml, and dynamic configurations belong in /data/coolify/proxy/dynamic/. Keep changes to the main compose file as small as possible so Coolify can continue managing the proxy safely.
Step 1: Deploy CrowdSec via Docker Compose
Create a CrowdSec container and connect it to the Coolify network. The image below matches the version used for the production test.
version: '3.8'
services:
crowdsec:
image: 'crowdsecurity/crowdsec:v1.8.1'
container_name: crowdsec
expose:
- "8080"
environment:
GID: '${GID-1000}'
COLLECTIONS: 'crowdsecurity/linux crowdsecurity/traefik'
volumes:
- 'crowdsec-db:/var/lib/crowdsec/data'
- './crowdsec/config:/etc/crowdsec/'
- './crowdsec/acquis.yaml:/etc/crowdsec/acquis.yaml'
- '/data/coolify/proxy:/traefik'
networks:
- coolify
security_opt:
- 'no-new-privileges:true'
restart: unless-stopped
volumes:
crowdsec-db: null
networks:
coolify:
external: true
The Coolify host stores the Traefik access log at /data/coolify/proxy/access.log. In this Compose setup, that directory is mounted into the CrowdSec container as /traefik, so CrowdSec reads the same log at /traefik/access.log.
Configure the acquisition file with the Traefik log source:
filenames:
- /traefik/access.log
labels:
type: traefik
log_type: http_access-log
Start or recreate the CrowdSec container, then confirm that the Traefik collection is installed:
docker compose up -d crowdsec
docker exec -it crowdsec cscli collections list
Step 2: Configure the Coolify Traefik proxy
Open /data/coolify/proxy/docker-compose.yml and add the following entries under Traefik’s command section. Coolify may regenerate this file, so keep a record of the changes and recheck them after proxy updates.
Register the CrowdSec Traefik plugin
The current plugin documentation registers the plugin with the key bouncer. The dynamic middleware below uses that same key.
- '--experimental.plugins.bouncer.modulename=github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin'
- '--experimental.plugins.bouncer.version=v1.7.1'
Enable the Traefik access log
Traefik writes /traefik/access.log inside the proxy container, which maps to /data/coolify/proxy/access.log on the Coolify host:
- '--accesslog=true'
- '--accesslog.format=json'
- '--accesslog.bufferingsize=0'
- '--accesslog.filepath=/traefik/access.log'
Apply the middleware globally
These entrypoint flags apply one CrowdSec Traefik middleware to HTTP and HTTPS traffic for every Coolify website:
- '--entrypoints.http.http.middlewares=crowdsec@file'
- '--entrypoints.https.http.middlewares=crowdsec@file'
Restart the proxy after saving the compose file:
docker restart coolify-proxy
Step 3: Create the CrowdSec Traefik middleware
Create /data/coolify/proxy/dynamic/crowdsec-plugin.yaml:
http:
middlewares:
crowdsec:
plugin:
bouncer:
enabled: true
crowdsecMode: live
crowdsecLapiHost: 'crowdsec:8080'
crowdsecLapiKey: 'PASTE_YOUR_TRAEFIK_BOUNCER_KEY_HERE'
Generate a dedicated LAPI key for the Traefik bouncer:
docker exec -it crowdsec cscli bouncers add traefik-bouncer
Copy the generated key into the dynamic configuration. Never publish the real key in an article, repository, screenshot, or support request.
The crowdsec middleware name is deliberately separate from the plugin registration key bouncer. The global entrypoint flags refer to crowdsec@file, while the middleware’s plugin block refers to the registered bouncer plugin.
Step 4: Protect all Coolify websites automatically
CrowdSec is now connected to the Traefik access log and applied globally through one middleware. You do not need to configure every application separately.
If you want additional router-level filtering, you can still use a narrow rule such as HostRegexp('.+'), but it is not required for the global middleware approach.
Step 5: Test the website protection
Use a temporary CrowdSec decision to test the bouncer. 203.0.113.10 is a documentation-only example address. Replace it with the test client’s real source IP only when you are ready to test, and remove the decision afterwards.
docker exec -it crowdsec cscli decisions add -i 203.0.113.10 -d 10m
docker exec -it crowdsec cscli decisions list
The test client should receive a blocked response when it requests a Coolify-hosted website through Traefik. Delete the temporary decision when finished:
docker exec -it crowdsec cscli decisions delete -i 203.0.113.10
Useful checks are:
docker exec -it crowdsec cscli alerts list
docker exec -it crowdsec cscli bouncers list
docker exec -it crowdsec cscli metrics
If CrowdSec is installed directly on the host instead of in the container shown above, use the equivalent commands without the Docker wrapper, for example sudo cscli decisions list, sudo cscli alerts list, sudo cscli bouncers list, and sudo cscli metrics.
Next.js users: avoid false bans from /_next/data/
One real production issue appeared on a Coolify site running Next.js. Normal page-navigation and prefetch requests to paths such as /_next/data/... generated many successful JSON requests in a short period. CrowdSec classified that traffic with crowdsecurity/http-crawl-non_statics, which caused a legitimate client to be banned.
Do not add an exception blindly. First inspect the alert and confirm that the requests are legitimate Next.js traffic:
docker exec -it crowdsec cscli alerts list
docker exec -it crowdsec cscli alerts inspect ALERT_ID
Only after confirming the false positive should you create a narrow local whitelist. Inside the CrowdSec container, create:
/etc/crowdsec/parsers/s02-enrich/zz-whitelist-nextjs-data.yaml
name: local/whitelist-nextjs-data
description: "Ignore legitimate Next.js data prefetch requests"
filter: "evt.Meta.service == 'http' && evt.Meta.log_type == 'http_access-log'"
whitelist:
reason: "Legitimate Next.js data prefetch"
expression:
- "evt.Meta.http_verb == 'GET' && evt.Meta.http_path startsWith '/_next/data/' && evt.Meta.http_status == '200'"
The file must be created in the host directory mounted to /etc/crowdsec so that the change persists when the container is recreated. Validate and restart the container:
docker exec -it crowdsec crowdsec -c /etc/crowdsec/config.yaml -t
docker restart crowdsec
docker exec -it crowdsec cscli alerts list --since 10m
For a host-installed CrowdSec service, the same file is /etc/crowdsec/parsers/s02-enrich/zz-whitelist-nextjs-data.yaml and the equivalent commands are:
sudo crowdsec -c /etc/crowdsec/config.yaml -t
sudo systemctl restart crowdsec
systemctl is-active crowdsec
sudo cscli alerts list --since 10m
This whitelist is a troubleshooting fix for a verified false positive, not a default recommendation for every Next.js or CrowdSec installation.
Want a real WAF? Add CrowdSec AppSec
The base CrowdSec Traefik middleware makes decisions primarily from client behaviour, reputation, and parsed access logs. It does not by itself inspect request content as a full web application firewall.
For request-level protection such as virtual patching and rules for application-layer attacks, add the CrowdSec AppSec component and configure the Traefik plugin to forward requests to it. Follow the official CrowdSec Traefik AppSec guide for the supported collections, acquisition, and middleware settings. Keep AppSec as an optional layer so the website-only IP protection setup remains easy to understand.
Website-only protection vs full-server security
This guide protects websites behind Coolify’s Traefik proxy. It does not protect SSH, host-level services, or arbitrary server ports.
For SSH and broader server security, you can compare the Coolify + Fail2Ban guide. For complete host and website protection with CrowdSec, nftables, and Traefik, follow the full Coolify server security guide.
Final thoughts
With this setup, all Coolify-hosted websites can share one global CrowdSec Traefik middleware. The Traefik access log feeds CrowdSec, CrowdSec analyses the behaviour, and the bouncer blocks clients with active decisions before they reach the application.
The result is a clean, scalable website-security layer without per-project labels. If you need SSH, host-port, or full Ubuntu protection as well, use the separate full-server guide rather than expanding this website-focused setup beyond its purpose.
