KATOエンジニヤリング開発日誌

「アウトプット無きエンジニアにインプットもチャンスも無い」の精神で書いています

conohaVPSでDjango開発環境を構築する

現在、個人的に進めているプロジェクトのためにconohaVPSでサーバーを構築し、DjangoでWebアプリケーションを作成していきます。

「vibakari*1」というカテゴリーは、自分がDjangoWebアプリケーションを作成するまでの記録として何回かに分けて記事にしていきます。

第1回はconohaVPSでDjangoのWebアプリケーション開発環境を構築するまでを記録します。

参考図書として下記の本を参照しています。

Two Scoops of Django: Best Practices for Django 1.8

Two Scoops of Django: Best Practices for Django 1.8

入門 Python 3

入門 Python 3

環境概要

  • ホストマシン
    • MacBookPro macOS Sierra
  • サーバOS
    • CentOS 7.3
  • python
  • Webフレームワーク
    • django
  • データベース
    • MariaDB
  • Webサーバ
    • nginx

conohaでVPSサーバを作成

f:id:masayuki_kato:20170511225827p:plain

  • タイプ
    • VPS
  • リージョン
    • 東京
  • メモリ
    • 1GB

f:id:masayuki_kato:20170511225838p:plain

  • イメージタイプ
    • OS
  • OS
    • CentOS
  • バージョン
    • 7.3(64bit)

f:id:masayuki_kato:20170511225845p:plain

  • 自動バックアップ
    • 無効
  • 追加ディスク
    • 切断
  • 接続許可ポート IPv4
    • SSH(22)
    • Web(20/21/80/443)
    • PostgreSQL(5432)
  • 接続許可ポート IPv6
    • SSH(22)
    • Web(20/21/80/443)
    • PostgreSQL(5432)
  • SSH Key
    • Keyを作成してダウンロードする

上記の設定後、画面下部の「追加」ボタンを押下すると、「サーバーリスト」画面に遷移する。

f:id:masayuki_kato:20170511231049p:plain

ステータスが「起動中」になるとサーバ構築が完了となる。

Python 3系のインストール

サーバーリスト画面から作成したサーバのネームタグをクリックすると、作成したサーバのネットワーク情報が表示されるので、IPアドレスを確認してターミナルソフトを利用してSSH接続する。

1. サーバにSSH接続する(ホストマシン側)

サーバ作成の際に作成し、ダウンロードしたkeyをホストマシンの「.ssh」ディレクトリにコピーする。

# ダウンロードしたkeyが「/Users/[ユーザ名]/Downloads」ディレクリにある場合
cd ~/.ssh
cp /Users/masayuki_kato/Downloads/[認証鍵名] ./

認証鍵が.sshディレクトリに格納されたら下記コマンドを入力し、サーバにssh接続する。

ssh -i [認証鍵名] root@[IPv4アドレス]

2.Python3系をインストール(サーバ側)

CentOS7.3はデフォルトでPythonがインストールされているが、バージョンは「2.7.5」だった。

[root@[IPv4 address] ~]# python --version
Python 2.7.5

バージョン「3.5.3」をダウンロードするために、下記コマンドを実行する。

[root@[IPv4 address] ~]# yum install -y https://centos7.iuscommunity.org/ius-release.rpm
[root@[IPv4 address] ~]# yum search python35
[root@[IPv4 address] ~]# yum install -y python35u python35u-libs python35u-devel python35u-pip
[root@[IPv4 address] ~]# ln -s /bin/python3.5 /bin/python3
[root@[IPv4 address] ~]# unlink /bin/python
[root@[IPv4 address] ~]# ln -s /bin/python3 /bin/python
[root@[IPv4 address] ~]# ln -s /bin/pip3.5 /bin/pip
[root@[IPv4 address] ~]# python --version
Python 3.5.3

最終的に「python –version」コマンドの実行時に「Python3.5.3」が返ってくれば成功。

作業用のユーザ作成

[root@[IPv4 address] ~]# useradd masayuki
[root@[IPv4 address] ~]# passwd masayuki
ユーザー masayuki のパスワードを変更。
新しいパスワード:
新しいパスワードを再入力してください:
passwd: すべての認証トークンが正しく更新できました。
# 作成したユーザが「sudo」コマンドを使えるようにする
[root@[IPv4 address] ~]# usermod -G wheel masayuki

pyvenvで仮想実行環境を構築

pyvenvは利用するパッケージやpythonのバージョンをプロジェクト単位で切り替えることができる仮想実行環境を作成することができるツールです。

