WebEngine

だらだらと綴る技術系メモ

Docker for MacでPython3環境の構築

きっかけ

仕事ではPHPとか、javascriptとかばっかりいじっているので、プライベートでは仕事で使う以外の言語でなにかつくったりしよう(遊ぼう)と思い立ったのが2ヶ月前くらいでした。
機械学習とか流行ってたなあ。出来たら面白そうだなあ。日本ではそれほどだけど、世界的なシェアはかなりある言語だから、まあやって損はないかな」なんて安直な理由でPythonを勉強しはじめました。

あくまで趣味の範囲なので、Macに最初から入っている2系のPythonを使っていました。しかし、ネットに落ちている情報などを見ていると、3系のPythonで書かれたソースコードが多くなってきているように感じます。いちいち2系と3系の違いを意識しながらプログラミングするのは面倒です。

しかし、趣味の範囲と言えど、3系のPythonを直接Macに落とし込むのは2系のPythonとバッティングしそうでなんとなく怖い。

というわけでDockerで仮想環境を立てることにしました。

Docker for Mac

下のリンクからダウンロードできます。僕は安定版(Stable)の方を入れました。

ダウンロードが終了したら起動しましょう。
ターミナルからバージョンを確認しておきます。

$ docker --version
Docker version 17.06.1-ce, build 874a737
$ which docker
/usr/local/bin/docker

Docker Hubから公式イメージを入手

Docker Hubというサイトで、どのようなイメージが配布されているかチェックできます。イメージをpullしてくるだけなら登録は必要ないです。

Official(公式)のものがあったので、そのイメージを利用することにします。

上のリンクにも書いてあるのですが、docker pull python:<バージョン>のようにして、バージョン指定を行うことができます。今回は3.6を取得します。

sudo docker pull python:3.6

入れたらdocker imagesで確認しておきます。

REPOSITORY  TAG    ...
python      3.6    ...

ほかにもIMAGE_IDSIZEを見ることができるはずです。

コンテナ起動

docker run -itでコンテナを作成し、操作できます。ここでは後につづく/bin/bashでログインしています。

--name 名前でコンテナに名前をつけることもできます。ここではpytestのことを指します。

docker run -it --name pytest python:3.6 /bin/bash


入ることに成功したら、Linuxディストリビューションの情報を確認してみます。 /etc/ディストリビューション名-release/etc/issueのどちらかのファイルを見てましょう。

OSのバージョンを確認するにはuname -aコマンドを使います。

# cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 8 (jessie)"
NAME="Debian GNU/Linux"
VERSION_ID="8"
VERSION="8 (jessie)"
ID=debian
HOME_URL="http://www.debian.org/"
SUPPORT_URL="http://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"

# cat /etc/issue
Debian GNU/Linux 8 \n \l

# uname -a
Linux 0823c3a40902 4.9.41-moby #1 SMP Fri Aug 18 01:58:38 UTC 2017 x86_64 GNU/Linux

pythonのバージョンを確認すると、ちゃんと3.6が入っています。

# python --version
Python 3.6.2

pythonを管理するのに便利なpipも入っていました。ありがたい。

# pip --version
pip 9.0.1 from /usr/local/lib/python3.6/site-packages (python 3.6)

Pythonを動かしてみる

僕の場合、エディタもなにも入っていなかったので、とりあえずVimを落としてきました。Emacs派の人はEmacsを、どちらもわからない人はnanoあたりをインストールしてきて使いましょう。

ちなみに、最初にapt-get updateは実行しないとapt-getが使えないようです。

sudoコマンドも入っていなかったのでrootユーザのままでエディタをインストールします。

# apt-get update
# apt-get install -y vim


rootユーザのままだと落ち着かないので、新しくユーザをつくって、そのユーザで操作することにします。

# useradd -m pytest

上記コマンドで新規ユーザを登録できます。オプション-m/homeにユーザを作成することを指示します。このオプションをつけないとどこにユーザがつくられるかわかりません。

ls /homepytestが追加されていることを確認したらsu pytestでpytestユーザになります。変わることができたかは、コマンドライン上の#$になったかならないかで判断できます。
su - pytestのようにコマンドを実行すると、一発でpytestのホームディレクトリまで移動してくれます。


/home/pytest/にまで移動し、そこでhello.pyを作成します。

#-*- coding: utf-8 -*-
print("hello, python3")

python hello.pyで実行し、文字列が出力されればオーケイです。

※2017.09.10追記
そのままの設定だと、rootユーザでないとファイル編集できないみたいです。(Permission denied)自分はこのファイルをつくったときtootでなかったような気がするのですが、実際新しくファイルを作成してみると「rootでないとダメ」とメッセージが表示されました。ファイル作成の際は、rootユーザの状態で行ってください。

※2017.09.14追記
スミマセン、上記の件ですが、普通にいろいろいじっていただけで勘違いでした。pytestユーザでもファイルを作成できることを確認しました。

終了するには

1回目のexitでルートユーザに戻り、2回目のexitでホスト環境へ戻ってきます。

コンテナの起動・停止

docker ps -aにより、停止しているコンテナも表示することができるのですが、上記までの流れをそのままやってみると、コンテナは自動的に停止しています。(STATUS項目にExitedと表示されていれば停止しています)

コンテナを起動するにはdocker start コンテナID 、もしくはdocker start コンテナ名を使います。

docker start pytest

もう一度docker ps -aで確かめると動いているのが確認できるはずです。(その場合ExitedがUpになっている) 稼働しているので、aオプションをつけなくても表示されます。

停止するには、docker stop コンテナID、またはdocker stop コンテナ名です。

docker stop pytest

もう一度ログインする

もう一度コンテナ内に入るためにはdocker execを使います。動作中のコンテナでコマンドを実行するコマンドです。裏を返せば停止してるコンテナは操作できないということです。

docker exec -it pytest /bin/bash

入ることができたら作成したhello.pyがあることを確認してみましょう。

ホストから編集・実行

お気づきの方もいるかもしれませんが、hello.pyがあるか確認するだけならば、docker execを使えばコンテナ内に潜る必要はありません。

docker exec -it pytest ls /home/pytest

pytestコンテナに「lsコマンドを実行せよ」と命令を出しています。ここではhello.pyを作成した/home/pytest下を見ています。

ということは、このようなこともできるわけです。

docker exec -it pytest vim /home/pytest/hello.py

軽く編集してみます。

#-*- coding: utf-8 -*-
print("hello, python3")
print("hello, docker!!")

execで実行。

docker exec -it pytest python /home/pytest/hello.py

追加した文字列がホストのターミナルに出力されるかと思います。

2017.09.10追記

上記のように

docker exec -it pytest python /home/pytest/hello.py

など、ホスト側でpythonを実行したとき、エラーではないけれど変な感じで出力されるときがあるかと思います。
そういう場合は、Ctrl + lなどで一度ターミナルをクリアしてから、もう一度プログラムを実行すると、上手く出力される 可能性があります。

また

docker exec -it pytest python

とすることでpythonの対話モードが呼び出せることも確認しました。ちょっとした確認ならば、こちらを使う方が良いでしょう。

参考