[{"data":1,"prerenderedAt":287},["ShallowReactive",2],{"seo-verification":3,"blog-self-host-headscale-on-a-vps-your-own-tailscale-control-server-ma-en":6,"promo-bar-likely":286},{"google":4,"bing":5},"EycwPY2XMyTkVzas3n1ygeNJFGAH513qrMjfDljzsMQ","",{"key":7,"data":8},"blog-self-host-headscale-on-a-vps-your-own-tailscale-control-server-ma-en",{"id":9,"slug":10,"slugs":11,"title":15,"excerpt":16,"readTime":17,"views":18,"isPinned":19,"noindex":19,"publishedAt":20,"updatedAt":21,"category":22,"categories":28,"featuredImage":30,"bgImage":31,"posterImage":32,"relatedSolution":33,"intro":36,"sections":37,"ctaTitle":226,"ctaBody":227,"ctaButton":228,"ctaUrl":229,"relatedPosts":230},164,"self-host-headscale-on-a-vps-your-own-tailscale-control-server",{"fr":12,"en":10,"ar":13,"es":14},"self-host-headscale-tailscale-vps","استضافة-headscale-على-vps-خادم-تحكم-tailscale-خاص-بك","auto-alojar-headscale-en-un-vps-servidor-tailscale","Self-Host Headscale on a VPS: Your Own Tailscale Control Server","Replace Tailscale's cloud control server with Headscale on your own VPS — unlimited users, full WireGuard mesh networking, magic DNS and ACLs, with no SaaS dependency.",19,2,false,"2026-07-05T00:00:00+00:00","2026-11-08T01:13:12+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":27},8,"Security & Monitoring","securite-monitoring","bg-rose-500\u002F10 text-rose-400","security",[29],{"id":23,"name":24,"slug":25,"color":26,"icon":27},null,"\u002Fblog\u002Fcovers\u002Fbg.svg","\u002Fblog\u002Fcovers\u002Fself-host-headscale-tailscale-vps-poster.svg",{"categorySlug":34,"appSlug":35},"networking-vpn","headscale","Tailscale's free tier (Personal) stops at 6 users, the Standard plan is billed per seat beyond that, and either way your network map lives in Tailscale's cloud. Headscale (BSD-3-Clause, more than 45,000 GitHub stars) is a drop-in open-source replacement for the Tailscale coordination server — deploy it on your VPS and keep using the official Tailscale clients on every device. Your team connects with zero-trust WireGuard tunnels, magic DNS and ACL-based access control, all self-hosted with no user cap.\n\nThis guide covers installation (Docker or `.deb` package), the HTTPS reverse proxy, mesh verification, moving a team that already runs on Tailscale, the break-even maths and what Headscale cannot do.",[38,42,56,59,66,91,94,109,112,116,119,131,134,146,149,164,167,208,211,218],{"type":39,"title":40,"body":41},"h2","Why self-host the control server","Tailscale is exceptional software — WireGuard performance, cross-platform clients, magic DNS that just works. Yet it does not carry your traffic: WireGuard packets travel directly from node to node, encrypted end to end. What runs in Tailscale's cloud is the control plane — the coordination server that exchanges public keys, lets peers discover each other, assigns `100.x.y.z` addresses, publishes MagicDNS names and distributes ACLs and the DERP relay map. Without it, nodes cannot find each other. Headscale reimplements that coordination server in open-source Go, speaking the same protocol, so you can run it on your own infrastructure: your Tailscale clients only change their login URL.\n\nBeyond the 6-user cap of the free tier, the main reason to self-host is data residency: the control plane knows which machines are on your network, their IPs, their names and your ACL policies. Running Headscale means that information stays on your VPS — not in someone else's cloud — and your network no longer depends on a third party's pricing decision or outage.",{"type":43,"title":44,"items":45},"ul","What self-hosted Headscale gives you",[46,47,48,49,50,51,52,53,54,55],"Users and devices without a cap: no limit imposed by the software, no per-seat pricing — your mesh grows with your team, bounded only by the VPS resources.","Official Tailscale clients everywhere: Linux, macOS, Windows, iOS, Android — no custom fork or alternative client required.","WireGuard peer-to-peer tunnels: Headscale only handles key exchange and ACL distribution; all actual traffic flows directly over WireGuard between peers.","Magic DNS: resolve every node in your mesh by hostname (`laptop.mesh.yourdomain.com`) without touching your public DNS.","HuJSON policies: the same policy file format as Tailscale, with ACLs and Grants — define which users and devices can reach which services.","DERP relay support: use Tailscale's public DERP map for NAT traversal, or enable Headscale's embedded DERP server to keep the relays in-house too.","headscale API and CLI: create users, issue pre-auth keys and manage nodes programmatically.","Registration without a tailscale.com account: your colleagues join the network with a key you generate, or through the OpenID Connect provider you already use (Keycloak, Authelia, Google Workspace…).","Subnet routers, exit nodes, Taildrop and Tailscale SSH: Tailscale's base features are supported by the server.","Under 50 MB of RAM at idle — runs comfortably on a 1 GB VPS alongside other workloads.",{"type":39,"title":57,"body":58},"Requirements","A VPS with at least 1 vCPU and 512 MB of RAM (1 GB leaves headroom for the system) running Ubuntu 22.04 or newer, or Debian 12 or newer — the distributions targeted by the official packages. For the Docker route, install Docker and Docker Compose v2. A public IP is required; a dual-stack IPv4 + IPv6 setup is recommended.\n\nA domain name pointing to the VPS is **required**: Tailscale clients connect to the control server by URL, and the project strongly recommends serving Headscale over HTTPS on port 443, since the Tailscale client assumes that port in some situations. Plan one subdomain for the server (`vpn.yourdomain.com`) and a separate one for MagicDNS names (`mesh.yourdomain.com`): Headscale refuses a MagicDNS domain equal to the `server_url` domain.",{"type":43,"title":60,"items":61},"Ports to open on the VPS",[62,63,64,65],"TCP 443: mandatory. Clients register and receive the network map over HTTPS; it is the only port the coordination server cannot do without.","TCP 80: only for Let's Encrypt HTTP-01 validation and the redirect to HTTPS.","UDP 3478: only if you enable the embedded DERP server, which needs it for STUN. With Tailscale's public DERP map there is no need to open it.","TCP 8080 (Headscale), 9090 (metrics) and 50443 (gRPC): keep them on `127.0.0.1`. The reverse proxy talks to 8080 locally; never expose the gRPC admin interface unless you need it.",{"type":67,"title":68,"steps":69},"steps","Deploy Headscale with Docker Compose",[70,73,76,79,82,85,88],{"title":71,"body":72},"Write the Compose file","The stack is a single service: the official `docker.io\u002Fheadscale\u002Fheadscale:0.29.7` image, the latest stable release as of 7 November 2026, started with the `serve` command. Headscale keeps everything — keys, database, node records — in two host directories: the configuration, mounted read-only at `\u002Fetc\u002Fheadscale`, and the data, at `\u002Fvar\u002Flib\u002Fheadscale`. No external database or cache service is needed; SQLite is built in.\n\n```bash\nmkdir -p \u002Fopt\u002Fheadscale\u002Fconfig \u002Fopt\u002Fheadscale\u002Flib\ncat > \u002Fopt\u002Fheadscale\u002Fcompose.yaml \u003C\u003C'EOF'\nservices:\n  headscale:\n    image: docker.io\u002Fheadscale\u002Fheadscale:0.29.7\n    container_name: headscale\n    restart: unless-stopped\n    read_only: true\n    tmpfs:\n      - \u002Fvar\u002Frun\u002Fheadscale\n    ports:\n      - \"127.0.0.1:8080:8080\"\n    volumes:\n      - \u002Fopt\u002Fheadscale\u002Fconfig:\u002Fetc\u002Fheadscale:ro\n      - \u002Fopt\u002Fheadscale\u002Flib:\u002Fvar\u002Flib\u002Fheadscale\n    command: serve\n    healthcheck:\n      test: [\"CMD\", \"headscale\", \"health\"]\nEOF\n```\n\nThe port is only published on `127.0.0.1`: the reverse proxy is what faces the internet.",{"title":74,"body":75},"Generate the configuration","Start from the example file of the exact version you deploy, then change only the keys below. `server_url` is the HTTPS URL your Tailscale clients will connect to; `listen_addr` must listen on `0.0.0.0` inside the container. The database is declared under `database` (`type: sqlite`). Only the noise key path remains to set: Headscale generates it on first start if the file does not exist.\n\n```bash\ncurl -Lo \u002Fopt\u002Fheadscale\u002Fconfig\u002Fconfig.yaml \\\n  https:\u002F\u002Fraw.githubusercontent.com\u002Fjuanfont\u002Fheadscale\u002Fv0.29.7\u002Fconfig-example.yaml\n```\n\n```yaml\nserver_url: https:\u002F\u002Fvpn.yourdomain.com\nlisten_addr: 0.0.0.0:8080\nnoise:\n  private_key_path: \u002Fvar\u002Flib\u002Fheadscale\u002Fnoise_private.key\ndatabase:\n  type: sqlite\n  sqlite:\n    path: \u002Fvar\u002Flib\u002Fheadscale\u002Fdb.sqlite\ndns:\n  magic_dns: true\n  base_domain: mesh.yourdomain.com\n```\n\nOn ServOrbit, the provisioning job writes `config.yaml` from your domain automatically.",{"title":77,"body":78},"Start the container and verify","Run `docker compose up -d` from `\u002Fopt\u002Fheadscale`. Headscale generates its noise key, then starts listening on port 8080. Check the health endpoint: `curl -s http:\u002F\u002F127.0.0.1:8080\u002Fhealth` should return `{\"status\":\"pass\"}`. The image is built on a distroless base with no shell, but the headscale CLI can be called directly: `docker exec headscale headscale version` confirms the running version, and `docker logs --follow headscale` shows the logs.",{"title":80,"body":81},"Create a user and generate an auth key","Headscale organizes devices into 'users' (formerly called namespaces). Create one, then note its numeric identifier: the `--user` option of `preauthkeys create` expects that ID, not the name.\n\n```bash\ndocker exec headscale headscale users create myteam\ndocker exec headscale headscale users list\ndocker exec headscale headscale preauthkeys create --user 1 --reusable --expiration 24h\n```\n\nWithout `--reusable` the key works only once, and without `--expiration` it expires after one hour. Copy the printed key — you will use it when registering each device.",{"title":83,"body":84},"Register a device","On any device with the official Tailscale client, point it at your Headscale instance: `tailscale up --login-server https:\u002F\u002Fvpn.yourdomain.com --authkey \u003Cyour-preauth-key>`. The device appears in Headscale's node list within seconds: `docker exec headscale headscale nodes list`. Without a key, the client opens a page showing an authentication ID; approve it on the server with `docker exec headscale headscale auth register --user myteam --auth-id \u003CAUTH_ID>`. Once registered, devices reach each other by their mesh IP (`100.64.x.y`) or by magic DNS hostname.",{"title":86,"body":87},"Define access control policies","As long as no policy is loaded, Headscale lets all traffic flow between nodes — fine for a small trusted team, not once developer laptops, contractors and production servers share the network. Create `\u002Fopt\u002Fheadscale\u002Fconfig\u002Fpolicy.hujson` and declare it in `config.yaml` with `policy.path: \u002Fetc\u002Fheadscale\u002Fpolicy.hujson`. Headscale uses the same HuJSON format as Tailscale: define user groups, tag devices as servers or workstations, and write rules stating which groups can reach which ports. The project recommends Grants over ACLs, which Tailscale considers legacy. Validate the file with `headscale policy check --file \u003Cfile>`, then reload: the policy is only re-read on reload (`docker kill --signal=HUP headscale`, or `systemctl reload headscale` on a native install). Keep the file in a private Git repository to retain a history of access changes.",{"title":89,"body":90},"Logging in for the first time","Headscale has no web interface and no account: it is the control server of your private network, driven from the command line. Over SSH: `docker exec -it headscale headscale users create monuser`, then the key with `preauthkeys create --user \u003CID> --reusable --expiration 24h`, and connect your machines with `tailscale up --login-server https:\u002F\u002F\u003Cyour-domain> --authkey \u003Ckey>`. The graphical apps can target a custom server too: on macOS, Option + click the Tailscale icon, open the Debug menu, then `Custom Login Server`; on iOS, `Use custom coordination server` in the login menu; on Android, `Use an alternate server`; on Windows, `tailscale login --login-server` in PowerShell.",{"type":39,"title":92,"body":93},"Without Docker: the official .deb package","The project publishes `.deb` packages for Debian and Ubuntu and recommends them on those distributions: they create the `headscale` system user, ship a default configuration and install the systemd unit. It is the simplest route if Headscale runs alone on its VPS or if you prefer a native service to a container. The management commands are the same as above, without the `docker exec headscale` prefix.",{"type":67,"title":95,"steps":96},"Install Headscale from the .deb package",[97,100,103,106],{"title":98,"body":99},"Download and install the package","Fetch the package for the version you want from the GitHub releases page, for your architecture (`amd64` or `arm64`), and install it with `apt`, which resolves dependencies:\n\n```bash\nHEADSCALE_VERSION=\"0.29.7\"\nHEADSCALE_ARCH=\"amd64\"\nwget --output-document=headscale.deb \\\n  \"https:\u002F\u002Fgithub.com\u002Fjuanfont\u002Fheadscale\u002Freleases\u002Fdownload\u002Fv${HEADSCALE_VERSION}\u002Fheadscale_${HEADSCALE_VERSION}_linux_${HEADSCALE_ARCH}.deb\"\nsudo apt install .\u002Fheadscale.deb\n```\n\nThen check: `headscale version` should print `0.29.7`.",{"title":101,"body":102},"Adapt the configuration","The package puts the configuration in `\u002Fetc\u002Fheadscale\u002Fconfig.yaml` and an up-to-date example in `\u002Fusr\u002Fshare\u002Fdoc\u002Fheadscale\u002Fexamples\u002Fconfig-example.yaml`. Change the same keys as for Docker (`server_url`, `database`, `dns.base_domain`), but keep `listen_addr: 127.0.0.1:8080`: the service runs on the host, and only the reverse proxy should reach it. Data lives in `\u002Fvar\u002Flib\u002Fheadscale`.",{"title":104,"body":105},"Restart and check the service","Restart the service so it re-reads the configuration, then check its state and logs:\n\n```bash\nsudo systemctl restart headscale\nsudo systemctl status headscale\nsudo journalctl -u headscale -f\n```\n\nThe output should show `Active: active (running)`. On first start, the most common errors are a `server_url` without the `https:\u002F\u002F` scheme and a MagicDNS domain identical to the server's.",{"title":107,"body":108},"Use the CLI without being root","The CLI talks to the service through the Unix socket `\u002Fvar\u002Frun\u002Fheadscale\u002Fheadscale.sock`, which by default only the `headscale` user and root can access. Use `sudo`, run the commands as the `headscale` user, or add your account to the `headscale` group. Check access with `headscale users list`.",{"type":39,"title":110,"body":111},"Serve Headscale over HTTPS behind Nginx","Tailscale clients talk to Headscale with their own protocol, carried over a WebSocket connection opened with POST, whose `Upgrade` header is `tailscale-control-protocol`. The reverse proxy must therefore pass the `Upgrade` and `Connection` headers through unchanged and must not buffer responses. The configuration below follows the example in the project documentation; get the certificate first with certbot (`certbot certonly --nginx -d vpn.yourdomain.com`).\n\n```nginx\nmap $http_upgrade $connection_upgrade {\n  default keep-alive;\n  ''      close;\n}\n\nserver {\n  listen 80;\n  server_name vpn.yourdomain.com;\n  location = \u002Fgenerate_204 { return 204; }\n  location \u002F { return 301 https:\u002F\u002F$server_name$request_uri; }\n}\n\nserver {\n  listen 443 ssl;\n  http2 on;\n  server_name vpn.yourdomain.com;\n  ssl_certificate     \u002Fetc\u002Fletsencrypt\u002Flive\u002Fvpn.yourdomain.com\u002Ffullchain.pem;\n  ssl_certificate_key \u002Fetc\u002Fletsencrypt\u002Flive\u002Fvpn.yourdomain.com\u002Fprivkey.pem;\n\n  location \u002F {\n    proxy_http_version 1.1;\n    proxy_set_header Upgrade $http_upgrade;\n    proxy_set_header Connection $connection_upgrade;\n    proxy_set_header Host $host;\n    proxy_set_header X-Real-IP $remote_addr;\n    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n    proxy_set_header X-Forwarded-Proto $scheme;\n    proxy_buffering off;\n    proxy_pass http:\u002F\u002F127.0.0.1:8080;\n  }\n}\n```\n\nLeave `tls_cert_path` and `tls_key_path` empty in `config.yaml`: Nginx terminates TLS, so the `listening without TLS` warning at startup is expected. For Headscale's logs to show clients' real IPs, declare the proxy as a trusted source. On a native install the loopback is enough; with Docker, also add the Docker bridge network (`docker network inspect`), because the container sees the proxy arriving from its gateway:\n\n```yaml\ntrusted_proxies:\n  - 127.0.0.1\u002F32\n  - ::1\u002F128\n```\n\nCaddy works as well, with a plain `reverse_proxy 127.0.0.1:8080`. The Cloudflare proxy and Cloudflare Tunnel, however, are not supported, since they do not handle WebSocket POSTs: the server's DNS record must stay DNS-only.",{"type":113,"title":114,"body":115},"tip","Pair Headscale with Authelia for MFA-protected network access","Headscale handles network-layer access control (which IPs can talk to which peers), but it does not enforce application-layer authentication. Pair it with \u003Ca href=\"\u002Fen\u002Fblog\u002Fself-host-authelia-on-a-vps-mfa-and-sso-for-your-whole-stack\">Authelia on the same VPS\u003C\u002Fa>: route your internal services (reachable only through the mesh) through Authelia's forward-auth layer. Users must complete MFA to access services even once they are on the mesh — defense in depth for sensitive workloads.",{"type":39,"title":117,"body":118},"Check that nodes can see each other","A node listed by `headscale nodes list` only proves it reached the coordination server. Before routing real traffic through the mesh, check the end-to-end path from the clients themselves.",{"type":67,"title":120,"steps":121},"Check the mesh from a client",[122,125,128],{"title":123,"body":124},"Read the network state","On a registered node, run `tailscale status`. It lists peers with their mesh IP, name and link type: `direct` means the WireGuard tunnel is established with no intermediary, `relay` means it goes through a DERP relay — working, but with higher latency.",{"title":126,"body":127},"Test connectivity","Take a peer's IP from `tailscale status`, then `ping 100.64.0.2`, or better `tailscale ping \u003Cnode-name>`, which tells you whether the reply arrives directly or through a relay. If the peer is listed but does not answer, `tailscale netcheck` measures latency to each DERP region and reports filtered outbound UDP.",{"title":129,"body":130},"Test MagicDNS resolution","With `dns.magic_dns: true`, every node answers to its short and full names: `ping node-name` or `ping node-name.mesh.yourdomain.com`. No public DNS record is needed for these internal names. If resolution fails, `tailscale dns status` shows the DNS configuration the client received from the server.",{"type":39,"title":132,"body":133},"Use case: SSH between VPSs without exposing port 22","Once your development and production VPSs are registered on the same mesh, SSH no longer needs to listen on the public interface: the connection uses the mesh address, inside the WireGuard tunnel. Keep console access open at your provider before touching the firewall, in case a rule locks you out.",{"type":67,"title":135,"steps":136},"Restrict SSH to the mesh network",[137,140,143],{"title":138,"body":139},"Find the mesh interface and address","On each VPS, the Tailscale client creates the `tailscale0` interface. `tailscale ip -4` prints the machine's mesh address; note the production server's, for example `100.64.0.3`.",{"title":141,"body":142},"Allow SSH only through tailscale0","On the production VPS, allow SSH on the mesh interface before denying it elsewhere — UFW applies the first matching rule:\n\n```bash\nufw allow in on tailscale0 to any port 22 proto tcp\nufw deny 22\u002Ftcp\nufw enable\nufw status verbose\n```\n\nPort 22 is no longer reachable from the internet, but stays open to every mesh node your policy allows.",{"title":144,"body":145},"Connect through the mesh","From the development VPS or your registered workstation, connect by IP or MagicDNS name: `ssh user@100.64.0.3` or `ssh user@vps-prod.mesh.yourdomain.com`. Everything travels inside the encrypted tunnel; then restrict in the Headscale policy which groups can reach this server's port 22.",{"type":39,"title":147,"body":148},"Migrate a team already on Tailscale","The switch requires no reinstallation: the official client accepts the `--login-server` option, so you only log it out of the old network and back into your server. Each machine drops for a few seconds during the operation. Because your server assigns `100.x` addresses and MagicDNS names itself, plan to update the scripts, firewall rules and configuration files that reference the old ones.",{"type":67,"title":150,"steps":151},"Move clients over to Headscale",[152,155,158,161],{"title":153,"body":154},"Carry over the access policy","Copy your tailnet's policy file from the Access controls editor in the Tailscale console and start from it: the HuJSON format is the same. Check it with `headscale policy check` before the switch — some features, such as IP sets, are not supported, and only a subset of autogroups exists.",{"title":156,"body":157},"Log each client out, then back in","On Linux or from the command line, chain the logout and the reconnection with a pre-auth key:\n\n```bash\ntailscale logout\ntailscale up --login-server https:\u002F\u002Fvpn.yourdomain.com --authkey \u003CPREAUTHKEY>\n```\n\nOn macOS, iOS, Android and Windows, log the account out in the app, then add the custom server as described above.",{"title":159,"body":160},"Start with test machines","Switch a test workstation and a test server first, check `tailscale status` and name resolution, then the development machines and, last, production. While some machines remain on the other side, the two networks cannot see each other: plan to move a service and its clients in the same window.",{"title":162,"body":163},"Close or downgrade the Tailscale account","Once all nodes are migrated and verified, close the tailnet or move back to the Personal plan if you keep a personal use. Generate a fresh pre-auth key for future registrations rather than keeping the migration key forever.",{"type":39,"title":165,"body":166},"Headscale vs Tailscale Cloud","Tailscale Cloud remains the easier path for small teams: no server to maintain, automatic upgrades, integrated billing — and the Personal plan stays free up to 6 users. Beyond that, the Standard plan is listed at $8 per user per month on the pricing grid in force since 8 April 2026: $40 a month for five people, $80 for ten. Headscale costs the price of the VPS whatever the headcount — on ServOrbit, the VPS Solo (2 vCPU \u002F 4 GB) at 99 DH\u002Fmonth is enough for dozens of nodes — plus operating time: upgrades, backups, monitoring.\n\nHeadscale therefore makes sense beyond 6 users, when data residency requires keeping your network topology off third-party servers, or when you want full auditability of your coordination logs. The clients are identical — moving from Tailscale Cloud to Headscale means re-running `tailscale up --login-server` on each device.",{"type":168,"title":169,"headers":170,"rows":175},"comparison","Tailscale Personal, Tailscale Standard and Headscale",[171,172,173,174],"Criterion","Tailscale Personal","Tailscale Standard","Headscale on a VPS",[176,181,186,188,192,196,200,204],[177,178,179,180],"Price","Free","$8 per user per month","The cost of the VPS",[182,183,184,185],"Users","Up to 6","No cap","No software limit",[187,184,184,185],"User devices",[189,190,190,191],"Coordination server","Tailscale cloud","Your VPS, under your control",[193,194,194,195],"Client","Official Tailscale client","Official Tailscale client (`--login-server`)",[197,198,198,199],"MagicDNS, ACLs, Grants","Yes","Yes, on your own domain",[201,202,202,203],"Funnel and Serve","Offered by Tailscale","Not supported",[205,206,206,207],"Maintenance","None (managed service)","Upgrades, backups, monitoring",{"type":39,"title":209,"body":210},"What Headscale does not replace","Headscale implements the coordination server, not the whole commercial platform. Its own documentation lists what is missing: Tailscale Funnel (publishing a local service to the internet), Tailscale Serve (sharing it in the tailnet through a local proxy) and network flow logs are not supported; OIDC groups cannot be used in ACLs. There is no official web console either: everything goes through the CLI or the API. If your use is limited to mesh connectivity, MagicDNS, access policies, subnet routers and exit nodes, Headscale covers the need; if you actively use Funnel or Serve, weigh those features against the savings before migrating — or look at \u003Ca href=\"\u002Fen\u002Fblog\u002Fnetbird-self-hosted-wireguard-mesh-vpn-on-a-vps\">NetBird\u003C\u002Fa>, which self-hosts its admin interface too.",{"type":43,"title":212,"items":213},"Backups and upgrades",[214,215,216,217],"Back up before every upgrade: Headscale applies its database migrations when the new version starts. Stop the service, copy the configuration and data, then start it again: `cd \u002Fopt\u002Fheadscale && docker compose stop`, `cp -aR \u002Fopt\u002Fheadscale \u002Fopt\u002Fheadscale.backup-$(date +%Y%m%d%H%M%S)`, `docker compose up -d`.","The data directory holds `db.sqlite` and `noise_private.key`: losing that key changes the server's identity and forces every node to re-register. Copy it off the VPS as well, for example to object storage.","Upgrade one version at a time: the project requires going through each stable minor version (for example `0.27`, then `0.28`, then `0.29`), always at its latest patch, without skipping any.","Read the release notes on GitHub before each upgrade: they flag breaking configuration changes. Then compare your `config.yaml` with the new version's example file.",{"type":43,"title":219,"items":220},"Troubleshooting: the most common errors",[221,222,223,224,225],"The client cannot register: check that `https:\u002F\u002Fvpn.yourdomain.com\u002Fhealth` answers from outside, that `server_url` exactly matches the certificate's domain, and that the proxy passes the `Upgrade` and `Connection` headers.","Connections in `relay` instead of `direct`: a strict NAT or a firewall blocks UDP between the two nodes. Run `tailscale netcheck` on both sides to see what is filtered; traffic still flows, through the DERP relays.","Node listed as `offline`: the client reached the server but does not keep the session. Check `systemctl status tailscaled` and `journalctl -u tailscaled` on the node; a local firewall cutting outbound connections is the most common cause.","Headscale refuses to start after an upgrade: a configuration key was renamed or removed. The log names it; refer to the example file of the installed version.","MagicDNS does not resolve: check that `dns.magic_dns` is `true` and that `dns.base_domain` differs from the `server_url` domain, then reconnect the client so it fetches the new DNS configuration.","Deploy Headscale on your VPS in one click","Self-host your Tailscale control server with unlimited users and no cloud dependency. ServOrbit provisions a ready-to-use Headscale instance — config generated, HTTPS ready, first auth key printed in the job output.","Deploy Headscale","\u002Fvps-cloud?template=headscale",[231,249,268],{"id":232,"slug":233,"slugs":234,"title":238,"excerpt":239,"readTime":240,"views":18,"isPinned":19,"noindex":19,"publishedAt":241,"updatedAt":21,"category":242,"categories":243,"featuredImage":30,"bgImage":31,"posterImage":245,"relatedSolution":246},141,"wireguard-on-a-vps-a-fast-lean-and-private-vpn",{"fr":235,"en":233,"ar":236,"es":237},"installer-wireguard-vps","wireguard-على-خادم-vps-شبكة-vpn-سريعة-ومبسطة-وخاصة","wireguard-en-un-vps-vpn-rapido-y-privado","WireGuard on a VPS: a fast, lean and private VPN","Deploy WireGuard on a ServOrbit VPS: fast tunnels, readable configuration, client QR codes and private remote access.",7,"2026-02-04T00:00:00+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":27},[244],{"id":23,"name":24,"slug":25,"color":26,"icon":27},"\u002Fblog\u002Fcovers\u002Finstaller-wireguard-vps-poster.svg",{"categorySlug":247,"appSlug":248},"securite","wireguard-server",{"id":250,"slug":251,"slugs":252,"title":256,"excerpt":257,"readTime":258,"views":259,"isPinned":19,"noindex":19,"publishedAt":260,"updatedAt":261,"category":262,"categories":263,"featuredImage":30,"bgImage":31,"posterImage":265,"relatedSolution":266},162,"self-host-authelia-on-a-vps-mfa-and-sso-for-your-whole-stack",{"fr":253,"en":251,"ar":254,"es":255},"self-host-authelia-vps","استضافة-authelia-على-vps-مصادقة-ثنائية-ودخول-موحد-لمنظومتك","alojar-authelia-en-un-vps","Self-hosting Authelia on a VPS: MFA and SSO for your entire stack","Deploy Authelia on a VPS with Docker Compose: TOTP, WebAuthn\u002Fpasskey, OIDC, LLDAP migration, Prometheus monitoring, and comparison with Authentik.",10,4,"2026-07-04T00:00:00+00:00","2026-09-24T12:27:51+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":27},[264],{"id":23,"name":24,"slug":25,"color":26,"icon":27},"\u002Fblog\u002Fcovers\u002Fself-host-authelia-vps-poster.svg",{"categorySlug":27,"appSlug":267},"authelia",{"id":269,"slug":270,"slugs":271,"title":275,"excerpt":276,"readTime":23,"views":277,"isPinned":19,"noindex":19,"publishedAt":278,"updatedAt":279,"category":280,"categories":281,"featuredImage":30,"bgImage":31,"posterImage":283,"relatedSolution":284},140,"openvpn-on-a-vps-private-controlled-remote-access",{"fr":272,"en":270,"ar":273,"es":274},"installer-openvpn-serveur-vps","openvpn-على-خادم-vps-وصول-عن-بعد-خاص-ومضبوط","openvpn-en-un-vps-acceso-remoto-privado","OpenVPN on VPS: install, harden and troubleshoot","Install OpenVPN Server on your VPS: prerequisites, Easy-RSA, server.conf, .ovpn profiles, fail2ban, ufw and common error troubleshooting.",0,"2026-02-05T00:00:00+00:00","2026-09-30T11:20:33+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":27},[282],{"id":23,"name":24,"slug":25,"color":26,"icon":27},"\u002Fblog\u002Fcovers\u002Finstaller-openvpn-serveur-vps-poster.svg",{"categorySlug":247,"appSlug":285},"openvpn-server",true,1794270486997]