我的 docker 笔记
这是一篇旧的 dokcer 笔记,大部分内容是基于 Docker Desktop for Windows 写的,但也适用于其他平台。
安装 Docker 先决条件
- 64 位系统
- Linux 内核大于 3.8
- 内核必须支持并开启 cgroup 和命名空间(namespace)
在 Ubuntu 和 Debian 中安装 Docker
安装时还是参考官网,这部分的笔记是很久之前记录的,现在可能已经不能使用了,但是还是保留下来,做个记录吧。
- 检查内核版本
uname -a
- 升级系统到最新
# 检查更新
sudo apt update
# 安装内核
sudo apt install linux-headers-x.xx.x-xx-generic
# 加载新内核
sudo update-grub
# 重启
sudo reboot
- 检查 Device Mapper 存储驱动
检查 Device Mapper
ls -l /sys/class/misc/device-mapper
在 /proc/devices 文件中检查是否有 device-mapper 条目
sudo grep device-mapper /proc/devices
如果无 device-mapper 相关信息,尝试加载 dm_mod 模块
sudo modprode dm_mod
- 安装 Docker
(1) Install packages to allowapt to use a repository over HTTPS:
sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
software-properties-common
(2) Add Docker’s official GPG key:
curl -fsSLhttps://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
Verify fingerprint
sudo apt-key fingerprint 0EBFCD88
(3)use stable repository
sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu\
$(lsb_release -cs) \
stable"
(4)安装 Docker 软件包
sudo apt install docker-engine
(5)确认 Docker 应正常安装并运行
sudo docker info
- Docker 中使用 UFW(Uncomplicated Firewall)
修改 /etc/default/ufw 文件
# 原始
DEFAULT_FORWARD_POLICY="DROP"
# 修改为
DEFAULT_FORWARD_POLICY="ACCEPT"
重新加载 UFW 防火墙
sudo ufw reload
docker 常用命令
列出本机所有 image 文件
docker image ls
删除 image 文件
docker image rm [imageName]
列出本机正在运行的容器
docker container ls
列出本机所有容器,包括终止运行的容器
docker container ls --all
终止运行容器
docker container kill [containerId]
删除容器
docker container rm [containerId]
启动容器
docker container start containerId
停止运行容器
docker container stop containerId
查看容器输出
docker container logs containerId
进入正在运行的容器
docker container exec -it constainerId /bin/bash
从正在运行的容器里将文件拷贝到本机
docker container cp constainerId:</path/to/file> .
Dockerfile 文件
Dockerfile 是一个用来配置生成 image 文件的文本文件。
.dockerignore
文件写入要排除在 image 文件外的文件/文件夹。
Dockerfile 文件内容示例:
FROM node:8.4
COPY . /app
WORKDIR /app
RUN ["npm", "install"]
EXPOSE 3000/tcp
- FROM node:8.4 ---> image 文件继承的 image,冒号表示继承 image 的标签
- COPY . /app ---> 将当前目录下除 .dockerignore 排除的路径的所有文件,都拷贝到 image 的 /app 目录
- WORKDIR /app ---> 指定接下来的工作路径为 /app
- RUN [“npm”, “install”] ---> 在 /app 目录下运行 npm install 安装依赖。安装后所有依赖都将打包到 image 文件
- EXPOSE 3000/tcp ---> 将容器 3000 端口暴露出来
创建 image 文件
docker image build -t [imageName][:tag] [fileDir]
-t
参数用来指定 image 文件名,文件名后的 :tag
为 image 指定标签,如果不指定,默认为 latest
,fileDir 表示 Dockerfile 所在路径,当前路径就是一个点。
如果运行成功,通过 docker image ls 查看新生成的 image 文件。
生成容器
docker container run -p 8000:3000 -it imageName[:tag] /bin/bash
- -p : 容器的 3000 端口映射到本机的 8000 端口
- -it : 容器的 shell 映射到当前的 shell,在本机窗口输入命令会传入容器
- imageName[:tag] : image 文件名[:标签]
- /bin/bash : 容器启动以后,内部第一个指定的命令,这里是启动 bash,保证用户能够使用 shell
CMD 命令
在 Dockerfile 中添加 CMD 命令,让容器启动后自动执行命令
FROM node:8.4
COPY . /app
WORKDIR /app
RUN ["npm", "install"]
EXPOSE 3000/tcp
CMD node demos/01.js
RUN 命令与 CMD 命令的区别:
RUN 命令在 image 文件构建阶段执行,执行结果打包进入 image 文件;CMD 命令在容器启动后执行。一个 Dockerfile 可以包含多个 RUN 命令,但只能有一个 CMD 命令。
指定了 CMD 命令后,docker container run 命令就不能附加命令了(比如 /bin/bash),否则会覆盖 CMD 命令。
发布 image 文件
docker image tag imageName <username>/<repository>[:<tag>]
或
docker image build -t <username>/<repositrory>[:<tag>] .
发布 image 文件
docker image push <username>/<repository>[:<tag>]
docker 安装 mysql 及 通过 nodejs 连接数据库
1、安装
以 5.7 为例:
docker pull mysql:5.7
2、创建 mysql 数据库文件存放目录
因为 docker 容器不保存数据,管理容器数据也就没有了,所以必须要设置数据存储目录,把数据存在本地磁盘上。例:
mkdir D:\docker\mysql
mkdir D:\docker\mysqlConf
3、启动 mysql 镜像
打开 powershell,执行如下命令:
docker run -d --rm --name Mysql -v D:\docker\mysql:/var/lib/mysql -v D:\docker\mysqlConf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=123456 -p 3306:3306 mysql:5.7 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
说明:
- -d:后台运行
- —rm:停止镜像自动删除镜像,如果配置好可以不删除,Windows 最新使用 Dashboard 管理容器,UI 界面会很方便,配置好后不删除。并且 Windows 下使用 Docker Desktop 时使用 Kitematic 管理镜像启停很方便,配置之后就不用删除了。
- —name:镜像别名
- -v:把本地目录映射到镜像目录
- -e:设置环境变量,通过 docker 安装的 mysql 必须设置 MYSQL_ROOT_PASSWORD,否则不能运行。
- -p:把本地端口映射到镜像端口,这里最好一致,否则可能有无法连接的问题
- —character-set-server 和 —collation-server 设置 mysql 编码,以便识别中文。
4、添加远程访问账户
mysql -u root -p
Linux 输入:
docker container exec -it <containerId> /bin/bash
再输入 mysql -u root -p
按照提示输入 root
密码。
创建一个新用户:
-- 创建一个用于本地访问的用户
CREATE USER 'username'@'localhost' IDENTIFIED BY 'password';
-- 创建一个所有网络均可访问的用户
CREATE USER 'username'@'%' IDENTIFIED BY 'password';
-- 创建一个指定 IP 访问的用户
CREATE USER 'username'@'IP' IDENTIFIED BY 'password';
设置新用户权限:
GRANT ALL PRIVILEGES ON _._ TO 'username'@'%' WITH GRANT OPTION;
-- 授予用户 testDb 内所有表的所有权限
GRANT ALL PRIVILEGES ON testDb.* TO 'username'@'%' WITH GRANT OPTION;
GRANT ALL PRIVILEGES ON testDb.* TO 'username'@'localhost' WITH GRANT OPTION;
-- 刷新用户权限
FLUSH PRIVILEGES;
5、通过 nodejs 的 mysql2 模块连接数据库
mysql2 用法查看 npm 文档。
连接过程中,如果出现以下错误:
Client does not support authentication protocol requested by server; consider upgrading MySQL client
按照如下方法解决:
在 Kitematic 界面点击 EXEC 进入命令行,然后登录:
mysql -u root -p
然后执行以下命令:
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'your_root_password';
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_root_password';
再执行以下命令查看是否设置成功,最后再尝试连接。
SELECT plugin FROM mysql.user WHERE User = 'root';
6、通过 mysql2 获取数据
mysql2 支持 promise,获取的数据是一个数据集,如果要获取数据表,只需要取数据集的第一张表(也就是索引为 0 的表)即可。
如果要获取一个数据表中数据行数,在使用 COUNT(*) 时最好设置一个别名,否则后续处理数据时会比较麻烦。
mysql2 的 query 方法的第一个参数是 SQL 语句,SQL 语句传入的变量可以用 ?
作为占位符,第二个参数即是传给 SQL 语句变量的参数。
docker 无法打开端口
第一步
Disable hyper-v (which will required a couple of restarts) dism.exe /Online /Disable-Feature:Microsoft-Hyper-V
第二步
When you finish all the required restarts, reserve the port you want so hyper-v doesn’t reserve it back netsh int ipv4 add excludedportrange protocol=tcp startport=50051 numberofports=1
第三步
Re-Enable hyper-V (which will require a couple of restart) dism.exe /Online /Enable-Feature:Microsoft-Hyper-V /All
docker 安装 jupyter 镜像容器
- 拉取镜像
以 minimal-notebook 镜像为例。
docker pull jupyter/minimal-notebook:latest
- 运行容器
docker run --rm -d --name Myjupyter -v D:\Jupyter\work:/home/jovyan/work -p 8888:8888 -e JUPYTER_ENABLE_LAB=yes jupyter/minimal-notebook:latest
- 所有配置项
docker run --rm -d --name Myjupyter --user root -e NB_USER=xuewu -e NB_UID=1000 -e NB_GID=100 -e NB_GROUP=$NB_USER -e CHOWN_HOME=yes -e GRANT_SUDO=yes -e RESTARTABLE=yes -w /home/$NB_USER -v D:\Jupyter\work:/home/xuewu/work -p 8888:8888 -e JUPYTER_ENABLE_LAB=yes jupyter/minimal-notebook:latest
docker 部署 mongodb
- 创建一个 volume
volume 的作用是用来存储数据,因为 windows 下 docker 功能限制,不能使用路径挂载的方式将数据库文件挂载到本地磁盘,因此只能使用这种方式。
docker volume create --name=[Your-volume-name]
- 运行 mongo 容器
docker run --name <mongodb-name> -p 27017:27017 -v [Your-volume-name]:/data/db -d mongo<:version>
—name: 数据库名字,不加参数则使用随机名
-p: 端口,前面是计算机端口,后面是容器上的端口
-v: 数据库目录,冒号前是创建的 volume 名,冒号后是容器上的路径
-d: 在后台运行
mongo: 镜像,后加版本号,不加版本号默认是 latest,最好制定版本号
- 创建管理员:
要为 mongodb 加入登录验证,就需要创建登录用户名和密码。
进入 mongo 命令行:
docker exec -it [mongodb-name] bash
mongo
进入数据库:
use database-name
执行以下命令:
db.createUser({ user: '<USER>', pwd: '<PASSWORD>', roles: [ { role: 'readWrite', db: 'database-name' } ]});
将 <USER>
和 <PASSWORD>
内容替换成自己需要的用户名和密码。
退出命令行,停止并移除当前容器,然后重新以验证方式开启一个新容器:
docker stop mongodb-name
docker rm mongodb-name
docker run --name mongodb-name -v mongodata:/data/db -d -p 27017:27017 mongo --auth
- 以验证方式连接数据库
mongodb://user:password@localhost:27017/database-name
- 导入数据
首先将数据集 json 或 bson 文件复制到 mongo 容器中:
docker cp a.json mongodb-name:/path
a.json 的位置可以写入一个 json 或 bson 文件,或者是一个路径,这样就能复制一整个路径下的文件。
path 是复制到 mongo 容器中的路径,自己新建一个路径,防止导入的文件弄乱容器目录,也方便下一步数据导入。
复制完数据后,进入 docker 命令行:
docker exec -it mongodb-name bash
之后,进入复制 json 文件路径,执行 mongorestore 命令:
mongorestore -d database-name ./ --username=user --password=password
mongorestore 官方指南: https://docs.mongodb.com/manual/reference/program/mongorestore/
Docker + WordPress 微服务
http://www.ruanyifeng.com/blog/2018/02/docker-wordpress-tutorial.html
Docker Compose
Compose 是一个用于管理多个 Docker 容器组成一个应用的工具。
Compose 配置文件是 YAML 格式的 docker-compose.yml。
写好多个容器之间的调用关系 .yml 配置文件后,只需要一个命令,就能同时启动/关闭这些容器。
Mac 和 Windows 在安装 docker 的时候,会一起安装 docker compose。Linux 系统下的安装参考官方文档。
安装完成后,运行命令查询:
docker-compose --version
compose wordpress 示例 yml
mysql:
image: mysql:5.7
environment:
- MYSQL_ROOT_PASSWORD=123456
- MYSQL_DATABASE=wordpress
web:
image: wordpress
links:
- mysql
environment:
- WORDPRESS_DB_PASSWORD=123456
ports:
- '127.0.0.3:8080:80'
working_dir: /var/www/html
volumes:
- wordpress:/var/www/html
启动两个容器:
docker-compose up
关闭两个容器:
docker-compose stop
关闭后,两个容器还在,数据不会丢失,下次启动时,还可以复用。
删除容器文件(容器必须已经停止):
docker-compose rm