Docker ubuntu Flaskアプリ用構築メモ

ubuntuPython Flaskのアプリを途中まで作ったので、
Dockerfileでdockerコンテナを構築してみた。

pyenv install 2.7.13 が動かない

dockerのイメージを作るために、
ubuntuコンテナ内でコマンドラインで作業していたら、
pyenv でpython実行環境のインストールができなかった。

root@7101ef82c1b0:~# pyenv install 2.7.13
Downloading Python-2.7.13.tar.xz...
-> https://www.python.org/ftp/python/2.7.13/Python-2.7.13.tar.xz

で止まる。エラーも出ない。

wgetがインストールされていないことが原因だった。

# apt-get install wget

# wget https://www.python.org/ftp/python/2.7.13/Python-2.7.13.tar.xz
root@7101ef82c1b0:~# pyenv install 2.7.13
Downloading Python-2.7.13.tar.xz...
-> https://www.python.org/ftp/python/2.7.13/Python-2.7.13.tar.xz
Installing Python-2.7.13...
Installed Python-2.7.13 to /root/.pyenv/versions/2.7.13

環境変数

http://qiita.com/TakashiOshikawa/items/2b8974c242a7054e0be5

コピー

http://stackoverflow.com/questions/24537340/docker-adding-a-file-from-a-parent-directory

http://qiita.com/ka2n/items/9659cb2b083ab7dcd844

Dockerfile でpip

一般ユーザーで
$ pip install appdirs
を実行したらエラー。

Installing collected packages: appdirs, beautifulsoup4, click, itsdangerous, Werkzeug, MarkupSafe, Jinja2, Flask, Flask-Script, SQLAlchemy, Flask-SQLAlchemy, lxml, pyparsing, six, packaging, requests
  Found existing installation: appdirs 1.4.3
    Uninstalling appdirs-1.4.3:
Exception:
Traceback (most recent call last):
  File "/home/user1/.local/lib/python2.7/site-packages/pip/basecommand.py", line 215, in main
    status = self.run(options, args)
  File "/home/user1/.local/lib/python2.7/site-packages/pip/commands/install.py", line 342, in run
    prefix=options.prefix_path,
  File "/home/user1/.local/lib/python2.7/site-packages/pip/req/req_set.py", line 778, in install
    requirement.uninstall(auto_confirm=True)
  File "/home/user1/.local/lib/python2.7/site-packages/pip/req/req_install.py", line 754, in uninstall
    paths_to_remove.remove(auto_confirm)
  File "/home/user1/.local/lib/python2.7/site-packages/pip/req/req_uninstall.py", line 115, in remove
    renames(path, new_path)
  File "/home/user1/.local/lib/python2.7/site-packages/pip/utils/__init__.py", line 267, in renames
    shutil.move(old, new)
  File "/usr/lib/python2.7/shutil.py", line 303, in move
    os.unlink(src)
OSError: [Errno 13] Permission denied: '/usr/local/lib/python2.7/dist-packages/appdirs-1.4.3.dist-info/DESCRIPTION.rst'

pythonの場所がpyenvのものじゃないのでおかしい。

RUN set -x eval "$(pyenv init -)"
RUN which pip

の結果が

Step 14/19 : RUN which pip
 ---> Running in fa1d2bb21a7d
/usr/bin/pip

なので、おかしい。
途中までできたdocker containerのターミナルでwhichすると.pyenvのパスになる。

$ eval "$(pyenv init -)"
$ which pip
/home/user1/.pyenv/shims/pip

apt-getでpipを入れたのがいけなかったっぽい。

RUN apt-get -y install \
            sudo \
            python-pip
Dockerfile でpip その2

まだエラーが直らない。

Removing intermediate container 96a19160fbe0
Step 19/19 : RUN pyenv global llnw &&  cd /var/www/llnw &&  pip install -r requirements.txt
 ---> Running in cc1395735ef6
Collecting beautifulsoup4==4.5.3 (from -r requirements.txt (line 2))

省略

