rukurxの日記

自分の日々の作業や調べたことのメモ

Pythonのrequirements.txt生成方法

pipコマンドから生成する

pip freeze > requirements.txt

この場合OSにインストールされているモジュールが対象になる。

プロジェクトで使っているモジュールのみを対象にしたい場合は仮想環境をアクティブにしてから実行する必要がある。

cd my_project
source venv/bin/activate
pip freeze > requirements.txt

Pipfile.lockから生成する

pipenv requirements > requirements.txt

pipenvの場合はlockファイルを見ているので仮想環境をアクティブにする必要がない。

開発で使ってるモジュールも含める場合は --dev オプションを付ける。

pipenv requirements --dev > dev-requirements.txt

参考

stackoverflow.com

BeanstalkでFlaskの起動サーバーにWSGIを使う

今回はWSGIの実装であるuWSGIを使う。 GunicornもあるがuWSGIの方が高機能で高速なため。

uWSGIをインストールするため、requirements.txtに追記する。

vi requirements.txt
uWSGI==2.0.20

Procfileに起動コマンドを既述する。

vi Procfile
web: uwsgi --http :8000 --wsgi-file application.py --master --processes 4 --threads 2

eb deploy すればuWSGIで起動してくれる。

Gunicornを使いたい場合も同様にProcfileに起動コマンドを記述してデプロイすればいい。 GunicornはデフォルトでサーバーにインストールされていなければuWSGI同様にインストールする。

vi Procfile
web: gunicorn --bind :8000 --workers 3 --threads 2 project.wsgi:application
vi requirements.txt
gunicorn==20.1.0

参考

docs.aws.amazon.com

qol-kk.com

BeanstalkでFlaskのAPIサーバーを構築する

  • プロジェクトフォルダを作成する
mkdir flask-prj
cd flask-prj
  • virtualenvをインストールする
pip install virtualenv
  • 仮想環境を構築する
virtualenv venv

直下に venv ディレクトリが作成される。

  • 仮想環境に入る
source virtualenv/bin/activate

または

. venv/bin/activate
  • 仮想環境を終了する
deactivate
  • デプロイ時のバンドルにvenvを含まないようにする。 デプロイ時には新しくvenvの構築がされるのでこの設定はなくてもいいが、バンドルの容量削減などに効果がある。
touch .ebignore
venv
  • Flaskをインストールする
pip install flask
  • requirements.txtファイル生成
pip freeze > requirements.txt
  • Flaskのアプリケーションを作成する application.pyを作成する
from flask import Flask

application = Flask(__name__)

@application.route("/")
def index():
    return "Hello World!"

if __name__ == "__main__":
    application.debug = True
    application.run()
  • ローカルで起動してみる
python application.py
  • Beanstalkのアプリケーションを作成する
eb init -p python-3.8 flask-prj-app --region ap-northeast-1
  • アプリケーション内に環境を構築する
eb create flask-prj-env
  • 構築した環境を開く
eb open

参考

docs.aws.amazon.com

Beanstalk の RDSにローカルから接続する。

そのままだとmysqlコマンド使えないのでec2にmysqlをインストールする

yum install mysql

sshポートフォワーディングする

ローカルの3307ポートにRDSの3306ポートを転送する

ssh -f -N -L 3307:abcdefg.ap-northeast-1.rds.amazonaws.com:3306 -i /Users/self/.ssh/aws.pem ec2-user@111.111.111.111

ローカルの3307ポートにmysqlで接続する

mysql -uroot -p -h 127.0.0.1 -P 3307
  • 終了する際はプロセスをkillする プロセスを表示する
ps -ax | grep ssh
 1306 ??         0:00.02 ssh -f -N -L 3307:abcdefg.ap-northeast-1.rds.amazonaws.com:3306 -i /Users/self/.ssh/aws.pem ec2-user@111.111.111.111

プロセスを終了する

kill 1306

参考

https://www.softel.co.jp/blogs/tech/archives/6637

EBのヘルスチェックでルートEBS ボリュームが足りてないエラー出たので拡張した

Beanstalkのヘルスチェックで以下エラーが表示されていた。

90 % of root file system is in use. 802 MB free.

どうやらルートのディスクボリュームが足りていない模様。

まずはec2にsshしてディスク容量の確認をすることに。

$ df -h
Filesystem      Size  Used Avail Use% Mounted on
devtmpfs        988M     0  988M   0% /dev
tmpfs           996M     0  996M   0% /dev/shm
tmpfs           996M   17M  979M   2% /run
tmpfs           996M     0  996M   0% /sys/fs/cgroup
/dev/xvda1      8.0G  7.3G  802M  91% /
tmpfs           200M     0  200M   0% /run/user/1000

/ (ルート)の空き容量が1GB切ってる...

パーティションの状態を確認する。

$ lsblk
NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda    202:0    0   8G  0 disk
└─xvda1 202:1    0   8G  0 part /

現在8GBある。

AWSコンソールからEBSのボリュームを増やす。 増やしたら再度確認する。

$ lsblk
NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda    202:0    0  15G  0 disk
└─xvda1 202:1    0   8G  0 part /

ボリューム全体の容量は増えたが、/ (rootのパーティション) は増えてない。

サイズを拡張する

$ sudo growpart /dev/xvda 1
CHANGED: partition=1 start=4096 old: size=16773087 end=16777183 new: size=31453151 end=31457247

$ lsblk
NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda    202:0    0  15G  0 disk
└─xvda1 202:1    0  15G  0 part /

/ (rootのパーティション) も15GBに増えてる。

ファイルシステムを確認する。

