Howdy,
I managed to solve this problem thanks to a few other resources and finally this thread!
In my case I had:
- cockpit-ws (provided alongside my Centos 9) on the host
- traefik v3 running in Docker as a container
The goal is to make cockpit-ws operate in non-ssl or HTTP only mode and have it only accessible on localhost and to docker. Then we let traefik talk to cockpit-ws to show it on my domain at cockpit.example.com via HTTPS only.
This is the setup (create any files that don't already exist).
/etc/systemd/system/cockpit.socket.d/listen.conf
[Socket]
ListenStream=
ListenStream=127.0.0.1:9090
ListenStream=172.17.0.1:9090
FreeBind=yes
From the TCP Port and Address docs, we make cockpit only accessible on localhost (127.0.0.1
) and docker (172.17.0.1
) .
Don't use 0.0.0.0
because then you're exposing it to the internet with HTTP on your servers IP!
After modifying this file, run:
sudo systemctl daemon-reload
sudo systemctl restart cockpit.socket
/etc/cockpit/cockpit.conf
[WebService]
Origins = http://cockpit.example.com ws://cockpit.example.com https://cockpit.example.com wss://cockpit.example.com
ProtocolHeader = X-Forwarded-Proto
AllowUnencrypted=true
Replace the example subdomain with your own. Origins
and ProtocolHeader
are required to allow a successful connection post login. Cockpit enforces a HTTPS requirement for non local host addresses so we allow HTTP by setting AllowUnencrypted
.
After modifying this file, run:
sudo systemctl restart cockpit
traefik/compose.yml
services:
traefik:
image: traefik:v3.1
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./traefik_static.yml:/etc/traefik/traefik.yml
- ./dynamic:/etc/traefik/dynamic
extra_hosts:
- "host.docker.internal:host-gateway"
networks:
- web
restart: unless-stopped
networks:
web:
external: true
Set extra_hosts
to bind host.docker.internal
to host-gateway
.
Note: If you don't want to do this you can also use the 172.17.0.1
directly to refer to the host from inside docker containers but this is not recommended.
traefik_dynamic.yml
# Cockpit setup
http:
routers:
cockpit:
rule: "Host(`cockpit.example.com`)"
entrypoints:
- https
tls: true
service: cockpit-service
services:
cockpit-service:
loadBalancer:
servers:
- url: "http://host.docker.internal:9090"
Add the above to your dynamic config. Replace the example subdomain with your own. Don't forget to setup the tls certificates as you normally would for this subdomain (not included in above config).
Note: You can use 172.17.0.1
here if you didn't want to use extra_hosts
in previous step.
Test everything
Redeploy traefik
on docker if needed, then test.
Make sure cockpit is working from your subdomain and localhost via curl.