Installing collected packages: beautifulsoup4, click, itsdangerous, Werkzeug, MarkupSafe, Jinja2, Flask, Flask-Script, SQLAlchemy, Flask-SQLAlchemy, lxml, pyparsing, requests
Exception:
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/pip/basecommand.py", line 215, in main
    status = self.run(options, args)
  File "/usr/local/lib/python2.7/dist-packages/pip/commands/install.py", line 342, in run
    prefix=options.prefix_path,
  File "/usr/local/lib/python2.7/dist-packages/pip/req/req_set.py", line 784, in install
    **kwargs
  File "/usr/local/lib/python2.7/dist-packages/pip/req/req_install.py", line 851, in install
    self.move_wheel_files(self.source_dir, root=root, prefix=prefix)
  File "/usr/local/lib/python2.7/dist-packages/pip/req/req_install.py", line 1064, in move_wheel_files
    isolated=self.isolated,
  File "/usr/local/lib/python2.7/dist-packages/pip/wheel.py", line 345, in move_wheel_files
    clobber(source, lib_dir, True)
  File "/usr/local/lib/python2.7/dist-packages/pip/wheel.py", line 316, in clobber
    ensure_dir(destdir)
  File "/usr/local/lib/python2.7/dist-packages/pip/utils/__init__.py", line 83, in ensure_dir
    os.makedirs(path)
  File "/usr/lib/python2.7/os.py", line 157, in makedirs
    mkdir(name, mode)
OSError: [Errno 13] Permission denied: '/usr/local/lib/python2.7/dist-packages/bs4'
RUN eval "$(pyenv init -)" && \
 pyenv global env1 && \
 cd /var/www/app1 && \
 pip install -r requirements.txt

のようにしたら動いた。

COPY コマンド

DockerfileのCOPYは、コマンドを実行したディレクトリ以下のファイルしかコピーできないらしい。

Step 5/5 : COPY ../ /var/www/appname1/
Forbidden path outside the build context: ../ ()

http://stackoverflow.com/questions/24537340/docker-adding-a-file-from-a-parent-directory

flaskアプリのルートにdocker.sh
プロジェクトのルートディレクトリにdocker.shファイルを作って、
そこから docker build をした。

sudo

ubuntuには、sudoというグループがある。
/etc/sudoers
に許可設定が書かれていて、このグループに入れるとsudoできるようになる。

# Allow members of group sudo to execute any command
%sudo   ALL=(ALL:ALL) ALL

起動用スクリプト

docker.sh

#!/bin/bash

APP_IMAGE_NAME=app1_image

# build image
docker build -t=$APP_IMAGE_NAME -f ./deploy/docker/Dockerfile . 

Dockerfile

# call this file from ../docker.sh

FROM ubuntu

RUN apt-get -y update
RUN apt-get -y install \
            build-essential \
            git \
            gcc \
            make \
            openssl \
            libssl-dev \
            libbz2-dev \
            libreadline-dev \
            libsqlite3-dev \
            wget \
            vim \
            python
RUN apt-get -y install \
            sudo \
            curl

RUN curl -kL https://bootstrap.pypa.io/get-pip.py | python

# TODO set password properly
RUN useradd -m -s /bin/bash user1 && \
    echo 'user1:user1' | chpasswd
RUN usermod -aG sudo user1

USER user1
ENV HOME /home/user1
RUN git clone https://github.com/yyuu/pyenv.git ~/.pyenv
RUN git clone https://github.com/yyuu/pyenv-virtualenv.git ~/.pyenv/plugins/pyenv-virtualenv
ENV PYENV_ROOT $HOME/.pyenv
ENV PATH $PYENV_ROOT/bin:$PATH
USER root
RUN echo 'export PYENV_ROOT="$HOME/.pyenv"' | tee -a /etc/profile.d/pyenv.sh
RUN echo 'export PATH="${PYENV_ROOT}/shims:${PYENV_ROOT}/bin:${PATH}"' | tee -a /etc/profile.d/pyenv.sh
USER user1

RUN pyenv install 2.7.13
RUN pyenv virtualenv 2.7.13 app1

COPY . /var/www/app1/

RUN eval "$(pyenv init -)" && \
 pyenv global app1 && \
 cd /var/www/app1 && \
 pip install -r requirements.txt

USER root
RUN chown -R user1:user1 /var/www/app1/
USER user1

RUN echo '' >> ~/.bashrc && \
 echo 'eval "$(pyenv init -)"' >> ~/.bashrc

RUN eval "$(pyenv init -)" && \
    cd /var/www/app1 && \
    python manage.py init_db

メモ

http://kubotti.hatenablog.com/entry/2017/02/08/110755

https://mzmttks.blogspot.jp/2011/12/python-site-packagesdist-packages.html

http://qiita.com/erscl/items/8d17b9d2d7a6a2ca0a57

http://cheng.logdown.com/posts/2015/06/14/-usr-bin-pip-no-such-file-or-directory