上一篇 下一篇 分享链接 返回 返回顶部

Docker 问题排查手册:从安装到部署的常用命令全整理

发布人:慈云数据-客服中心 发布时间:23小时前 阅读量:1

Docker 常见问题汇总|附完整命令

Docker 是目前最常用的容器化技术之一,广泛应用于开发环境搭建、微服务部署、持续集成、测试环境隔离以及生产环境交付。它可以将应用程序及其依赖环境打包成镜像,并以容器的形式快速运行,从而解决“在我电脑上能跑,到服务器就不行”的环境一致性问题。

不过,很多人在实际使用 Docker 时,经常会遇到安装、镜像、容器、网络、数据卷、权限、日志、清理、部署等方面的问题。本文将围绕 Docker 日常使用中的高频问题进行整理,并附上常用完整命令,方便开发、测试、运维人员快速查阅。


一、Docker 基础概念常见问题

1. Docker 是什么?

Docker 是一个开源的容器化平台,它可以将应用程序、运行环境、系统依赖、配置文件等打包成一个标准化的镜像,然后通过容器运行。

简单理解:

  • 镜像 Image:类似应用安装包,包含应用和依赖环境。
  • 容器 Container:镜像运行后的实例。
  • 仓库 Registry:存放镜像的地方,如 Docker Hub、阿里云镜像仓库、Harbor。
  • Dockerfile:用于构建镜像的脚本文件。
  • 数据卷 Volume:用于持久化容器数据。
  • 网络 Network:用于容器之间、容器与宿主机之间通信。

2. Docker 和虚拟机有什么区别?

Docker 容器不是完整虚拟机,它共享宿主机操作系统内核,因此启动速度快、资源占用低。

对比项 Docker 容器 虚拟机
启动速度 秒级 分钟级
资源占用 较低 较高
隔离级别 进程级隔离 系统级隔离
操作系统 共享宿主机内核 每台虚拟机独立系统
适用场景 应用部署、微服务、CI/CD 完整系统隔离、传统虚拟化

二、Docker 安装与启动问题

1. 如何查看 Docker 是否安装成功?

docker --version

或:

docker version

如果能够看到 Docker Client 和 Server 版本信息,说明 Docker 已正确安装并启动。


2. 如何启动 Docker 服务?

在 Linux 系统中可以使用:

sudo systemctl start docker

设置 Docker 开机自启动:

sudo systemctl enable docker

查看 Docker 服务状态:

sudo systemctl status docker

重启 Docker 服务:

sudo systemctl restart docker

停止 Docker 服务:

sudo systemctl stop docker

3. 普通用户执行 docker 命令提示权限不足怎么办?

常见报错如下:

permission denied while trying to connect to the Docker daemon socket

原因是当前用户没有访问 Docker 守护进程的权限。可以将当前用户加入 docker 用户组:

sudo usermod -aG docker $USER

然后退出当前终端,重新登录,或执行:

newgrp docker

再次测试:

docker ps

注意:将用户加入 docker 组后,该用户基本拥有等同 root 的容器管理权限,应谨慎操作。


三、Docker 镜像常见问题

1. 如何搜索镜像?

docker search nginx

示例:

docker search mysql
docker search redis
docker search openjdk

2. 如何拉取镜像?

docker pull nginx

指定版本:

docker pull nginx:1.25

拉取 MySQL 8:

docker pull mysql:8.0

拉取 Redis:

docker pull redis:7

如果不指定标签,默认拉取 latest

docker pull nginx:latest

3. 如何查看本地镜像?

docker images

或:

docker image ls

查看镜像详细信息:

docker image inspect nginx:latest

4. 如何删除镜像?

删除指定镜像:

docker rmi nginx:latest

通过镜像 ID 删除:

docker rmi 镜像ID

强制删除镜像:

docker rmi -f 镜像ID

删除所有未被使用的镜像:

docker image prune

强制删除所有未使用镜像:

docker image prune -a

5. 镜像删除失败怎么办?

如果镜像正在被容器使用,会出现类似错误:

conflict: unable to remove repository reference

解决方法是先查看使用该镜像的容器:

docker ps -a

停止相关容器:

docker stop 容器ID或容器名

删除相关容器:

docker rm 容器ID或容器名

然后再删除镜像:

docker rmi 镜像ID

四、Docker 容器常见问题

1. 如何运行一个容器?

运行 Nginx 容器:

docker run -d --name nginx-test -p 8080:80 nginx

