目录
- 什么是 Docker?
- 核心思想
- 为什么使用 Docker?
- 核心概念
- 镜像
- 容器
- 仓库
- Dockerfile
- 环境准备
- 安装 Docker
- 验证安装
- Docker 常用命令详解
- 镜像命令
- 容器生命周期命令
- 容器交互命令
- 其他实用命令
- 实战案例:运行一个 Nginx 服务器
- 实战案例:构建一个自定义 Python 应用镜像
- 创建项目
- 编写
Dockerfile - 构建镜像
- 运行容器
- 数据持久化:Docker 卷
- 什么是 Docker 卷?
- 创建和使用卷
- Docker Compose:管理多容器应用
- 什么是 Docker Compose?
- 安装 Docker Compose
- 编写
docker-compose.yml文件 - 启动和管理应用
- 最佳实践与总结
- 使用
.dockerignore - 以非 root 用户运行容器
- 只运行一个进程
- 使用
什么是 Docker?
Docker 是一个开源的容器化平台,它可以将你的应用程序及其依赖(比如库、系统工具、运行时环境)打包到一个标准化的单元中,这个单元就叫做 容器。

核心思想
想象一下,你开发了一个应用在 Windows 10 上运行得很好,但部署到 Linux 服务器上却因为缺少某个库而失败,Docker 解决的就是这个问题。
- 传统方式:在你的机器上安装操作系统、安装运行时、安装依赖、部署应用,这个过程在不同机器间重复,容易出错。
- Docker 方式:你将应用和它所需的一切打包成一个 镜像,这个镜像在任何安装了 Docker 的机器上都能以完全相同的方式运行,就像一个标准化的集装箱,可以轻松地在不同的“船”(服务器)之间运输。
为什么使用 Docker?
- 环境一致性:“在我机器上明明是好的!” —— Docker 彻底解决了这个问题,确保开发、测试、生产环境完全一致。
- 可移植性:可以在笔记本、物理服务器、云服务器上无缝运行。
- 隔离性:每个容器都是独立的,互不干扰,一个容器的崩溃不会影响其他容器或宿主机。
- 资源高效:容器共享宿主机的内核,启动速度快,占用资源远小于虚拟机。
- 快速部署和扩展:可以快速创建、启动、停止大量容器,非常适合微服务架构和自动化运维。
核心概念
理解 Docker,必须先理解这几个核心概念:
- 镜像:一个只读的模板,用来创建容器,可以把它看作是面向对象编程中的 类,一个 Ubuntu 镜像,一个 Nginx 镜像,镜像可以分层构建,非常灵活。
- 容器:镜像的运行实例,它是从镜像创建出来的,带有可读写的层,可以把它看作是类创建出来的 对象,容器是轻量级、可隔离的进程。
- 仓库:用来存储和分发镜像的地方,最著名的公共仓库是 Docker Hub,你可以把它想象成一个 代码仓库,但存放的是镜像,你也可以搭建自己的私有仓库。
- Dockerfile:一个文本文件,包含了构建镜像所需的所有指令,通过
docker build命令可以自动构建镜像。
关系图:
Dockerfile -> docker build -> 镜像 -> docker run -> 容器
环境准备
安装 Docker
根据你的操作系统,参考官方文档进行安装:

