Simon Y.
open main menu
Part of series: tech

我的 docker 笔记

/ 13 min read

这是一篇旧的 dokcer 笔记,大部分内容是基于 Docker Desktop for Windows 写的,但也适用于其他平台。

安装 Docker 先决条件

  • 64 位系统
  • Linux 内核大于 3.8
  • 内核必须支持并开启 cgroup 和命名空间(namespace)

在 Ubuntu 和 Debian 中安装 Docker

安装时还是参考官网,这部分的笔记是很久之前记录的,现在可能已经不能使用了,但是还是保留下来,做个记录吧。

  1. 检查内核版本
uname -a
  1. 升级系统到最新
#  检查更新
sudo apt update
#  安装内核
sudo apt install linux-headers-x.xx.x-xx-generic
#  加载新内核
sudo update-grub
#  重启
sudo reboot
  1. 检查 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
  1. 安装 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
  1. 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、添加远程访问账户

打开 Kitematic  点击运行中的  mysql  镜像,点击  EXEC 图标,弹出命令行界面,输入下面的命令:

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 镜像容器

  1. 拉取镜像

以 minimal-notebook 镜像为例。

docker pull jupyter/minimal-notebook:latest
  1. 运行容器
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
  1. 所有配置项
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

  1. 创建一个 volume

volume 的作用是用来存储数据,因为 windows 下 docker 功能限制,不能使用路径挂载的方式将数据库文件挂载到本地磁盘,因此只能使用这种方式。

docker volume create --name=[Your-volume-name]
  1. 运行 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,最好制定版本号

  1. 创建管理员:

要为 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
  1. 以验证方式连接数据库
mongodb://user:password@localhost:27017/database-name
  1. 导入数据

首先将数据集 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

MySQL 网页客户端 Docker 容器 - Adminer