python3系ではデフォルトで用意されているのでインストールは不要。

# ユーザを作業用のユーザに変更
[root@[IPv4 address] ~]# su - masayuki
[masayuki@[IPv4 address] ~]# pwd
/home/masayuki
# アプリ用のディレクトリを作成
[masayuki@[IPv4 address] ~]# mkdir djang_app
[masayuki@[IPv4 address] ~]# cd djang_app/
# vibakari用の仮想環境を構築
[masayuki@[IPv4 address] djang_app]# pyvenv-3.5 vibakari
[masayuki@[IPv4 address] djang_app]# ls -la
total 4
drwxrwxr-x 5 masayuki masayuki 4096 May 14 21:57 vibakari
# 作成した仮想実行環境を読み込む
[masayuki@[IPv4 address] djang_app]# source vibakari/bin/activate
(vibakari) [masayuki@[IPv4 address] djang_app]$ python --version
Python 3.5.3
(vibakari) [masayuki@[IPv4 address] djang_app]$ which python
~/djang_app/vibakari/bin/python
# 仮想実行環境から抜ける
(vibakari) [masayuki@[IPv4 address] djang_app]$ deactivate
# 再度仮想実行環境を読み込む
[masayuki@[IPv4 address] djang_app]$ source vibakari/bin/activate
(vibakari) [masayuki@[IPv4 address] djang_app]$

以降は仮想実行環境に入った状態で進める。

MariaDBのインストール

(vibakari) [masayuki@[IPv4 address] djang_app]$ sudo yum install -y mariadb-server mariadb-devel
  File "/bin/yum", line 30
    except KeyboardInterrupt, e:
                            ^
SyntaxError: invalid syntax

SyntaxErrorが発生したので原因を調査してみた。

yumが死ぬ件 : hayashikunsan

yumはpythonで動いているらしいので、先ほどpython3系をインストールするときに「ln」コマンドで設定を変えたことが原因っぽい。

# pythonのシンボリックリンクを確認
(vibakari) [masayuki@[IPv4 address] djang_app]$ ls -la | grep python
lrwxrwxrwx   1 root root         12 May 11 23:47 python -> /bin/python3
# yumの設定ファイルを編集する
(vibakari) [masayuki@[IPv4 address] djang_app]$ sudo vim /usr/bin/yum

/usr/bin/yumの設定ファイルの内容

#!/usr/bin/python2.7
import sys
try:
    import yum
