docker安装与搭建qqbot

前置知识:

  • 网络

  • python

docker安装与搭建qqbot

docker是什么

Docker 属于 Linux 容器的一种封装,提供简单易用的容器使用接口。 它是目前最流行的 Linux 容器解决方案。

Docker 将应用程序与该程序的依赖,打包在一个文件里面。运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样。有了 Docker,就不用担心环境问题。

总体来说,Docker 的接口相当简单,用户可以方便地创建和使用容器,把自己的应用放入容器。容器还可以进行版本管理、复制、分享、修改,就像管理普通的代码一样。

比起虚拟机,docker具有运行速度快,体积小,占用资源少等诸多优点,这让docker十分流行。

docker 安装

docker存在社区版与付费的企业版,本次使用的是免费的社区版。

本次使用的是windows的docker,可以点进下载链接进行下载,具体安装流程可以参考官方文档。

值得注意的是,官网并没有提供windows家庭版的安装流程,笔者在这里给出家庭版的流程。

1.安装Hyper-V

将下列代码保存为.cmd文件并以管理员身份运行,执行完毕后重启电脑

1
2
3
4
5
6
7
8
9
pushd "%~dp0"

dir /b %SystemRoot%\servicing\Packages\*Hyper-V*.mum >hyper-v.txt

for /f %%i in ('findstr /i . hyper-v.txt 2^>nul') do dism /online /norestart /add-package:"%SystemRoot%\servicing\Packages\%%i"

del hyper-v.txt

Dism /online /enable-feature /featurename:Microsoft-Hyper-V-All /LimitAccess /ALL

2.解决Containers Windows Feature is not available问题

虽然网上教程没有遇到这个问题,但笔者遇到了。解决方法为将下列代码保存为.bat文件,并且以管理员权限运行并重启电脑

1
2
3
4
5
6
pushd "%~dp0"
dir /b %SystemRoot%\servicing\Packages\*containers*.mum >containers.txt
for /f %%i in ('findstr /i . containers.txt 2^>nul') do dism /online /norestart /add-package:"%SystemRoot%\servicing\Packages\%%i"
del containers.txt
Dism /online /enable-feature /featurename:Containers -All /LimitAccess /ALL
pause

3.修改注册表

在cmd执行以下命令

1
REG ADD "HKEY_LOCAL_MACHINE\software\Microsoft\Windows NT\CurrentVersion" /v EditionId /T REG_EXPAND_SZ /d Professional /F

重启后注册表会还原,但不会影响linux容器正常使用。

4.安装installer

注意不要勾选windows容器的选项,一路next就行了。

docker运行

docker容器运行的基本流程:下载或打包程序的image->将image run起来,形成容器。

1.注册账号

docker需要账号才能运行,在此不过多赘述

2.修改配置文件,添加镜像源

在windows界面可以通过gui,在setting->docker engine中修改,然后重启docker,可以改成如下:

1
2
3
4
"registry-mirrors": [
"https://dockerhub.azk8s.cn",
"https://hub-mirror.c.163.com"
],

3.image文件

docker将应用程序和依赖全部打包在image文件中,并且通过该文件生成容器。image文件是通用的,可以将一台机器上的image文件上放入另一台的image进行使用。image文件也可以继承另一个image文件进行开发。

image文件可以上传到仓库进行共享,而docker hub作为官方的仓库,是最为重要的仓库。

下面通过运行实例hello-world进行说明。

首先,可以执行以下命令将官方的hello-world的image文件拉至本地。

1
docker image pull hello-world

等待抓取成功后,可以通过以下命令查看image文件

1
docker image ls

4.run

通过以下命令运行hello-world的image文件

1
docker run hello world

你会看到docker官方给出的信息,并且该容器会在信息结束后自动终止。但并非所有容器都是如此。

至此,简单的docker操作就结束了,下面研究有关将项目搭进docker的应用问题。

项目简介

这次搭建的是构建在flask上的基于coolq-http的qqbot项目。项目内使用了redis进行数据的存储。本次将redis和BotServer分别打包进入容器中,实现redis和BotServer两个容器之间的通信,实现BotServer与宿主机上5700端口上的coolq-http通信。

本次项目所有python代码都在BotServer.py文件中。

关于bot怎么写在此不过多赘述,可以详见coolq-http的文档。

下面将详细解释搭建过程。

整理项目依赖

项目基于flask实现,并且使用了redis通信模块。我们需要将所有的依赖写进requirement.txt文件中,并放入和项目的BotServer.py文件所在的文件夹。对于python项目,可以使用pipreqs进行自动编写。使用也很简单,cmd进入项目所在文件夹,执行以下命令即可。

