- Windows 10 专业版 64 位(10.0,版本 18362)
- Docker version 19.03.5, build 633a0ea
基础命令
docker --help
# 开启互动
-i, --interactive Keep STDIN open even if not attached
# 连接交互
-t, --tty Allocate a pseudo-TTY
# 交互式终端
-it
# 公开 Docker 端口到宿主端口
-P, --publish-all Publish all exposed ports to
# 装载 Docker 文件系统 `host path:container path`
-v, --volume list Bind mount a volume
命令嵌套
docker COMMAND $(docker COMMAND)
镜像
构建镜像
# 指定路径
> docker image build .
# -t, --tag list Name and optionally a tag in the 'name:tag' format
# 指定标签
> docker image build -t list:1.0 .
镜像列表
# images List images
> docker images
删除镜像
# rmi Remove one or more images
# 删除指定镜像,根据 ImageID
> docker rmi IMAGEID
# 删除所有镜像,根据 ImageID
> docker rmi $(docker images -q)
容器
构建容器
# --name string Assign a name to the container
# 指定一个名称,您可以在后续命令中使用该名称来引用您的容器,在这种情况下为 n1
> docker container run --name n1 node-app:1.0
# -p, --publish list Publish a container's port(s) to the host
# 要求Docker将主机端口8000上传入的流量转发到容器的端口8080
> docker container run --publish 8000:8080 --name nn node-app:1.0
# -d, --detach Run container in background and print
# 要求Docker在后台运行此容器
> docker container run --detach
容器列表
# ps List containers(运行中的容器)
# 运行中的容器
> docker ps
# -a, --all Show all containers (default shows just running)
# 显示所有容器(默认显示为正在运行)
> docker ps -a
删除容器
# 删除指定容器,根据 AssignName
> docker container rm n1
# -q, --quiet Only display numeric IDs
# 删除所有容器,根据 ProcessID
> docker rm $(docker ps -q)
Dockerfile
FROM
必须是第一条指令,指定基础镜像
RUN
# shell 格式 `RUN <命令>`
RUN yarn
# exec 格式 `RUN ["可执行文件","参数1","参数2"]`
RUN ["npm","install"]
运行 Shell 命令,提供两种模式。shell
和exec
后者更像是函数调用方式
CMD
# shell 格式 `CMD <命令>`
CMD service nginx start # == CMD [ "sh", "-c", "service nginx start"]
# exec 格式 `CMD ["可执行文件", "参数1", "参数2"...]`
CMD ["nginx", "-g", "daemon off;"]
容器启动时指定 shell 命令工具
ENTRYPOINT
# 入口点 `<ENTRYPOINT> "<CMD>"`
ENTRYPOINT [ "curl", "-s", "https://ip.cn" ]
> docker run myip -i # == curl -s https://ip.cn -i
将CMD
作为参数传递给 ENTRYPOINT
运行。应用场景如下:
- 让镜像变成像命令一样使用
- 应用运行前的准备工作
COPY
# 拷贝文件 `COPY <client> <remote>`
COPY ./package.json /app/
ADD
# URL 拷贝 `ADD <target> <remote>
ADD ubuntu-xenial-core-cloudimg-amd64-root.tar.gz /
COPY
基础上增加远程下载,可以自动解压文件
ENV
# 设置单个变量 `ENV <key> <value>`
ENV NODE_VERSION 7.2.0
# 设置多个变量 `ENV <key1>=<value1> <key2>=<value2>...`
ENV VERSION=1.0 DEBUG=on
NAME="Happy Feet"
定义环境变量,以供在后续指令中调用
EXPOSE
# 声明端口 `EXPOSE <端口1> [<端口2>...]`
EXPOSE 9000
运行脚本docker run -P
时,会自动随机映射EXPOSE
端口
WORKDIR
# 指定工作目录 `WORKDIR <工作目录路径>`
WORKDIR /usr/local/app
指定Docker
镜像工作目录,或者称当前目录。后续命令都将在指定目录基础上运行
实战一:Docker 化 create-react-app 示例!
容器化 React 开发环境,同时以create-react-app
脚手架为基础。构建简洁高效的开发体验,同时为 VSCode Remote 微服务开发架构做准备!详细步骤如下:
1.安装create-react-app
脚手架,并且创建一个全新项目
npx create-react-app my-app --template typescript
2.排除项目node_modules
目录,构建时将其留在镜像内部
cd my-app
rm -rf node_modules
3.创建Dockerfile
完善其构建流程
FROM node:current-slim
ADD yarn.lock /yarn.lock
ADD package.json /package.json
ENV NODE_PATH=/node_modules
ENV PATH=$PATH:/node_modules/.bin
RUN yarn
WORKDIR /app
ADD . /app
EXPOSE 3000
EXPOSE 35729
ENTRYPOINT ["/bin/bash", "/app/run.sh"]
CMD ["start"]
FROM node:current-slim
指定基础镜像为node官方简洁版,提供了Node
、Yarn
、Npm
ADD yarn.lock /yarn.lock
拷贝依赖关系至Docker
引擎根目录
ENV NODE_PATH=/node_modules
指定node_modules
安装目录为容器根目录,而不会因"当前工作目录"而导致重复添加
WORKDIR /app
设置工作目录为容器 /app 路径
ADD . /app
将当前目录文件复制到容器 /app 目录下
ENTRYPOINT["/bin/bash","/app/run.sh"]
指定Linux
系统/bin/bash
作为Shell
工具,运行/app/run.sh
脚本。并且可接收运行时命令参数作为其附加参数
4.创建run.sh
文件,扩展命令行工具
#!/usr/bin/env bash
set -eo pipefail
case $1 in
start)
# The '| cat' is to trick Node that this is an non-TTY terminal
# then react-scripts won't clear the console.
yarn start | cat
;;
build)
yarn build
;;
test)
yarn test $@
;;
*)
exec "$@"
;;
esac
#!/usr/bin/env bash
在linux
运行脚本需在开头指定脚本的解释程序,env可以在系统的PATH目录中查找
#!/usr/bin/env python
#!/usr/bin/env perl
#!/usr/bin/env zimbu
#!/usr/bin/env ruby
- set -eo pipefail
设置程序异常退出处理
linux
中shell
变量的含义:
$1~$n
# 添加到Shell的各参数值。$1是第1参数、$2是第2参数…
$@
# 所有参数列表。如"$@"用「"」括起来的情况、以"$1" "$2" … "$n" 的形式输出所有参数。
5.建立容器
# 构建镜像,指定仓库为react、tag标记为app
> docker image build -t react:app .
# 查看 react 仓库下 app 标签镜像:大小为 524MB
> docker image ls react:app
6.运行容器
# 看看容器内部,启动进入 bash 工具
> docker container run -it react:app bash
root@********:/app# ls
Dockerfile package.json run.sh tsconfig.json
# 运行容器,公开端口到宿主机器
> docker container run -it -p 3000:3000 react:app
预览 React 默认程序:http://localhost:3000
7.启用热加载
docker container run -it -p 3000:3000 -p 35729:35729 -v $(pwd):/app react:app
启用热加载我们需要做两件事情:
1)将当前工作目录挂载到Docker
容器中
-v $(pwd):/app
-volume
指定Docker文件系统装载路径。:
前 为主机路径,:
后为容器路径,这里表示挂载容器中/app
目录,也就是我们指定的工作目录,指向我们源码
2)将端口35729暴露给主机
-p 35729:35729
create-react-app
支持两种刷新模式,实时加载和热重载。其中热重载使用WebSockets
技术,将信息发送给浏览器,其端口号为35729
到这里完成热重载配置,修改app.tsx浏览器自动刷新,修改App.css页面进行热替换
8.运行测试
> docker container run -it -v $(pwd):/app react:app test
9.调试 node_modules
...
10.运行打包
> docker container run -it -v $(pwd):/app react:app build
10.NodeJS Shell
> docker container run -it -v $(pwd):/app react:app bash
11.集成VSCode调试
结论
到这里基础功能基本完成封装!
- 所有经过打包的人员和团队都获得所有内容完全相同的版本,包括Node和Yarn
node_modules
目录将不会在本地生成- 使用
docker-compose
将实现更复杂命令组合 - 集成VSCode源码断点调试(后面实现)
- 远程微服务器将连接本地开发(后面实现)
这里查看完整源码:
shitaozhang/docker-examplegithub.com