except ImportError:
    print >> sys.stderr, """\
There was a problem importing one of the Python modules
required to run yum. The error leading to this problem was:

... 以下、省略

設定ファイルの1行目「#!/usr/bin/python」を「#!/usr/bin/python2.7」に変更する。

再度、MariaDBのインストールコマンドを実行する。

(vibakari) [masayuki@[IPv4 address] djang_app]$ sudo yum install -y mariadb-server mariadb-devel
Loaded plugins: fastestmirror, langpacks
base                                                                                                        | 3.6 kB  00:00:00
epel/x86_64/metalink                                                                                        | 6.3 kB  00:00:00
epel                                                                                                        | 4.3 kB  00:00:00
epel-debuginfo/x86_64/metalink                                                                              | 6.5 kB  00:00:00
epel-debuginfo                                                                                              | 3.0 kB  00:00:00
epel-source/x86_64/metalink                                                                                 | 6.3 kB  00:00:00
epel-source                                                                                                 | 3.5 kB  00:00:00
extras                                                                                                      | 3.4 kB  00:00:00
ius                                                                                                         | 2.3 kB  00:00:00
updates                                                                                                     | 3.4 kB  00:00:00
  File "/usr/libexec/urlgrabber-ext-down", line 28
    except OSError, e:
                  ^
SyntaxError: invalid syntax


Exiting on user cancel

先ほどのエラーは解消したが、別のエラーが発生したので再度調査。

How to switch between Python versions on Fedora Linux - LinuxConfig.org

pythonのデフォルトのグローバルバージョンに関連したエラーらしい。

「/usr/libexec/urlgrabber-ext-down」ファイルの冒頭にあるpythonのバージョンを2.7に指定してあげる。

(vibakari) [masayuki@[IPv4 address] djang_app]$ sudo vim /usr/libexec/urlgrabber-ext-down

/usr/libexec/urlgrabber-ext-downの設定ファイルの内容

#! /usr/bin/python2.7
#  A very simple external downloader
#  Copyright 2011-2012 Zdenek Pavlas

... 以下、省略

設定ファイルの1行目「#! /usr/bin/python」を「#! /usr/bin/python2.7」に変更する。

再々度、MariaDBのインストールコマンドを実行する。

(vibakari) [masayuki@[IPv4 address] djang_app]$ sudo yum install -y mariadb-server mariadb-devel
Loaded plugins: fastestmirror, langpacks
Loading mirror speeds from cached hostfile
 * base: ftp.iij.ad.jp
 * epel: ftp.riken.jp
 * epel-debuginfo: ftp.riken.jp
 * epel-source: ftp.riken.jp
 * extras: ftp.iij.ad.jp
 * ius: mirrors.tuna.tsinghua.edu.cn
 * updates: ftp.iij.ad.jp
(1/4): epel-debuginfo/x86_64/primary_db                                                                     | 620 kB  00:00:00
(2/4): epel-source/x86_64/primary_db                                                                        | 1.7 MB  00:00:00
(3/4): epel/x86_64/primary_db                                                                               | 4.7 MB  00:00:00
(4/4): ius/x86_64/primary_db

... 中略

Installed:
  mariadb-server.x86_64 1:5.5.52-1.el7

Dependency Installed:
  mariadb.x86_64 1:5.5.52-1.el7          perl-Compress-Raw-Bzip2.x86_64 0:2.061-3.el7  perl-Compress-Raw-Zlib.x86_64 1:2.061-4.el7
  perl-DBD-MySQL.x86_64 0:4.023-5.el7    perl-DBI.x86_64 0:1.627-4.el7                 perl-Data-Dumper.x86_64 0:2.145-3.el7
  perl-IO-Compress.noarch 0:2.061-2.el7  perl-Net-Daemon.noarch 0:0.48-5.el7           perl-PlRPC.noarch 0:0.2020-14.el7

Complete!

MariaDBのインストールが完了したので、pythonでMariaDBを操作する「mysqlclient」パッケージをインストールする。

(vibakari) [masayuki@[IPv4 address] djang_app]$ sudo yum -y install python-devel mysql-devel
(vibakari) [masayuki@[IPv4 address] djang_app]$ sudo pip install mysqlclient
Collecting mysqlclient
  Downloading mysqlclient-1.3.10.tar.gz (82kB)
    100% |████████████████████████████████| 92kB 9.7MB/s
Installing collected packages: mysqlclient
  Running setup.py install for mysqlclient ... error

...中略

    unable to execute 'gcc': No such file or directory
    error: command 'gcc' failed with exit status 1

    ----------------------------------------
Command "/usr/bin/python3.5 -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-yzt89rtn/mysqlclient/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /tmp/pip-lg8y26oc-record/install-record.txt --single-version-externally-managed --compile" failed with error code 1 in /tmp/pip-build-yzt89rtn/mysqlclient/

pipでCエクステンションビルドに必要なものが足りなくてエラーが発生しているもよう。

下記コマンドで必要なパッケージを取得してあげ、再度mysqlclientをpipでインストールする。

(vibakari) [masayuki@[IPv4 address] djang_app]$  sudo yum -y install gcc gcc-c++ kernel-devel

... 省略

Installed:
  gcc.x86_64 0:4.8.5-11.el7           gcc-c++.x86_64 0:4.8.5-11.el7           kernel-devel.x86_64 0:3.10.0-514.16.1.el7

Dependency Installed:
  cpp.x86_64 0:4.8.5-11.el7                     glibc-devel.x86_64 0:2.17-157.el7_3.1   glibc-headers.x86_64 0:2.17-157.el7_3.1
  kernel-headers.x86_64 0:3.10.0-514.16.1.el7   libmpc.x86_64 0:1.0.1-3.el7             libstdc++-devel.x86_64 0:4.8.5-11.el7
  mpfr.x86_64 0:3.1.1-4.el7

Complete!
(vibakari) [masayuki@[IPv4 address] djang_app]$ sudo pip install mysqlclient
[sudo] password for masayuki:
Collecting mysqlclient
  Using cached mysqlclient-1.3.10.tar.gz
Installing collected packages: mysqlclient
  Running setup.py install for mysqlclient ... done
Successfully installed mysqlclient-1.3.10

mysqlclientのインストールが成功した。

次はMariaDBを起動してrootユーザでログインしてみる。

(vibakari) [masayuki@[IPv4 address] djang_app]$ sudo systemctl start mariadb
(vibakari) [masayuki@[IPv4 address] djang_app]$ sudo systemctl enable mariadb
(vibakari) [masayuki@[IPv4 address] djang_app]$ mysql -u root
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 2
Server version: 5.5.52-MariaDB MariaDB Server

Copyright (c) 2000, 2016, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> exit
Bye

nginxのインストール

nginx yumレポジトリを追記する。

(vibakari) [masayuki@[IPv4 address] djang_app]$ sudo vim /etc/yum.repos.d/nginx.repo

# vimで開いた(作成した)ファイルに下記を記載する
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=0
enabled=1

yumコマンドでnginxをインストールする。

(vibakari) [masayuki@[IPv4 address] djang_app]$ sudo yum install -y nginx

...省略

  Verifying  : 1:nginx-1.13.0-1.el7.ngx.x86_64                                      1/1

Installed:
  nginx.x86_64 1:1.13.0-1.el7.ngx

Complete!

(vibakari) [masayuki@[IPv4 address] djang_app]$ nginx -v
nginx version: nginx/1.13.0

nginxを起動する。

(vibakari) [masayuki@[IPv4 address] djang_app]$ sudo systemctl start nginx.service
(vibakari) [masayuki@[IPv4 address] djang_app]$ sudo systemctl enable nginx.service
Created symlink from /etc/systemd/system/multi-user.target.wants/nginx.service to /usr/lib/systemd/system/nginx.service.

インストール直後のnginxの設定ファイルを確認する。

(vibakari) [masayuki@[IPv4 address] djang_app]$ less  /etc/nginx/nginx.conf

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    # includeディレクティブで指定したファイルもnginxの設定ファイルとなる
    include /etc/nginx/conf.d/*.conf;
}

includeディレクティブで指定されている「/etc/nginx/conf.d/」ディレクトリ配下の末尾に「.conf」とつくファイルもnginxの設定ファイルになるので、そちらも確認する。

(vibakari) [masayuki@[IPv4 address] djang_app]$ less /etc/nginx/conf.d/default.conf

server {
    listen       80;
    server_name  localhost;

    #charset koi8-r;
    #access_log  /var/log/nginx/log/host.access.log  main;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    #location ~ \.php$ {
    #    root           html;
    #    fastcgi_pass   127.0.0.1:9000;
    #    fastcgi_index  index.php;
    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    #    include        fastcgi_params;
    #}

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}

「location / 」ディレクティブで指定されているindex.htmlファイルにアクセスできるか確認する。

はじめに、「/usr/share/nginx/html/index.html」ファイルの内容を確認する。

(vibakari) [masayuki@[IPv4 address] djang_app]$ less /usr/share/nginx/html/index.html

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

次に「http://[IPアドレス]」にアクセスして、上記のindex.htmlファイルの内容が表示されることを確認する。

IPアドレスはConoHaのコントロールパネルから確認できる。

f:id:masayuki_kato:20170521233539p:plain

以上でnginxの構築が完了した。

Djangoのインストール

pipを利用してDjangoのインストールを行う。

(vibakari) [masayuki@[IPv4 address] djang_app]$ pip install django
Collecting django
  Downloading Django-1.11.1-py2.py3-none-any.whl (6.9MB)
    100% |████████████████████████████████| 7.0MB 175kB/s
Collecting pytz (from django)
  Downloading pytz-2017.2-py2.py3-none-any.whl (484kB)
    100% |████████████████████████████████| 491kB 1.6MB/s
Installing collected packages: pytz, django
Successfully installed django-1.11.1 pytz-2017.2

uWSGIのインストール

djangoで開発したWebアプリケーションとWebサーバーを連動させるインタフェースであるuWSGI*2をインストールする。

(vibakari) [masayuki@[IPv4 address] djang_app]$ pip install uwsgi
Collecting uwsgi
  Downloading uwsgi-2.0.15.tar.gz (795kB)
    100% |████████████████████████████████| 798kB 1.2MB/s
Installing collected packages: uwsgi
  Running setup.py install for uwsgi ... done
Successfully installed uwsgi-2.0.15

pipでインストールしたソフトウェアの確認

(vibakari) [masayuki@[IPv4 address] djang_app]$ pip list
Django (1.11.1)
pip (9.0.1)
pytz (2017.2)
setuptools (28.8.0)
uWSGI (2.0.15)

*1:vibakariは今回作成しようとしているWebアプリケーション名です

*2:WSGIはWeb Server Gateway Interfaceと呼ばれる