视频加载失败

Docker 部署项目与容器管理:挂载卷、查看、启动、停止和重启

2546 字
13 分钟
Docker 部署项目与容器管理:挂载卷、查看、启动、停止和重启
Docker 部署项目与容器管理:挂载卷、查看、启动、停止和重启

Docker 部署项目时,通常会经历三个步骤:先把项目构建成镜像,再根据镜像创建容器,最后通过端口映射和卷挂载让服务对外提供访问,并把需要长期保存的数据放到容器之外。

本文使用一个监听容器内 3000 端口、数据目录为 /app/data 的通用项目作为示例。不同项目的启动命令、端口和数据目录可能不同,使用时需要替换成项目实际配置。

封面图来源:Docker Workflow,用于直观展示从 Dockerfile、镜像到容器和部署环境的基本流程。

一、镜像、容器和卷是什么#

  • 镜像(image):项目运行所需的程序、依赖和基础系统的只读模板。
  • 容器(container):镜像启动后的运行实例,可以启动、停止和重启。
  • 卷(volume):独立于容器生命周期保存数据的存储。删除并重新创建容器后,只要卷还在,数据就不会丢失。

如果把数据库文件、上传文件或配置文件只写在容器内部,容器被删除后这些数据也可能一起消失。因此,部署有状态项目时,卷挂载是必须认真配置的一步。

本文假设已经安装 Docker,并且当前用户可以直接执行 docker 命令。若执行 Docker 命令时出现 socket 权限错误,可以把用户加入 docker 用户组后重新登录:

Terminal window
sudo usermod -aG docker "$USER"

二、构建项目镜像#

在项目根目录准备 Dockerfile。下面是 Node.js 项目的一个通用示例:

FROM node:22-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
EXPOSE 3000
CMD ["npm", "run", "start"]

如果项目使用 pnpm、Python 或其他运行时,应将基础镜像、依赖安装命令和启动命令替换为项目自己的配置。EXPOSE 只是镜像中的说明,真正让宿主机可以访问服务,还需要在启动容器时进行端口映射。

进入项目目录后构建镜像:

Terminal window
cd /path/to/your-project
docker build -t my-app:1.0 .

其中:

  • -t my-app:1.0 为镜像设置名称和标签。
  • 最后的 . 表示使用当前目录作为构建上下文。

查看已经构建的镜像:

Terminal window
docker image ls

三、创建容器并挂载卷#

1. 使用宿主机目录挂载#

如果希望直接看到宿主机上的文件,可以使用 bind mount:

Terminal window
mkdir -p data
docker run -d \
--name my-app \
--restart unless-stopped \
-p 8080:3000 \
-v "$(pwd)/data:/app/data" \
my-app:1.0

这条命令完成了几件事:

  • -d:让容器在后台运行。
  • --name my-app:为容器指定一个便于管理的名称。
  • --restart unless-stopped:容器异常退出时自动尝试启动,手动停止后不会自动恢复。
  • -p 8080:3000:把宿主机的 8080 端口映射到容器的 3000 端口。
  • -v "$(pwd)/data:/app/data":把当前项目下的 data 目录挂载到容器内的 /app/data。

端口映射的格式是 宿主机端口:容器端口。启动后,访问 http://服务器地址:8080 就会请求容器内监听的 3000 端口。

也可以使用可读性更好的 --mount 写法:

Terminal window
docker run -d \
--name my-app \
--mount type=bind,src="$(pwd)/data",dst=/app/data \
-p 8080:3000 \
my-app:1.0

如果容器只需要读取配置,不应该修改宿主机文件,可以加上只读选项:

Terminal window
docker run -d \
--name my-app \
--mount type=bind,src="$(pwd)/config",dst=/app/config,readonly \
-p 8080:3000 \
my-app:1.0

2. 使用 Docker 命名卷#

如果不需要直接通过固定路径管理文件,可以使用 Docker 命名卷。命名卷由 Docker 管理,适合数据库、缓存和应用数据:

Terminal window
docker volume create my-app-data
docker run -d \
--name my-app \
--restart unless-stopped \
-p 8080:3000 \
-v my-app-data:/app/data \
my-app:1.0

查看命名卷:

Terminal window
docker volume ls
docker volume inspect my-app-data

宿主机目录挂载和命名卷的区别可以简单理解为:宿主机目录挂载更直观,适合配置文件和需要人工查看的文件;命名卷更容易交给 Docker 管理,适合不关心宿主机具体存储路径的数据。

如果挂载的是宿主机目录,必须先确认目录存在,并检查目录权限。容器内进程使用的用户可能不是 root,因此宿主机目录即使存在,也不一定可写。

四、查看已经部署的容器#

查看当前正在运行的容器:

Terminal window
docker ps

查看所有容器,包括已经停止的容器:

Terminal window
docker ps -a

输出中的几个常用字段如下:

字段含义
CONTAINER ID容器 ID,可以使用前几位作为简写
IMAGE容器使用的镜像
COMMAND容器启动时执行的命令
STATUS当前运行状态或退出状态
PORTS端口映射关系
NAMES容器名称

只查看某个容器的状态:

Terminal window
docker inspect -f '{{.State.Status}}' my-app

查看容器的完整配置,包括环境变量、挂载卷、网络和启动命令:

Terminal window
docker inspect my-app

查看端口映射:

Terminal window
docker port my-app

查看容器日志。排查容器启动后立即退出的问题时,通常应该先看日志:

Terminal window
docker logs --tail 100 my-app
docker logs -f my-app

其中 -f 会持续跟随输出,按 Ctrl+C 只会退出日志查看,不会停止容器。

查看容器中的进程和资源占用:

