Docker 安装部署与常见问题详解

Docker 是一个开源的容器化平台,允许开发者将应用程序及其依赖打包成轻量级、可移植的容器,在任何支持 Docker 的环境中运行。

目录

一、Docker 简介
二、Windows 上安装 Docker Desktop
三、Linux 上安装 Docker(Ubuntu / Debian / CentOS)
四、WSL 2 中安装 Docker
五、Docker 基本配置与优化
六、Docker Compose 安装与使用
七、常见问题与解决方案
八、Docker 进阶技巧
九、构建第一个 Docker 镜像
十、卸载与重装

一、Docker 简介

Docker 是一个开源的容器化平台,允许开发者将应用程序及其依赖打包成一个轻量级、可移植的容器,在任何支持 Docker 的环境中运行。Docker 容器与虚拟机不同,它共享宿主机的操作系统内核,因此启动速度极快(通常只需几秒)、占用资源极少(通常只有几十MB内存开销)。

Docker 的核心优势:

  • 环境一致性:开发、测试、生产环境完全一致,消除”在我机器上能跑”的问题
  • 资源隔离:每个容器相互隔离,不会相互影响
  • 快速部署:容器可以在秒级启动和停止
  • 版本控制:每个容器镜像都可以像 Git 一样进行版本管理
  • 可复用性:Docker Hub 上有数以万计的官方和社区镜像可供使用

几个核心概念

  • 镜像(Image):一个只读的模板,包含了运行应用程序所需的所有文件系统和依赖
  • 容器(Container):镜像的运行实例,是一个可写的层
  • 仓库(Repository):存储和分发镜像的地方,Docker Hub 是最大的公共仓库
  • Dockerfile:定义如何构建镜像的脚本文件

二、Windows 上安装 Docker Desktop

2.1 系统要求

  • Windows 11 64位专业版/企业版/教育版,或 Windows 10 64位专业版/企业版/教育版(1903+)
  • 启用 WSL 2(推荐)或 Hyper-V
  • 至少 4GB 内存(推荐 8GB+)
  • BIOS 中启用虚拟化(Virtualization)

2.2 安装步骤

1. 前往 Docker 官方网站 下载 Docker Desktop Installer.exe

2. 双击运行安装包,勾选”Use WSL 2 instead of Hyper-V”(推荐)选项

3. 安装完成后,Docker Desktop 会自动启动,你会在系统托盘看到一个鲸鱼图标

4. 打开 PowerShell 或命令提示符,验证安装:

docker --version
docker-compose --version

2.3 启用 WSL 2 后端(推荐)

如果安装时未勾选 WSL 2 选项,可以手动切换:

1. 右键点击 Docker Desktop 图标 → Settings → General

2. 勾选”Use WSL 2 instead of Hyper-V”

3. 点击 Apply & Restart

三、Linux 上安装 Docker(Ubuntu / Debian / CentOS)

3.1 Ubuntu / Debian 安装

方式一:使用官方安装脚本(最简单,推荐新手)

curl -fsSL https://get.docker.com | sudo sh

方式二:手动安装(更可控)

第一步:更新软件源并安装依赖

sudo apt update
sudo apt install -y apt-transport-https ca-certificates curl gnupg lsb-release

第二步:添加 Docker 官方 GPG 密钥

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

第三步:添加 Docker 仓库

echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

第四步:安装 Docker Engine 和 containerd

sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

第五步:验证安装

sudo docker run hello-world

3.2 CentOS / RHEL / Fedora 安装

第一步:卸载旧版本(如果有)

sudo yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine

第二步:安装 yum-utils 并添加 Docker 仓库

sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

第三步:安装 Docker Engine

sudo yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

第四步:启动 Docker

sudo systemctl start docker
sudo systemctl enable docker

第五步:验证

sudo docker run hello-world

3.3 免 sudo 运行 Docker(可选但推荐)

sudo usermod -aG docker $USER
newgrp docker

注销并重新登录,或者运行 newgrp docker 立即生效。

四、WSL 2 中安装 Docker

在 WSL 2 中运行 Docker 有两种主流方案,各有优缺点。

方案一:Docker Desktop WSL 2 后端(推荐)

当你在 Windows 上安装了 Docker Desktop 并启用 WSL 2 后端后,WSL 2 发行版可以直接使用 Docker CLI:

# 在 WSL 2 终端中验证
docker --version
docker ps
# 尝试运行一个容器
docker run -d --name nginx-test -p 8080:80 nginx

这种方式实际上是让 Docker Desktop 在 Windows 宿主机上运行 Docker 守护进程,WSL 2 通过 Docker socket 与其通信。

