Docker 基本使用

date
Feb 6, 2022
slug
docker
status
Published
tags
使用笔记
summary
镜像:是一个文件系统同时又提供了运行时所需的依赖和配置...
type
Post

基本概念

  • 镜像:是一个文件系统同时又提供了运行时所需的依赖和配置
  • 容器:是镜像的运行时,命名空间独立,环境隔离
    • 与虚拟机功能类似,但更轻量更快速,共享宿主主机内核
    • 当容器销毁时数据也会消失,不能用于数据存储
    • 可使用 数据卷(Volume)、绑定宿主目录 进行储存
  • 分层储存:镜像构建时,每一次命令的执行(包括容器的运行)都会在上一层基础上构建新的镜像
    • 优点:每层构建之间互不干扰
    • 缺点:耗费空间
      • 优化方式:
        • 减少无用的命令
        • 尽量多个命令缩写
        • 多阶段构建
        • 复用缓存,使变动的文件在最上层
  • docker build -t test . 工作原理
      1. Docker 在运行时分为 Docker 引擎 客户端工具
      1. 客户端工具 通过 Docker 引擎 提供的 REST API 进行交互
        1. 如:docker run ...docker build...
      1. 命令中的 . 则代表将当前目录作为上下文上传给 Docker 引擎,其引擎便得到了构建镜像时用到的所有文件
       

Docker-compose

定义 运行多容器 的 Docker 应用程序的工具,通过运行 YML 文件 创建所有服务并启动
 
 
Dockerfile Demo
FROM node:12 as build-stage # 指定基础镜像并设置别名为 build-stage
WORKDIR /app                # 指定工作目录为 /app
COPY package*.json /app     # 将上下文中的 package 文件赋值到 /app 工作目录
RUN npm ci                  # 在工作目录执行命令
# 把上下文目录复制到当前工作目录(会忽视 .dockerignore 的文件中符合规则的文件)
# 为什么不直接执行 COPY . . 之后在 npm ci 呢 ?
# 是因为可以通过镜像堆叠复用缓存,在项目中依赖一般是改变是比较少,而代码改动的是比较多的
# 这样当代码只有代码有改动时,就可复用上一次的下载依赖的镜像,
# 再次基础上进行操作,复用了缓存,减少了构建的时间。
COPY . .
RUN npm run build           # 打包静态资源

FROM nginx                  # 指定新的基础镜像, 会清除先前指令创建的任何状态
RUN mkdir /app              # 创建目录
# 引用 build-stage 阶段构建的镜像作为上下文,
# 并复制该镜像 /app/build 路径下的文件到当前镜像的 /app 目录
COPY --from=build-stage /app/build /app
# 复制上下文当前目录的 nginx.conf 到镜像下的路径下
COPY nginx.conf /etc/nginx/nginx.conf
FROM node:14.1.0-alpine3.10             # 指定基础镜像
ARG APPLICATION_ENV=production          # 声明变量

# prepare build tools
RUN apk add --no-cache git curl \       # 链式下载依赖,避免多构建镜像
    && mkdir /app

WORKDIR /app                            # 指定工作目录

# install dependencies
COPY package*.json /app/                # 复制依赖文件到工作目录
RUN npm ci                              # 下载依赖  

# run build
COPY . .                               # 将上下文中所有的文件递归复制到当前工作目录下
RUN rm -rf /app/.next/   
RUN APPLICATION_ENV=${APPLICATION_ENV} npm run build

EXPOSE 3000                           # 暴露端口,使外呼可以访问
# 这种形式运行命令无法使用变量, 比如 CMD ["npm", "run", "start:$ENV"], 
# 当中的 $ENV 变量就不会被替换
# npm run start:$ENV 可以执行,但需要将传入的 ARG 在用 ENV 声明一下
# 类似这样
# FROM node:14-alpine
# ARG APPLICATION_ENV
# ENV APPLICATION_ENV ${APPLICATION_ENV}
# CMD npm run start:${APPLICATION_ENV} 
# 应为 ARG 只存在于 docker build 阶段,当 container 运行时就不存在了,ENV 是存在于运行时的

