_log

備忘録

VagrantでPython開発環境

今更ながらVagrantでローカル開発用のベースをさっくり作り直したので備忘用ログ
DebianにPython3入れて、pyvenv上でFlaskを実行する

環境

インストールは略

Add box & Initialize

$ vagrant box add debian/jessie64
---(略)---
$ vagrant box list
debian/jessie64 (virtualbox, 8.4.0)

boxを追加して

$ vagrant init debian/jessie64

初期化する。VagrantFileができる

VagrantFile編集

gist.github.com

まんまだけど、

  • boxの指定
  • プライベートIPの設定
  • 同期フォルダの指定
  • プロビジョニング用のスクリプト指定

を行っている 

provision/script.sh作成

スクリプト書く

gist.github.com

Python3インストール

現在3.5.1が最新
Debian8だとまだPython2がデフォルト
今回は試しにビルドしてインストールしてみた
(パス周りとか危うい気がするが...)

ちなみにPython3がデフォルトになるのもそろそろらしい

Debian 9 (Stretch) または10 (Buster) でPython 3をデフォルトにするべく作業が始まっている。 http://orangain.hatenablog.com/entry/python3-as-default

パスワードプロンプトの省略

MySQL周りでパスワードの入力を求められる。debconf-utilsでこれに対応する
これも開発環境なのでまぁよしということで..

apt-get

適当に使いそうなもの入れる

Hello Vagrant

起動&プロビジョニングして、sshで接続

$ vagrant up
---(略)---
$ vagrant ssh
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Thu May 19 15:31:52 2016 from 10.0.2.2
vagrant@debian-jessie:~$

ログインできた 。諸々の確認&作業

Python

vagrant@debian-jessie:~$ python3
Python 3.5.1 (default, May 18 2016, 18:15:52)
[GCC 4.9.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> print('Hello Vagrant')
Hello Vagrant

pyvenv

vagrant@debian-jessie:~$ pyvenv venv
vagrant@debian-jessie:~$ source venv/bin/activate
(venv) vagrant@debian-jessie:~$ python -V
Python 3.5.1

pip

(venv) vagrant@debian-jessie:~$ pip list
pip (7.1.2)
setuptools (18.2)
You are using pip version 7.1.2, however version 8.1.2 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
(venv) vagrant@debian-jessie:~$ pip install --upgrade pip
---(略)---
Successfully installed pip-8.1.2

ネットワーク

(venv) vagrant@debian-jessie:~$ sudo ifconfig
eth0      Link encap:Ethernet  HWaddr 08:00:27:1e:c6:7e
          inet addr:10.0.2.15  Bcast:10.0.2.255  Mask:255.255.255.0
          inet6 addr: fe80::a00:27ff:fe1e:c67e/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:158984 errors:0 dropped:0 overruns:0 frame:0
          TX packets:20658 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:206872864 (197.2 MiB)  TX bytes:3140153 (2.9 MiB)

eth1      Link encap:Ethernet  HWaddr 08:00:27:c6:95:d1
          inet addr:192.168.33.10  Bcast:192.168.33.255  Mask:255.255.255.0
          inet6 addr: fe80::a00:27ff:fec6:95d1/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:54 errors:0 dropped:0 overruns:0 frame:0
          TX packets:22 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:8863 (8.6 KiB)  TX bytes:1910 (1.8 KiB)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

VagrantFileで指定したプライベートネットワークが追加されている
これを通じて、ゲストとホストのみでやり取りする

Flask on Vagrant

Flaskを起動して、ホストからアクセスできるか試す

(venv) vagrant@debian-jessie:~$ pip install flask
---(略)---
(venv) vagrant@debian-jessie:~$ cat src/hello.py
from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return "Hello Vagrant!"

if __name__ == '__main__':
    app.run(host='0.0.0.0')

(venv) vagrant@debian-jessie:~$ python src/hello.py
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)