1
2
pip install pipreqs
pipreqs ./ --encoding=utf8

–encoding为可选项,但在windows下不加上这个选项会报错。

编写dockerfile

docker image的创建是通过docker一步步执行dockerfile来实现的。所以在编写好requirement.txt后,我们需要编写dockerfile。

在BotServer.py和requirement.txt所在的目录下,新建一个名为Dockerfile的文件(注意,没有后缀名),将以下内容写进去。

1
2
3
4
5
6
7
8
9
10
11
FROM python:3.6-slim 

WORKDIR /app

COPY . /app

RUN pip install -r ./requirements.txt

EXPOSE 5701

CMD ["python","BotSever.py"]

FROM语句,含义是继承了官方的3.6-slim版本的python镜像。冒号表示标签,这里标签便是3.6-slim。

WORKDIR语句,指明接下来的工作目录为/app

COPY语句,将本目录的所有文件复制到/app目录下去

RUN语句,指在build过程中执行该指令。这里执行的指令指使用pip将requirements.txt里的头文件全部安装。

EXPOSE语句,将端口5701开放。

CMD语句,在run的时候执行,在这里是指用python运行BotServer.py文件。

改写代码

在打包成image之前,我们需要改写代码中的ip以及端口,来实现容器和容器之间的通信以及容器和宿主机的通信。

在原来的代码中,我们连接redis的方法如下:

1
self.redis_pool = redis.ConnectionPool(host='127.0.0.1', port=6379, password='', db=0)

host指向了127.0.0.1,也就是本机ip,但这在容器中是行不通的。由于隔离,无法直接将本机ip和容器中的127.0.0.1连接起来,我们可以将这一行改写成如下形式:

1
2
self.redis_pool = redis.ConnectionPool(
host='redis', port=6379, password='', db=0)

使用了redis代指本机ip,在run的时候,可以通过–link选项,将redis所在的容器与该项目所在的容器连接起来。

同理,我们需要将flask监听的地址,从127.0.0.1,改为0.0.0.0,来接受任何连接。

1
self.bot_server.run(host="0.0.0.0", port=5701)

在发送信息时,我们需要想宿主机的coolq-http的端口发送信息,就需要将代码中本机的url改为宿主机的url。在windows中,我们可以将127.0.0.1改为host.docker.internal。例如:

1
2
url = "http://127.0.0.1:12345/send_group_msg"  # 原来的url
url = "http://host.docker.internal:12345/send_group_msg"

这样我们就能实现容器和宿主机的连接。

打包image

在改写完代码后,我们就可以打包image了。用cmd进入项目所在目录,执行以下命令:

1
docker build -t qqbot .

-t用来指定image的名字,**.** 点代表本文件夹。打包需要一些时间下载。在完成后,我们就可以进行下一步。

安装运行redis

redis安装是较为简单的一步,与hello word类似,我们可以直接从官方镜像源下载并且安装redis,执行命令如下:

1
2
docker pull redis:latest
docker run -itd --name redis-test -p 6379:6379 redis

其中-p是将宿主机的6379端口(前一个6379)映射到容器的6379端口,从而便于外部访问。-d命令为后台运行。 -i: 以交互模式运行容器,通常与 -t 同时使用, -t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用。

运行qqbot

我们搭建好了redis的镜像并成功运行了起来,搭建好了bot的镜像,现在所需要做的便是将bot的镜像运行起来。在run之前,我们先查看redis所在的容器。可以执行以下命令查看:

1
docker ps -a

在本台电脑上,显示如下:

2c30a28c3979 redis “docker-entrypoint.s…” 24 hours ago Up 3 hours 0.0.0.0:6379->6379/tcp redis-test

将最前面的container id复制下来,将之前改写的redis和容器地址使用–link连接起来,执行以下命令,便可以将bot跑起来了:

1
docker run --name bot -itd --link  2c30a28c3979:redis -p 5701:5701 qqbot

这样,我们就成功将qqbot搭建进docker之中。

后记

本文主要是记录自己踩过的一些坑,将整个流程写了一遍,其中改写代码的环节虽然很短,但耗费了我一天半的时间。有些问题很玄学,比如安装installer时报错,重启电脑就解决了。有时候pip时间过长会报错,重启docker就解决了。

为什么不把coolq也放进docker里,主要是因为懒……

本次没有将qqbot全部代码展现出来,主要是因为代码质量目前还欠佳。等我有时间(没时间)将代码优化后,再来详细讲解bot。

Author

王钦砚

Posted on

2020-04-19

Licensed under

CC BY-NC-SA 4.0

Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×