CMD ["npm", "start"]                  # 容器启动时执行的命令
Dockerfile 常用指令
COPY       = 复制文件
ADD        = 更高级的复制文件
ENV        = 设置环境变量
EXPOSE     = 暴露端口
FROM       = 指定基础镜像
LABEL      = 为镜像添加元数据
CMD        = 容器启动命令
RUN        = 执行命令
USER       = 指定当前用户
VOLUME     = 定义匿名卷
WORKDIR    = 指定工作目录
ONBUILD    = 配合其他指令使用, 一般用于作为基础镜像的指令
Docker 常用命令
管理命令:
  container   管理容器
  image       管理镜像
  network     管理网络
命令:
  attach      介入到一个正在运行的容器
  build       根据 Dockerfile 构建一个镜像
  commit      根据容器的更改创建一个新的镜像
  cp          在本地文件系统与容器中复制 文件/文件夹
  create      创建一个新容器
  exec        在容器中执行一条命令
  images      列出镜像
  kill        杀死一个或多个正在运行的容器    
  logs        取得容器的日志
  pause       暂停一个或多个容器的所有进程
  ps          列出所有容器
  pull        拉取一个镜像或仓库到 registry
  push        推送一个镜像或仓库到 registry
  rename      重命名一个容器
  restart     重新启动一个或多个容器
  rm          删除一个或多个容器
  rmi         删除一个或多个镜像
  run         在一个新的容器中执行一条命令
  search      在 Docker Hub 中搜索镜像
  start       启动一个或多个已经停止运行的容器
  stats       显示一个容器的实时资源占用
  stop        停止一个或多个正在运行的容器
  tag         为镜像创建一个新的标签
  top         显示一个容器内的所有进程
  unpause     恢复一个或多个容器内所有被暂停的进程
Docker 常用参数
	-d, --detach=false      # 指定容器运行于前台还是后台,默认为false   
	-i, --interactive=false # 打开STDIN,用于控制台交互  
	-t, --tty=false         # 分配tty设备,该可以支持终端登录,默认为false  
	-u, --user=""           # 指定容器的用户  
	-a, --attach=[]         # 登录容器(必须是以docker run -d启动的容器)
	-w, --workdir=""        # 指定容器的工作目录 
	-c, --cpu-shares=0      # 设置容器CPU权重,在CPU共享场景使用  
	-e, --env=[]            # 指定环境变量,容器中可以使用该环境变量  
	-m, --memory=""         # 指定容器的内存上限  
	-P, --publish-all=false # 指定容器暴露的端口  
	-p, --publish=[]        # 指定容器暴露的端口 
	-h, --hostname=""       # 指定容器的主机名  
	-v, --volume=[]         # 给容器挂载存储卷,挂载到容器的某个目录 
	-f                      # 指定 Dockerfile 的路径
	--volumes-from=[]       # 给容器挂载其他容器上的卷,挂载到容器的某个目录
	--cidfile=""            # 运行容器后,在指定文件中写入容器PID值,一种典型的监控系统用法  
	--cpuset=""             # 设置容器可以使用哪些CPU,此参数可以用来容器独占CPU  
	--device=[]             # 添加主机设备给容器,相当于设备直通  
	--dns=[]                # 指定容器的dns服务器  
	--dns-search=[]         # 指定容器的dns搜索域名,写入到容器的/etc/resolv.conf文件  
	--entrypoint=""         # 覆盖image的入口点  
	--env-file=[]           # 指定环境变量文件,文件格式为每行一个环境变量  
	--expose=[]             # 指定容器暴露的端口,即修改镜像的暴露端口  
	--link=[]               # 指定容器间的关联,使用其他容器的IP、env等信息  
	--name=""               # 指定容器名字,后续可以通过名字进行容器管理,links特性需要使用名字  
	--rm=false              # 指定容器停止后自动删除容器(不支持以docker run -d启动的容器)  
 
.dockerignore 表示以下三个路劲要排除,不要打包进入 image 文件
.git
node_modules
npm-debug.log
 

© jianxiaoBai 2021 - 2024