Cockpit: The Easiest Way to Manage Linux Servers
Video write-up
In this video, I show how to use Cockpit as a lightweight Linux server dashboard for the tasks you normally do over SSH. We’ll install Cockpit on Ubuntu, log in to the web interface, look at updates, logs, services, storage, networking, users, and terminal access, then make the setup safer by binding Cockpit to localhost and putting Caddy in front with trusted TLS.
I’ll also show how Cockpit applications can extend the dashboard with features like file management, virtual machines, and Docker management, how remote server access works over SSH, and where Cockpit is useful compared to Proxmox, Ansible, or just staying in the terminal.
Short companion notes for the video. This is not a full article — just the main commands, config snippets, notes, and links.
What this setup does
- Install Cockpit as a lightweight Linux server dashboard.
- Open Cockpit on the default port
9090for the first test. - Restrict Cockpit to
127.0.0.1:9090. - Put Caddy in front of Cockpit for a trusted HTTPS certificate.
- Add a few optional Cockpit applications.
- Use Cockpit’s remote login flow to connect to another server over SSH.
Install Cockpit
Commands vary by distribution. Check the official installation page first:
For Ubuntu LTS releases, Cockpit usually recommends installing from backports:
. /etc/os-release
sudo apt install -t ${VERSION_CODENAME}-backports cockpit
On my Ubuntu 26.04 test VM, Cockpit was available from the normal universe repository, so this was enough:
sudo apt update
sudo apt install cockpit
Enable the Cockpit socket:
sudo systemctl enable --now cockpit.socket
Open Cockpit in the browser:
https://<server-ip>:9090
Login with a normal Linux user account.
Make Cockpit listen only on localhost
Create a systemd socket override:
sudo mkdir -p /etc/systemd/system/cockpit.socket.d
sudo nano /etc/systemd/system/cockpit.socket.d/listen.conf
/etc/systemd/system/cockpit.socket.d/listen.conf
[Socket]
ListenStream=
ListenStream=127.0.0.1:9090
Notes:
- The empty
ListenStream=line clears the default listener. - Without it, systemd may keep the original Cockpit listener as well.
- This only makes sense when the reverse proxy runs on the same server as Cockpit.
Apply and verify:
sudo systemctl daemon-reload
sudo systemctl restart cockpit.socket
sudo systemctl status cockpit.socket
sudo ss -ltnp | grep 9090
Cockpit reverse proxy settings
Create or edit the Cockpit config:
sudo nano /etc/cockpit/cockpit.conf
/etc/cockpit/cockpit.conf
[WebService]
Origins = https://cockpit.example.com wss://cockpit.example.com
ProtocolHeader = X-Forwarded-Proto
Replace cockpit.example.com with the real DNS name you use for the dashboard.
Notes:
- Cockpit uses WebSockets, so the external browser origin must be allowed.
ProtocolHeader = X-Forwarded-Prototells Cockpit that the browser-facing connection is HTTPS.
Restart Cockpit:
sudo systemctl restart cockpit.socket
Caddy reverse proxy example
Example Caddyfile with DNS-01 through Cloudflare:
/etc/caddy/Caddyfile
cockpit.example.com {
tls {
dns cloudflare {env.CF_API_TOKEN}
resolvers 1.1.1.1
}
reverse_proxy https://127.0.0.1:9090 {
header_up Host {host}
transport http {
tls_insecure_skip_verify
}
}
}
Apply the Caddy config:
sudo caddy fmt --overwrite /etc/caddy/Caddyfile
sudo systemctl reload caddy
sudo journalctl -u caddy -f
Important: protect custom xcaddy builds from apt upgrades
Yes: if you simply replace /usr/bin/caddy with an xcaddy build, a future apt upgrade of the caddy package can overwrite that custom binary with the packaged Caddy binary. That would remove custom modules such as the Cloudflare DNS plugin.
The Caddy project recommends using Debian's dpkg-divert plus update-alternatives when you want to keep the packaged service files but run a custom binary:
sudo systemctl stop caddy
sudo dpkg-divert --divert /usr/bin/caddy.default --rename /usr/bin/caddy
sudo mv ./caddy /usr/bin/caddy.custom
sudo update-alternatives --install /usr/bin/caddy caddy /usr/bin/caddy.default 10
sudo update-alternatives --install /usr/bin/caddy caddy /usr/bin/caddy.custom 50
sudo systemctl start caddy
caddy version
caddy list-modules | grep cloudflare
With this setup, package upgrades update /usr/bin/caddy.default, while /usr/bin/caddy remains managed by alternatives and points to /usr/bin/caddy.custom.
To switch manually between the packaged and custom binary:
sudo update-alternatives --config caddy
sudo systemctl restart caddy
Notes:
tls_insecure_skip_verifyis acceptable here only because the upstream connection is local: Caddy →127.0.0.1:9090.- For a remote upstream, use a proper certificate or internal CA instead.
- If Caddy runs as a systemd service, make sure
CF_API_TOKENis available to the service environment. - Be careful with commands like
caddy run --environwhile recording or sharing logs, because they can print environment variables.
Ubuntu / PackageKit offline workaround
If Cockpit’s Software Updates page shows something like Cannot refresh cache whilst offline, this can happen on Ubuntu/Debian when NetworkManager is not managing the main interface.
Cockpit FAQ:
Workaround from the Cockpit FAQ:
sudo mkdir -p /etc/NetworkManager/conf.d
sudo nano /etc/NetworkManager/conf.d/10-globally-managed-devices.conf
/etc/NetworkManager/conf.d/10-globally-managed-devices.conf
[keyfile]
unmanaged-devices=none
Add a dummy NetworkManager interface:
sudo nmcli con add type dummy con-name fake ifname fake0 ip4 192.0.2.2/24 gw4 192.0.2.1
sudo reboot
Verify after reboot:
nmcli general status
nmcli device status
Optional Cockpit applications
Official Cockpit applications:
For optional Cockpit applications, follow the installation instructions from the linked project or GitHub repository, because the setup can vary depending on the operating system, distribution version, and packaging method.
Remote server management
Cockpit can connect to another Linux server over SSH from the login page.
Basic flow:
Logout → Connect to → <remote-server-ip-or-hostname> → Login
Notes:
- The remote server needs SSH access.
- The remote server needs Cockpit or at least the Cockpit bridge available.
- The remote server does not need to expose Cockpit on port
9090. - The old multi-host/host-switching feature is deprecated, so I would not use Cockpit as a central management platform for random or untrusted servers.