$ df -h
Filesystem      Size  Used Avail Use% Mounted on
devtmpfs        988M     0  988M   0% /dev
tmpfs           996M     0  996M   0% /dev/shm
tmpfs           996M   17M  979M   2% /run
tmpfs           996M     0  996M   0% /sys/fs/cgroup
/dev/xvda1      8.0G  7.3G  802M  91% /
tmpfs           200M     0  200M   0% /run/user/1000

ファイルシステムは8GBのままで拡張されていない。

リサイズする。

$ sudo resize2fs /dev/xvda1
resize2fs 1.42.9 (28-Dec-2013)
resize2fs: Bad magic number in super-block while trying to open /dev/xvda1
Couldn't find valid filesystem superblock.

エラーになった...

どうやら、CentOS7からファイルシステムがかわり resize2fs は使えなくなった。 代わりに xfs_growfs コマンドを使う。

$ sudo xfs_growfs /dev/xvda1
meta-data=/dev/xvda1             isize=512    agcount=4, agsize=524159 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=1 spinodes=0
data     =                       bsize=4096   blocks=2096635, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
log      =internal               bsize=4096   blocks=2560, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
data blocks changed from 2096635 to 3931643

リサイズできているか確認する。

$ df -h
Filesystem      Size  Used Avail Use% Mounted on
devtmpfs        988M     0  988M   0% /dev
tmpfs           996M     0  996M   0% /dev/shm
tmpfs           996M   17M  979M   2% /run
tmpfs           996M     0  996M   0% /sys/fs/cgroup
/dev/xvda1       15G  7.3G  7.8G  49% /
tmpfs           200M     0  200M   0% /run/user/1000

/ の容量が15GBに増えている。

参考

aws.amazon.com

Google Colaboratoryでフォルダをダウンロードする

Google Colaboratoryで学習したモデルや学習に用いたデータをダウンロードするには対象のファイルを右クリックからダウンロードを選択すればできます。 しかし、フォルダの場合は右クリックのメニューにダウンロードがないので、コードセルにコマンドやコードを書いてダウンロードする必要があります。

以下の流れで進めます。

1.対象フォルダのパスを習得する 2.フォルダを圧縮する 3.圧縮ファイルをダウンロードする

1. 対象フォルダのパスを習得する

ファイル一覧を開きダウンロードしたいフォルダ上で右クリックメニューの パスをコピー からパスを習得する。今回は sample_data 上でやったので /content/sample_data を取得しました。 全てのファイルとフォルダをダウンロードしたい場合は /content を対象のフォルダにします。

右クリックメニューでパスをコピー
パスをコピー

2. フォルダを圧縮する

Linuxのコマンドの zip を使ってフォルダを圧縮します。 Google Colabでは コードセル にコマンドを記述して実行します。 また、Google ColabでLinuxのコマンドを実行するにはコマンド行の先頭に ! を付ける必要があります。 まず、コードセル を開いてから以下コマンドを実行して content フォルダ内のコンテンツを file.zip に圧縮します。しばらくすると content フォルダ直下に file.zip が表示されます。

!zip -r /content/file.zip /content/sample_data

3. 圧縮ファイルをダウンロードする

ライブラリを使い圧縮ファイルを指定してダウンロードする。

from google.colab import files
files.download("/content/file.zip")

DockerでローカルにFlask環境を構築する

以下作成するファイル一覧。

$ tree
.
├── Dockerfile
├── app.py
├── docker-compose.yml
└── requirements.txt

まずDockerを使う前にローカルでFlaskの環境を構築する。

Flaskをインストールするため requirements.txt を作成する。

$ cat requirements.txt
Flask==2.1.2

Flaskをインストールする。

$ pip install --no-cache-dir -r requirements.txt

次にアプリケーション app.py を作成する。

from flask import Flask

app = Flask(__name__)

@app.route("/")
def index():
    return "Hello World!"

Flaskを起動する。

$ flask run
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on http://127.0.0.1:5000
Press CTRL+C to quit

http://127.0.0.1:5000 を開いて確認する。

ここまでがFlaskのアプリケーションの準備。

Dockerの環境を用意する。

まずは Dockerfile を作成する。

FROM python:3.10.7-slim-bullseye

WORKDIR /usr/src/app

ENV FLASK_APP=app.py
ENV FLASK_ENV=development

COPY requirements.txt ./

RUN pip install --upgrade pip
RUN pip install --no-cache-dir -r requirements.txt

Dockerのイメージは DOCKER OFFICIAL IMAGE から出ている slim-bullseye を使う。 Alpineの方が一般的だが、Pythonのイメージとして使う場合、ビルドが遅かったりイメージが肥大化するので非推奨とのこと。

pythonspeed.com

次に docker-compose.yml を作成する。

version: "3"
services:
  app:
    build: .
    ports:
      - "5001:5001"
    container_name: flask
    volumes:
      - ./:/usr/src/app
    command: flask run --host=0.0.0.0 --port=5001

Dockerを起動する。

$ docker-compose up

http://127.0.0.1:5001/ を開いて確認する。

Dockerfile 使わずに docker-compose.yml だけを使う場合。

version: "3"
services:
  app:
    image: python:3.10.7-slim-bullseye
    container_name: "flask"
    environment:
      - FLASK_APP=app.py
      - FLASK_ENV=development
    working_dir: /usr/src/app
    build: .
    ports:
      - "5001:5001"
    container_name: flask
    volumes:
      - ./:/usr/src/app
    command: >
      sh -c '
        pip install --upgrade pip &&
        pip install --no-cache-dir -r requirements.txt &&
        flask run --host=0.0.0.0 --port=5001
      '