参数说明:

  • -d:后台运行
  • --name nginx-test:指定容器名称
  • -p 8080:80:将宿主机 8080 端口映射到容器 80 端口
  • nginx:使用的镜像名称

访问:

curl http://localhost:8080

2. 如何查看正在运行的容器?

docker ps

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

docker ps -a

只显示容器 ID:

docker ps -q

查看所有容器 ID:

docker ps -aq

3. 如何停止容器?

docker stop nginx-test

或:

docker stop 容器ID

停止所有正在运行的容器:

docker stop $(docker ps -q)

4. 如何启动已停止的容器?

docker start nginx-test

重启容器:

docker restart nginx-test

5. 如何删除容器?

删除已停止容器:

docker rm nginx-test

强制删除正在运行的容器:

docker rm -f nginx-test

删除所有已停止容器:

docker container prune

删除所有容器:

docker rm -f $(docker ps -aq)

注意:删除容器不会自动删除镜像,但容器内未挂载的数据可能会丢失。


6. 如何进入容器内部?

进入正在运行的容器:

docker exec -it nginx-test /bin/bash

如果容器没有 bash,可以使用 sh:

docker exec -it nginx-test /bin/sh

查看容器内文件:

ls
pwd
cat /etc/os-release

退出容器:

exit

7. docker attach 和 docker exec 有什么区别?

docker attach 会连接到容器主进程终端,如果退出方式不当,可能导致容器停止。

docker attach 容器名

docker exec 是在容器中启动一个新的命令进程,更适合日常排查:

docker exec -it 容器名 /bin/bash

通常推荐使用 docker exec


五、Docker 端口映射问题

1. 容器启动后访问不了服务怎么办?

首先确认容器是否运行:

docker ps

查看端口映射:

docker port 容器名

检查容器日志:

docker logs 容器名

确认宿主机端口是否监听:

ss -lntp

或:

netstat -lntp

如果容器内服务只监听 127.0.0.1,外部可能无法访问。应让服务监听 0.0.0.0


2. 如何映射端口?

格式:

docker run -p 宿主机端口:容器端口 镜像名

示例:

docker run -d --name web -p 8080:80 nginx

多个端口映射:

docker run -d --name app -p 8080:8080 -p 9000:9000 my-app:latest

只允许本机访问:

docker run -d --name web -p 127.0.0.1:8080:80 nginx

3. 端口被占用怎么办?

查看端口占用:

sudo lsof -i :8080

或:

sudo ss -lntp | grep 8080

结束占用进程:

sudo kill -9 进程ID

也可以更换宿主机端口:

docker run -d --name nginx-test -p 8081:80 nginx

六、Docker 数据卷与文件挂载问题

1. 容器删除后数据会丢失吗?

如果数据只保存在容器内部,删除容器后数据会丢失。因此数据库、上传文件、配置文件等通常需要挂载到宿主机目录或 Docker Volume。


2. 如何使用宿主机目录挂载?

docker run -d \
  --name nginx-web \
  -p 8080:80 \
  -v /opt/nginx/html:/usr/share/nginx/html \
  nginx

含义:

  • /opt/nginx/html:宿主机目录
  • /usr/share/nginx/html:容器内目录

如果宿主机目录不存在,Docker 会自动创建,但可能会产生权限问题。


3. 如何使用 Docker Volume?

创建数据卷:

docker volume create mysql-data

查看数据卷:

docker volume ls

查看数据卷详情:

docker volume inspect mysql-data

使用数据卷运行 MySQL:

docker run -d \
  --name mysql8 \
  -p 3306:3306 \
  -e MYSQL_ROOT_PASSWORD=123456 \
  -v mysql-data:/var/lib/mysql \
  mysql:8.0

删除数据卷:

docker volume rm mysql-data

清理未使用的数据卷:

docker volume prune

4. 挂载目录后容器无法写入怎么办?

通常是权限问题。可以修改宿主机目录权限:

sudo chmod -R 755 /opt/nginx/html

如果仍然无法写入,可以临时设置更宽松权限:

sudo chmod -R 777 /opt/nginx/html

更推荐修改目录属主:

sudo chown -R 1000:1000 /opt/app/data

具体 UID/GID 需要根据容器内运行用户决定:

docker exec -it 容器名 id

七、Docker 日志常见问题

1. 如何查看容器日志?

docker logs 容器名

实时查看日志:

docker logs -f 容器名

查看最近 100 行:

