Docker 入门:把博客和数据库装进容器
Words: 987Read Time: 3 minLast edited: 2026-8-4
之前部署博客的流程是:本地发布、scp 上传、ssh 上去重启。服务器上装了什么、什么版本,全凭记忆。最近把博客和数据库都搬进了 Docker,环境终于能跟着代码走了。这篇是入门记录,写给同样刚接触 Docker 的 .NET 选手。
先搞懂三个概念
Docker 教程一抓一大把,但很多一上来就甩命令。我觉得先想清楚三个概念更重要:
- 镜像(Image):一个只读的打包文件,里面有应用和它需要的全部运行环境,可以理解为"安装包+系统环境"的快照
- 容器(Container):镜像跑起来的实例。同一个镜像可以跑多个容器,互相隔离
- 卷(Volume):容器删了数据就没了,所以持久化数据要放到卷里。卷由 Docker 统一管理,容器只是挂载它
一句话总结:镜像是类,容器是对象,卷是外挂硬盘。"数据一定要放卷里",这句话值很多钱,后面讲为什么。
用 Dockerfile 打包应用
我的博客是 ASP.NET Core 8 的项目,官方有现成镜像,Dockerfile 写起来很短:
这是典型的多阶段构建:第一阶段用 sdk 镜像编译,第二阶段只把发布产物拷进更小的 aspnet 运行时镜像,最终镜像从 800 多 MB 缩到 200 MB 出头。构建和运行:
注意一个坑:.NET 8 的容器镜像默认监听端口从 80 改成了 8080,所以是
-p 5000:8080。我照抄老教程写成 5000:80,容器起来了但怎么都访问不通,查了半天日志才发现。-v 参数把宿主机的 /data/myblog 挂进容器,上传的图片、SQLite 文件都放在这里。docker-compose 编排应用和数据库
单个容器用 docker run 还行,但博客还要带一个 PostgreSQL,命令越写越长,于是上 docker-compose,用一个文件描述整个栈:
docker compose up -d 一把起两个容器,compose 会自动建网络,blog 容器里直接用 db 当主机名连数据库。密码写在旁边的 .env 文件里,compose 会自动读取替换 ${DB_PASSWORD},不用硬编码。数据卷误删,血泪教训
重点来了。有一次磁盘报警,我清理空间时执行了类似
docker system prune --volumes 的命令——--volumes 会把"没有被任何容器使用的卷"一起删掉。当时数据库容器正好被我 stop 了,于是 pgdata 被判定为"未使用",整个数据库没了。幸好还有前一天的 pg_dump 备份,恢复到凌晨的数据,只丢了几条评论。如果连备份也没有,这博客就真从头开始了。
教训刻烟吸肺:
- 任何带
prune的命令,执行前默数三秒,确认--volumes不在里面
- 重要数据用命名卷,别用匿名卷,至少
docker volume ls里能一眼认出来
- 备份是底线:我现在每天凌晨 pg_dump 一次,保留最近 7 天
容器化带来的好处是实打实的:以后换服务器只需要装好 Docker、拉代码、up -d,十分钟搬家。但那行 prune 命令的教训,估计我这辈子都忘不了。
Loading...