Traefik can route raw TCP connections, not just HTTP.
Let’s say you have a database that needs to be accessible directly over TCP, not through a web interface. You want Traefik to be the single entry point for all your services, including this database.
Here’s how you’d configure Traefik to do that. First, you need to enable the TCP entrypoint in your traefik.yml or traefik.toml:
# traefik.yml
entryPoints:
web:
address: ":80"
websecure:
address: ":443"
database: # New TCP entrypoint
address: ":3306" # Port for your database
This tells Traefik to listen on port 3306 for incoming TCP connections. Next, you define a TCP router in your configuration. This router will match incoming connections on the database entrypoint and direct them to a specific TCP service.
# traefik.yml
tcpRouters:
my-database-router:
rule: "HostSNI(`*`)" # Match any SNI, or be more specific if needed
entryPoints:
- database
service: "my-database-service"
tcpServices:
my-database-service:
loadBalancer:
servers:
- address: "192.168.1.100:3306" # The actual IP and port of your database
The HostSNI rule is used for TLS connections, but for raw TCP without TLS, you can use HostSNI("*") as a catch-all. If your TCP service uses TLS, you’d configure it here. For plain TCP, this setup routes any connection arriving on the database entrypoint to the specified backend server.
The service section points to the actual backend where your database is running. Traefik will then establish a connection to 192.168.1.100:3306 for every client that connects to Traefik’s database entrypoint.
Here’s what this looks like in practice. Imagine your Traefik instance is accessible at traefik.example.com. If you want to connect to your database, you’d point your database client to traefik.example.com:3306. Traefik, listening on its database entrypoint (also port 3306 in this example), receives the connection. It then applies the my-database-router. The HostSNI("*") rule matches, and Traefik forwards the raw TCP connection to the backend defined in my-database-service, which is 192.168.1.100:3306.
This is powerful because it allows Traefik to act as a unified gateway for all your services, simplifying your network topology and security. You don’t need to expose your database directly to the internet or manage firewall rules for it; Traefik handles the ingress.
The key difference between HTTP and TCP routing in Traefik lies in the level of abstraction. For HTTP, Traefik inspects headers like Host and Path to make routing decisions. For TCP, it can inspect TLS Server Name Indication (SNI) if TLS is enabled, or it can simply route based on the entrypoint and a generic rule like HostSNI("*") for unencrypted TCP. The connection itself is then treated as a stream of bytes, passed transparently between the client and the backend.
A common pitfall is forgetting that TCP routers don’t have access to HTTP-level information. If you try to use HTTP-specific rules like PathPrefix or Headers in a TCP router, it simply won’t work. The HostSNI rule is the closest equivalent for TLS-enabled TCP, allowing you to route based on the hostname the client is requesting during the TLS handshake. For non-TLS TCP, you’re typically routing based on the entrypoint alone, or perhaps a very simple pattern if the protocol itself embeds some form of identifier early on, though this is less common for generic TCP services.
If you’re setting up TLS for your TCP service, you’ll need to configure Traefik’s TLS options for the TCP router. This involves specifying the certificates and keys that Traefik will use to present to the client during the TLS handshake.
# traefik.yml
tls:
certificates:
- certFile: /path/to/your/database.crt
keyFile: /path/to/your/database.key
stores:
- default
tcpRouters:
my-database-router:
rule: "HostSNI(`db.example.com`)" # Specific SNI for TLS
entryPoints:
- database
service: "my-database-service"
tls:
certResolver: myresolver # Or use direct certFile/keyFile
# Or if using direct certs:
# tlsOptions:
# certificates:
# - certFile: /path/to/your/database.crt
# keyFile: /path/to/your/database.key
tcpServices:
my-database-service:
loadBalancer:
servers:
- address: "192.168.1.100:3306"
In this TLS scenario, Traefik will terminate the TLS connection using the specified certificate and then establish a new, potentially unencrypted or re-encrypted, connection to your backend database. The HostSNI rule becomes crucial here, as it allows Traefik to select the correct certificate if you have multiple TLS services routed through the same entrypoint.
The next step is typically understanding how to combine TCP and HTTP routing on the same entrypoint, which Traefik handles by allowing multiple router types to be associated with a single address.