docker logs --tail=100 容器名

查看带时间戳日志:

docker logs -t 容器名

组合使用:

docker logs -f --tail=200 -t 容器名

2. 容器日志太大怎么办?

Docker 默认日志驱动可能会不断写入 JSON 日志文件,时间久了可能占满磁盘。

查看容器日志文件位置:

docker inspect --format='{{.LogPath}}' 容器名

清空日志文件:

sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' 容器名)

推荐配置日志轮转,编辑 Docker 配置文件:

sudo mkdir -p /etc/docker
sudo vi /etc/docker/daemon.json

写入:

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m",
    "max-file": "3"
  }
}

重启 Docker:

sudo systemctl daemon-reload
sudo systemctl restart docker

八、Docker 网络常见问题

1. 如何查看 Docker 网络?

docker network ls

查看网络详情:

docker network inspect bridge

2. 如何创建自定义网络?

docker network create app-net

指定网段:

docker network create \
  --subnet=172.20.0.0/16 \
  app-net

3. 容器之间如何通过名称访问?

如果容器在同一个自定义网络中,可以直接通过容器名访问。

创建网络:

docker network create app-net

运行 Redis:

docker run -d \
  --name redis \
  --network app-net \
  redis:7

运行应用容器:

docker run -d \
  --name app \
  --network app-net \
  my-app:latest

应用中可以使用:

redis:6379

访问 Redis,而不需要写 IP 地址。


4. 如何将已有容器加入网络?

docker network connect app-net 容器名

断开网络:

docker network disconnect app-net 容器名

九、Dockerfile 常见问题

1. 一个简单的 Dockerfile 示例

以 Spring Boot 项目为例:

FROM eclipse-temurin:17-jre

WORKDIR /app

COPY target/app.jar /app/app.jar

EXPOSE 8080

ENTRYPOINT ["java", "-jar", "/app/app.jar"]

构建镜像:

docker build -t my-spring-app:1.0 .

运行容器:

docker run -d \
  --name my-spring-app \
  -p 8080:8080 \
  my-spring-app:1.0

2. Dockerfile 中 CMD 和 ENTRYPOINT 有什么区别?

CMD 提供容器默认执行命令,可以被 docker run 后面的命令覆盖。

CMD ["nginx", "-g", "daemon off;"]

ENTRYPOINT 更像固定入口,不容易被覆盖,适合作为容器主程序。

ENTRYPOINT ["java", "-jar", "app.jar"]

两者也可以配合使用:

ENTRYPOINT ["java", "-jar"]
CMD ["app.jar"]

3. 如何减少镜像体积?

常见做法:

  • 使用更小的基础镜像,如 alpineslim
  • 使用多阶段构建
  • 减少无用依赖
  • 合并 RUN 命令
  • 清理缓存文件

Go 项目多阶段构建示例:

FROM golang:1.22 AS builder

WORKDIR /src
COPY . .
RUN go build -o app main.go

FROM alpine:3.20

WORKDIR /app
COPY --from=builder /src/app /app/app

EXPOSE 8080

ENTRYPOINT ["/app/app"]

构建:

docker build -t go-app:1.0 .

十、Docker Compose 常见问题

1. Docker Compose 是什么?

Docker Compose 是 Docker 官方提供的多容器编排工具。它通过 docker-compose.yml 文件定义多个服务、网络、数据卷等,适合本地开发环境和中小型服务部署。


2. 一个 Nginx + MySQL 的 Compose 示例

创建文件:

mkdir docker-demo
cd docker-demo
vi docker-compose.yml

内容如下:

services:
  nginx:
    image: nginx:1.25
    container_name: demo-nginx
    ports:
      - "8080:80"
    volumes:
      - ./html:/usr/share/nginx/html
    networks:
      - demo-net

  mysql:
    image: mysql:8.0
    container_name: demo-mysql
    ports:
      - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: "123456"
      MYSQL_DATABASE: "demo"
    volumes:
      - mysql-data:/var/lib/mysql
    networks:
      - demo-net

volumes:
  mysql-data:

networks:
  demo-net:

启动:

docker compose up -d

查看服务:

docker compose ps

查看日志:

docker compose logs -f

停止服务:

docker compose down

停止并删除数据卷:

docker compose down -v

重新构建并启动:

docker compose up -d --build

十一、Docker 清理与磁盘空间问题

1. 如何查看 Docker 占用空间?

docker system df

查看更详细信息:

docker system df -v

