一、获取 Ubuntu

1.1 选择版本

生产环境建议 Ubuntu LTS 系列,目前推荐 24.04 LTS 或 22.04 LTS。LTS 提供 5 年安全更新,稳字当头。

桌面端直接去 ubuntu.com/download 下载镜像制作启动盘。云服务器(阿里云/腾讯云/AWS)创建实例时选 Ubuntu 镜像即可,省去安装步骤。

1.2 最小化安装后第一件事

1
2
3
4
5
# 拿到机器先更新一波
sudo apt update && sudo apt upgrade -y

# 确认版本
lsb_release -a

二、安装依赖库与环境工具

2.1 基础编译工具链

1
sudo apt install -y build-essential gcc g++ make cmake

2.2 常用运维工具

1
2
3
4
5
sudo apt install -y \
curl wget git vim \
htop iotop net-tools \
unzip zip jq tree \
tmux rsync

2.3 语言运行时(按需安装)

1
2
3
4
5
6
7
8
9
# Python 3
sudo apt install -y python3 python3-pip python3-venv

# Node.js(通过 NodeSource)
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt install -y nodejs

# 验证
node -v && npm -v

2.4 防火墙基础配置

1
2
3
4
5
6
# ufw 通常已预装
sudo ufw allow 2222/tcp # SSH 端口(改过的)
sudo ufw allow 80/tcp # HTTP
sudo ufw allow 443/tcp # HTTPS
sudo ufw enable
sudo ufw status verbose

三、配置日常运维账号

原则:永远不用 root 直接操作。

3.1 创建运维账号

1
2
3
4
5
# 创建用户,-m 创建家目录,-s 指定 shell
sudo useradd -m -s /bin/bash opadmin

# 设密码
sudo passwd opadmin

3.2 赋予 sudo 权限

1
2
3
4
5
6
# 把 opadmin 加入 sudo 组
sudo usermod -aG sudo opadmin

# 验证
su - opadmin
sudo whoami # 应该输出 root

3.3 配置 SSH Key 登录(禁止密码登录)

1
2
3
4
5
6
7
8
# 在本地机器生成密钥对(如果还没有)
ssh-keygen -t ed25519 -C "your-email@example.com"

# 把公钥拷到服务器(在本地执行)
ssh-copy-id opadmin@<服务器IP>

# 回到服务器,加固 SSH 配置
sudo vim /etc/ssh/sshd_config

关键配置项:

1
2
3
4
5
6
7
8
# 禁止 root 登录
PermitRootLogin no

# 禁止密码登录(确认 Key 登录正常后再开)
PasswordAuthentication no

# 改端口减少扫描(可选,记得开防火墙)
Port 2222
1
2
# 重载 SSH 使配置生效
sudo systemctl reload sshd

重要:在关掉密码登录前,另开一个终端确认 Key 登录正常,别把自己锁在外面。

3.4 配置 sudo 免密码(可选)

1
sudo visudo -f /etc/sudoers.d/opadmin

添加一行:

1
opadmin ALL=(ALL) NOPASSWD:ALL

四、安装 Nginx

4.1 官方源安装(推荐)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 添加 Nginx 官方仓库,拿到最新稳定版
sudo apt install -y curl gnupg2 ca-certificates lsb-release ubuntu-keyring

curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
| sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg > /dev/null

echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
http://nginx.org/packages/ubuntu $(lsb_release -cs) nginx" \
| sudo tee /etc/apt/sources.list.d/nginx.list

sudo apt update
sudo apt install -y nginx

# 确认版本和运行状态
nginx -v
sudo systemctl status nginx

4.2 基础配置速查

1
2
3
4
5
6
# 配置目录结构
/etc/nginx/
├── nginx.conf # 主配置
├── conf.d/ # server 块放这里
├── snippets/ # 可复用的配置片段(ssl 参数等)
└── sites-available/ # 另一种组织方式(需手动 include)

常用运维命令:

1
2
3
4
sudo nginx -t                # 测试配置语法
sudo nginx -s reload # 热重载配置
sudo systemctl reload nginx # 同上
sudo systemctl restart nginx # 重启

4.3 第一个站点