この状態でブラウザから(http://192.168.33.10:5000/)アクセェェェス!!
「Hello Vagrant!」が表示される

続き

Flask(on Vagrant)でモック開発のための骨組みを作る - nanahara.log

参考

Dockerことはじめ

FlaskをDockerコンテナ上で起動させるところまで

インストール

Docker ToolBoxでインストール

環境変数

.zshrcに↓を追加

echo "eval $(docker-machine env default)" >> ~/.zshrc

ない場合はDockerQuickstartTerminal.appを都度叩く形になる? 参考までにない時に出るエラー

$ docker images
Cannot connect to the Docker daemon. Is the docker daemon running on this host?

Get started with Docker Machine and a local VM - Docker

Command

オプション付コマンドを雑にメモ

最後に実行したコンテナのIDのみ表示

docker ps -l -q

Dockerfileからイメージを構築

docker build -t docker_sample .

イメージを起動して、exitしたらコンテナを壊す

docker run -it --rm docker_sample bash

コンテナの一括削除

docker rm `docker ps -a -q`

Dockerfile

サンプルとしてGit,Vim,Python関連

gist.github.com

--no-install-recommendはイメージを軽量にするためやっておいた方が良さそう

FlaskをDocker上で動かす

最低限で動かす

+ web
  - app.py
  - requirements.txt
- 

web/app.py Flaskのサンプル。ほぼhttp://flask.pocoo.org/より

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello():
    return 'Hello World!'

if __name__ == '__main__':
    app.run(debug=True, host=)

web/requirement/txt

Flask

docker-compose

docker-composeを使うと複数コンテナ管理をyamlで行うことができる 今回は複数使わないけど、こちらでやってみる

以下がdocker-composeが必要になった経緯が分かりやすい

docker-composeを使うと複数コンテナの管理が便利に - Qiita docker-compose.yml

web:
  build: ./web
  ports:
   - "5000:5000"
  volumes:
   - .:/code

いざup

$ docker-compose up

デフォルトのIPを以下で確認して、アクセスする(今回はhttp://192.168.99.100:5000/ )と「HelloWorld!」が表示される

$ docker-machine ip default
192.168.99.100

Tips

15 Docker Tips in 5 MinutesでTipsが紹介されている。例えばこんなalias

echo "alias dl='docker ps -l -q'" >> ~/.zshrc

雑感

永続化周りとか、構成管理系のツールとの組み合わせベストプラクティスとかどういうのが主流なのかな

開発環境として使ってみたかったけど、Vagrant+Ansibleとかでとりあえず良い気がしてきた

参考

Dockerのライフサイクルを理解するハンズオン資料

Effective Python 読んだ感想

Effective Python ―Pythonプログラムを改良する59項目

Effective Python ―Pythonプログラムを改良する59項目

Python歴約1年の今、以下の2点を目的として読んだ

  • 現状の知識整理
  • Pythonic Thinkingについて学習

本書はその目的に沿う本で、今のタイミングで読むことができて良かった

以下、トピック毎に軽く感想

PEP8スタイルガイド

  • 項目2 PEP8スタイルガイドに従う

Python始めた時に、最初にいいなと思ったのがPEP8(とThe Zen of Python)だった
本質から離れた箇所に体力を使わないのはとても良い
特にチーム開発において、ある程度統一したスタイルでコードを書くことは生産性の向上に繋がる
flake8とか、チェッカーを使うと更に幸せ。エディタでも検知できる仕組みが色々ある

リスト内包表記

  • 項目7 mapやfilterの代わりにリスト内包表記を使う
  • 項目8 リスト内包表記には、3つ以上の式を避ける
  • 項目9 大きな内包表記にはジェネレーター式を考える

Pythonでもリスト内包表記が使用可能で、
最初は少し戸惑うかもしれないけれど、慣れればコードがシンプルになる
節度は守るべしで、そのバランス感覚についての話

イテレータ

  • 項目16 リストを返さずにイテレータを返すことを考える
  • 項目17 引数に対してイテレータを使う時には確実さを尊ぶ

イテレータプロトコル(__iter__メソッドの実装)が面白い
複数回呼び出されることを許容できるケースにあまり出くわさなそうではある

メタクラス

イマイチ理解しきれていなかったメタクラスだが、
具体的なケースでどのように使われるかが紹介されていて分かりやすい

実際どのように使われているのか気になって、GitHubで探してたら
例えばFlaskだと↓のように使われている
https://github.com/pallets/flask/blob/740c42217cb349ab4f03ecba37973ec0c9bed421/flask/views.py#L105-L120

ツール

  • 項目56 unittestですべてをテストする
  • 項目57 pdbで対話的にデバッグすることを考える
  • 項目58 最適化の前にプロファイル
  • 項目59 メモリの使用とリークを理解するにはtracemallocを使う

Pythonの組み込みモジュールはデバッグ、テスト、最適化まで提供されている
言語仕様だけでなく、組み込みモジュールまで一貫して機能が揃えようとしていることにもPythonの思想を感じられて良い
他にもプログラム周りの組み込みモジュールについては第6章で取り上げられている

おわりに

全部取り上げると無駄に長編になってしまうのでこの辺で…
他にも様々な思想やTipsが取り上げらているが、どれもPythonicな考えが染み込んでいる
理解を深めるために別途手を動かしながら読み直したい。特に第5章