这是「把自己部署到互联网上」系列的第 18 篇。
前面一段时间,我花了几篇文章处理服务器安全:普通用户、root 登录、SSH、安全组、防火墙、数据库端口、扫描日志和基础安全清单。安全边界处理完后,终于要进入部署阶段。
但在真正部署博客之前,遇到了一个实际选择:生产环境到底该用 Conda 还是 Docker?
这个问题和我的项目直接相关。个人博客会涉及 Python 环境、依赖安装、数据库、服务启动、后续迁移和长期维护。如果只是本地开发,Conda 很方便;但如果要放到长期运行的云服务器上,还要考虑 Nginx、HTTPS、多项目共存、数据库和未来个人官网,选择就不只是“哪个工具熟”这么简单。
不是哪个简单就用哪个。先择更合理的方式,是把 Conda 和 Docker 放回真实场景里比较。
应用场景
这个合集的目标不是大型企业系统,也不是复杂云原生架构,而是一台小型云服务器,先部署一个 Python 相关的博客项目,后面继续部署个人官网和其他项目。入口由 Nginx 统一处理,HTTPS 证书配置,数据库要长期保存数据,项目支持一键打包、迁移,维护者只有我一个人。
这个应用场景不大,但有几个关键点:
- 要长期运行,不是跑一次脚本
- 会逐渐变成多项目环境
- 必须便于一个人维护
- 需要可复制,如果换服务器,能比较快地重新拉起来
Conda 部署
Conda 在本地开发和数据科学场景里很好用。创建环境、安装 Python 版本、管理依赖都比较直观。如果熟悉 Python,首相想到的是用 Conda 创建一个虚拟环境、部署一个项目:
conda create -n blog python=3.11
conda activate blog
pip install -r requirements.txt
这套流程简单直接,初期部署成本低。不需要写 Dockerfile,不需要理解镜像、容器、网络、卷挂载和 Compose。把代码拉到服务器,激活环境,安装依赖,启动服务,就能跑起来。对于临时验证、小脚本或单个轻量项目,Conda 完全可用。
相关问题
但放到长期生产环境里,Conda 的问题会逐渐出现。
第一个问题是环境复现依赖记录习惯
Conda 可以导出 environment.yml,但真实部署里往往还会混入 pip 包、系统依赖、环境变量、服务启动脚本、数据库配置和 Nginx 配置。这些不完全在 Conda 环境里。
第二个问题是服务管理要额外设计
项目后台怎么运行?用 nohup、screen、systemd,还是 supervisor?都可以,但需要自己规划启动、停止、重启和日志。
第三个问题是多项目容易变散。
一个项目一个 Conda 环境没问题,但项目多了以后,环境、依赖、启动脚本、日志路径、配置文件可能分散在服务器各处。
第四个问题是迁移偏手工。
换服务器时,要重新安装 Miniconda、创建环境、安装依赖、恢复配置、配置服务、确认系统依赖是否一致。不是做不到,但需要更多人工记忆和文档约束。
第五个问题是 Conda 只管 Python 环境
不负责组织数据库、网络、数据卷、服务依赖和多服务关系。
当项目从单个 Python 服务变成完整部署环境时,还需要补很多其他工具。
Docker 部署
Docker 的思路不同。它不是只管理 Python 环境,而是把应用运行环境封装成镜像和容器。对我的应用场景来说,最大的价值是把部署过程文件化。
项目需要什么基础镜像、安装什么依赖、执行什么启动命令,可以写进 Dockerfile。博客应用、数据库、缓存等服务之间的关系,可以用 Docker Compose 管理。这对长期维护很关键,因为部署过程不再完全依赖手工记忆。
优势
Docker 的优势主要有几个。
-
环境隔离更清晰。每个项目有自己的容器和依赖,不容易污染系统环境。
-
迁移更方便。只要 Dockerfile、Compose 文件、配置和数据卷处理好,换服务器时更容易重新跑起来。
-
多服务编排更自然。应用、数据库、缓存、Nginx 可以通过 Compose 或清晰的网络关系管理。
-
启动和停止更统一:
shell
docker compose up -d
docker compose down
docker compose logs
- 更适合多项目共存。每个项目可以有自己的 Compose 文件,外部入口交给全局 Nginx 管理。
缺点
当然,Docker 也有成本。
- 首先是学习成本。需要理解镜像、容器、网络、端口映射、数据卷、Dockerfile 和 Compose。
- 其次是排查方式变化。项目出问题时,不只看本机进程,还要看容器状态、容器日志、网络、卷挂载和环境变量。
- 配置更显式。Docker 会逼你把启动方式、依赖关系、端口映射和数据目录写清楚。一开始麻烦,但长期看有利于维护。
- 误配置也会带来风险。比如不该映射的数据库端口映射到了宿主机,数据卷没挂好导致容器重建后数据丢失,环境变量写错导致服务启动失败。
Docker 不是自动安全,也不是免运维,它只是把部署细节显式化。
对比
放到个人项目场景里,环境可复现、服务边界清晰、多项目不互相污染、迁移成本低、启停方式统一、配置可以写进文件。Docker 更容易实现。
所以我的结论是:在这次个人博客生产部署里,Docker 更合适。
但这不代表 Conda 不好。Conda 适合本地开发、数据分析、实验环境,也适合一些简单服务器脚本。只是对一个长期运行、后续扩展、多项目共存的个人项目基础设施来说,Docker 更匹配目标。
可以简单对比:
| 维度 | Conda | Docker |
|---|---|---|
| 上手速度 | 快 | 中等 |
| Python 环境管理 | 方便 | 需要镜像配置 |
| 多服务管理 | 需要额外工具 | Compose 更自然 |
| 环境复现 | 依赖记录习惯 | 更容易固化到文件 |
| 多项目隔离 | 环境级隔离 | 容器级隔离 |
| 迁移成本 | 偏手工 | 相对更低 |
| 服务启停 | 需要额外设计 | 命令更统一 |
| 学习成本 | 低 | 中等 |
| 长期维护 | 容易变散 | 更适合结构化管理 |
为什么选择 Docker
我最终选择 Docker,主要有四个原因。
- 让部署过程文件化。环境、依赖和启动方式,不应该只存在于服务器手工操作记录里
- 后面会部署多个项目。博客只是第一个,后面还有官网、作品站和其他小工具。多项目共存时,容器边界更清楚
- 我想降低迁移成本。如果以后换服务器,希望能通过代码仓库、Compose 文件和数据备份,把项目快速重新拉起来
- 使用
Nginx统一入口更清晰。外部只开放 80 和 443,内部项目通过Docker网络或本地端口与Nginx配合,比每个项目散落在系统里更好维护。
如果你也在纠结 Conda 和 Docker,可以先问几个问题:
- 项目是长期运行还是短期脚本?
- 是否需要数据库、缓存、
Nginx等多个服务配合? - 未来是否会部署多个项目?
- 是否希望换服务器时容易迁移?
- 是否愿意学习 Docker 的基本概念?
- 是否需要把部署过程写成可复用文件?
如果答案偏向短期、单一、实验,Conda 很舒服。如果答案偏向长期、服务化、多项目、可迁移,Docker 更合适。
对我这次个人博客上线来说,我会选择 Docker。不是因为 Docker 更高级,而是因为它更适合这个项目的生产部署目标。
下一篇,我会继续复盘:为什么我最终放弃了 Conda 部署。那篇会记录我从“Conda 也能用”,走到“还是换 Docker”的具体思考。
本文由 楸木 原创,转载请注明出处。