Docker的使用

Docker的使用

参考:阮一峰-Docker入门教程

安装Docker

安装教程就参考官网文档吧。

传送门:

安装完成之后,运行下面的命令,验证安装是否成功:

1
2
3
docker version
# 或者
docker info

创建一个Docker Image

目标:实现一个express服务。

创建一个Express项目

参考:expressjs/express

编写Dockerfile

Dockerfile文件就是描述这个项目该怎么运行。
运行Express项目流程:

  1. 安装好Node(必选先有环境才能执行js)
  2. 编写代码
  3. 安装依赖(npm install
  4. 运行(npm run start

说明:

  • Dockerfile文件里,每一行都是一个命令
  • 命令可以分为两部分:指令和指令参数,例如FROM node:14FROM就是指令,node:14即使参数
  • 命令从上到下按顺序执行
  • 注释以#开头
  • 第一条命令必须使用指令From,该指令将指定一个已存在的Image,后续指令将基于该Image进行,该Image被称为base image
  • 基础镜像可以到这里Docker Hub查找需要的
1
2
3
4
5
6
7
8
9
10
# 创建基础镜像
FROM node:14
# 将当前目录(`.`)copy到image的`/app`目录下
COPY . /app
# 设置工作文件夹
WORKDIR /app
# 安装npm依赖
RUN npm install
# 暴露端口
EXPOSE 3000
  • FROM:创建基础镜像
    • 创建base image,使用Node.js体统的node镜像版本为14
  • COPY:将当前目录(.)copy到image的/app目录下
    • 该指令有三部分:COPY为指令,需要拷贝的东西.,要拷贝到的地方(image内的目录)/app
  • WORKDIR:设计工作文件夹
    • 类型cd /app命令
    • 这个指令就是表示后面的指令都是在该工作文件夹下面操作
  • RUN:安装npm依赖
    • 执行命令
    • 执行命令的指令出了RUN之后还有CMDENTRYPOINT
    • RUN执行命令并创建新的镜像层,常用于安装软件包
    • CMD设置容器启动后默认执行的命令及参数,但CMD能够被docker run后面跟的命令行参数替换
    • ENTRYPOINT配置容器启动时运行的命令
  • EXPOSE:暴露端口
    • 用户可以访问暴露出来的端口

创建image文件

1
docker image build -t docker-express-demo:0.0.1 .

注意:最后有一个点,表示当前目录

  • docker image build:创建image文件
  • -t docker-express-demo:image的名字为docker-express-demo
  • :0.0.1:image的版本号为0.0.1
  • .:表示当前目录

命令执行完毕(需要等一会儿)之后显示:

1
2
=> => writing image ha256:3138fdd3a13a686b4b6aa3b6cb4291f8569b0eaad3b852d05ed7dc0b099734de
=> => naming to docker.io/library/docker-express-demo:0.0.1

这时候运行docker image ls就是看到创建的image了

1
2
REPOSITORY            TAG       IMAGE ID       CREATED         SIZE
docker-express-demo 0.0.1 3138fdd3a13a 3 minutes ago 949MB

生成容器

上面生成的image叫做镜像,镜像是一个文件,并不能够运行,所有我们要生成容器(container)运行。

1
docker container run -p 3000:3000 -it docker-express-demo:0.0.1 /bin/bash  
  • docker container run:从image生成容器
  • -p 3000:3000:后面数字表示容器的端口,前面的数据表示要映射到本机的端口。
  • -it:指在当前的 shell 里执行容器的 shell 命令(类似通过命令行 ssh 登录到服务器后,本地的命令行上实际上运行的是服务器的 shell)
  • docker-express-demo:0.0.1:指运行该image的0.0.1版本
  • bin/bash:指容器启动后,内部执行的第一个命令(即 bash),这样才能在容器内部运行命令

执行完之后就进入了容器的命令行了

1
root@452a5a2034a4:/app# 

在这里,我们输入npm run start就可以启动咱们的项目了。

可以访问一下http://localhost:3000/就可以看到Express返回的内容了。

现在这种方式有点小复杂,可以简化一下。

1
2
3
4
5
6
FROM node:14
COPY . /app
WORKDIR /app
RUN npm install
EXPOSE 3000
CMD npm run start

重新打包:

1
docker image build -t docker-express-demo:0.0.1 .

运行:

1
docker container run -d -p 3000:3000 -it docker-express-demo:0.0.1 > ./id.log
  • -d:表示后台运行
  • > ./id.log:表示将内容输出到id.log文件中

在id.log文件中可以看到dockerID,可以通过docker logs dockerID查看容器日志。

进入Docker容器并执行bash命令

有时候我们需要进去容器内部做一些其他的操作,这是要我们就可以用下面的命令了。

1
docker exec -it 容器ID /bin/bash
  • 容器ID可以通过docker ps或者docker container ls获取,后面加上-a可以获取全部的,默认是获取正在运行的
  • 这个ID与之前的ID是不一样的这个是短ID之前创建容器时返回的是长ID,这两个ID都可以使用

命令运行完之后,就可以进入到容器的命令行了。

想结束的时候使用快捷键Ctrl + D或者输入exit都可以退出。

容器管理

RUN 生成容器

  • 创建好image之后,可以使用run运行
  • 每次运行,都会创建一个新的容器
  • 新建的容器可以用过docker container ls -a或者docker ps -a查看
  • 创建完之后都会返回一个长ID

start 启动容器

1
docker container start 容器ID
  • 启动成功后会返回容器ID
  • 启动成功后通过docker container ls -a可以看到STATUSUp 44 seconds

stop 停止容器

1
docker container stop 容器ID
  • 可以将正在运行的容器停止,停止已经停止的也没有问题
  • 停止完成后,返回容器的ID
  • 停止后通过docker ps -a查看,可以看到STATUSExited (137) 51 seconds ago
  • 只有新建好的容器(能通过命令查到的),才可以使用本命令
  • 使用命令的前提是该容器【已经生成】并且【已经停止运行】;
  • 容器ID通过docker container ls -a或者docker ps -a查看

restart 重启容器

1
docker container restart 容器ID
  • 也可以写为docker restart 容器ID

logs 查看日志

1
docker container logs 容器ID
  • 可以通过docker container logs 容器ID > x.log将日志写到文件中

删除容器日志

  • 首先要将容器停止
  • 日志文件路径为/var/lib/docker/containers/[容器长ID]/[容器ID-json].log
  • 不同返回可能路径不一样,具体请Google

exec -it 进入正在运行的容器(命令行)

1
docker container exec -it 容器ID /bin/bash

rm 删除容器

1
docker rm 容器ID
  • 停止后才可以删除
  • 删除所有非运行的容器docker rm $(docker ps -aq)或者docker container prune

kill 杀死容器

1
docker kill 容器ID
  • 强制关闭,比stop快很多

cp 将容器内部文件复制出来

1
docker container cp 容器ID:路径 本地路径

查看所有容器的IP地址

1
docker inspect -f '{{.Name}} - {{.NetworkSettings.IPAddress }}' $(docker ps -aq)

container、image、文件的相互转化

Image转为container

使用run

Image转为文件

1
docker save 镜像名称 > 文件路径
  • 镜像名称可以用过docker image ls查询
  • 文件路径需要tar文件

container转为image

1
docker commit 容器ID 镜像名称:版本号

container转为文件

1
docker export 容器ID > 文件路径

文件转为Image

1
2
3
docker load < 文件路径
# 或者
docker import 文件路径 镜像名称:版本号
  • 镜像名称没写的话名字和tag将都是<none>
  • 版本号不写的话会默认为latest

在Docker中使用MySQL

MySQL最好不要安装在Docker上面,容易造成数据丢失,本章节主要介绍容器如何与宿主环境共享数据。容器负责业务逻辑,把数据存放在宿主中。

1
2
3
4
# 拉取MySQL镜像
docker pull mysql:8
# 生成容器
docker container run --name mysql-demo -p 12347:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:8

运行起来后,进入到容器内:

1
docker container exec -it 容器ID /bin/bash

然后mysql -u root -p进入MySQL,密码是刚才设置的123456,就可以正常使用了。

将MySQL数据放到容器之外

在创建容器的时候通过参数-v 容器外路径:容器内路径就可以了

1
docker container run --name mysql-demo -v $PWD/mysqldata:/var/lib/mysql -p 12347:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:8
  • 将本机的$PWD/mysqldata目录链接到容器的/var/lib/mysql目录($PWD为当前目录)
  • /var/lib/mysql是MySQL默认目录

创建容器网络

Docker的常见问题

  • 安装依赖遇到墙,可以Google搜索一下加速镜像。

Docker的使用
https://www.shaohang.xin/2020/10/02/technical/docker/
作者
少航
发布于
2020年10月2日
许可协议