
Trả lời nhanh: Chạy Tailscale trong Docker bằng image chính chủ tailscale/tailscale: cấp /dev/net/tun + cap NET_ADMIN, đăng nhập bằng biến TS_AUTHKEY, mount volume giữ state. Pattern đáng giá nhất là sidecar: container app dùng network_mode: service:tailscale: app xuất hiện trong tailnet như một máy riêng, không mở port nào trên host.
Khi dịch vụ đã đóng gói Docker cả, câu hỏi tự nhiên: Tailscale nên đứng ở đâu, cài trên host hay chạy trong container? Bài này trả lời dứt điểm bằng tiêu chí chọn, rồi đi sâu pattern được cộng đồng dùng nhiều nhất: sidecar cho từng dịch vụ, mỗi container một danh tính tailnet riêng, bật tắt theo compose file, cực hợp mô hình VPS chạy nhiều dịch vụ nội bộ chỉ dành cho tailnet.
- Chọn nhanh: host cài Tailscale khi cả máy cần vào tailnet; container khi muốn từng dịch vụ có danh tính riêng
- Image
tailscale/tailscalecần: /dev/net/tun, cap NET_ADMIN, volume state, TS_AUTHKEY - Sidecar: app
network_mode: service:ts: dịch vụ vào tailnet như một máy độc lập - Auth key nên loại reusable + tag để container recreate không phải đăng nhập lại
- Kết hợp TS_SERVE/funnel biến container thành dịch vụ HTTPS nội bộ hoặc công khai
Host hay container: chọn theo bài toán
Cài Tailscale trên host (như bài cài đặt) khi: bạn cần SSH vào máy qua tailnet, và các container chỉ cần được truy cập qua địa chỉ host, đơn giản nhất, một danh tính cho cả máy. Chạy Tailscale trong container khi: muốn mỗi dịch vụ là một node riêng trong tailnet (tên riêng, ACL riêng), môi trường không cho cài lên host (NAS hạn chế, PaaS), hay cả stack phải nằm gọn trong một compose file dựng lại được ở bất cứ đâu. Hai cách chung sống tốt: host có Tailscale để quản trị, vài dịch vụ nhạy cảm thêm sidecar riêng để siết ACL.
Chạy container Tailscale chuẩn: các mảnh bắt buộc
docker run -d --name=ts-node
--cap-add=NET_ADMIN
--device=/dev/net/tun
-v ts-state:/var/lib/tailscale
-e TS_AUTHKEY=tskey-auth-xxxxx
-e TS_HOSTNAME=docker-node-01
tailscale/tailscaleBốn mảnh không được thiếu: NET_ADMIN + /dev/net/tun cho phép tạo giao diện mạng ảo; volume /var/lib/tailscale giữ khóa máy, thiếu nó, mỗi lần recreate là một node mới mọc ra trong console; TS_AUTHKEY đăng nhập không cần trình duyệt, tạo loại reusable gắn tag (ví dụ tag:docker) như bài Ubuntu toàn tập hướng dẫn để không hết hạn theo user. Môi trường không cấp được tun (một số host bó tay) vẫn chạy được ở chế độ userspace networking, chậm hơn nhưng thông.
Pattern sidecar: mỗi dịch vụ một danh tính tailnet
Đây là lý do thật để đọc bài này. Ví dụ đưa một dashboard nội bộ (cổng 3000) vào tailnet, không mở port nào trên host:
services:
ts-dashboard:
image: tailscale/tailscale
hostname: dashboard # ten hien trong tailnet
cap_add: [NET_ADMIN]
devices: [/dev/net/tun]
volumes: [ts-dashboard:/var/lib/tailscale]
environment:
- TS_AUTHKEY=tskey-auth-xxxxx
restart: unless-stopped
dashboard:
image: ten-app-cua-ban
network_mode: service:ts-dashboard # chia se network voi sidecar
depends_on: [ts-dashboard]
volumes:
ts-dashboard:Dòng ăn tiền là network_mode: service:ts-dashboard: container app dùng chung network namespace với sidecar, nên mọi thiết bị trong tailnet mở http://dashboard:3000 là tới, còn internet công cộng không thấy gì: không ports mapping, không reverse proxy, không firewall rule. Nhân bản pattern cho database, Grafana, n8n… mỗi dịch vụ một cặp sidecar, phân quyền từng cái bằng ACL theo tag.
Nâng cấp: TS_SERVE và funnel ngay trong container
Image chính chủ hỗ trợ khai báo serve qua biến môi trường/file config, sidecar tự bọc HTTPS cho app: đặt TS_SERVE_CONFIG trỏ file JSON khai proxy cổng 3000, container nhận chứng chỉ ts.net và phục vụ HTTPS cho cả tailnet; cần công khai tạm thời cho khách xem thì nâng thành funnel, cơ chế và giới hạn đã mổ xẻ trong bài Funnel & Serve. Với đa số trường hợp, cách khai đơn giản hơn là exec vào container chạy tailscale serve 3000 một lần, cấu hình được ghi vào state volume, sống qua restart.
Vận hành: update, log, và các hố quen thuộc
Update: pull image mới + recreate, nhờ volume state, node giữ nguyên danh tính. Log: docker logs ts-dashboard khi node không lên; lỗi hay gặp nhất là quên /dev/net/tun (log than không tạo được tun) và authkey hết hạn (tạo key mới, recreate). Hố DNS: container app dùng chung namespace với sidecar nên phân giải tên tailnet chạy qua MagicDNS của sidecar, nếu app cần gọi cả dịch vụ Docker khác theo tên compose, lưu ý network_mode service không tham gia network Docker thường; giải pháp là cho các dịch vụ nói chuyện với nhau qua tên tailnet luôn, đồng bộ một kiểu đặt tên. Bảo mật: authkey là bí mật, đưa qua secret/env file, đừng commit vào git.
Câu hỏi thường gặp
Chạy Tailscale trong container có chậm hơn cài trên host không?
Có kernel tun thì hiệu năng gần tương đương host. Chỉ chế độ userspace networking (khi không cấp được tun) mới chậm rõ. Trên VPS của bạn thì luôn cấp được tun nên không phải lo.
Một VPS chạy được bao nhiêu sidecar Tailscale?
Mỗi sidecar là một node nhẹ (vài chục MB RAM), VPS 2GB chạy cả chục sidecar thoải mái. Giới hạn đáng nhớ hơn là quota thiết bị của gói Tailscale (100 thiết bị gói cá nhân), mỗi sidecar chiếm một suất.
Docker trên NAS Synology có làm được pattern này không?
Được, Container Manager của Synology cho khai devices và cap_add trong compose. Đây là đường đưa từng app trên NAS vào tailnet với danh tính riêng thay vì cài gói Tailscale toàn máy.
Sidecar có hoạt động với Headscale không?
Có, thêm biến TS_EXTRA_ARGS=--login-server=https://hs.ten-mien.vn vào sidecar, authkey tạo bằng lệnh headscale preauthkeys. Toàn bộ pattern giữ nguyên.
Bài viết liên quan
- Docker Compose là gì? Chạy cả stack bằng một file
- Tailscale Funnel & Serve: đưa web ra internet không mở port
- Tailscale trên Ubuntu toàn tập: headless, autostart, DNS
- Thuê VPS: 7 câu phải hỏi nhà cung cấp trước khi xuống tiền
- Cài Forgejo trên VPS: thay GitHub Private cho team indie
- Tailscale vs ZeroTier vs NetBird 2026: chọn mesh VPN nào?
- DevOps thuê ngoài vs hire in-house: so sánh 2026
- Dự báo điều chỉnh giá dịch vụ VPS tại TND
- Wireguard VPN cá nhân trên VPS US: streaming + dev access



