首页 / Docker / Docker入门到精通

Docker入门到精通:从安装到部署完整指南

Docker 是当今最流行的容器化平台,它通过将应用及其依赖打包到一个轻量级、可移植的容器中,彻底改变了软件的开发、测试与部署方式。无论你是后端开发、运维工程师,还是全栈开发者,掌握 Docker 都已成为一项必备技能。本文将从零开始,带你系统学习 Docker 的核心概念与实战操作。

一、Docker 核心概念

在动手之前,我们需要先理解 Docker 的几个核心概念,这是后续学习的基础。

简单理解:镜像是蓝图,容器是根据蓝图造出来的房子,仓库是存放蓝图的图书馆,Dockerfile 则是绘制蓝图的说明书。

二、Docker 安装

2.1 Linux 环境安装(以 Ubuntu 为例)

推荐使用官方仓库安装 Docker CE(社区版),这是最稳定的方式。

bash# 更新 apt 包索引并安装依赖
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg lsb-release

# 添加 Docker 官方 GPG 密钥
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
  sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

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

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

# 将当前用户加入 docker 组,免 sudo 运行
sudo usermod -aG docker $USER
# 重新登录后生效,或执行 newgrp docker

# 验证安装
docker --version
sudo docker run hello-world

2.2 配置镜像加速

国内拉取 Docker Hub 镜像速度较慢,建议配置镜像加速器。编辑 /etc/docker/daemon.json

json{
  "registry-mirrors": [
    "https://mirror.ccs.tencentyun.com",
    "https://docker.mirrors.ustc.edu.cn"
  ],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m",
    "max-file": "3"
  }
}

配置完成后重启 Docker 服务:

bashsudo systemctl daemon-reload
sudo systemctl restart docker

三、镜像管理

镜像是 Docker 的基础,掌握镜像的搜索、拉取、查看与构建至关重要。

bash# 搜索镜像
docker search nginx

# 拉取镜像(默认 latest 标签)
docker pull nginx
docker pull nginx:1.25-alpine   # 指定版本

# 列出本地镜像
docker images

# 删除镜像
docker rmi nginx:1.25-alpine
docker image prune -f   # 清理悬空镜像

# 查看镜像详情
docker inspect nginx

# 给镜像打标签
docker tag nginx:latest myrepo/nginx:v1.0

四、容器操作

容器是镜像的运行实例,下面介绍容器的核心操作命令。

bash# 运行一个容器(前台交互模式)
docker run -it --name my-ubuntu ubuntu:22.04 /bin/bash

# 运行一个后台容器(守护模式)
docker run -d \
  --name web-server \
  -p 8080:80 \
  -v /data/html:/usr/share/nginx/html \
  --restart unless-stopped \
  nginx:latest

# 参数说明:
# -d        后台运行
# --name    指定容器名称
# -p        端口映射  宿主机端口:容器端口
# -v        数据卷挂载  宿主机路径:容器路径
# --restart 重启策略

# 查看运行中的容器
docker ps
docker ps -a    # 查看所有容器(包括已停止)

# 启动 / 停止 / 重启 / 删除容器
docker start web-server
docker stop web-server
docker restart web-server
docker rm web-server          # 删除已停止的容器
docker rm -f web-server       # 强制删除运行中的容器

# 进入运行中的容器
docker exec -it web-server /bin/bash

# 查看容器日志
docker logs web-server
docker logs -f --tail 100 web-server   # 实时跟踪最后100行

# 查看容器资源占用
docker stats

五、Dockerfile 编写

Dockerfile 是构建自定义镜像的核心。下面以构建一个 Node.js 应用镜像为例,讲解常用指令。

dockerfile# 使用官方 Node.js 轻量镜像作为基础
FROM node:20-alpine

# 设置工作目录
WORKDIR /app

# 设置环境变量
ENV NODE_ENV=production
ENV PORT=3000

# 先复制依赖文件,利用缓存层加速构建
COPY package*.json ./
RUN npm install --production

# 再复制源代码
COPY . .

# 声明端口
EXPOSE 3000

# 健康检查
HEALTHCHECK --interval=30s --timeout=3s \
  CMD wget --quiet --tries=1 --spider http://localhost:3000/health || exit 1

# 以非 root 用户运行(安全最佳实践)
USER node

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

构建并运行该镜像:

bash# 构建镜像,-t 指定名称和标签
docker build -t myapp:1.0 .

# 运行容器
docker run -d --name myapp -p 3000:3000 myapp:1.0

构建优化技巧:把变化频率低的操作(如安装依赖)放在前面,变化频率高的操作(如复制源码)放在后面,这样可以充分利用 Docker 的层缓存,大幅加快重复构建速度。

