VPS(Vultr)デプロイチュートリアル
自己紹介
プログラミング講師の飼鳥晴康(@hathle)です。
エンジニア歴は10年以上で海外(カナダ)就労も経験しています。
カナダでは、映画を作っていました。
現在は、独立して、Python、Djangoをメインにオンラインでマンツーマンレッスンをしています。
お問い合わせなどは、Twitter(@hathle)からお願いいたします。
プログラミングは人生を変えることができます。
目標に向かって、一緒に頑張っていきましょう!!
はじめに
VPS(Vultr)を契約してDjangoをデプロイしましょう。
VPSとは?
VPSはVirtual Private Serverの略です。
仮想専用サーバーになります。
ユーザー毎の専用領域を作成して使用します。
一からサーバーを構築するので、インフラの知識が必要になってきます。
VPSはVultrを利用します。
上記のリンクから登録すると、$100無料です。
Zenn
Zennのチュートリアルは見やすくなっています。
目標
下記を学習していきます。
・VPS契約
・サーバー構築方法
・公開方法
・ドメイン取得
前提知識
デプロイを始める前に、下記は学習しておいて下さい。
・Linuxコマンド
・インフラ
・サーバー構築
ブログ構成チュートリアルでDjangoを詳しく説明していますので、まだ実施していない方は、実施して下さい。
では、始めて行きましょう!!
Vultrサーバー構築
Vultrでサーバーを構築する準備をします。
Vultrとは?
Vultrはオーストラリアの会社が運営している格安VPSになります。
安くて高性能なので多くの人が利用しています。
Vultrの特徴
・初期費用がない
・東京リージョンがある
・コントロールパネルが使いやすい
・ファイヤーウォールの設定が可能
・料金が安い
・高性能で早い
アカウント登録
Vultrでアカウントを作成します。
Vultrを使用するには、クレジットカードを登録する必要があります。
登録しても勝手に課金されることはないので安心してください。
メールアドレスの認証もしておいてください。
sshキー作成
ローカルでsshキーを作成します。
$ ssh-keygen -t rsa
sshキーをcatコマンドで表示できるので、コピーします。
$ cat ~/.ssh/id_rsa.pub
sshキー登録
vultrにログインして、コピーしたsshキーを登録します。
ファイヤーウォール設定
ProductsのFirewall画面に遷移して、プラスボタンをクリックします。
Descriptionに適当な名前を入力します。
下記のように登録します。
・ssh:22番
・http:80番
・https:443番
・mysql:3306番
VPSレンタル
VPSをレンタルします。
ProductsのInstances画面に遷移して、プラスボタンをクリックします。
インスタンスの種類を順番に選択していきます。
・Choose Server:Cloud Compute
・Server Location:Tokyo
・Server Type:Ubuntu 18.04
・Server Size:$5
・SSH Keys:先ほど登録したsshキー
・Firewall Group:先ほど登録したfirewall
Deploy Nowをクリックすると、インスタンスが作成されます。
インスタンスができると、サーバーの情報を表示することができます。
IPアドレスと管理パスワードはメモしておきます。
ログイン
ローカルのターミナルから、vultrのVPSサーバーにログインできるか試してみましょう。
xxx.xxx.xxx.xxxは作成したIPアドレスになります。
$ ssh root@xxx.xxx.xxx.xxx
ユーザー作成
rootでログインできたら、ユーザーを作成します。
パスワードは表示されないので、慎重に入力してください。
英数字、記号も混じっていないとはじかれると思います。
user infomationは全部Enterを押して進行します。
・Full Name []:
・Room Number []:
・Work Phone []:
・Home Phone []:
・Other []:
root@vultr:~# adduser haruyasu
ユーザー権限変更
ユーザーにsudo権限を与えます。
root@vultr:~# gpasswd -a haruyasu sudo
ユーザーでログイン
root@vultr:~# su haruyasu
アップデート
haruyasu@vultr:~$ sudo apt update
haruyasu@vultr:~$ sudo apt upgrade
haruyasu@vultr:~$ sudo apt install nginx python3-pip python3-venv
作業用のフォルダ作成
作業用のフォルダを作成し、ここにプロジェクトをおくようにすると整理しやすくなります。
haruyasu@vultr:~$ mkdir src
VSCodeでログイン
VSCodeにRemote SSHというプラグインがあるので、ダウンロードしましょう。
Remote SSHを使用すると、VSCodeがVultrに接続できるので、フォルダが見れるようになります。
このコマンドでアクセスできます。
ssh haruyasu@xxx.xxx.xxx.xxx
デプロイ設定
デプロイに必要な設定をします。
ローカルで開発しているだけでは設定を変える必要はないですが、デプロイするとなると、セキュリティ面を考慮して設定を変更する必要があります。
.gitignore
GitHubにコミットしないように、追加します。
.gitignore
myvenv
db.sqlite3
.vscode
__pycache__
*.pyc
.DS_Store
images
media
local_settings.py
.env
requirements.txt
django-environとgunicornを追加します。
requirements.txt
Django~=2.2.10
Pillow~=2.2.1
django-widget-tweaks~=1.4.8
django-environ~=0.4.5
gunicorn~=20.0.4
settings
settingsを下記のように変更します。
本番環境ではDEBUGをFalseに設定し、envファイルからパスワードなどの重要な値を取得するようにします。
mysite/settings.py
import os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app',
'widget_tweaks',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'mysite.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'mysite.wsgi.application'
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
LANGUAGE_CODE = 'ja'
TIME_ZONE = 'Asia/Tokyo'
USE_I18N = True
USE_L10N = True
USE_TZ = True
STATIC_URL = '/static/'
MEDIA_URL = '/media/'
# デプロイ設定
DEBUG = False
try:
from .local_settings import *
except ImportError:
pass
# ローカル用設定
if DEBUG:
ALLOWED_HOSTS = ['*']
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
if not DEBUG:
import environ
env = environ.Env()
env.read_env(os.path.join(BASE_DIR,'.env'))
SECRET_KEY = env('SECRET_KEY')
ALLOWED_HOSTS = env.list('ALLOWED_HOSTS')
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587
EMAIL_HOST_USER = env('EMAIL_HOST_USER')
EMAIL_HOST_PASSWORD = env('EMAIL_HOST_PASSWORD')
EMAIL_USE_TLS = True
STATIC_ROOT = '/usr/share/nginx/html/static'
MEDIA_ROOT = '/usr/share/nginx/html/media'
コード解説
STATIC_ROOTとMEDIA_ROOTをnginxのディレクトリに設定します。
アップロードした画像は、nginxのmediaフォルダに直接アップデートされます。
STATIC_ROOT = '/usr/share/nginx/html/static'
MEDIA_ROOT = '/usr/share/nginx/html/media'
local_settings
ローカル用のsettingsファイルを用意します。
DEBUGはTrueにして、シークレットキーを追加しておきます。
mysite/local_settings.py
DEBUG = True
SECRET_KEY = 'xxxxxxxxxxxxxxxxxxxxxxxxxxx'
urls
画像を使用する場合は、if settings.DEBUG:として判定します。
mysite/urls.py
from django.contrib import admin
from django.urls import path, include
from django.conf.urls.static import static
from django.conf import settings
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('app.urls')),
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
env
環境設定ファイルを用意します。
ローカルでは必要ないですが、本番環境で使用するために、準備しておきます。
ルートディレクトリに.envファイルを作成します。
.env
SECRET_KEY=xxxxxxxxxxxxxxxx
ALLOWED_HOSTS=127.0.0.1,xxx.xxx.xxx.xxx,yourdomain.com
EMAIL_HOST_USER=xxxxx@gmail.com
EMAIL_HOST_PASSWORD=xxxxxxxx
コード解説
ALLOWED_HOSTS はVultrのIPアドレスとドメインを指定します。
ALLOWED_HOSTS=127.0.0.1,xxx.xxx.xxx.xxx,yourdomain.com
デプロイ
デプロイ用の設定が完了したので、デプロイしていきます。
サーバーの構成は、クライアント → Nginx → gnicorn → djangoとなります。
クローン
アプリケーションをGitHubからクローンします。
cd
mkdir src
cd src
git clone https://github.com/xxxx/deploytest.git
cd deploytest
仮想環境構築
仮想環境を構築します。
haruyasu@vultr:~/src/deploytest$ python3 -m venv myvenv
仮想環境実行
仮想環境を実行します。
haruyasu@vultr:~/src/deploytest$ source myvenv/bin/activate
最新pipコマンド
最新にアップデートしておきます。
(myvenv) haruyasu@vultr:~/src/deploytest$ pip3 install --upgrade pip setuptools
パッケージのインストール
requirements.txtに記載されたパッケージがインストールされます。
(myvenv) haruyasu@vultr:~/src/deploytest$ pip3 install -r requirements.txt
Nginxディレクトリ作成
staticとmediaフォルダを作成します。
$ sudo mkdir /usr/share/nginx/html/static
$ sudo mkdir /usr/share/nginx/html/media
静的ファイル収集
Nginxで静的ファイルを読み込むには、下記コマンドでまとめます。
staticにあるCSSや画像を変更した場合は、必ずこのコマンドが必要になります。
このコマンドを実行するために、仮想環境ではなく直接サーバーにDjangoをインストールして下さい。
(myvenv) haruyasu@vultr:~/src/deploytest$ sudo python3 manage.py collectstatic
マイグレート
マイグレートをしておきます。
(myvenv) haruyasu@vultr:~/src/deploytest$ python3 manage.py migrate
Nginx設定
Nginxの設定を修正します。
$ sudo nano /etc/nginx/sites-available/default
デフォルトの設定を下記のように書き換えます。
Ctrl + Xで保存することができます。
server {
listen 80;
server_name xxx.xxx.xxx.xxx;
location /static {
alias /usr/share/nginx/html/static;
}
location /media {
alias /usr/share/nginx/html/media;
}
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
コード解説
server_nameはVultrのIPアドレスを指定します。
server_name xxx.xxx.xxx.xxx
HTTPS化
HTTPSに対応するには、SSL証明書を取得する必要があります。
Let's EncryptでSSL証明書を取得できます。
証明書が取得できたら、下記をHTTPS用の設定に変更する必要があります。
後で解説します。
Nginx設定確認
下記コマンドでNginxの設定が正しいかを確認することができます。
$ sudo nginx -t
Nginx再起動
$ sudo systemctl restart nginx
Nginx起動確認
nginxだけでDjangoを動作させます。
ブラウザでVultrのIPアドレスを入力して、Djangoのページが表示されることを確認します。
(myvenv) haruyasu@vultr:~/src/deploytest$ python3 manage.py runserver 0.0.0.0:8000
Gunicorn起動確認
次にGunicornを通して、Djangoを動作させます。
ブラウザでVultrのIPアドレスを入力して、このコマンドでもDjangoのページが表示されることを確認します。
(myvenv) haruyasu@vultr:~/src/deploytest$ gunicorn --bind 127.0.0.1:8000 mysite.wsgi:application
コマンド登録
起動・再起動・停止がしやすいように、systemctlコマンドへの登録をします。
deploytest.serviceなど分かりやすい名前にします。
$ sudo nano /etc/systemd/system/deploytest.service
下記のように修正します。
[Unit]
Description=gunicorn
After=network.target
[Service]
WorkingDirectory=/home/haruyasu/src/deploytest
ExecStart=/home/haruyasu/src/deploytest/myvenv/bin/gunicorn --bind 127.0.0.1:8000 mysite.wsgi:application
[Install]
WantedBy=multi-user.target
コード解説
WorkingDirectoryはDjangoプロジェクトのディレクトリです。
WorkingDirectory=/home/haruyasu/src/deploytest
gunicornの場所は仮想環境の場所になります。
which gunicornでディレクトリを表示できます。
ExecStart=/home/haruyasu/src/deploytest/myvenv/bin/gunicorn --bind 127.0.0.1:8000 mysite.wsgi:application
起動・再起動・停止
下記コマンドで容易にプロジェクトの起動停止ができます。
起動
起動コマンドは、startを使用します。
sudo systemctl start deploytest
再起動
再起動コマンドは、restartを使用します。
sudo systemctl restart deploytest
停止
停止コマンドは、stopを使用します。
sudo systemctl stop deploytest
確認
コマンドで起動したら、ブラウザでIPアドレスを入力してDjangoが表示されていることを確認しましょう。
ドメイン設定
ドメインは、お名前ドットコムで取得します。
ドメインを取得したら、ネームサーバーの設定からネームサーバーの変更を選択します。
変更するドメインを選択します。
下記のように設定します。
ネームサーバー1 ns1.vultr.com
ネームサーバー2 ns2.vultr.com
Vultr側のDNS設定
Vultr側でも設定する必要があります。
DNS画面でプラスボタンを押して、ドメイン名とIPアドレスを入力します。
環境設定変更
ALLOWED_HOSTSにドメイン名を追加します。
.env
SECRET_KEY=xxxxxxxxxxxxxxxx
ALLOWED_HOSTS=127.0.0.1,xxx.xxx.xxx.xxx,yourdomain.com
EMAIL_HOST_USER=xxxxx@gmail.com
EMAIL_HOST_PASSWORD=xxxxxxxx
サーバー再起動
サーバーを再起動させます。
sudo systemctl restart deploytest
確認
ネームサーバー変更は時間がかかります。
お名前.comからネームサーバー変更のメールが通知されるので、それまでしばらくお待ちください。
[お名前.com]ネームサーバー情報変更 完了通知
メールが届いたら、ブラウザでドメイン名を入力してページが表示されることを確認します。
もし表示されない場合は、設定を見直してください。
・サーバーが立ち上がっているか
・ファイヤーウォールは設定しているか
・ポート番号はあっているか
・httpでアクセスしているか
HTTPS化
デプロイが成功したら、HTTPS化しておきましょう。
Webアプリケーションを作成したら、HTTPS化は必須となります。
Let's Encryptをインストール
$ sudo apt-get install letsencrypt
サーバー証明書取得
Nginxを一度止めておきます。
$ sudo systemctl stop nginx
証明書を取得します。
$ sudo letsencrypt certonly --standalone -d yourdomain.com
Nginx設定
Nginxの設定をHTTPS用に修正します。
$ sudo nano /etc/nginx/sites-available/default
/etc/nginx/sites-available/default
server {
listen 80;
listen [::]:80;
server_name yourdomain.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name yourdomain.com;
client_max_body_size 10M;
ssl on;
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
location /static {
alias /usr/share/nginx/html/static;
}
location /media {
alias /usr/share/nginx/html/media;
}
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
コード解説
yourdomain.comのところは、ドメイン名に変更して下さい。
80番ポートにアクセスがあった場合に、443ポートにリダイレクトするように設定しています。
server {
listen 80;
listen [::]:80;
server_name yourdomain.com;
return 301 https://$host$request_uri;
}
画像のアップロードサイズはデフォルトでは少ないので、最大10Mとしています。
client_max_body_size 10M;
Let's Encryptで証明書を取得すると、/etc/letsencrypt/live/に格納されます。
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
collectstaticをすると、静的ファイルは/usr/share/nginx/html/staticに格納されます。
location /static {
alias /usr/share/nginx/html/static;
}
画像をアップロードすると、画像は/usr/share/nginx/html/mediaに格納されます。
location /media {
alias /usr/share/nginx/html/media;
}
設定確認
下記コマンドでnginxの設定が正しいことを確認します。
sudo nginx -t
Nginx開始
Nginxを開始します。
$ sudo systemctl start nginx
Gnicorn再起動
プロジェクトを再起動します。
sudo systemctl restart deploytest
確認
httpsでアプリケーションが表示されることを確認しましょう。
自動更新設定
証明書は90日で期限が切れてしまうので、定期的に証明書を更新します。
$ sudo crontab -e
下記を追加します。
00 05 01 ・・sudo systemctl stop nginx; sudo letsencrypt renew; sudo systemctl start nginx
VPSデプロイテクニック
初回のデプロイは設定が色々あるので、大変ですが、2回目以降は簡単です。
ローカルで開発
ローカルで開発して、動作を確認します。
GitHubにコミット
すべてのファイルをGitHubにコミットします。
VPSに接続
sshコマンドでVPSに接続します。
ssh haruyasu@xxx.xxx.xxx.xxx
フォルダ移動
gitのあるファルダに移動します。
cd src/django-portfolio
データ取得
GitHUbから最新ファイルを取得します。
git pull
静的ファイル収集
静的ファイルをnginxに集めます。
sudo python3 manage.py collectstatic
サーバー再起動
ファイルを更新したので、再起動します。
sudo systemctl restart portfolio
確認
ブラウザにURLを入力して、正常に動作していることを確認します。
以上が2回目以降の手順です。
簡単にデプロイすることができます。
おわりに
チュートリアルを最後まで読んでいただき、誠にありがとうございました。
VPSデプロイのチュートリアルはここまでで終わりとなります。
デプロイ方法
サーバー構築と本番環境へのデプロイ方法が理解できましたでしょうか!?
どんどんWebアプリケーションを開発して、全世界に公開していきましょう。
Djangoは奥の深いフレームワークで、多くの機能を搭載することができます。
公式ドキュメントを参考にして、さらに理解を深めていきましょう。
ぜひオリジナルのアプリケーションを開発してみてください。
フィードバック
チュートリアルのフィードバックは、Twitter(@hathle)までお願いいたします。
どんどんDjangoチュートリアルを作成していきますので、楽しみにしていてください。
ではまた!!
最後まで読んでいただきありがとうございました😃 サポートは、プログラミングチュートリアル開発の手助けとなります。 シェアもして頂くと嬉しいです。 Twitterのフォローもお願いします。 https://twitter.com/hathle