1
sudo vim /etc/nginx/conf.d/default.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
server {
listen 80;
server_name _; # 匹配所有请求,后续换成域名

location / {
root /var/www/html;
index index.html;
}

# 健康检查端点
location /health {
access_log off;
return 200 "ok";
}
}
1
2
3
4
sudo mkdir -p /var/www/html
echo '<h1>Hello from Nginx</h1>' | sudo tee /var/www/html/index.html

sudo nginx -t && sudo nginx -s reload

浏览器访问 http://<服务器IP> 看到 Hello 页面即成功。


五、安装 Docker

5.1 官方脚本安装

1
2
3
4
5
6
7
8
9
10
11
# 卸载旧版本(如果有)
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do
sudo apt remove -y $pkg 2>/dev/null
done

# 官方一键脚本(推荐)
curl -fsSL https://get.docker.com | sudo bash

# 验证
docker --version
docker compose version

5.2 免 sudo 使用 Docker

1
2
3
4
5
6
# 将当前用户加入 docker 组
sudo usermod -aG docker $USER

# 重新登录后生效,或者临时切换
newgrp docker
docker ps

5.3 配置镜像加速(国内环境)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<'EOF'
{
"registry-mirrors": [
"https://docker.xuanyuan.me",
"https://docker.1ms.run",
"https://docker.m.daocloud.io",
"https://docker.nju.edu.cn",
"https://docker.mirrors.ustc.edu.cn"
]
}
EOF

sudo systemctl daemon-reload
sudo systemctl restart docker

5.4 Docker 开机自启

1
sudo systemctl enable docker containerd

六、域名与 HTTPS 加密

6.1 域名解析

在域名服务商控制台添加 A 记录,将域名指向服务器 IP:

类型 主机记录 记录值
A @ 服务器IP
A www 服务器IP

生效后验证:

1
2
3
# 等几分钟 DNS 传播后验证
dig your-domain.com +short
ping your-domain.com

6.2 安装 Certbot(Let’s Encrypt)

1
2
3
4
5
6
7
# snap 是 certbot 官方推荐的安装方式
sudo snap install core
sudo snap refresh core
sudo snap install --classic certbot

# 确保 certbot 命令可用
sudo ln -sf /snap/bin/certbot /usr/bin/certbot

6.3 泛域名证书(DNS 手动验证)

如果需要 *.your-domain.com 泛域名证书:

1
2
3
4
# 手动 DNS 验证模式
sudo certbot certonly --manual \
--preferred-challenges dns \
-d "*.your-domain.com" -d "your-domain.com"

Certbot 会输出一条 TXT 记录,去域名服务商添加后回车确认。

6.4 自动续期

1
2
3
4
5
# certbot 自带续期 timer,看一眼确认
sudo systemctl status snap.certbot.renew.timer

# 手动测试续期流程(不实际续)
sudo certbot renew --dry-run

Let’s Encrypt 证书有效期 90 天,snap 安装的 certbot 会自动续期,基本不用操心。


七、Nginx 反向代理实战

证书拿到后,Nginx 的核心用途是 反向代理——把外部请求转发到后端 Docker 容器。

典型的服务器场景:每个 Docker 容器对应一个二级域名。

1
2
blog.cpaden.site      → 127.0.0.1:4000   (Hexo 博客)
manage.cpaden.site → 127.0.0.1:0000 (管理面板)

理念是 一站一文件,公共配置抽 snippet。SSL 参数、proxy header 这种每个站点一模一样的配置,抽到 snippets/ 里统一维护,每个站点的 .conf 只保留真正不同的东西——server_nameproxy_pass

7.1 创建复用片段

SSL 通用参数:

1
sudo vim /etc/nginx/snippets/ssl-params.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 证书路径(泛域名证书所有子域名共用)
ssl_certificate /etc/letsencrypt/live/cpaden.site/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/cpaden.site/privkey.pem;

ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;

# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;

反向代理通用 header:

1
sudo vim /etc/nginx/snippets/proxy-params.conf
1
2
3
4
5
6
7
8
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 60s;

Gzip 和上传限制 放到 nginx.confhttp 块全局生效,不应在每个站点重复:

1
sudo vim /etc/nginx/nginx.conf
1
2
3
4
5
6
7
http {
# ... 已有配置 ...

gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
client_max_body_size 20m;
}

7.2 单站点配置

以博客 blog.cpaden.site 反向代理到本地 3000 端口为例:

