Docker核心概念
Docker通过客户端-服务器架构实现容器管理,核心组件包括:
- Docker守护进程(Docker Daemon)
负责管理容器生命周期(创建、运行、停止等),与客户端通信 - 镜像(Image)
只读模板,包含运行环境(代码、依赖、配置等),支持分层构建以节省空间 - 容器(Container)
镜像的运行实例,提供隔离的运行环境(文件系统、网络、进程空间)。 - 仓库(Registry)
存储和分发镜像,如Docker Hub(公共)和私有仓库
技术原理:
- Linux命名空间(Namespaces):隔离容器资源(进程、网络等)。
- 控制组(cgroups):限制容器资源使用(CPU、内存等)。
- 联合文件系统(UnionFS):实现镜像分层和轻量级文件系统
常用Docker命令
镜像操作
- 拉取镜像
docker pull 镜像名:标签
(如docker pull nginx:latest
)。 - 查看本地镜像
docker images
docker image list
docker image ls
- 删除镜像
docker rmi 镜像ID或名称
容器操作
- 创建并运行容器
docker run -d -p 主机端口:容器端口 --name 容器名 镜像名
docker run -d -p 3000:80 --name my-nginx nginx
- 查看容器状态
docker ps
(运行中)或docker ps -a
(所有容器)。
docker container ls
docker container list
- 重启容器
使用docker reset <container_name>
可以重启一个容器。
例如:docker restart my-frontend-container
- 通过
docker update
修改重启策略(可选)
若希望容器在宿主机重启后自动启动,可设置重启策略:
docker update --restart=always my-frontend-container
此后,即使手动停止容器,它也会随宿主机自动重启 - 进入容器调试
docker exec -it 容器名 /bin/bash
数据与网络
- 挂载数据卷
docker run -v 主机路径:容器路径 镜像名
(如docker run -v /host/data:/container/data nginx
)。 - 创建自定义网络
docker network create 网络名
,容器通过--network
加入。
清理 Docker 缓存
- 删除构建缓存
运行以下命令清理 Docker 构建缓存:
docker builder prune -a
然后重新构建镜像:
docker build -t mirco-base .
从零部署前端项目
1. 项目准备
- 确保前端有可运行的项目
- 安装
docker
, 例如:systemctl start docker
2. 编写Dockerfile
在项目根目录创建Dockerfile
,示例如下:
dockerfile
# 基础镜像(Node.js)
FROM node:14-alpine
# 设置工作目录
WORKDIR /app
# 复制依赖文件
COPY package*.json ./
# 安装依赖
RUN npm install
# 复制项目文件
COPY . .
# 构建生产环境
RUN npm run build
# 使用Nginx部署静态文件
FROM nginx:alpine
COPY --from=0 /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
说明:
- 多阶段构建减少镜像体积。
- 最终镜像基于轻量级Nginx镜像。
3. 构建与运行容器
bash
# 构建镜像 -t micro-base 指定镜像名称,`micro-base` 是镜像名
docker build -t micro-base .
# 运行容器(映射端口80到主机8080)micro-base-container 为容器名 --name 是指定容器名
docker run -d -p 8080:80 --name micro-base-container micro-base
注意: 通过 docker build -t micro-base .
构建镜像时,.
表示构建上下文路径 ,即 Dockerfile 所在的目录(当前目录)。 Docker 会将此目录下的所有文件(除 .dockerignore
排除的)发送给构建引擎。 如果发现某个目录找不到,可能是应为它被添加到了 .dockerignore
文件中,例如前端打包生成的dist
目录。
4. 持续集成(可选)
结合CI/CD工具(如GitHub Actions),自动化构建和推送镜像到仓库。
Dockerfile核心指令
Dockerfile
包含了构建 Docker
镜像的所有指令。
镜像构建指令
指令 | 用途 | 示例 |
---|---|---|
FROM | 指定基础镜像 | FROM nginx:alpine |
COMPY | 复制文件到容器 | COPY src/ /app/src |
ADD | 比COPY多支持URL和自动解压tar包(不推荐) | ADD xxx.com/file.tar.gz |
RUN | 执行命令(会生成新的镜像层) | RUN npm run build |
FROM
:指定基础镜像,它是 Dockerfile
中第一条指令,所有的镜像构建都是基于一个已有的基础镜像来构建。
COPY
:用于将构建上下文(Context)中的文件复制到镜像中的指定路径。
dockerfile
COPY <源路径> <目标路径>
ADD
:指令虽然比 COPY
指令多了一些功能,比如支持 URL 和自动解压 tar 包,但由于它的功能比较复杂,容易引入一些安全问题,所以一般不推荐使用。
RUN
:用于在容器中执行命令,它会生成一个新的镜像层,所以在使用时可用尽量合并多个命令,减少镜像层的数量。
例如:
csharp
RUN apt-get update && apt-get install -y curl \
&& apt-get clean && rm -rf /var/lib/apt/lists/*
环境配置指令
指令 | 用途 | 示例 |
---|---|---|
WORKDIR | 设置当前工作目录(类似于执行cd命令) | WORKDIR /app |
ENV | 设置环境变量 | ENV APP_ENV=production |
ARG | 设置构建时的临时变量 | ARG APP_VERSION=1.0.0 |
USER | 指定运行命令的用户 | USER appuser |
WORKDIR
:设置后续命令的工作目录,类似 cd
。
ENV
:设置容器运行时环境变量,整个生命周期有效,可以被容器中的应用使用。
ARG
:定义构建时的临时变量,仅在构建阶段有效。
示例:
dockerfile
ARG APP_VERSION=1.0.0
RUN wget http://example.com/app-${APP_VERSION}.tar.gz
USER
:用于指定运行命令的用户(非 root 用户),需要提前通过 RUN
创建用户和组。
一个简单的示例:
dockerfile
# 使用 Ubuntu 基础镜像
FROM ubuntu:20.04
# 更新并安装必要工具
RUN apt-get update && apt-get install -y sudo
# 创建用户组和用户
RUN groupadd -r appgroup && useradd -r -g appgroup appuser
# 设置工作目录并赋予权限
WORKDIR /app
RUN chown -R appuser:appgroup /app
# 切换用户
USER appuser
# 启动命令
CMD ["bash"]
容器运行指令
指令 | 用途 | 示例 |
---|---|---|
CMD | 容器启动时执行的默认命令(可被 docker run 覆盖) | CMD ["python", "app.py"] |
ENTRYPOINT | 容器启动时执行的固定命令(参数可追加) | ENTRYPOINT ["python", "app.py"] |
EXPOSE | 声明容器使用的端口 | EXPOSE 80 443 |
VOLUME | 创建数据卷(容器外存储数据) |
CMD
:用于指定容器启动时执行的默认命令,它可用被 docker run
命令中的参数副高。
ENTRYPOINT
:用于指定容器启动时执行的固定命令,可追加参数。
有以下特点:
- 强制性与不可覆盖性 :默认情况下,
docker run
传递的参数会追加到ENTRYPOINT
命令后,而非覆盖(可通过--entrypoint
标志强制覆盖)。 - 与 CMD 的协作 :若同时定义
ENTRYPOINT
和CMD
,CMD
的参数会作为ENTRYPOINT
的默认参数,且docker run
的参数会覆盖CMD
内容。 - 容器入口固定化:适合定义初始化脚本、长期运行的服务(如 Web 服务器)等需要稳定启动逻辑的场景。
EXPOSE
:用于声明容器使用的端口,但是它只是一个声明,并不会实际进行端口映射,需要配合 docker run -p
选项来进行端口映射。
例如:docker run -p 80:80
VOLUME
:用于指定创建数据卷,数据卷可以将容器内的数据存储到容器外,这样即使容器被删除,数据也不会丢失。
多阶段构建
多阶段构建通过在一个Dockerfile中定义多个构建阶段 (FROM
指令),每个阶段使用不同基础镜像,最终仅保留运行环境所需文件。其核心优势包括:
- 减小镜像体积:删除构建工具链(如Node.js、npm),仅保留静态文件和运行时环境(如Nginx)。
- 提升安全性:减少攻击面,避免敏感构建工具残留。
- 简化维护:无需维护多个Dockerfile,所有逻辑集中在一个文件中。
多阶段构建有助于从最终映像中删除不必要的文件,确保映像保持轻量级并专注于生产需求。
多阶段构建配置
Dockerfile
dockerfile
# 第一阶段:构建前端应用(Node.js环境)
FROM node:16 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# 第二阶段:运行环境(仅保留Nginx和静态文件)
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
CMD ["nginx", "-g", "daemon off;"]
--from=builder
:指定从名为 builder
的构建阶段复制文件。这里的 builder
是前一个阶段的命名。 除了使用 --from=<阶段名>
,还可以通过索引引用(如 --from=0
表示第一个阶段)。 AS builder
:定义阶段名。
总结
本文最初只是自己学习 Docker
过程中的笔记,记着记着就成了一篇文章。
Docker已成为现代应用部署的基石技术 ,本文循序渐进的从简单介绍 Docker
和核心架构、底层原理开始,以部署一个前端项目为例,介绍了镜像构建、容器操作、数据卷挂载等高频命令,并给出前端项目容器化部署全流程指南 。最后分类说明 Dockerfile
中的关键指令和多阶段构建。
希望这篇文章能让你像我一样快速熟悉 Docker
,提升交付效率。