方案二:直接在 WSL 2 中安装 Docker Engine

如果你不想安装 Docker Desktop for Windows,可以直接在 WSL 2 中安装完整的 Docker Engine:

# 更新软件包
sudo apt update && sudo apt upgrade -y

# 安装依赖
sudo apt install -y apt-transport-https ca-certificates curl gnupg lsb-release

# 添加 Docker GPG 密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

# 添加 Docker 仓库
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# 安装 Docker
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# 启动 Docker 服务
sudo service docker start

# 验证
sudo docker run hello-world

注意:WSL 2 中的 Docker daemon 不会开机自启,每次启动 WSL 2 后需要手动 sudo service docker start

WSL 2 中 Docker 开机自启

创建脚本 C:\wsl-docker-start.bat

@echo off
wsl -d Ubuntu-24.04 -e sudo service docker start 2>nul

然后用任务计划程序在用户登录时运行(Win+R → taskschd.msc → 创建基本任务)。

五、Docker 基本配置与优化

5.1 Docker 镜像加速

在国内访问 Docker Hub 速度较慢,建议配置国内镜像加速器。修改或创建 /etc/docker/daemon.json

{
  "registry-mirrors": [
    "https://docker.1ms.run",
    "https://docker.rainbond.cc",
    "https://docker.xuanyuan.me"
  ]
}

然后重启 Docker:

sudo systemctl restart docker

5.2 Docker daemon 完整配置示例

完整的 /etc/docker/daemon.json 配置:

{
  "registry-mirrors": [
    "https://docker.1ms.run"
  ],
  "live-restore": true,
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  },
  "default-ulimits": {
    "nofile": {
      "Name": "nofile",
      "Hard": 65536,
      "Soft": 65536
    }
  },
  "dns": ["8.8.8.8", "8.8.4.4"]
}

参数说明:

  • live-restore:Docker daemon 重启时容器保持运行
  • log-driver:日志驱动,json-file 支持日志轮转
  • max-size:单个日志文件最大 10MB
  • max-file:最多保留 3 个日志文件
  • default-ulimits:容器的默认资源限制

5.3 配置 Docker 镜像存储位置

如果系统盘空间不足,可以将 Docker 镜像存储到其他盘:

# 停止 Docker
sudo systemctl stop docker

# 创建新的存储目录
sudo mkdir -p /mnt/d/docker

# 迁移现有数据
sudo rsync -aP /var/lib/docker/ /mnt/d/docker/

# 备份原目录
sudo mv /var/lib/docker /var/lib/docker.bak

# 创建软链接
sudo ln -s /mnt/d/docker /var/lib/docker

# 重启 Docker
sudo systemctl start docker

# 验证
docker info | grep "Docker Root Dir"

5.4 Docker 网络配置

Docker 默认创建三种网络:bridge、host、none。你也可以创建自定义网络来实现容器间隔离:

# 创建自定义桥接网络
docker network create --driver bridge --subnet=172.18.0.0/16 my_network

# 在自定义网络中运行容器
docker run -d --name nginx --network my_network -p 8080:80 nginx

# 将已有容器连接到网络
docker network connect my_network nginx-test

# 查看网络信息
docker network inspect my_network

六、Docker Compose 安装与使用

6.1 什么是 Docker Compose

Docker Compose 是一个用于定义和运行多容器 Docker 应用的工具。通过一个 YAML 文件,你可以同时启动、停止和构建多个服务,非常适合本地开发、微服务架构等场景。

6.2 安装 Docker Compose

Docker Desktop 和最新版 Docker 安装时已经包含了 docker-compose 插件。如果需要单独安装:

# 下载最新版本
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

# 添加执行权限
sudo chmod +x /usr/local/bin/docker-compose

# 验证
docker-compose --version

6.3 docker-compose.yml 完整示例

以下是一个典型的 LNMP 架构的 docker-compose.yml:

version: "3.9"

services:
  nginx:
    image: nginx:latest
    container_name: my_nginx
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
      - ./www:/usr/share/nginx/html:ro
    depends_on:
      - php
    networks:
      - app_net
    restart: unless-stopped

  mysql:
    image: mysql:8.0
    container_name: my_mysql
    environment:
      MYSQL_ROOT_PASSWORD: root_secret_pass
      MYSQL_DATABASE: myapp
      MYSQL_USER: myuser
      MYSQL_PASSWORD: user_secret_pass
    volumes:
      - mysql_data:/var/lib/mysql
    networks:
      - app_net
    restart: unless-stopped
    command: --default-authentication-plugin=mysql_native_password

  php:
    image: php:8.3-fpm
    container_name: my_php
    volumes:
      - ./www:/var/www/html:ro
      - ./php/php.ini:/usr/local/etc/php/php.ini:ro
    depends_on:
      - mysql
    networks:
      - app_net
    restart: unless-stopped