验证安装
打开终端(或命令提示符),运行以下命令:
docker --version # 或者 docker version
如果看到版本信息,说明安装成功。
Docker 常用命令详解
镜像命令
-
搜索镜像:从 Docker Hub 搜索镜像。
docker search nginx
-
拉取镜像:从仓库下载镜像到本地。
(图片来源网络,侵删)# 默认拉取最新版本 (latest tag) docker pull nginx # 拉取指定版本 docker pull nginx:1.25.1
-
查看本地镜像:列出本地所有镜像。
docker images # 或者 docker image ls
-
删除镜像:删除本地一个或多个镜像。
# 删除单个镜像 docker rmi nginx:1.25.1 # 强制删除(即使有容器正在使用它) docker rmi -f nginx
容器生命周期命令
-
运行容器:这是最核心的命令,用于从镜像创建并启动一个容器。
# 最简单的运行,后台启动 Nginx docker run --name my-nginx -d nginx # 参数解释: # --name my-nginx: 为容器指定一个名字,方便管理。 # -d: 后台运行容器。 # -p 8080:80: 将容器的 80 端口映射到宿主机的 8080 端口。 # nginx: 使用的镜像名。 docker run --name my-nginx -d -p 8080:80 nginx
-
查看正在运行的容器:
docker ps # 查看所有容器(包括已停止的) docker ps -a
-
停止容器:
docker stop my-nginx
-
启动已停止的容器:
docker start my-nginx
-
重启容器:
docker restart my-nginx
-
删除容器:
# 删除已停止的容器 docker rm my-nginx # 强制删除正在运行的容器 docker rm -f my-nginx
容器交互命令
-
查看容器日志:
docker logs my-nginx # 实时查看日志 docker logs -f my-nginx
-
在容器内执行命令:
# 进入容器的 bash docker exec -it my-nginx /bin/bash # 参数解释: # -i: 保持标准输入打开。 # -t: 分配一个伪终端。 # /bin/bash: 要在容器内执行的命令。
-
查看容器详细信息:
docker inspect my-nginx
实战案例:运行一个 Nginx 服务器
让我们通过一个简单的例子来巩固上面的命令。
-
拉取 Nginx 镜像:
docker pull nginx
-
运行容器:
docker run --name web-server -d -p 8080:80 nginx
- 我们创建了一个名为
web-server的容器。 - 它在后台运行。
- 访问你宿主机的
8080端口,请求会被转发到容器的80端口。
- 我们创建了一个名为
-
验证:
- 打开浏览器,访问
http://localhost:8080。 - 你应该能看到 Nginx 的欢迎页面。
- 打开浏览器,访问
-
停止并删除容器:
docker stop web-server docker rm web-server
实战案例:构建一个自定义 Python 应用镜像
假设我们有一个简单的 Flask 应用,我们想把它打包成 Docker 镜像。
创建项目
项目结构如下:
my-flask-app/
├── app.py
├── requirements.txt
└── Dockerfile
app.py:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello, Docker World!'
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
requirements.txt:
Flask==2.2.2
编写 Dockerfile
Dockerfile 是构建镜像的蓝图,我们在 my-flask-app 目录下创建它:
Dockerfile:
# 1. 选择一个基础镜像,使用官方的 Python 3.9 镜像 FROM python:3.9-slim # 2. 设置工作目录,后续的命令都在这个目录下执行 WORKDIR /app # 3. 复制 requirements.txt 文件到工作目录 COPY requirements.txt . # 4. 安装项目依赖 RUN pip install --no-cache-dir -r requirements.txt # 5. 复制项目所有文件到工作目录 COPY . . # 6. 声明容器对外暴露的端口 EXPOSE 5000 # 7. 定义容器启动时执行的命令 CMD ["python", "app.py"]
构建镜像
在 my-flask-app 目录下,打开终端,运行:
# -t: 给镜像打一个标签,格式为 name:tag # .: 指定 Dockerfile 所在的路径(当前目录) docker build -t my-flask-app .
构建成功后,运行 docker images,你就能看到 my-flask-app 这个镜像。
运行容器
docker run --name flask-app -d -p 5001:5000 my-flask-app
- 我们将容器的
5000端口映射到宿主机的5001端口。
验证:
打开浏览器,访问 http://localhost:5001,你应该能看到 "Hello, Docker World!"。
数据持久化:Docker 卷
默认情况下,容器内的文件是临时的,当容器被删除时,其内部的所有数据都会丢失。Docker 卷就是为了解决这个问题而设计的,它用于持久化数据。
什么是 Docker 卷?
卷是 Docker 管理的目录,可以绕过容器的联合文件系统,提供持久化存储,它可以:
- 在容器间共享数据。
- 将数据持久化到宿主机上。
创建和使用卷
-
创建一个卷:
docker volume create my-data-volume
-
运行容器并挂载卷: 我们可以用这个卷来存储 Nginx 的网页文件。
docker run --name nginx-with-data -d -p 8081:80 -v my-data-volume:/usr/share/nginx/html nginx
-v my-data-volume:/usr/share/nginx/html:将名为my-data-volume的卷挂载到容器的/usr/share/nginx/html目录。
-
测试持久化:
- 进入容器,修改默认页面:
docker exec -it nginx-with-data /bin/bash echo "Hello from Docker Volume!" > /usr/share/nginx/html/index.html exit
- 删除容器:
docker stop nginx-with-data docker rm nginx-with-data
- 重新用同一个卷启动一个新的容器:
docker run --name nginx-with-data-2 -d -p 8081:80 -v my-data-volume:/usr/share/nginx/html nginx
- 再次访问
http://localhost:8081,你会发现 "Hello from Docker Volume!" 依然存在。
- 进入容器,修改默认页面:
Docker Compose:管理多容器应用
当你的应用由多个服务组成时(比如一个 Web 服务 + 一个数据库服务),手动管理每个容器会变得非常复杂。Docker Compose 可以解决这个问题。
什么是 Docker Compose?
Docker Compose 是一个用于定义和运行多容器 Docker 应用工具,你只需要一个 docker-compose.yml 文件来配置所有服务,然后用一个命令就可以启动和停止整个应用。
安装 Docker Compose
Docker Desktop 已经包含了 Docker Compose,如果没有,可以按照官方文档安装。
编写 docker-compose.yml 文件
假设我们要运行一个 WordPress 应用,它需要一个 Web 服务器 和一个 MySQL 数据库。
docker-compose.yml:
version: '3.8'
services:
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: example
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress:
depends_on:
- db
image: wordpress:latest
ports:
- "8082:80"
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DB_NAME: wordpress
volumes:
- wordpress_data:/var/www/html
volumes:
db_data:
wordpress_data:
启动和管理应用
在 docker-compose.yml 文件所在的目录下,运行以下命令:
-
启动所有服务(在后台):
docker-compose up -d
-
查看服务状态:
docker-compose ps
-
查看日志:
docker-compose logs # 查看特定服务的日志 docker-compose logs wordpress
-
停止并删除容器、网络、卷:
docker-compose down # 如果想连同数据卷一起删除 docker-compose down -v
最佳实践与总结
使用 .dockerignore
和 .gitignore 类似,创建一个 .dockerignore 文件来排除构建镜像时不需要的文件(如 .git 目录、__pycache__、虚拟环境等),可以减小镜像大小并加快构建速度。
以非 root 用户运行容器
出于安全考虑,最好在容器内创建一个非 root 用户来运行应用,可以在 Dockerfile 中添加:
RUN addgroup -g 1000 appuser && adduser -u 1000 -G appuser -s /bin/sh -D appuser USER appuser
只运行一个进程
一个容器最好只运行一个主进程(如一个 Web 服务器、一个数据库),这使得容器更简单、更易于维护和扩展。
恭喜你!你已经完成了 Docker 的入门教程,现在你应该掌握了:
- Docker 的核心概念(镜像、容器、仓库)。
- 使用
docker命令管理镜像和容器。 - 编写
Dockerfile来构建自定义镜像。 - 使用 Docker 卷来持久化数据。
- 使用 Docker Compose 来管理复杂的多容器应用。
Docker 是一个非常强大的工具,是现代软件开发和运维的基石,继续探索和实践,你会发现它极大地提升了你的工作效率。
