Docker 使用详解:从安装配置到常用命令实战

Docker 已经成为后端开发和部署中非常常见的基础工具。

无论是本地开发,还是测试、CI/CD、服务器部署,都经常会遇到:

MySQL
Redis
RabbitMQ
Nginx
PHP
Node.js
Python

这些服务都可以通过 Docker 快速运行。

相比直接在操作系统中安装各种软件,Docker 最大的优势之一是:

把应用及其运行环境封装成容器,让开发、测试和部署环境更加一致。

本文不深入讨论 Docker 底层实现,而是以实际使用为主,从安装开始,重点介绍日常开发中最常用的 Docker 命令。

1. Docker 是什么?

Docker 是一个容器化平台。

传统方式安装一个 PHP 项目,可能需要:

操作系统
 ↓
PHP
 ↓
PHP 扩展
 ↓
Composer
 ↓
Nginx
 ↓
MySQL
 ↓
Redis

不同开发者的电脑可能存在:

PHP 版本不同
MySQL 版本不同
扩展不同
配置不同
系统环境不同

于是就容易出现:

“我的电脑上可以运行,你的电脑为什么不行?”

Docker 的思路是把应用运行环境标准化。

例如:

Docker
├── PHP 8.3
├── Nginx
├── MySQL 8
└── Redis

每个服务运行在独立容器中。

例如:

┌─────────────────────────────┐
│          Docker Host        │
│                             │
│  ┌───────┐  ┌───────────┐  │
│  │ PHP   │  │   Nginx   │  │
│  │Container│ │ Container │  │
│  └───────┘  └───────────┘  │
│                             │
│  ┌───────┐  ┌───────────┐  │
│  │ MySQL │  │   Redis   │  │
│  │Container│ │ Container │  │
│  └───────┘  └───────────┘  │
└─────────────────────────────┘

Docker 中几个最重要的概念是:

Image       镜像
Container   容器
Volume      数据卷
Network     网络
Registry    镜像仓库

可以简单理解为:

Image
  ↓ 创建
Container
  ↓ 挂载
Volume
  ↓ 连接
Network

2. Docker 安装

Docker Desktop 是 Windows 和 macOS 上比较方便的 Docker 使用方式。

Linux 服务器通常直接安装 Docker Engine。

官方安装文档:

Docker Engine 官方安装文档

Windows

Windows 开发环境通常使用:

Docker Desktop

安装完成后打开 PowerShell:

docker --version

例如:

Docker version 28.x.x

再执行:

docker info

如果能够正常返回 Docker Server 信息,说明 Docker Engine 已经正常运行。

macOS

安装 Docker Desktop 后执行:

docker --version

Ubuntu

Linux 服务器推荐按照 Docker 官方文档安装 Docker Engine,而不是直接使用过旧的系统仓库版本。

安装完成:

docker --version

然后:

sudo docker run hello-world

如果看到:

Hello from Docker!

说明 Docker 已经能够正常运行。


3. Docker 基础配置

安装 Docker 后,开发环境中通常还需要关注三个问题:

镜像源
数据目录
代理

3.1 镜像源

Docker 拉取镜像时默认访问 Docker Hub。

例如:

docker pull mysql:8.4

如果网络环境访问 Docker Hub 较慢,可以根据所在环境配置镜像加速或使用可访问的镜像仓库。

需要注意:

镜像仓库配置属于环境问题,不建议把某个临时镜像地址直接写死到项目配置中。

企业环境更常见的方案是使用自己的:

Harbor
云厂商 Container Registry
GitHub Container Registry
Docker Hub

3.2 Docker 数据目录

Linux Docker 默认会把镜像、容器、Volume 等数据存储在 Docker 的数据目录中。

可以通过:

docker info

查看:

Docker Root Dir

例如:

Docker Root Dir: /var/lib/docker

如果服务器磁盘空间较小,需要提前规划 Docker 数据目录。

3.3 查看 Docker 信息

docker info

这是排查 Docker 环境问题非常重要的命令。


4. Docker 镜像命令

镜像是 Docker 使用过程中最基础的对象之一。

例如:

docker pull redis:7

下载 Redis 镜像。

4.1 拉取镜像

docker pull mysql:8.4

指定版本:

docker pull mysql:8.4

不建议生产环境长期使用:

docker pull mysql:latest

因为 latest 指向的具体版本可能发生变化。

更推荐:

mysql:8.4
redis:7.4
nginx:1.27

根据实际需求固定版本。

4.2 查看镜像

docker images

或者:

docker image ls

例如:

REPOSITORY   TAG      IMAGE ID       SIZE
mysql        8.4      xxx            ...
redis        7.4      xxx            ...
nginx        1.27     xxx            ...

4.3 删除镜像

docker rmi nginx:1.27

如果镜像正在被容器使用,可能无法删除。

可以先:

docker ps -a

找到相关容器。

4.4 查看镜像详细信息

docker image inspect mysql:8.4

也可以:

docker inspect mysql:8.4

4.5 查看镜像历史

docker history mysql:8.4

这个命令对于分析 Dockerfile 构建过程很有帮助。


5. Docker 容器命令

镜像解决的是:

“运行什么?”

容器解决的是:

“现在正在运行什么?”

5.1 创建并运行容器

最基本的命令:

docker run nginx

后台运行:

docker run -d nginx

指定名称:

docker run -d --name my-nginx nginx

这里:

-d

表示后台运行。

--name

指定容器名称。

5.2映射端口

例如 Nginx 容器监听:

80

映射到宿主机:

8080

执行:

docker run -d \
    --name my-nginx \
    -p 8080:80 \
    nginx

访问:

http://localhost:8080

端口格式:

宿主机端口:容器端口

例如:

8080:80
3307:3306
6379:6379

查看运行中的容器

docker ps

查看全部:

docker ps -a

这是 Docker 日常使用频率最高的命令之一。

停止容器

docker stop my-nginx

启动容器

docker start my-nginx

重启容器

docker restart my-nginx

删除容器

docker rm my-nginx

如果需要强制删除:

docker rm -f my-nginx

不过生产环境中不要习惯性使用 -f。

查看容器状态

docker inspect my-nginx

可以查看:

容器配置
网络
挂载
环境变量
IP
启动参数

6. 容器内部操作:exec、logs、cp

实际开发中,下面几个命令非常重要。

查看日志

docker logs my-nginx

持续查看:

docker logs -f my-nginx

查看最后 100 行:

docker logs --tail 100 my-nginx

例如:

docker logs -f --tail 100 my-nginx

这是排查容器启动失败、应用报错时最常用的方法之一。


进入容器

docker exec -it my-nginx /bin/bash

如果镜像没有 Bash:

docker exec -it my-nginx /bin/sh

进入之后:

ls

查看文件。

ps

查看进程。

env

查看环境变量。

退出:

exit

在容器中执行命令

不进入容器,也可以直接执行:

docker exec my-nginx nginx -t

例如 PHP 容器:

docker exec php php -v

Composer:

docker exec php composer --version

这种方式在开发和部署脚本中非常常见。


文件复制

从容器复制到宿主机:

docker cp my-nginx:/etc/nginx/nginx.conf ./nginx.conf

从宿主机复制到容器:

docker cp ./nginx.conf my-nginx:/etc/nginx/nginx.conf

7. Volume:容器数据持久化

容器本身应该尽量设计成:

可删除、可重新创建。

例如 MySQL:

MySQL Container
     ↓
删除容器
     ↓
数据库数据也可能消失

因此数据库数据不能只放在容器可写层中。

应该使用 Volume。

创建:

docker volume create mysql-data

查看:

docker volume ls

查看详情:

docker volume inspect mysql-data

运行 MySQL:

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

这里:

-v mysql-data:/var/lib/mysql

表示:

Docker Volume
      ↓
/var/lib/mysql

MySQL 数据不再完全依赖容器本身。

删除容器:

docker rm -f mysql

重新创建:

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

原来的数据仍然可以使用。

查看 Volume

docker volume ls

删除:

docker volume rm mysql-data

需要特别注意:

删除 Volume 可能导致数据丢失。

生产环境执行 docker volume rm 前必须确认数据已经备份。


8. Docker Network:容器之间如何通信?

Docker 默认会创建网络。

查看:

docker network ls

创建自定义网络:

docker network create app-network

启动 Redis:

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

启动 PHP:

docker run -d \
    --name php \
    --network app-network \
    php:8.3-fpm

此时 PHP 容器可以通过:

redis:6379

访问 Redis。

这里非常重要:

容器之间通信时,不应该使用宿主机的 localhost 访问另一个容器。

例如 PHP 容器中:

redis://127.0.0.1:6379

表示访问:

PHP 容器自己

而:

redis://redis:6379

才是访问:

Redis 容器

Docker 自定义网络会提供容器名称解析。


9. Dockerfile:构建自己的镜像

实际项目中,不可能所有东西都直接使用官方镜像。

例如 PHP 项目需要:

PHP
Composer
Redis 扩展
Swoole
项目代码

这时需要 Dockerfile。

例如:

FROM php:8.3-cli

WORKDIR /app

COPY . .

CMD ["php", "-S", "0.0.0.0:8000", "-t", "public"]

构建:

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

查看:

docker images

运行:

docker run -d \
    --name my-php-app \
    -p 8000:8000 \
    my-php-app:1.0

Dockerfile 常用指令

最常见的是:

FROM
WORKDIR
COPY
ADD
RUN
ENV
ARG
EXPOSE
CMD
ENTRYPOINT

例如:

FROM php:8.3-cli

WORKDIR /app

COPY composer.json composer.lock ./

RUN composer install --no-dev --prefer-dist --no-interaction

COPY . .

EXPOSE 8000

CMD ["php", "server.php"]

其中:

FROM

指定基础镜像。

WORKDIR

设置工作目录。

COPY

复制文件。

RUN

构建镜像时执行命令。

CMD

指定容器默认启动命令。


10. Docker Compose:管理多个容器

实际项目很少只有一个容器。

例如一个 PHP 项目可能需要:

Nginx
PHP
MySQL
Redis
RabbitMQ

如果全部使用 docker run:

docker run ...
docker run ...
docker run ...
docker run ...
docker run ...

管理起来非常麻烦。

这时可以使用 Docker Compose。

创建:

docker-compose.yml

例如:

services:
  php:
    image: php:8.3-cli
    container_name: app-php
    working_dir: /app
    volumes:
      - ./:/app
    networks:
      - app

  redis:
    image: redis:7
    container_name: app-redis
    networks:
      - app

  mysql:
    image: mysql:8.4
    container_name: app-mysql
    environment:
      MYSQL_ROOT_PASSWORD: example
      MYSQL_DATABASE: app
    volumes:
      - mysql-data:/var/lib/mysql
    networks:
      - app

networks:
  app:

volumes:
  mysql-data:

启动:

docker compose up -d

查看:

docker compose ps

查看日志:

docker compose logs

查看指定服务:

docker compose logs -f php

进入 PHP:

docker compose exec php sh

停止:

docker compose stop

删除容器:

docker compose down

如果连 Volume 一起删除:

docker compose down -v

这个命令需要谨慎使用,因为:

-v

可能删除数据库 Volume。


11. Docker 日常命令速查

日常开发可以重点记住下面这些命令。

镜像

docker pull nginx:1.27
docker images
docker image ls
docker rmi nginx:1.27
docker image inspect nginx:1.27
docker history nginx:1.27

容器

docker run -d nginx
docker ps
docker ps -a
docker start nginx
docker stop nginx
docker restart nginx
docker rm nginx
docker rm -f nginx
docker inspect nginx

日志

docker logs nginx
docker logs -f nginx
docker logs --tail 100 nginx

进入容器

docker exec -it nginx sh
docker exec -it nginx bash

文件

docker cp nginx:/etc/nginx/nginx.conf .
docker cp ./nginx.conf nginx:/etc/nginx/nginx.conf

Volume

docker volume ls
docker volume create app-data
docker volume inspect app-data
docker volume rm app-data

Network

docker network ls
docker network create app-network
docker network inspect app-network
docker network rm app-network

Build

docker build -t my-app:1.0 .
docker image ls

Compose

docker compose up -d
docker compose ps
docker compose logs -f
docker compose exec php sh
docker compose restart
docker compose stop
docker compose down

12. 实际开发中的 Docker 操作流程

掌握命令之后,可以把 Docker 的日常使用总结成几个固定流程。

启动一个服务

例如 Redis:

docker pull redis:7

docker run -d \
    --name redis \
    -p 6379:6379 \
    redis:7

检查:

docker ps

查看日志:

docker logs redis

进入容器:

docker exec -it redis redis-cli

排查容器启动失败

按照:

docker ps -a
        ↓
docker logs container
        ↓
docker inspect container
        ↓
docker exec -it container sh

逐步排查。


更新应用

典型流程:

docker build -t my-app:2.0 .

docker stop my-app

docker rm my-app

docker run -d \
    --name my-app \
    -p 8080:8080 \
    my-app:2.0

生产环境则通常通过镜像仓库、Compose、CI/CD 或编排平台完成,而不是手工执行这一套命令。


总结

Docker 日常使用并不需要一开始掌握所有功能。

最重要的是理解:

Image
   ↓
Container
   ↓
Network
   ↓
Volume

然后掌握几个核心命令:

docker pull
docker run
docker ps
docker stop
docker start
docker rm
docker logs
docker exec
docker inspect
docker cp
docker build
docker volume
docker network
docker compose

如果按照实际开发场景来看,可以形成一套固定的 Docker 工作流:

拉取镜像
   ↓
启动容器
   ↓
映射端口
   ↓
配置 Volume
   ↓
加入 Network
   ↓
查看日志
   ↓
进入容器
   ↓
排查问题
   ↓
Dockerfile 构建自己的镜像
   ↓
Compose 管理整个项目

对于 PHP、Hyperf、MySQL、Redis 等后端项目来说,真正需要熟练的并不是几十个冷门参数,而是:

能快速启动服务、理解容器之间如何通信、正确处理数据持久化,并能够通过 ps / logs / exec / inspect 快速定位容器问题。

Docker 掌握到这个程度,就已经可以覆盖绝大多数日常开发和测试场景。