networks:
  app_net:
    driver: bridge

volumes:
  mysql_data:

6.4 常用 Docker Compose 命令

# 启动所有服务(后台运行)
docker-compose up -d

# 启动并重新构建镜像
docker-compose up -d --build

# 查看运行状态
docker-compose ps

# 查看日志
docker-compose logs -f nginx

# 停止所有服务
docker-compose down

# 停止并删除数据卷
docker-compose down -v

# 进入容器内执行命令
docker-compose exec nginx sh

# 重新构建某个服务
docker-compose build php

# 拉取所有服务的最新镜像
docker-compose pull

七、常见问题与解决方案

问题 1:docker run 报错 “permission denied while trying to connect to the Docker daemon socket”

原因:当前用户没有 Docker socket 的访问权限。

解决:将用户加入 docker 组(见本文 3.3 节),或者每次命令前加 sudo

# 永久解决:将用户加入 docker 组
sudo usermod -aG docker $USER
# 然后注销并重新登录,或立即生效:
newgrp docker

问题 2:Docker daemon 无法启动,报错 “Cannot connect to the Docker daemon”

解决

# 检查 Docker 服务状态
sudo systemctl status docker

# 如果未运行,启动它
sudo systemctl start docker

# 设置开机自启
sudo systemctl enable docker

# 验证
sudo docker info

问题 3:容器内无法访问外网,但宿主机正常

原因:Docker 的 DNS 解析配置问题,或者网络模式冲突。

解决

# 方法1:指定 DNS
docker run --dns 8.8.8.8 -it ubuntu bash

# 方法2:在 docker-compose.yml 中配置
services:
  app:
    dns:
      - 8.8.8.8
      - 114.114.114.114

# 方法3:修改 /etc/docker/daemon.json
{
  "dns": ["8.8.8.8", "114.114.114.114"]
}

# 修改后重启
sudo systemctl restart docker

问题 4:pull 镜像速度极慢或超时

原因:Docker Hub 在国内访问受限。

解决:配置国内镜像加速器(见本文 5.1 节)。如果加速器也不稳定,可以尝试使用代理,或者使用阿里云容器镜像服务的专属加速地址。

问题 5:容器可以运行但无法通过端口访问

原因:端口映射错误,或防火墙阻止。

解决

# 检查容器端口映射
docker port nginx

# 检查防火墙(Linux)
sudo iptables -L -n | grep 8080

# 如果是 ufw 防火墙,开放端口
sudo ufw allow 8080/tcp

# 如果是云服务器,还需要开放云平台的安全组规则

问题 6:容器内文件修改后重启数据丢失

原因:没有使用持久化存储(数据卷)。

解决:使用 -v 或 –mount 挂载宿主机目录或命名数据卷:

# 挂载宿主机目录(推荐,用于代码和配置)
docker run -v /host/path:/container/path nginx

# 使用命名数据卷(推荐,用于数据库数据)
docker volume create my_data
docker run -v my_data:/container/path nginx

# docker-compose 中的写法
services:
  mysql:
    volumes:
      - mysql_data:/var/lib/mysql
      - ./config:/etc/mysql/conf.d

volumes:
  mysql_data:

问题 7:容器内中文乱码

原因:容器没有配置 UTF-8 编码环境变量。

解决

# 设置环境变量
docker run -e LANG=C.UTF-8 -e LC_ALL=C.UTF-8 ubuntu

# 或者在 Dockerfile 中配置
ENV LANG=C.UTF-8
ENV LC_ALL=C.UTF-8

问题 8:docker build 报错 “no space left on device”

原因:Docker 镜像和容器占满了磁盘空间。

解决

# 查看 Docker 磁盘使用情况
docker system df

# 清理未使用的镜像、容器、网络
docker system prune -a

# 清理构建缓存
docker builder prune

# 删除所有悬空镜像(无标签)
docker image prune

问题 9:MySQL/PostgreSQL 容器无法启动,报权限错误

原因:挂载了宿主机目录作为数据目录,但目录中原有文件与容器初始化文件冲突。

解决

# 方法1:使用命名数据卷而非绑定挂载
docker volume create mysql_data