Terminal window
docker top my-app
docker stats my-app

如果需要进入正在运行的容器进行检查,可以执行:

Terminal window
docker exec -it my-app sh

有些镜像内置的是 Bash,也可以使用 bash;Alpine 镜像通常只有 sh。

五、启动、停止和重启容器#

启动已经存在但当前停止的容器#

docker start 会使用容器原本的配置重新启动它,不会创建新的容器:

Terminal window
docker start my-app

启动后确认状态:

Terminal window
docker ps --filter name=my-app

停止容器#

优先使用 docker stop,它会先向应用发送停止信号,给程序留出清理资源的机会:

Terminal window
docker stop my-app

如果程序没有在默认等待时间内退出,可以强制终止:

Terminal window
docker kill my-app

docker kill 不会等待应用完成清理,应该只作为异常情况下的处理手段。

重启容器#

Terminal window
docker restart my-app

修改了宿主机挂载目录中的配置文件后,通常可以重启容器让应用重新读取配置:

Terminal window
docker restart my-app
docker logs --tail 50 my-app

但如果修改了 Dockerfile、依赖或镜像内的文件,单纯重启并不会重新构建镜像。此时应重新构建镜像,并重新创建容器:

Terminal window
docker build -t my-app:1.1 .
docker stop my-app
docker rm my-app
docker run -d \
--name my-app \
--restart unless-stopped \
-p 8080:3000 \
-v "$(pwd)/data:/app/data" \
my-app:1.1

删除容器不会自动删除命名卷,但会删除容器本身的临时文件层。删除前可以先确认卷和挂载关系:

Terminal window
docker inspect my-app --format '{{json .Mounts}}'

六、使用 Docker Compose 管理项目#

当项目包含多个服务,或者不希望每次手动输入很长的 docker run 命令时,可以在项目根目录创建 compose.yaml:

services:
app:
build: .
container_name: my-app
ports:
- "8080:3000"
volumes:
- app-data:/app/data
# 需要从宿主机读取配置时,可以改用下面的 bind mount:
# - ./config:/app/config:ro
restart: unless-stopped
volumes:
app-data:

进入 compose.yaml 所在目录后,常用操作如下:

Terminal window
# 构建镜像并在后台启动项目
docker compose up -d --build
# 查看项目中的容器
docker compose ps
# 查看日志
docker compose logs -f app
# 启动已经停止的服务
docker compose start app
# 停止服务,但保留容器和数据
docker compose stop app
# 重启服务
docker compose restart app
# 停止并删除容器、网络,但保留命名卷
docker compose down

修改 Dockerfile 或项目代码后,常用的更新命令是:

Terminal window
docker compose up -d --build

这会根据新的配置重新构建镜像,并让 Compose 重新创建需要更新的容器。docker compose stop 和 docker compose down 不同:前者只停止服务,后者还会删除 Compose 创建的容器和网络。

注意不要随意执行下面的命令:

Terminal window
docker compose down -v

-v 会同时删除 Compose 声明的命名卷,数据库和应用数据可能因此丢失。只有在确认数据已经备份,或者明确希望清空环境时才使用它。

七、常见问题排查#

1. 端口已被占用#

如果出现 address already in use,说明宿主机端口已经被其他进程或容器占用。可以查看端口和容器映射:

Terminal window
docker ps --format 'table {{.Names}}\t{{.Ports}}'
sudo ss -lntp | grep ':8080'

确认占用者后,可以停止它,或者把项目的宿主机端口改成其他端口,例如 8081:3000。

2. 容器启动后马上退出#

先查看状态和日志:

Terminal window
docker ps -a --filter name=my-app
docker logs my-app

常见原因包括启动命令错误、环境变量缺失、应用没有监听正确端口,以及应用只绑定了 127.0.0.1。在容器中运行的 Web 服务通常需要监听 0.0.0.0,否则即使端口映射正确,宿主机也可能无法访问。

3. 挂载目录不可写#

确认宿主机目录权限:

Terminal window
ls -ld data
docker exec my-app id

如果容器内应用使用普通用户运行,需要让宿主机目录的用户或用户组与容器进程匹配,或者根据镜像文档设置正确的权限。不要为了绕过问题而长期使用 chmod -R 777。

4. 修改文件后数据看起来没有变化#

检查容器实际使用的挂载关系:

Terminal window
docker inspect my-app --format '{{range .Mounts}}{{println .Source "->" .Destination}}{{end}}'

重点确认宿主机路径、容器内路径和读写模式是否正确。还要注意,挂载卷会覆盖容器内同一目录原有的文件;如果把一个空目录挂载到包含默认配置的目录,镜像中的默认文件可能会暂时不可见。

总结#

单容器部署的核心命令可以记成下面这条链路:

docker build → docker run → docker ps / docker logs → docker stop / start / restart

需要持久化的数据使用 -v 或 --mount 挂载;需要长期维护的多服务项目使用 Docker Compose。日常排错时,先看 docker ps -a 和 docker logs,更新镜像时使用 docker compose up -d --build,清理环境前则务必确认不会误删命名卷中的数据。

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

Docker 部署项目与容器管理:挂载卷、查看、启动、停止和重启
https://chachaprj.top/posts/2026-10-19/
作者
ChaCha
发布于
2026-10-19
许可协议
CC BY-NC-SA 4.0
Profile Image of the Author
ChaCha
Pain Equals Gain
公告
欢迎来到我的博客!
分类
标签
最新动态
站点统计
文章
15
分类
7
标签
19
总字数
21,598
运行时长
0 天
最后活动
0 天前
站点信息
构建平台
Local
博客版本
Firefly v6.16.8
文章许可
CC BY-NC-SA 4.0
文章目录