# Docker笔记
感谢:docker.easydoc.net (opens new window)
Docker 1小时快速上手教程,无废话纯干货 (opens new window)
# Docker 是什么
Docker 是一个应用打包、分发、部署的工具(其实就是个安装软件、制作软件的)
你也可以把它理解为一个轻量的虚拟机,它只虚拟你软件需要的运行环境,多余的一点都不要, 而普通虚拟机则是一个完整而庞大的系统,包含各种不管你要不要的软件。
什么是容器?
简而言之,容器是您机器上的沙盒进程,与主机上的所有其他进程隔离。可以理解成安装好的微信客户端。
什么是容器镜像?运行容器时,它使用隔离的文件系统。此自定义文件系统由容器映像提供。可以理解成微信安装包。
# 安装Docker
桌面版(Windows、macOS等):https://www.docker.com/products/docker-desktop 服务器版(Ubuntu、Debian等):https://docs.docker.com/engine/install/#server
# 用Docker安装运行软件 - docker run
Docker run reference (opens new window)
Docker 安装的优点
- 一个命令就可以安装好,快速方便
- 有大量的镜像,可直接使用
- 没有系统兼容问题,Linux 专享软件也照样跑
- 支持软件多版本共存
- 用完就丢,不拖慢电脑速度
- 不同系统和硬件,只要安装好 Docker 其他都一样了,一个命令搞定所有
从哪里安装呢?
去hub.docker.com (opens new window) 搜索。
比如我想下载阿里云盘第三方客户端,搜索aliyundrive
就会看到很多,然后我找到了这个:
https://github.com/messense/aliyundrive-webdav
# 运行
# 直接运行,本地没有镜像就会从远程拉取,macOS测试通过
docker run -d --name=aliyundrive-webdav --restart=unless-stopped -p 2337:8080 \
-v /Users/topcheer/Documents/PPFile/PPDocker/etc/aliyundrive-webdav/:/etc/aliyundrive-webdav/ \
-e REFRESH_TOKEN='换成你的access_token' \
-e WEBDAV_AUTH_USER=admin \
-e WEBDAV_AUTH_PASSWORD=panda \
messense/aliyundrive-webdav
# 群晖测试通过(ssh登录后再登录root用户)
docker run -d --name=aliyundrive-webdav --restart=unless-stopped -p 2337:8080 \
-v /volume2/Panda/docker/etc/aliyundrive-webdav/:/etc/aliyundrive-webdav/ \
-e REFRESH_TOKEN='换成你的access_token' \
-e WEBDAV_AUTH_USER=admin \
-e WEBDAV_AUTH_PASSWORD=panda \
messense/aliyundrive-webdav
解释下上面的命令:
run:运行(本地没有就先下载再运行)
-d:后台运行
--name:设置本地容器名字
-p 2337:8080:容器的8080映射到宿主机的9090端口。比如docker容器源码程序是运行在8080端口,我让他在本地运行在2337端口
-v /Users/xxx/Documents/PPFile/PPDocker/etc/aliyundrive-webdav/:/etc/aliyundrive-webdav/:冒号左边是你的电脑的目录,右侧是容器程序的目录
-e WEBDAV_AUTH_USER=admin:设置环境变量
messense/aliyundrive-webdav:镜像名字
官方教程:
docker run -d -p 80:80 docker/getting-started
现在打开 http://localhost/tutorial/ 即可在浏览器看到教程网站
通过上面的命令,现在你成功运行了第一个Docker镜像
不过这行命令是啥意思呢?
-d
- 以分离模式(detached mode,即在后台)运行容器-p 80:80
- 将主机(本电脑)的 80 端口映射到容器(container)中的端口 80docker/getting-started
- 要使用的镜像(image)
你也可以组合单字符标志(single character flags)来缩短完整命令。例如,上面的命令可以编写为:
docker run -dp 80:80 docker/getting-started
映像包含容器的文件系统,因此它必须包含运行应用程序所需的所有内容 - 所有依赖项、配置、脚本、二进制文件等。该映像还包含容器的其他配置,如环境变量、要运行的默认命令和其他元数据。
# Docker 常用命令:
# 查看当前运行中的容器(docker ps -a查看所有)
docker ps
# 查看镜像列表(同docker image ls)
docker images
# 删除指定 id 的镜像
docker rmi image-id
# 删除指定 id 的容器
docker rm container-id
# 它用来启动已经生成、已经停止运行的容器文件
docker start container-id
# 停止指定 id 的容器
docker stop container-id
# 查看 volume 列表
docker volume ls
# 查看网络列表
docker network ls
# 查看 docker 容器的输出,即容器里面 Shell 的标准输出。如果docker run命令运行容器的时候,没有使用-it参数,就要用这个命令查看输出
docker container logs [containerID]
# 制作自己的镜像
https://docker.easydoc.net/doc/81170005/cCewZWoN/N9VtYIIi
# 编写 Dockerfile
#该 image 文件继承官方的 node image,冒号表示标签,这里标签是11,即11版本的 node
FROM node:11
MAINTAINER easydoc.net
# 把当前文件夹下的所有代码复制到image 文件的`/app`目录
ADD . /app
# 设置容器启动后的默认运行目录(接下来的工作路径为)
WORKDIR /app
# 运行命令,安装依赖
# RUN 命令可以有多个,但是可以用 && 连接多个命令来减少层级。
# 例如 RUN npm install && cd /app && mkdir logs
RUN npm install --registry=https://registry.npm.taobao.org
# CMD 指令只能一个,是容器启动后执行的命令,算是程序的入口。
# 如果还需要运行其他命令可以用 && 连接,也可以写成一个shell脚本去执行。
# 例如 CMD cd /app && ./start.sh
CMD node app.js
# Build 为镜像(安装包)和运行
编译 docker build -t test:v1 .
-t
设置镜像名字和版本号
命令参考:https://docs.docker.com/engine/reference/commandline/build/
运行 docker run -p 8080:8080 --name test-hello test:v1
-p
映射容器内端口到宿主机
--name
容器名字
-d
后台运行
命令参考文档:https://docs.docker.com/engine/reference/run/
# 不常用
.git
node_modules
npm-debug.log
上面代码表示,这三个路径要排除,不要打包进入 image 文件。如果你没有路径要排除,这个文件可以不新建。
# 目录挂载
bind mount` 方式用绝对路径 `-v D:/code:/app
volume` 方式,只需要一个名字 `-v db-data:/app
示例:
docker run -p 8080:8080 --name test-hello -v D:/code:/app -d test:v1
注意!
因为挂载后,容器里的代码就会替换为你本机的代码了,如果你代码目录没有node_modules
目录,你需要在代码目录执行下npm install --registry=https://registry.npm.taobao.org
确保依赖库都已经安装,否则可能会提示“Error: Cannot find module ‘koa’”
如果你的电脑没有安装 nodejs (opens new window),你需要安装一下才能执行上面的命令。
# # 常见问题
docker: Error response from daemon: Conflict. The container name "/aliyundrive-webdav" is already in use by container "xxxxx". You have to remove (or rename) that container to be able to reuse that name.
删除吧:
➜ docker docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
600bc0c09349 messense/aliyundrive-webdav "/sbin/tini -- /usr/…" 37 seconds ago Created 0.0.0.0:2337->8080/tcp aliyundrive-webdav
➜ docker docker rm 600bc0c09349