2026.08.01 — ARCHIVE — 3 MIN

Docker 入门:把应用装进盒子里

以前部署项目总要手动装各种环境,换台机器就报错。学了 Docker 之后发现,把应用和依赖打包在一起,到哪都能跑。


Docker 入门:把应用装进盒子里

之前部署项目的时候,遇到过这样一个问题:

本地跑得好好的,放到服务器上就跑不起来。

问了原因,发现是环境不一样。

本地 Java 17,服务器上 Java 11;本地 MySQL 8.0,服务器上 MySQL 5.7;还有的库版本对不上,报各种错。

折腾了好久才搞定,后来听说有 Docker 这种东西,才解决了这个问题。


Docker 到底是什么

Docker 是一种容器化技术,核心思想很简单:

把应用和它运行所需的一切(代码、依赖、运行时、配置)打包成一个镜像,然后从这个镜像运行出容器。

代码 + 依赖 + 运行时 + 配置 → 镜像(只读的模板)
镜像 → 运行 → 容器(正在运行的实例)

镜像是静态的模板,容器是动态的运行实例。

一个镜像可以跑多个容器,每个容器之间互相隔离。

核心价值就一句话:"一次构建,到处运行"。


为什么需要 Docker

没有 Docker 的时候,部署项目要经历什么:

  • 换台服务器,先装系统
  • 装 Java、MySQL、Redis、Nginx
  • 配置环境变量、防火墙、路径
  • 部署应用,调各种配置

每一步都可能出问题,而且不同环境配置还不一样。

Docker 解决的是什么:

  • 镜像把环境打包在一起,到哪都一样
  • 多个容器可以跑不同版本,互不干扰
  • 一条命令启动,秒级拉起
  • 容器极轻量,一台服务器可以跑几十个

Docker vs 虚拟机

有人可能会问,这不是和虚拟机差不多吗?

确实有相似之处,但关键区别很大:

对比项 虚拟机 Docker 容器
重量 重(GB 级) 轻(MB 级)
启动时间 分钟级 秒级
隔离性 完整 OS 隔离 进程级隔离
资源占用 每个 VM 独占内核 共享宿主机内核
磁盘占用

简单理解:虚拟机是「一台完整的电脑」,容器是「一个进程被隔离起来了」。


核心概念三件套

学 Docker 记住三个词就够了:

镜像(Image) — 只读的模板,类似「类」 容器(Container) — 镜像的运行实例,类似「对象」 仓库(Registry) — 存放镜像的地方,类似「代码仓库」

最常见的仓库是 Docker Hub(docker.io),里面有各种官方镜像。


常用命令

镜像操作

docker images           # 查看本地镜像
docker pull nginx       # 拉取镜像
docker rmi nginx        # 删除镜像

容器操作

docker ps               # 查看运行中的容器
docker ps -a            # 查看所有容器(含停止的)
docker run nginx        # 运行容器
docker start/stop/restart <容器名>   # 控制容器状态
docker rm <容器名>      # 删除容器
docker exec -it <容器名> bash   # 进入容器内部
docker logs <容器名>    # 查看容器日志

一个完整的例子

# 拉取并运行 Nginx,映射 80 端口
docker run -d --name my-nginx -p 80:80 nginx

# 查看运行状态
docker ps

# 进入容器
docker exec -it my-nginx bash

# 查看日志
docker logs my-nginx

# 停止并删除
docker stop my-nginx
docker rm my-nginx

Dockerfile:自定义镜像

官方镜像不够用的时候,就需要自己写 Dockerfile。

Dockerfile 是一个文本文件,每一行是一个指令,Docker 按顺序执行这些指令来构建镜像。

打包 Spring Boot 应用

# 编译阶段
FROM maven:3.9-eclipse-temurin-17 AS builder
WORKDIR /build
COPY pom.xml .
RUN mvn dependency:go-offline -B
COPY src ./src
RUN mvn package -DskipTests -B

# 运行阶段
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
COPY --from=builder /build/target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java"]
CMD ["-jar", "app.jar", "--spring.profiles.active=prod"]

这里用了多阶段构建,第一阶段编译(用完整版 Maven),第二阶段运行(用精简 JRE)。

好处是最终镜像体积很小,从 800MB 降到 200MB 左右。

打包 Vue 前端

# 构建阶段
FROM node:20-alpine AS builder
WORKDIR /app
COPY package.json ./
RUN npm install
COPY . .
RUN npm run build

# 运行阶段
FROM nginx:1.24-alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

Docker Compose:多容器编排

一个项目通常不止一个容器,可能有 MySQL、Redis、后端、前端四个。

一个个 docker run 太麻烦了,Docker Compose 就是来解决这个问题的。

用一个 YAML 文件定义所有容器及其关系,一条命令启动:

services:
  mysql:
    image: mysql:8.0
    container_name: myapp-mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: Root@123456
      MYSQL_DATABASE: myapp
    volumes:
      - mysql-data:/var/lib/mysql
    networks:
      - app-net

  redis:
    image: redis:7-alpine
    container_name: myapp-redis
    restart: always
    volumes:
      - redis-data:/data
    networks:
      - app-net

  backend:
    build: ./backend
    container_name: myapp-backend
    restart: always
    ports:
      - "8080:8080"
    environment:
      SPRING_PROFILES_ACTIVE: prod
      DB_HOST: mysql
      REDIS_HOST: redis
    depends_on:
      - mysql
      - redis
    networks:
      - app-net

  frontend:
    image: nginx:1.24-alpine
    container_name: myapp-frontend
    restart: always
    ports:
      - "80:80"
    volumes:
      - ./frontend/dist:/usr/share/nginx/html:ro
    networks:
      - app-net
    depends_on:
      - backend

networks:
  app-net:
    driver: bridge

volumes:
  mysql-data:
  redis-data:

然后一条命令启动所有服务:

docker compose up -d

关闭:

docker compose down

服务间怎么通信

Docker Compose 会自动为每个服务创建 DNS 记录,服务名就是主机名。

所以后端访问 MySQL,不需要写 IP,直接写服务名:

SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/myapp

mysql 就是 Compose 里定义的 service 名字,Docker 会自动解析。


数据持久化

容器删了数据会丢失,所以要挂数据卷:

volumes:
  - mysql-data:/var/lib/mysql

或者绑定挂载:

volumes:
  - ./data/mysql:/var/lib/mysql

第一种由 Docker 管理,第二种直接映射到宿主机目录,更方便备份。


常用命令汇总

# 构建并启动
docker compose up -d

# 查看状态
docker compose ps

# 查看日志
docker compose logs -f

# 停止所有服务
docker compose down

# 销毁容器和数据卷(⚠️ 数据会丢失)
docker compose down -v

一句话总结

Docker 的核心就三件事:

镜像打包环境,容器运行应用,Compose 编排多容器。

学完 Docker 之后,部署项目终于不用手动装环境了。

项目换个服务器,只需要复制镜像和 Compose 文件,一条命令搞定。

这种"把所有问题都解决在盒子里"的感觉,还挺爽的。

End of plate