Appearance
第7章:Linux、容器与发布——让产品不是只在你电脑上能运行
7.1 独立开发者必会的 Linux 运维硬底功
在云主机和生产服务器上,你必须能完全脱离图形界面独立完成以下排查:
- 定位进程与资源占用:
ps aux | grep app、top -b -n 1、htop; - 实时跟踪日志排障:
journalctl -u myapp.service -f -n 200、tail -f /var/log/nginx/error.log; - 端口与网络连通性验证:
ss -tlnp、curl -Iv https://api.internal、dig +short mydomain.com; - 环境变量与权限安全隔离:严禁使用 root 权限无脑运行服务,必须创建低权限专属系统用户并严格配置目录所属权
chown -R appuser:appgroup /opt/app。
Docker 容器化最佳工程实践:
- 多阶段构建(Multi-Stage Build):分离构建依赖与运行环境,避免将编译器、测试框架和临时文件打包进最终镜像,将镜像体积从 1GB 压缩到 80MB;
- 非 root 用户运行:在 Dockerfile 末尾必须显式声明
USER 1001; - 敏感凭证防泄露铁律:
- 严禁将数据库密码、Stripe 秘钥或 OpenAI API Key 直接硬编码在 Dockerfile 镜像层中;
- 严禁将含有密钥的
.env提交到公开或私有 Git 仓库; - 生产环境统一通过 Docker Compose 环境变量或容器运行时 Secret 动态注入。
7.2 一条真正的现代化 CI/CD 自动化交付流水线
mermaid
graph LR
Git[Git 提交 PR] --> Lint[1. 静态代码检查 ruff/eslint]
Lint --> UT[2. 单元测试与覆盖率门禁]
UT --> Build[3. Docker 镜像多阶段构建]
Build --> SecScan[4. 容器安全扫描 Trivy]
SecScan --> Staging[5. 部署预发环境 Staging]
Staging --> Smoke[6. 自动化冒烟测试 Smoke Test]
Smoke --> Prod[7. 灰度发布上线生产]交付原则:
对于个人或小团队独立项目,CI/CD 最核心的价值不在于用了多么炫酷的工具,而在于:
- 每次发布都有清晰的证据链(哪个 Git Commit 哈希、对应哪个 Docker 镜像 Tag、测试是否全绿);
- 发布一旦发生致命异常,必须能在 60 秒内一键安全回滚(Rollback)到上一版本!
7.3 备份不是备份文件,恢复才是终极目标
许多开发者虽然配置了定时任务 cron 每天备份数据库,但整整一年中从未亲手演练过一次恢复!
当真正遭遇勒索病毒、磁盘损坏或误删库灾难时,才惊恐地发现:
- 备份脚本由于磁盘满早在一个月前就静默中断了;
- 备份文件被破坏、解密密钥早已遗忘;
- 恢复数据库耗时整整 8 个小时,业务客户早已流失殆尽。
灾难恢复核心两大黄金指标:
- RPO (Recovery Point Objective,恢复点目标):系统最多能够接受丢失多长时间跨度的数据(如:每天凌晨备份一次,则最大可丢失 24 小时数据);
- RTO (Recovery Time Objective,恢复时间目标):从灾难发生到业务全面恢复正常运行所能容忍的最长时间(如:必须在 30 分钟内完成数据恢复与服务拉起)。
7.4 实战任务与验收自测
实战任务:
- 编写一份完整的
docker-compose.yml,在单机上拉起并互联:web(FastAPI / Node API 容器);worker(异步 Celery / Redis 消费者容器);db(PostgreSQL 16 容器,带持久化挂载 Volume);redis(带密码与内存上限配置)。
- 编写数据库每日自动备份脚本,将加密备份转储至对象存储(S3 / OSS / 独立备份机);
- 在一台完全空白的新服务器上执行一次“从零灾难恢复演练”:从备份拉取数据并验证全部服务正常运行,精确记录全流程所需分钟数。
验收思考题:
- 为什么“Docker 容器进程处于 Running 状态”绝对不代表底层服务是健康的?为什么必须在 Docker 中显式配置
HEALTHCHECK探针? - 为什么必须把数据库恢复演练写成每一步都可执行的操作清单(Runbook),而不是凭记忆临时操作?