六、数据卷与持久化

容器内的数据是临时的,容器删除后数据也会丢失。数据卷(Volume)用于实现数据持久化与容器间数据共享。

bash# 创建命名数据卷
docker volume create mydata

# 挂载数据卷运行容器
docker run -d \
  --name db \
  -v mydata:/var/lib/mysql \
  -e MYSQL_ROOT_PASSWORD=secret \
  mysql:8.0

# 查看数据卷
docker volume ls
docker volume inspect mydata

# 绑定挂载(挂载宿主机目录)
docker run -d \
  --name web \
  -p 8080:80 \
  -v /home/user/www:/usr/share/nginx/html:ro \
  nginx:latest
# :ro 表示只读挂载,容器内无法修改

七、Docker 网络

Docker 提供了多种网络模式,理解网络是进行多容器通信的关键。

网络模式 说明 使用场景
bridge 默认模式,通过网桥连接容器 单机多容器通信
host 容器直接使用宿主机网络 对网络性能要求高
none 无网络 安全隔离场景
自定义网络 用户创建的桥接网络,支持 DNS 解析 多容器按服务名互访
bash# 创建自定义网络
docker network create app-net

# 将容器加入网络(可通过容器名互相访问)
docker run -d --name app-db --network app-net -e MYSQL_ROOT_PASSWORD=secret mysql:8.0
docker run -d --name app-web --network app-net -p 8080:80 nginx:latest

# 在 app-web 容器内可以直接用 app-db 这个名字访问数据库
# 无需关心 IP 地址,Docker 内置 DNS 会自动解析

八、Docker Compose 多容器编排

当应用由多个服务组成时,手动管理容器非常繁琐。Docker Compose 通过一个 YAML 文件定义和运行多容器应用。

yaml# docker-compose.yml - 一个典型的 Web + 数据库架构
version: '3.8'

services:
  web:
    build: .
    container_name: app-web
    ports:
      - "8080:3000"
    environment:
      - NODE_ENV=production
      - DB_HOST=db
      - DB_PORT=3306
    depends_on:
      - db
    restart: unless-stopped
    networks:
      - app-net

  db:
    image: mysql:8.0
    container_name: app-db
    environment:
      MYSQL_ROOT_PASSWORD: secret
      MYSQL_DATABASE: appdb
      MYSQL_USER: appuser
      MYSQL_PASSWORD: apppass
    volumes:
      - db-data:/var/lib/mysql
    restart: unless-stopped
    networks:
      - app-net

volumes:
  db-data:

networks:
  app-net:
    driver: bridge

使用 Compose 管理应用:

bash# 构建并启动所有服务(后台运行)
docker compose up -d --build

# 查看服务状态
docker compose ps

# 查看日志
docker compose logs -f web

# 停止并删除容器、网络(保留数据卷)
docker compose down

# 停止并删除所有(包括数据卷)
docker compose down -v

九、生产环境部署最佳实践

9.1 镜像优化

dockerfile# 多阶段构建示例:编译阶段与运行阶段分离
FROM golang:1.21-alpine AS builder
WORKDIR /build
COPY . .
RUN CGO_ENABLED=0 go build -o myapp -ldflags="-s -w" .

# 最终运行镜像,体积仅几 MB
FROM alpine:3.19
RUN apk add --no-cache ca-certificates
COPY --from=builder /build/myapp /usr/local/bin/
EXPOSE 8080
CMD ["myapp"]

9.2 安全加固

bashdocker run -d \
  --name app \
  --read-only \
  --tmpfs /tmp \
  --memory=512m \
  --cpus=1.0 \
  --user 1000:1000 \
  myapp:1.0

十、常用命令速查表

命令 作用
docker build构建镜像
docker run创建并启动容器
docker ps查看运行中的容器
docker exec在容器中执行命令
docker logs查看容器日志
docker stats查看资源占用
docker system prune清理无用资源
docker compose up启动编排服务

总结

本文从 Docker 的核心概念出发,系统讲解了安装配置、镜像管理、容器操作、Dockerfile 编写、数据卷、网络以及 Docker Compose 多容器编排,最后给出了生产环境的最佳实践。Docker 的学习曲线相对平缓,但要真正用好它,关键在于理解镜像分层、网络模型和持久化机制,并在实际项目中不断实践。

建议你按照本文的步骤动手操作一遍,从运行第一个 hello-world 容器开始,逐步构建自己的应用镜像。当你能熟练使用 Docker Compose 编排多服务应用时,就已经迈入了容器化部署的大门。后续可以进一步学习 Kubernetes,进入云原生的更广阔世界。