在Azure VM上运行Ubuntu 20.04(LTS)并使用Python3和MongoDB(继续收集Hololive视频流计划的第二部分)
首先
上次(https://qiita.com/kerobot/items/fa728f665d559b969e1c)我们已经实现了将Hololive的直播预定和视频信息从Holodule和YouTube收集并存入MongoDB的功能。
这次我们将尝试将整个系统部署到Azure VM的Ubuntu上,并定期执行。
我将之前在 Windows 10 上搭建的系统,包括 Poetry + pyenv + Python3 + WebDriver + MongoDB,移植到 Azure VM 的 Ubuntu 系统中,并通过 cron 定期执行。
最終我想要做的事情
最近我经常浏览的虚拟YouTuber制作公司”hololive”等的视频直播计划,我希望能够定期将其存储在数据库中,并通过WebAPI进行查阅浏览的安卓应用程序。
-
- 创建一个用于收集视频流计划的程序(已完成)
-
- 创建并自动化收集视频流计划的数据库(前一次+本次已经实现自动化)
-
- 创建用于查看已存储的视频流计划的Web API
- 创建用于浏览视频流计划的Android应用程序,通过Web API来查看。
做过的事情 de
这次我们继续进行了「创建用于存储收集到的视频发布计划的数据库并自动化收集」中的第2个任务,即自动化收集。
-
- 在中文的原生环境下重新表述如下:
环境准备
将Azure VM上的Ubuntu从18.04(LTS)升级到20.04(LTS)
确认Python3和pip3可用
环境构建
安装所需软件包
安装pyenv
利用pyenv安装Python 3.8.6
安装Poetry
安装MongoDB
程序部署
在MongoDB上创建用户
部署和配置程序
安装geckodriver
创建.env文件
进行程序的运行确认
配置cron定时任务
环境的准备
我們準備了以下結構的環境。
-
- Azure VM の Ubuntu 18.04(LTS) ※Python3 と git 導入済
-
- Windows 10 1909
-
- WSL Ubuntu 20.04.1 LTS (GNU/Linux 4.4.0-18362-Microsoft x86_64)
- PowerShell 7.0.3 + Microsoft Azure CLI 2.14.0
我升级到了Ubuntu 20.04(LTS),因为它的基本系统中包含的Python已经升级到了Python 3.8版本,而Ubuntu 18.04(LTS)则没有。
- Azure VM の Ubuntu を 18.04(LTS) から 20.04(LTS) へアップグレードしたら Grub が壊れた→復旧
結果的にアップグレードは成功し、Ubuntu 20.04.1 LTS (GNU/Linux 5.4.0-1031-azure x86_64) となりました。
为了确保,我会在升级之后更新软件包。
$ sudo apt update
$ sudo apt upgrade
我会尝试检查Python的版本。
$ python -V
Python 2.7.18
$ python3 -V
Python 3.8.5
在python3命令中,版本为3.8.5,而在python命令中,版本似乎为2.7.18。
由于未安装pip3,因此请先进行安装。
$ sudo apt install python3-pip
$ pip3 -V
pip 20.0.2 from /usr/lib/python3/dist-packages/pip (python 3.8)
我会从这种状态开始进行环境建设的尝试。
環境の構築
必要なパッケージのインストール
请先安装运行pyenv等所需的包。
实际上,我是根据使用pyenv安装Python时出现的错误,以及使用Poetry安装包时遇到的错误,查找并安装了所需的包。
# エラー1 can't decompress data; zlib not available
# zlib1g-dev をインストール
$ sudo apt install zlib1g-dev
# エラー2 Missing the OpenSSL lib
# libssl-dev をインストール
$ sudo apt install libssl-dev
# エラー3 ModuleNotFoundError: No module named '_ctypes'
# libffi-dev をインストール
$ sudo apt install libffi-dev
# エラー4 Poetry を利用したパッケージインストール(仮想環境の構築)が失敗する場合
# python3-venv をインストール
$ sudo apt install python3-venv
安装pyenv
从GitHub安装pyenv来管理Python的执行环境。
$ git clone https://github.com/pyenv/pyenv.git ~/.pyenv
添加pyenv的路径和初始化到~/.bash_profile中。
$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
$ echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init -)"\nfi' >> ~/.bash_profile
~/.bashrc を読み込むための記述を ~/.bash_profile の最後に記述しておきます。
$ test -r ~/.bashrc && . ~/.bashrc
~/.bash_profile を適用しておきます。
$ source ~/.bash_profile
先检查一下 pyenv 的版本。
$ pyenv --version
pyenv 1.2.21
使用 pyenv 安装 Python 3.8.6
使用pyenv安装Python 3.8.6来运行程序。
# インストール可能な Python の確認
$ pyenv install --list
# Python 3.8.6 のインストール
$ pyenv install 3.8.6
虽然有几个警告,但是我成功安装了 Python 3.8.6。
Downloading Python-3.8.6.tar.xz...
-> https://www.python.org/ftp/python/3.8.6/Python-3.8.6.tar.xz
Installing Python-3.8.6...
WARNING: The Python bz2 extension was not compiled. Missing the bzip2 lib?
WARNING: The Python readline extension was not compiled. Missing the GNU readline lib?
WARNING: The Python sqlite3 extension was not compiled. Missing the SQLite3 lib?
Installed Python-3.8.6 to /home/mcuser/.pyenv/versions/3.8.6
如果出现错误,请检查所需的软件包是否已安装。
使用pyenv切换全局环境的Python版本。
$ pyenv global 3.8.6
# ローカル環境の切り替えはプロジェクトのディレクトリを作った後に行う。
# $ pyenv local 3.8.6
我需要确认一下Python的全局环境版本已经切换了。
$ pyenv versions
system
* 3.8.6 (set by /home/mcuser/.python-version)
确认由 pyenv 管理的 Python 的位置。
$ which python
/home/ユーザー/.pyenv/shims/python
检查Python在全局环境中的版本。
$ python -V
Python 3.8.6
$ python3 -V
Python 3.8.6
供参考,pyenv 的卸载方法如下。
# ~/.bash_profile から、PATH や pyenv init の記述を手作業で削除したうえでディレクトリを削除する。
$ rm -rf $(pyenv root)
诗歌的安装
安装Poetry以管理Python的包和项目。
$ curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python -
Retrieving Poetry metadata
# Welcome to Poetry!
This will download and install the latest version of Poetry,
a dependency and package manager for Python.
It will add the `poetry` command to Poetry's bin directory, located at:
$HOME/.poetry/bin
This path will then be added to your `PATH` environment variable by
modifying the profile files located at:
$HOME/.profile
$HOME/.bash_profile
You can uninstall at any time by executing this script with the --uninstall option,
and these changes will be reverted.
Installing version: 1.1.4
- Downloading poetry-1.1.4-linux.tar.gz (57.03MB)
Poetry (1.1.4) is installed now. Great!
To get started you need Poetry's bin directory ($HOME/.poetry/bin) in your `PATH`
environment variable. Next time you log in this will be done
automatically.
To configure your current shell run `source $HOME/.poetry/env`
当您安装Poetry时,它会自动将路径写入~/.bash_profile和~/.profile文件中。
# 自動で書き込んでくれるのでこれらの設定は不要。
echo 'export PATH="$HOME/.poetry/bin:$PATH"' >> ~/.profile
echo 'export PATH="$HOME/.poetry/bin:$PATH"' >> ~/.bash_profile
我已经将 ~/.bash_profile 进行了以下设置。
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
if command -v pyenv 1>/dev/null 2>&1; then
eval "$(pyenv init -)"
fi
export PATH="$HOME/.poetry/bin:$PATH"
test -r ~/.bashrc && . ~/.bashrc
我会应用 ~/.bash_profile。
$ source ~/.bash_profile
我会确认一下诗歌的版本。
$ poetry --version
Poetry version 1.1.4
将 Poetry 创建的 Python 虚拟环境位置设置在项目目录中。
$ poetry config --list
$ poetry config virtualenvs.in-project true
以下是参考Poetry的卸载方法。
# ~/.bash_profile や ~/.profile から、PATH の記述を自動で削除してくれます。
$ curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | POETRY_UNINSTALL=1 python -
安装MongoDB
安装 MongoDB 以便注册收集的信息。
首先,您需要导入用于软件包管理系统的公钥。
$ wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | sudo apt-key add -
创建用于包管理系统的MongoDB列表文件。
$ echo "deb [ arch=amd64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/4.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list
我们将更新软件包管理系统的数据库。
$ sudo apt update
安装MongoDB。
sudo apt install -y mongodb-org
数据目录,日志目录和配置文件的位置如下所示。
データディレクトリ
/var/lib/mongodb
ログディレクトリ
/var/log/mongodb
設定ファイル
/etc/mongod.conf
MongoDB作为服务进行注册后,可以通过以下方式来检查状态、启动和停止。
$ sudo systemctl status mongod
$ sudo systemctl start mongod
$ sudo systemctl stop mongod
$ sudo systemctl restart mongod
检查MongoDB的版本。
$ mongo --version
MongoDB shell version v4.4.1
Build Info: {
"version": "4.4.1",
"gitVersion": "ad91a93a5a31e175f5cbf8c69561e788bbc55ce1",
"openSSLVersion": "OpenSSL 1.1.1f 31 Mar 2020",
"modules": [],
"allocator": "tcmalloc",
"environment": {
"distmod": "ubuntu2004",
"distarch": "x86_64",
"target_arch": "x86_64"
}
}
使用Mongo shell在MongoDB中创建一个admin用户。
$ mongo
> use admin
> db.createUser( { user:"admin", pwd:"password", roles:[{ "role" : "root", "db" : "admin" }] } );
> exit
确认在 MongoDB 中创建了名为 admin 的用户。
$ mongo
> use admin
> db.system.users.find();
> exit
为了启用MongoDB的身份验证设置,需要编辑mongod.conf文件。
sudo cp /etc/mongod.conf /etc/mongod.conf.org
sudo vi /etc/mongod.conf
我会进行这个描述。
# mongod.conf
security:
authorization: enabled
重新启动MongoDB服务。
$ sudo systemctl restart mongod
确认MongoDB的身份验证配置已启用。
$ mongo
> use admin
switched to db admin
# 認証無しだとエラー
> db.system.users.find();
Error: error: {
"ok" : 0,
"errmsg" : "command find requires authentication",
"code" : 13,
"codeName" : "Unauthorized"
}
# 認証ありだと成功
> db.auth("admin", "password");
1
> db.system.users.find();
{ "_id" : "admin.admin", "userId" : ...
> exit
如果同时启动Mongo shell并指定了数据库进行认证的情况下
$ mongo localhost:27017/admin -u admin -p
MongoDB shell version v4.4.1
Enter password:
...
> exit
程序布局
在MongoDB中创建用户。
在使用程序与 MongoDB 时,我们需要创建一个用户。
$ mongo localhost:27017/admin -u admin -p
MongoDB shell version v4.4.1
Enter password:
...
> use holoduledb
> db.createUser( { user:"owner", pwd:"password", roles:[{ "role" : "dbOwner", "db" : "holoduledb" }] } );
> exit
确认能够使用创建的用户进行连接。
$ mongo localhost:27017/holoduledb -u owner -p
MongoDB shell version v4.4.1
Enter password:
...
> exit
程序的布置和设置
从GitHub上获取程序并部署。
$ cd ~
$ git clone https://github.com/kerobot/holocrawler.git holocrawler
$ cd holocrawler
为了预先确认程序运行所需的 Python 版本,请进行检查。
$ cat pyproject.toml
...
python = "^3.8"
...
使用pyenv来切换本地环境中的Python版本。
$ pyenv local 3.8.6
请确认本地环境中 Python 和 pip 的版本。
$ python -V
Python 3.8.6
$ pip -V
pip 20.2.1 from /home/mcuser/.pyenv/versions/3.8.6/lib/python3.8/site-packages/pip (python 3.8)
使用诗歌来安装Python虚拟环境和包。
$ poetry install
我将更新Python虚拟环境中的pip工具。
$ /home/mcuser/holocrawler/.venv/bin/python -m pip install --upgrade pip
Collecting pip
Downloading pip-20.2.4-py2.py3-none-any.whl (1.5 MB)
|████████████████████████████████| 1.5 MB 5.4 MB/s
Installing collected packages: pip
Attempting uninstall: pip
Found existing installation: pip 20.2.2
Uninstalling pip-20.2.2:
Successfully uninstalled pip-20.2.2
Successfully installed pip-20.2.4
安装geckodriver
在程序中使用的geckodriver需要先进行安装。
$ sudo apt install firefox-geckodriver
请确认geckodriver的版本。
$ geckodriver --version
geckodriver 0.27.0
创建 .env 文件
您可以创建一个文件来设置YouTube Data API v3的API密钥和MongoDB的连接信息。
$ cp .env.sample .env
HOLODULE_URL = "<Holodule URL>"
API_KEY = "<Youtube Data API Key>"
API_SERVICE_NAME = "youtube"
API_VERSION = "v3"
MONGODB_USER = "<user>"
MONGODB_PASSWORD = "<password>"
MONGODB_HOST = "<localhost:27017>"
验证程序的功能
プログラムを実行してみます。
$ cd ~/holocrawler
$ poetry run python main.py
データベースを確認してみます。
$ mongo localhost:27017/holoduledb -u owner -p
MongoDB shell version v4.4.1
Enter password:
...
> show collections
holodules
> db.holodules.find();
{ "_id" : ObjectId("5fa6b670ff1b800180c43355"), "key" : "HL0303_20201106_000100", "video_id" : "HIiuFLswKsM", "datetime" : "20201106 000100", "name" : "不知火フレア", "title" : "【マインクラフト/Minecraft】真夜中でも楽しいマイクラ☽Midnight fun minecraft【ホロライブ/不知火フレア】", "url" : "https://www.youtube.com/watch?v=HIiuFLswKsM", "description" : "ホロ ライブ所属3期生の不知火フレア(Flare Shiranui)だよ~!磯〇~~~!地下室にプチエンド作ろうぜ!!------------------------------------------" }
{ "_id" : ObjectId("5fa6b671ff1b800180c43356"), "key" : "HL0002_20201106_000900", "video_id" : "3KAobkipFrY", "datetime" : "20201106 000900", "name" : "ロボ子さん", "title" : "【UNO】帰ってきちゃ!深夜の夜更かし #UNOLIVE ?【ホロライブ/ロボ子さん】", "url" : "https://www.youtube.com/watch?v=3KAobkipFrY", "description" : "#UNOLIVE #UNO #ホロライブメンバー@フブキCh。白上フブキ @Polka Ch. 尾丸ポルカ @Watame Ch. 角巻わため @Roboco Ch. - ロボ子 おすすめ翻訳!字幕" }
...
> exit
程序似乎没有问题,可以正常运行。
cron 的设置
我尝试使用cron来定期执行程序。
まずは、cron の状態を確認します。
$ sudo service cron status
$ または /etc/init.d/cron status
● cron.service - Regular background program processing daemon
Loaded: loaded (/lib/systemd/system/cron.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2020-11-06 19:58:59 JST; 2 days ago
Docs: man:cron(8)
Main PID: 90947 (cron)
Tasks: 1 (limit: 4671)
Memory: 7.7M
CGroup: /system.slice/cron.service
└─90947 /usr/sbin/cron -f
使用crontab命令来设置当前用户的cron。
$ crontab -e
# $ sudo crontab -e これは root の cron になります。
我将尝试设定每天执行4次,分别在5:30、11:30、17:30和23:30。
# 分 時 日 月 曜日 コマンド
30 5,11,17,23 * * * /home/mcuser/holocrawler.sh > /home/mcuser/holocrawler.log 2>&1
使用crontab命令检查当前用户的cron计划表。
$ crontab -l
我将创建一个由Cron定时执行的Shell脚本。
$ cd ~
$ touch holocrawler.sh
$ sudo chmod 755 holocrawler.sh
$ vi holocrawler.sh
#!/bin/bash
SHELL=/bin/bash
PYENV_ROOT=$HOME/.pyenv
POETRY_ROOT=$HOME/.poetry
PATH=$PYENV_ROOT/bin:$POETRY_ROOT/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
if command -v pyenv 1>/dev/null 2>&1; then
eval "$(pyenv init -)"
fi
cd ~/holocrawler
$POETRY_ROOT/bin/poetry run python main.py
为了确保,我会重新启动 cron。
$ sudo service cron restart
$ または /etc/init.d/cron restart
根据需要查阅日志(syslog)。
$ less /var/log/syslog | grep CRON
最后一句话
在设置了cron之后,过了一段时间检查了MongoDB的集合,确认定期传递的信息已成功注册。
现在,我已经完成了对于项目2中“创建并自动化收集视频发布计划所需的数据库”的任务。
继续开发用于参考 MongoDB 文档的 Web API,但是简单的 Web API 不够有趣,我想尝试一些 Azure API Apps、Azure Functions 或 Graph API 等等。