1
sudo vim /etc/nginx/conf.d/blog.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# HTTP → HTTPS 强制跳转
server {
listen 80;
server_name blog.cpaden.site;
return 301 https://$host$request_uri;
}

# HTTPS 代理
server {
listen 443 ssl http2;
server_name blog.cpaden.site;

include snippets/ssl-params.conf;

access_log /var/log/nginx/blog.access.log;
error_log /var/log/nginx/blog.error.log;

location / {
proxy_pass http://127.0.0.1:3000;
include snippets/proxy-params.conf;
}
}

泛域名证书 *.cpaden.site 对所有二级域名有效,证书路径已收进 ssl-params.conf,站点文件完全不用管。

7.3 关键 proxy 参数说明

参数 作用
proxy_pass 后端服务地址
Host $host 传递原始域名,后端据此区分站点
X-Real-IP 传递客户端真实 IP,否则后端看到的是 127.0.0.1
X-Forwarded-For 代理链,记录完整转发路径
X-Forwarded-Proto 告知后端前端用的是 https
Upgrade / Connection WebSocket 支持,必加

7.4 最终目录结构

1
2
3
4
5
6
7
8
9
/etc/nginx/
├── nginx.conf # 主配置(gzip、日志格式等全局项)
├── conf.d/
│ ├── blog.conf # blog.cpaden.site → :3000
│ ├── manager.conf # manager.cpaden.site → :0000
│ └── ... # 其他子域名,来一个加一个
└── snippets/
├── ssl-params.conf # SSL 安全策略,所有站点复用
└── proxy-params.conf # 反向代理通用 header,所有站点复用

后续加新服务三步走:

1
2
3
4
5
6
7
8
9
# 1. 拉起 Docker 容器
docker run -d --name whoami -p 8080:8080 containous/whoami

# 2. 复制已有 conf 改 server_name 和 proxy_pass
sudo cp /etc/nginx/conf.d/blog.conf /etc/nginx/conf.d/whoami.conf
# 替换 blog → whoami,proxy_pass 端口改成 8080

# 3. 测试并重载
sudo nginx -t && sudo nginx -s reload

7.5 验证与排错

1
2
3
4
5
6
7
8
9
10
11
12
# 测试配置
sudo nginx -t

# 查看端口监听
sudo ss -tlnp | grep -E '80|443'

# 跟踪日志
sudo tail -f /var/log/nginx/blog.access.log
sudo tail -f /var/log/nginx/blog.error.log

# 重载
sudo nginx -s reload

八、全流程总结

搞定上面七步后,你就有了一台:

  1. 环境齐全:编译工具链、语言运行时、防火墙基础配置就绪
  2. 安全:禁用 root、SSH Key 登录、防火墙开放最小端口
  3. 可维护:独立运维账号、sudo 权限受控
  4. 能跑应用:Docker 容器化部署,环境隔离不打架
  5. 对外服务:Nginx 反向代理,多站点各走各的
  6. 加密通信:Let’s Encrypt 免费证书 + 自动续期

后续加新服务只需要三步:

1
2
3
4
5
6
7
8
# 1. 用 Docker 拉起服务
docker run -d --name myapp -p 8080:8080 myapp:latest

# 2. 在 Nginx 加一个 server 块指向 8080
sudo vim /etc/nginx/conf.d/myapp.conf

# 3. 申请证书(手动 DNS 验证)
sudo certbot certonly --manual --preferred-challenges dns -d myapp.your-domain.com

附:速查命令一览

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 系统
sudo apt update && sudo apt upgrade -y # 更新系统
sudo ufw status # 防火墙状态
sudo ss -tlnp # 查看监听端口

# 用户
sudo useradd -m -s /bin/bash <user> # 创建用户
sudo usermod -aG sudo <user> # 加 sudo 权限

# Nginx
sudo nginx -t # 测试配置
sudo nginx -s reload # 热重载
sudo tail -f /var/log/nginx/error.log # 错误日志

# Docker
docker ps # 运行中的容器
docker compose up -d # Compose 启动
docker logs -f <container> # 跟踪日志

# HTTPS
sudo certbot certonly --manual --preferred-challenges dns -d <domain> # 手动申请证书
sudo certbot renew --dry-run # 测试续期
sudo certbot certificates # 查看已有证书