# 方法2:如果必须使用宿主机目录,先清空目录
rm -rf /host/mysql/data/*

# 方法3:检查并修改权限
sudo chown -R 999:999 /host/mysql/data

问题 10:修改 docker-compose.yml 后服务没有更新

原因:容器没有重新创建。

解决

# 重新构建并启动
docker-compose up -d --force-recreate

# 如果改了 Dockerfile,需要重新 build
docker-compose up -d --build

# 查看实际运行的配置
docker-compose config

八、Docker 进阶技巧

8.1 多阶段构建(Multi-stage Builds)

多阶段构建可以大幅减小最终镜像体积,前一个阶段用于编译,后一个阶段只复制运行所需的产物:

# syntax=docker/dockerfile:1

# 第一阶段:构建
FROM golang:1.22 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp .

# 第二阶段:运行(镜像体积从 800MB 降到 15MB)
FROM alpine:3.19
WORKDIR /root/
COPY --from=builder /app/myapp .
CMD ["./myapp"]

8.2 Docker BuildKit 构建缓存优化

启用 BuildKit 可以并行构建并更好地利用缓存:

# 启用 BuildKit
export DOCKER_BUILDKIT=1

# 构建时自动利用缓存
docker build -t myapp .

或者在 /etc/docker/daemon.json 中永久启用:

{
  "builder": {
    "gc": {
      "enabled": true,
      "defaultKeepStorage": "20GB"
    }
  }
}

8.3 容器健康检查(HEALTHCHECK)

在 Dockerfile 中添加健康检查,Docker 会自动检测容器健康状态:

FROM nginx:latest

HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD curl -f http://localhost/ || exit 1

# 也可以在 docker-compose.yml 中配置
services:
  nginx:
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost/"]
      interval: 30s
      timeout: 3s
      retries: 3

# 查看健康状态
docker inspect --format="{{.State.Health.Status}}" nginx

8.4 容器资源限制

防止单个容器占满全部系统资源:

# 限制 CPU 和内存
docker run -d --name myapp \
  --memory="512m" \
  --memory-swap="1g" \
  --cpus="1.0" \
  --cpuset-cpus="0-1" \
  myapp:latest

# 在 docker-compose.yml 中配置
services:
  myapp:
    deploy:
      resources:
        limits:
          cpus: "1.0"
          memory: 512M

8.5 使用 Dockerignore 优化构建

在项目根目录创建 .dockerignore 文件:

.git
.gitignore
node_modules
.env
.env.*
docker-compose*.yml
.DS_Store
__pycache__
*.pyc
vendor
coverage
dist

九、构建第一个 Docker 镜像

9.1 编写 Dockerfile

假设我们有一个 Node.js 应用 app.js

const http = require("http");

const server = http.createServer((req, res) => {
  res.end("Hello from Docker! Your IP is: " + req.socket.remoteAddress);
});

server.listen(3000, () => {
  console.log("Server running on http://localhost:3000");
});

创建 Dockerfile

# 基于官方 Node.js 镜像
FROM node:20-alpine

# 设置工作目录
WORKDIR /app

# 复制 package.json(先复制它可以利用 Docker 缓存)
COPY package.json .

# 安装依赖
RUN npm install

# 复制应用代码
COPY . .

# 暴露端口
EXPOSE 3000

# 启动命令
CMD ["node", "app.js"]

9.2 构建并运行

# 构建镜像
docker build -t my-nodejs-app .

# 运行容器
docker run -d -p 3000:3000 --name myapp my-nodejs-app

# 验证
curl http://localhost:3000

# 查看容器日志
docker logs -f myapp

9.3 将镜像推送到 Docker Hub

# 登录 Docker Hub
docker login -u your_username

# 为镜像打标签
docker tag my-nodejs-app:latest your_username/my-nodejs-app:v1.0

# 推送到仓库
docker push your_username/my-nodejs-app:v1.0

十、卸载与重装

10.1 Windows 卸载 Docker Desktop

1. 打开”设置” → “应用” → “已安装的应用”
2. 找到 Docker Desktop,点击”卸载”
3. 运行清理脚本(PowerShell):

Remove-Item -Recurse -Force "$env:ProgramData\Docker"
Remove-Item -Recurse -Force "$env:ProgramFiles\Docker"
Remove-Item -Recurse -Force "$env:LOCALAPPDATA\Docker"
wsl --unregister Docker-Desktop

10.2 Linux 卸载 Docker

# 停止服务
sudo systemctl stop docker

# 卸载 Docker Engine
sudo apt purge -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras

# 删除所有镜像、容器、数据卷
sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd

# 删除用户组
sudo delgroup docker

# 删除软件源
sudo rm /etc/apt/sources.list.d/docker.list
sudo rm /usr/share/keyrings/docker-archive-keyring.gpg

这样,你就完成了 Docker 的完整安装与配置。祝你使用愉快!

评论

发表回复