导读:为什么要学 Docker?
在没有 Docker 之前,我们部署项目经常会遇到一个终极难题:“这段代码在我的电脑上明明能跑,怎么到了服务器上就报错了?”
这是因为你的电脑和服务器的环境、配置、依赖不同。Docker 的出现就是为了解决这个问题。它将代码、运行环境、配置文件打包在一起,形成一个“集装箱”。只要服务器装了 Docker,这个集装箱就能原封不动地跑起来。
一句话总结:Docker 实现了“一次构建,到处运行”。
一、 Docker 核心概念(入门必看)
要想玩转 Docker,必须先搞懂它的“核心三要素”:
- 镜像 (Image):镜像就像是软件的安装包,或者系统恢复的“Ghost镜像”。它包含了运行程序所需的全部环境和代码。它是只读的。
- 容器 (Container):容器是镜像运行后的实体。你可以把它当成一台极其轻量级的虚拟机。一个镜像可以启动无数个相同的容器,它们之间互相隔离。
- 仓库 (Repository):类似于 GitHub,或者手机上的“应用商店”。官方提供了一个最大的公共仓库叫 Docker Hub,我们可以在里面下载别人做好的镜像(比如 MySQL、Nginx)。
1. 镜像(Image) = “应用程序安装包”或“类 (Class)”
镜像是只读的(Read-only),它包含了一切运行 MySQL 所需要的核心文件、操作系统环境和默认配置。它就像是一个“安装光盘”或“设计图纸”。
- 在你的例子中:当你下达
docker pull mysql:8.0指令时,你下载下来的这个几百 MB 的文件,就是**“镜像”**。你不能直接在镜像里面写入你的业务数据,因为它是死的、只读的范本。
2. 容器(Container) = “运行中的软件”或“对象 (Object)”
容器是镜像运行起来之后的实体。当你拿着“安装包”(镜像)把它运行起来,它就变成了一个活生生、可以互动的“容器”。
- 在你的例子中:当你下达
docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:8.0后,Docker 就会根据 MySQL 的镜像,为你创造出一个独立运作的空间。这个空间里有正在运行的 MySQL 服务,你可以去修改密码、建立数据表。这个活着的、你正在使用的环境,就是“容器”。 - 重点:一个“MySQL 镜像”,可以同时启动出无数个“MySQL 容器”(例如你可以启动一个跑在 3306 端口的开发环境容器,再启动一个跑在 3307 端口的测试环境容器),它们彼此完全独立。
3. 仓库(Repository) = “应用商店 (App Store)”
仓库是集中存放各种“镜像”的地方。就像你手机里的 App Store 或 Google Play。
- 在你的例子中:你下载的
mysql:8.0镜像从哪里来的?是从 Docker 官方提供的一个叫做 Docker Hub 的云端仓库下载来的。
🛠️ 常用高频命令速查表
docker images:查看本地所有的镜像。docker pull <镜像名>:从仓库下载镜像(如docker pull mysql:8.0)。docker ps:查看当前正在运行的容器(加-a查看所有,包括已停止的)。docker rm <容器ID>:删除容器(必须先停止运行)。docker rmi <镜像ID>:删除本地镜像。docker logs <容器名称>:查看容器运行的日志(排错必备)。
二、 常用软件部署实战 (MySQL + Nginx)
这里介绍 Docker 最强大的命令 docker run,以部署 MySQL 和 Nginx 为例。
1. 部署 MySQL 数据库
如果手动安装 MySQL,要配置环境变量、修改注册表,非常繁琐。用 Docker 只需要一行命令:
Bash
docker run -d \
--name mysql \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-v /mydata/mysql/data:/var/lib/mysql \
mysql:8.0
📜 参数白话文解析:
-d:后台运行(不占用当前终端窗口)。--name mysql:给这个容器起个名字叫mysql。-p 3306:3306:端口映射。将服务器宿主机的 3306 端口,映射到容器内的 3306 端口。外界访问服务器的 3306 就能访问到这个数据库。-e:设置环境变量。这里是初始化 root 用户的密码为 123456。-v:数据卷挂载(极其重要)。将宿主机的目录挂载到容器内的数据目录。这样就算你不小心删除了容器,宿主机上的数据还在,保证数据不丢失!
2. 部署 Nginx 服务器
部署前端项目必备的服务器软件。
Bash
docker run -d \
--name nginx \
-p 80:80 \
-v /mydata/nginx/html:/usr/share/nginx/html \
-v /mydata/nginx/conf/nginx.conf:/etc/nginx/nginx.conf \
nginx
💡 笔记重点:
Nginx 的挂载非常有讲究。我们挂载了 html 目录和 nginx.conf 配置文件。以后前端发了新版代码,你只需要把 HTML 文件扔进宿主机的 /mydata/nginx/html 目录里,容器内的页面会自动更新,完全不需要重启容器!
三、 进阶:Docker 自定义镜像 (Dockerfile)
刚才我们都是用官方提供的别人写好的镜像,如果我们自己写了一个 Java (Spring Boot) 项目或者 Python 项目,怎么打包成镜像呢?
答案就是:Dockerfile。
Dockerfile 是一个文本文件,里面写满了一条条“指令”,Docker 会根据这些指令自动为你构建镜像。
📝 Dockerfile 核心指令解析
FROM:指定基础镜像。比如你的项目是 Java 写的,基础镜像就是FROM openjdk:11。ENV:配置环境变量。COPY:将宿主机的项目文件(如 jar 包)拷贝到镜像内。EXPOSE:声明容器需要暴露的端口(仅作为文档说明,不会真正映射端口)。ENTRYPOINT:容器启动时默认执行的命令。
🚀 实战:打包 Spring Boot 项目
假设你有一个打好的 Java 包 app.jar。在它同级目录下新建一个名叫 Dockerfile 的文件(无后缀名):
Dockerfile
# 1. 指定基础镜像:Java 11 环境
FROM openjdk:11-jre-slim
# 2. 将本地的 app.jar 拷贝到容器根目录下,并重命名为 app.jar
COPY app.jar /app.jar
# 3. 声明端口(假设项目端口是 8080)
EXPOSE 8080
# 4. 容器启动时执行的命令:java -jar /app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]
构建并运行:
- 构建镜像:
docker build -t my-app:1.0 .(注意最后有个.,代表当前目录)。 - 运行项目:
docker run -d -p 8080:8080 --name my-java-app my-app:1.0。搞定!你的项目已经被成功容器化了。
四、 高级杀器:Docker Compose 项目实战一套搞定
❓ 痛点:为什么需要 Docker Compose?
一个真实的企业级项目,往往包含:微服务后端 A、微服务后端 B、前端、MySQL、Redis、Nginx。
如果用 docker run,你需要手动敲好几次长长的命令,还要考虑它们的启动顺序和网络互通问题,非常反人类。
Docker Compose 就是用来做“微服务编排”的。你只需要写一个 docker-compose.yml 文件,定义好所有需要的服务,然后一行命令,同时启动所有容器!
✍️ 实战:docker-compose.yml 示例
假设我们要同时部署:后端 API 项目 + 数据库 MySQL。
新建 docker-compose.yml:
YAML
version: "3.8" # Compose 语法版本
services:
# 服务1:MySQL
mysql:
image: mysql:8.0
container_name: mysql
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: root
volumes:
- /mydata/mysql/data:/var/lib/mysql
# 服务2:自定义后端项目
my-backend:
build: . # 根据当前目录的 Dockerfile 自动构建镜像
container_name: web-api
ports:
- "8080:8080"
depends_on:
- mysql # 关键:告诉 Docker,我的后端依赖数据库,必须等 MySQL 启动后再启动我
⚡ 见证奇迹的时刻
在 docker-compose.yml 所在的目录下,只需敲下这行命令:
Bash
docker-compose up -d
Docker 会自动帮你:下载 MySQL -> 构建后端项目镜像 -> 启动 MySQL 容器 -> 启动后端容器 -> 并且自动把它们放在同一个内部网络里。
停止并销毁所有环境:
Bash
docker-compose down
🌟 总结与避坑指南
- 永远不要把数据存在容器内部:容器是随时可以被销毁和重建的。所有的数据库数据、Nginx 配置、日志,必须用
-v挂载到宿主机上(数据卷持久化)。 - 巧用自定义网络:在 Docker Compose 中,同一份文件里的服务天然在同一个网络下。你的后端程序连接数据库,数据库的 IP 不要写本地 IP,直接写服务名(如:
jdbc:mysql://mysql:3306/db),Docker 会自动进行内部 DNS 解析! - 学以致用:学完这一套,以后在公司接手新项目、配置开发环境、甚至是自己买云服务器建站,再也不用痛苦地配环境了,全部 Docker 化,省时省力。
如果你觉得这篇笔记对你有帮助,欢迎点赞收藏! 准备好一台服务器或者本地装好 Docker Desktop,跟着上面的命令一行行敲下去,你会发现部署项目原来可以这么优雅。
Comments NOTHING