2. 如何清理未使用资源?

清理停止的容器、未使用网络、悬空镜像、构建缓存:

docker system prune

强制清理,不询问:

docker system prune -f

清理所有未使用镜像:

docker system prune -a

同时清理数据卷:

docker system prune -a --volumes

注意:--volumes 可能删除未被容器使用的数据卷,执行前务必确认数据是否重要。


3. 如何清理构建缓存?

docker builder prune

强制清理:

docker builder prune -f

清理所有构建缓存:

docker builder prune -a

十二、Docker 容器自启动问题

1. 如何设置容器开机自启动?

运行容器时指定:

docker run -d \
  --name nginx-auto \
  --restart=always \
  -p 8080:80 \
  nginx

对已有容器设置:

docker update --restart=always nginx-auto

取消自启动:

docker update --restart=no nginx-auto

2. restart 策略有哪些?

策略 含义
no 默认策略,不自动重启
always 无论退出原因,都会重启
unless-stopped 除非手动停止,否则自动重启
on-failure 只有异常退出时才重启

示例:

docker run -d \
  --name app \
  --restart=unless-stopped \
  my-app:latest

十三、Docker 常用排查命令

1. 查看容器详细信息

docker inspect 容器名

查看 IP 地址:

docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' 容器名

2. 查看容器资源占用

docker stats

查看指定容器:

docker stats 容器名

3. 查看容器进程

docker top 容器名

4. 在容器和宿主机之间复制文件

从宿主机复制到容器:

docker cp ./app.conf 容器名:/app/app.conf

从容器复制到宿主机:

docker cp 容器名:/app/logs ./logs

十四、常见应用部署命令示例

1. 部署 MySQL

docker run -d \
  --name mysql8 \
  --restart=always \
  -p 3306:3306 \
  -e MYSQL_ROOT_PASSWORD=123456 \
  -e MYSQL_DATABASE=testdb \
  -v mysql-data:/var/lib/mysql \
  mysql:8.0

进入 MySQL:

docker exec -it mysql8 mysql -uroot -p

2. 部署 Redis

docker run -d \
  --name redis7 \
  --restart=always \
  -p 6379:6379 \
  -v redis-data:/data \
  redis:7 \
  redis-server --appendonly yes

进入 Redis:

docker exec -it redis7 redis-cli

3. 部署 Nginx

docker run -d \
  --name nginx \
  --restart=always \
  -p 80:80 \
  -p 443:443 \
  -v /opt/nginx/html:/usr/share/nginx/html \
  -v /opt/nginx/conf:/etc/nginx/conf.d \
  -v /opt/nginx/logs:/var/log/nginx \
  nginx:1.25

测试配置:

docker exec -it nginx nginx -t

重载配置:

docker exec -it nginx nginx -s reload

十五、Docker 使用建议

  1. 生产环境不要长期使用 latest 标签
    推荐使用明确版本,例如 mysql:8.0nginx:1.25,避免镜像更新导致不可预期问题。

  2. 重要数据必须挂载数据卷或宿主机目录
    数据库、上传文件、配置文件、证书等不要只放在容器内部。

  3. 为容器设置 restart 策略
    生产环境建议使用 --restart=always--restart=unless-stopped

  4. 限制日志大小
    避免 Docker 日志无限增长占满磁盘。

  5. 使用自定义网络连接多个容器
    不建议依赖容器 IP,因为容器重启后 IP 可能变化。

  6. 定期清理无用镜像和容器
    但执行清理前要确认是否包含重要数据卷。

  7. 尽量使用 Docker Compose 管理多容器应用
    这样配置更清晰,部署和迁移更方便。


总结

Docker 极大提升了应用交付和环境管理效率,但在实际使用过程中,镜像拉取、容器启动、端口映射、数据挂载、日志管理、网络通信、磁盘清理等问题非常常见。掌握本文中的常用命令和排查思路,可以快速解决大多数 Docker 日常问题。

对于个人开发者来说,Docker 可以快速搭建 MySQL、Redis、Nginx、RabbitMQ、Elasticsearch 等开发环境;对于团队和企业来说,Docker 可以统一开发、测试、生产环境,配合 Docker Compose、Kubernetes、CI/CD 工具进一步提升交付效率。

建议在使用 Docker 时始终牢记三点:镜像要可追溯,数据要持久化,日志要可控制。只要做好这些基础规范,Docker 就能成为稳定、高效、可靠的应用部署工具。

目录结构
全文