跳到正文
全部 31 篇FREN中文
目录
第 2 部分 · 第 6 篇,共 6 篇 难度:进阶 阅读时间:16 分钟 适用平台:Linux

Docker:隔离您的项目

每个项目都待在自己密封的泡泡里。Docker 防止您的项目互相踩脚,在 agent 做实验时把损失关在盒子里,还让您的部署可复现。新手老手都受用。

本文目录
  1. 01为什么它改变人生(尤其是有了 agent)
  2. 02安装 Docker
  3. 03第一级,跑一个现成的东西(新手)
  4. 04第二级,一个多服务的小项目(Docker Compose)
  5. 05第三级,打包您自己的项目(Dockerfile)
  6. 06专家级,加固隔离
  7. 07常见问题

要点速览

Docker 把每个项目装进一个容器:一个轻量的盒子,自带它自己的 Node 或 Python 版本和依赖。项目之间不再互相踩脚,部署结果完全一致,agent 做实验时出的乱子也被关在盒子里。用官方脚本安装(curl -fsSL https://get.docker.com | sudo sh),用 docker run 运行现成的镜像,用 compose.yml 描述多服务项目,再用 Dockerfile 打包您自己的代码。对外暴露的服务要加固:不用 root 用户、限制资源、只发布真正需要的端口。

请先完成: Git、GitHub 与备份

您将在这台机器上同时跑好几个项目。一个还停在 Node 20,另一个要 Node 24。这个需要某个库的老版本,那个要最新版。如果「一锅烩」地装到系统上,它们迟早互相踩脚,于是您撞上那个经典桥段:「可它之前明明能跑」。Docker 一劳永逸地解决这个问题:每个项目都活在自己密封的泡泡里。

为什么它改变人生(尤其是有了 agent)

三个理由,而第三个被严重低估了:

  • 版本冲突再见。 每个项目自带它确切的环境。这里 Node 20,那里 Node 24,互不干扰。您不再「全局」装任何可能搞坏另一个项目的东西。
  • 可复现的部署。 在您这里跑的容器,跟将来在线上跑的那个一模一样。「在我机器上能跑」消失了:您的机器,就是那个容器。这极大地简化了上线(见 Cloudflare Tunnel)。
  • 损失留在盒子里。 这是和 agent 一起干活时的关键点。一个在做实验的 agent、一个可疑的依赖、一个跑偏的脚本:被关在容器里,它们没法破坏整台机器。这是比「项目文件夹」高一级的隔离,每个项目一个真正的沙箱(与 保护访问安全 相关联)。

安装 Docker

# 官方方法,一条命令
curl -fsSL https://get.docker.com | sudo sh
# 允许您的用户在不用 sudo 的情况下操控 Docker(之后注销/重新登录)
sudo usermod -aG docker $USER

验证:docker run hello-world 应该下载一个迷你镜像并显示一条欢迎信息。看到它,您就准备好了。

第一级,跑一个现成的东西(新手)

Docker 起步时最美妙的地方,是您能直接享用别人的成果。成千上万的应用已经「打包入盒」,开箱即用。某个项目需要一个 PostgreSQL 数据库?不用费力安装:

# 一行启动一个隔离的 PostgreSQL 数据库
docker run -d --name ma-db -e POSTGRES_PASSWORD=secret -p 5432:5432 postgres:16
docker ps              # 看看在跑什么
docker logs ma-db      # 看日志
docker stop ma-db      # 停止(docker start ma-db 可重新启动)
docker rm ma-db        # 删除容器(盒子干干净净地消失)

第二级,一个多服务的小项目(Docker Compose)

大多数项目都由好几块组成:比如一个 app + 一个数据库。Docker Compose 把这一切描述在单个 compose.yml 文件里,再用一条命令把整套都启动起来。

# compose.yml, 一个小型 web app + 它的数据库,一起隔离
services:
  app:
    build: .
    ports:
      - "8080:8080"
    depends_on:
      - db
  db:
    image: postgres:16
    environment:
      POSTGRES_PASSWORD: secret
    volumes:
      - db-data:/var/lib/postgresql/data   # 数据在重启后存活
volumes:
  db-data:
docker compose up -d      # 全部启动,在后台
docker compose logs -f    # 跟踪发生了什么
docker compose down       # 全部停止并清理

第三级,打包您自己的项目(Dockerfile)

要把您自己的代码装进盒子,您写一个 Dockerfile:那份说明该如何构建您项目镜像的菜谱。

# Dockerfile,您这个盒子的配方
#(Docker 的注释要单独占一行:行尾的 # 会被当成参数)
# 从一个官方的、轻量的 Node 镜像出发
FROM node:24-slim
WORKDIR /app
COPY package*.json ./
# 在盒子里安装依赖
RUN npm ci
COPY . .
EXPOSE 8080
# 启动 app 的命令
CMD ["node", "server.js"]
docker build -t mon-app .   # 从 Dockerfile 构建镜像
docker run -d -p 8080:8080 mon-app

从此,您的项目和它的环境合为一体。您可以在任何装了 Docker 的机器上原样启动它。

专家级,加固隔离

容器已经隔离了不少,但默认情况下它没把篱笆扎到该扎的地方。当您托管一个对外暴露的服务,或者要圈住一个 agent 时,把螺丝拧紧:

  • 不要在容器里以 root 运行 : 在您的 Dockerfile 里加一个非特权用户(USER node)。如果有人从 app 里逃出来,他也不是 root。
  • 只读文件系统 : docker run --read-only 阻止容器往不该写的地方写。
  • 限制资源 : --memory=512m --cpus=1 防止一个失控的容器把整台机器憋死。
  • 削减权限 : --cap-drop=ALL 移除用不上的 Linux capabilities;需要时再一个一个加回来。
  • 隔离网络 : 只发布(-p)真正必要的端口;其余的保持不可见。而您对外发布的东西,要经由 Cloudflare Tunnel 或留在 Tailscale 上,绝不裸奔在互联网上。

常见问题

Docker 容器和虚拟机有什么区别?

容器要轻得多:它共享宿主机的 Linux 内核,而不是自带一个,所以并排跑十个也互不干扰。代价是隔离性较弱。要隔离真正有风险的代码,不再共享宿主机内核的虚拟机能提供最牢固的隔离。

怎样使用 Docker 而不必每条命令都加 sudo?

用 sudo usermod -aG docker $USER 把您的用户加入 docker 组,然后注销并重新登录。此时运行 docker run hello-world,应该会下载一个小镜像并显示欢迎信息:这说明一切就绪。

Docker 能完全保护机器不受 AI 智能体影响吗?

它能大大缩小破坏范围:做实验的智能体或失控的脚本都被关在容器里。但容器与宿主机共享内核,并不是无法逃脱的牢笼。对于无人看管、独立运行的智能体,请以无 root 模式运行 Docker 守护进程,容器本身也不用 root,甚至可以把一切都放进虚拟机里。

Portainer 和 Dokploy 是做什么的?

Portainer 是 Docker 的网页管理面板:可以看到所有容器、它们的日志和资源占用,点两下就能启动、停止或重新部署。Dokploy 更进一步:它是一个自托管的部署平台,能从 Git 仓库构建并上线您的项目,还会处理域名和证书。最好先在命令行里把基础学会。

Docker 里数据库的数据重启后还在吗?

只要给它挂一个卷就在。在 compose.yml 中,把一个命名卷关联到 PostgreSQL 的数据目录,数据就能在重启之间保留。没有卷的话,容器一旦删除就不留任何痕迹。

本文涉及的术语: Docker容器Docker 镜像Linux

发现错误?

命令失效了,价格变了?

这些工具每个月都在变。请告诉我这篇文章哪里不对,我会改正并更新日期。

只保留页面、您的留言和选填的联系方式,别无其他。

第 14 / 31 篇 · 第 2 部分 还没有读过任何一篇 打开文章目录