国内云开发主机初始化实操¶
配置目标见:国内云开发主机标准配置
本文只覆盖开发工作区与开发环境;Tailscale 接入方式沿用既有 Docker 版方案,不在这里重复展开完整运行面设计。
0. 约定¶
- 系统:Ubuntu LTS
- 主机名:
cn-bce-dev-01 - 用户名:
<dev-user> - 本文默认先用服务商提供的初始用户登录
1. 基础更新¶
sudo apt update
sudo apt upgrade -y
sudo apt install -y unattended-upgrades curl git tmux zsh htop ufw fail2ban
sudo dpkg-reconfigure -plow unattended-upgrades
sudo timedatectl set-timezone Asia/Shanghai
sudo hostnamectl set-hostname cn-bce-dev-01
2. 创建日常用户¶
sudo adduser <dev-user>
sudo usermod -aG sudo <dev-user>
echo '<dev-user> ALL=(ALL) NOPASSWD:ALL' | sudo tee /etc/sudoers.d/90-<dev-user>
sudo chmod 440 /etc/sudoers.d/90-<dev-user>
sudo visudo -cf /etc/sudoers.d/90-<dev-user>
id <dev-user>
这样配置后,<dev-user> 使用 sudo 不再需要输入账户密码。
3. 写入 SSH 公钥¶
sudo -iu <dev-user>
mkdir -p ~/.ssh
chmod 700 ~/.ssh
nano ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
exit
把本地公钥内容粘进去后保存。
如果本地使用的不是默认私钥文件名,例如 ~/.ssh/2026-02-12,后续登录时需要在本地 ~/.ssh/config 中显式指定 IdentityFile,否则 ssh 可能仍会优先尝试 id_rsa 等默认文件。
4. 加固 SSH¶
sudo tee /etc/ssh/sshd_config.d/99-dev-control.conf > /dev/null <<'EOF'
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
PermitEmptyPasswords no
KbdInteractiveAuthentication no
X11Forwarding no
AllowUsers <dev-user>
EOF
检查并重启:
sudo sshd -t
sudo systemctl restart ssh
sudo systemctl status ssh --no-pager
先新开一个终端验证新用户能登录,再关闭旧会话。
5. 配置 UFW¶
先把 SSH 放行并启用 UFW,再继续后续步骤,避免装完其他组件后才回头补防火墙。
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp comment 'SSH'
sudo ufw allow 41641/udp comment 'Tailscale Direct'
sudo ufw --force enable
sudo ufw status verbose
如果后续需要 dev 子域名,再补开:
sudo ufw allow 80/tcp comment 'HTTP for dev preview'
sudo ufw allow 443/tcp comment 'HTTPS for dev preview'
sudo ufw reload
6. 启用 fail2ban¶
sudo systemctl enable fail2ban
sudo systemctl restart fail2ban
sudo systemctl status fail2ban --no-pager
7. 创建目录¶
sudo mkdir -p /srv/workspace /srv/devtools /opt/infra/bootstrap
sudo chown -R <dev-user>:<dev-user> /srv/workspace /srv/devtools /opt/infra
ls -ld /srv/workspace /srv/devtools /opt/infra /opt/infra/bootstrap
8. 安装 Docker¶
保留 Docker,用于依赖服务、镜像验证和最小复现;这台机器不把 Docker 作为所有项目的默认开发环境,也不在本文中作为 /opt/infra 运行面的管理手段。
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker <dev-user>
docker --version
docker compose version
重新登录一次,让 docker 组生效。
可选增强:
如果后续频繁使用 docker -p 暴露端口,或这台机开始承载长期运行的本机容器,再补 ufw-docker;首轮初始化不默认安装。
sudo wget -O /usr/local/bin/ufw-docker https://github.com/chaifeng/ufw-docker/raw/master/ufw-docker
sudo chmod +x /usr/local/bin/ufw-docker
sudo ufw-docker install
sudo ufw reload
在启用 ufw-docker 之前,开发容器尽量只绑定 127.0.0.1,不要直接暴露到 0.0.0.0。
9. 安装 Python 底座与 uv¶
sudo apt install -y python3 python3-venv python3-pip pipx
pipx ensurepath
pipx install uv
uv --version
原则: - 系统只保留 Python 底座 - 每个项目单独维护自己的环境 - 不在系统级共用一套 Python 依赖
10. 可选:为 Docker 单独配置代理¶
如果开发机直连 docker.io 不稳定,优先只给 Docker daemon 配代理,不把整机流量全局代理化。
当前实际可用做法:
- 安装
sing-box - 用订阅生成本地客户端配置
- 让
sing-box监听127.0.0.1:7890 - 让 Docker daemon 仅通过该端口出网
安装 sing-box:
curl -fsSL https://sing-box.app/install.sh | sudo sh
确认服务与本地监听端口:
sudo systemctl enable sing-box
sudo systemctl restart sing-box
sudo systemctl status sing-box --no-pager
ss -ltnp | grep 7890
Docker 代理 drop-in:
sudo mkdir -p /etc/systemd/system/docker.service.d
sudo tee /etc/systemd/system/docker.service.d/http-proxy.conf > /dev/null <<'EOF'
[Service]
Environment="HTTP_PROXY=http://127.0.0.1:7890"
Environment="HTTPS_PROXY=http://127.0.0.1:7890"
Environment="NO_PROXY=localhost,127.0.0.1,::1"
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
sudo systemctl show --property=Environment docker
确认 Docker 已吃到代理后,再继续 docker pull 或 docker compose up。
11. 接入 Docker 版 Tailscale¶
本机 Tailscale 接入方式沿用既有 Docker 版方案。你先在 /opt/infra/bootstrap/docker-compose.yml 写入既有可用配置,再执行:
cd /opt/infra/bootstrap
docker compose up -d
docker compose ps
sudo ufw allow in on tailscale0 comment 'Allow Tailscale'
ip addr show tailscale0
完成接入后,再检查:
docker logs net-tailscale --tail 50
关于 DERP: - 本次初始化不默认自建 DERP - 先完成接入,再观察是否经常走 relay - 只有在直连效果差、海外 DERP 明显拖慢连接时,再单独评估国内 DERP
12. 安装 Node.js¶
如果当前项目确实需要 Node,再安装系统级 LTS 即可;没有明确需求时可以先不装。
sudo apt install -y nodejs npm
node -v
npm -v
真出现多版本冲突时,再补多版本管理器。
如果安装过程较长,建议放到 tmux 会话里后台执行,而不是一直挂着当前 SSH:
tmux new -s bootstrap
在 tmux 里执行安装命令,离开会话使用:
Ctrl-b d
重新进入:
tmux attach -t bootstrap
13. 建立工作区¶
后续所有活跃开发副本统一放在 /srv/workspace,不要把系统环境当成各项目共用依赖池。
示例:
sudo -iu <dev-user>
cd /srv/workspace
git clone <your-repo-url> autopcr
git clone <your-repo-url> pcrdb
exit
Python 项目示例:
cd /srv/workspace/<project-name>
uv venv
uv sync
14. 远程开发¶
终端开发:
ssh <dev-user>@<server-ip-or-domain>
如果本地私钥不是默认命名,建议在本地 ~/.ssh/config 添加:
Host cn-bce-dev-01
HostName <server-ip-or-domain>
User <dev-user>
IdentityFile ~/.ssh/<private-key-name>
IdentitiesOnly yes
之后可直接使用:
ssh cn-bce-dev-01
浏览器联调优先使用端口转发:
ssh -L 3000:127.0.0.1:3000 <dev-user>@<server-ip-or-domain>
然后在本地浏览器访问:
http://127.0.0.1:3000
15. 验收¶
whoami
sudo -l
sudo ufw status verbose
sudo systemctl status ssh --no-pager
sudo systemctl status fail2ban --no-pager
docker ps
uv --version
sudo systemctl status sing-box --no-pager
ip addr show tailscale0
确认:
- 新用户可登录
- 密码登录已关闭
- root 不可直登
- ufw 已启用
- Docker 正常
- uv 正常
- 如启用代理,sing-box 正常
- tailscale0 已出现
- /srv/workspace 可写
16. 后续补充项¶
按需再做,不作为首轮初始化必做项:
- dev 子域名反代
- 访问其他服务器的统一 SSH 配置
- 备份脚本与迁移脚本