見出し画像

UbuntuでDjangoの環境を立ち上げてセキュリティからドメイン設定、SSL化まで最低限のセットアップをする

DjangoアプリケーションをUbuntuサーバーでセットアップする方法を紹介します。
セットアップの内容としては下記になっています。

・SSH接続をセキュアにするための設定(暗号化・ポート番号変更など)
・PyenvによるPythonのバージョンを指定してのインストール
・Djangoの環境構築
・uWSGIを使ってNginxとDjangoを連携させる
・uWSGIの自動起動設定
・ドメイン設定
・SSL化設定
・SSL自動更新設定

想定する読者はLinuxサーバーを触ったことのある方を対象としています。今回はLinuxサーバーでDjangoのセットアップをすることが目的ですので、Django開発について詳しい知識は必要としません。Webの基礎的な知識があると理想ですが、Linuxで簡単なコマンド操作とvim操作ができるだけでも進められます。
また、セキュリティの設定も行いますが、簡単な設定ですので安心してください。
本記事で説明するDjango構築は、かなりしっかりとしているので本番運用にも使えるような内容となっています。

ホスティングはConoHaサーバーを使用します。
ConoHaサーバーのセットアップから説明するので、レンタルサーバーを使用したことがない方でも読み進められます。
別のホスティングを使う方はConoHaサーバーの説明部分は読み飛ばしていただいて構いません。

バージョン

バージョンは下記構成を前提に進めますが、PythonのバージョンとDjangoのバージョンは適宜変更いただいて構いません。
ただし、pyenvというPythonのバージョン管理ツールを使うので、Pythonのバージョンはpyenvがサポートしているものに限ります。

・Ubuntu 20.04
・Python 3.9.2
・Django 3.2.4

ConoHaのセットアップ

まずはConoHaにログインします。
https://www.conoha.jp/login/?mode=logout

アカウントをお持ちでない方は、新しく作成しましょう。
こちらの招待リンクからアカウントを作成すると割引クーポンがもらえます。
https://www.conoha.jp/referral/?token=7gWDu4ReZhjRU_.0LPokM5CoENfSbzgBZbQS2CcHeqSyEnTtFfg-R88

ログインするとこのような画面が表示されます

スクリーンショット 2021-06-13 21.12.02

サイドバーの「サーバー追加」を押してください。

スクリーンショット 2021-06-13 21.12.02

デフォルトでVPS割引きっぷが「利用する」になっているかもしれないので、よくチェックをしておきましょう。
プランは一番低い512MBを選択しますが、必要に応じてスペックは切り替えてください。

スクリーンショット 2021-06-13 21.43.02

今回はUbuntuを使うので、OS選択でUbuntu 20.04を選んでください。

スクリーンショット 2021-06-13 21.46.07

そのまま、rootパスワードを入力し、追加を押してください。
ネームタグは変更しても構いません。

スクリーンショット 2021-06-13 21.51.42

追加が完了するとサーバーリストが表示され、新たに作成したサーバーがリストに追加されます。

スクリーンショット 2021-06-13 22.05.08

追加されたサーバーのネームタグを押すとこのような画面が表示されます。

スクリーンショット 2021-06-13 22.28.38

ネットワーク情報からIPアドレスをコピーし、ターミナルから下記のコマンドを実行してください。

ssh root@サーバーのipアドレス -p 22

実行すると、
Are you sure you want to continue connecting (yes/no/[fingerprint])?
と出てくるのでそのままyesと答えてください。

続いてパスワードを求められるので、サーバーを追加する時に設定したrootパスワードを入力してください。

以上でConoHaサーバーの設定とサーバーにアクセスできるようになりました。

ユーザーの作成

まずはターミナルからサーバーにアクセスしてください。
ConoHaのセットアップを読み進めていただいた方は、すでにサーバーにアクセスしているのでそのまま進めていただいて構いません。

root権限のまま作業するのはあまりよくないので、ユーザーを新たに作成して作成したユーザーに切り替えます。

$ adduser [username]
$ usermod -G sudo [username] # sudo権限を作成したユーザーに付与
$ su [username]

adduserコマンドで下記質問が出てきますが、すべて空欄のままでも問題ありません。

スクリーンショット 2021-06-13 23.06.13

秘密鍵・公開鍵の設定

必要最低限のセキュリティ対策は必要ですので、サーバーへのアクセスを秘密鍵・公開鍵形式にします。
自分のPCのターミナルで下記を実行してください。
このときに気をつけるのは、アクセス先のサーバーで実行しないことです。

ssh-keygen -t rsa -f [file_name]

実行後
Enter passphrase (empty for no passphrase):
とパスフレーズの入力を求められますが、そのまま入力せずにエンターすることもできます。
なるべく入力をしておきましょう。

生成した鍵はパーミッションの設定をしておきましょう。
2つ鍵が生成されているので、どちらにも設定します。
ちなみに.pubが付いている方は公開鍵ファイルで、付いていない方は秘密鍵ファイルです。

chmod 600 [ファイル名] [ファイル名].pub

設定後、公開鍵をサーバーに送信しますが、先に鍵ファイルを入れておくディレクトリを作成しておきます。

cd ~
mkdir .ssh

続いてscpコマンドを使って公開鍵を送信します。
誤って秘密鍵を送信しないように注意しましょう。

scp [公開鍵] [作成したユーザー]@[サーバーのIPアドレス]:~/.ssh/

SSH接続の設定をする

今のままだと、ポート番号22がデフォルトになっており、秘密鍵・公開鍵でのアクセスもできないので、SSH設定ファイルを編集して設定を有効にしましょう。

下記を実行して設定ファルを開いてください。

sudo vim /etc/ssh/sshd_config

設定内容は以下のようになります。

Port 40230 # ポート番号
PermitRootLogin no # rootログインの可否
RSAAuthentication    yes # RSAによる認証可否
PubkeyAuthentication yes # 公開鍵による認証可否
AuthorizedKeysFile   %h/.ssh/id_rsa.pub # 公開鍵のファイルパス指定
PasswordAuthentication no # パスワード認証の可否

Portの番号は別の番号でも大丈夫ですが、ウェルノウンポートと呼ばれるあらかじめ使用が決められているポートは避けましょう。
ウェルノウンポートについてはIANAというインターネットに関する正式な機関が公表しています。
詳細は下記を参照してください。
https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml

設定を有効化するため、sshサーバーを再起動してください。

sudo systemctl restart ssh

念の為、起動ができているか確認しておきましょう。

sudo systemctl status ssh

active (running)と表示されていると無事に設定が有効化されています。

今度は実際に設定した内容通りにPCのターミナルからサーバーにアクセスできるか確認しましょう。
下記コマンドを実行してください。

ssh [作成したユーザー]@[サーバーのIPアドレス] -p 40230 -i ~/.ssh/[秘密鍵]

アクセスできたらSSH接続の設定は以上となります。
Congratulations !

Pythonのインストール

Pythonのインストールには、pyenvというPythonのバージョンを複数使い分けることができる管理ツールを使用します。

Ubuntu20.04にpyenvをインストールするには、いくつかライブラリをインストール必要があります。
下記を実行してください。

sudo apt update
sudo apt upgrade
sudo apt install -y build-essential
sudo apt install -y libffi-dev
sudo apt install -y libssl-dev
sudo apt install -y zlib1g-dev
sudo apt install -y liblzma-dev
sudo apt install -y libbz2-dev libreadline-dev libsqlite3-dev # bz2, readline, sqlite

pyenv本体をインストールします。

.bashrcを更新し、pyenvが読み込まれるようにします。

echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(pyenv init --path)"' >> ~/.bashrc
source ~/.bashrc

これでpyenvを使ってバージョン指定したPythonをインストールできるようになりました。
ここでは3.9.2を選びますが、適宜必要なバージョンをインストールしてください。

pyenv install 3.9.2
pyenv versions # 使用できるバージョンの確認
pyenv global 3.9.2

Djangoのインストール

Pythonの準備ができたところでDjangoをインストールしていきます。
/varディレクトリにDjango環境を置くディレクトリを作成し、構築していきます。

cd /var
sudo mkdir mysite
sudo chmod 777 /var/mysite
cd mysite

python -m venv env
source source env/bin/activate # Pythonの仮想環境が起動
pip install django==3.2.4
django-admin startproject project .
python manage.py migrate # デフォルトのマイグレーションファイルをマイグレート

python -m venv envでPythonの仮想環境が構築できます。

これでDjangoアプリを立ち上げる環境が整いました。
python manage.py runserver を実行すると、このようなメッセージが現れます。

スクリーンショット 2021-06-14 2.19.51

ブラウザからはまだ確認できませんが、この状態になっていればサーバーの起動はできています。

uWSGIとNginxの設定

Djangoや他の多くのWebフレームワークでも同じですが、NginxやApachなどのWebサーバーとWebアプリケーションを直接つなげることができないので、間にインターフェースを設ける必要があります。

Pythonの実行が可能なインターフェースの定義をWSGI(Web Server Gateway Interface)といい、今回はこのWSGIに準拠して実装された、uWSGIというのを使って設定を進めていきます。

uWSGIがWSGIを実装したものであることはドキュメントに記載されています。
uWSGI Concept
WSGI
uWSGI

ちなみにWSGIの読み方はウィズギィーだそうです。

まずはNginxをインストールしてください。

sudo apt install nginx

インストール後、ブラウザでサーバーのIPアドレスを指定して開くとこのような画面が表示されます。

スクリーンショット 2021-06-14 2.27.25


続いてuWSGIをインストールします。

sudo apt install uwsgi

次にNginxとuWSGIが値の受け渡しをするために、パラメーターを定義したファイルを作成します。
[mysite]ディレクトリでvim uwsgi_paramsを実行して、下記をファイルに追加してください。

uwsgi_param  QUERY_STRING       $query_string;
uwsgi_param  REQUEST_METHOD     $request_method;
uwsgi_param  CONTENT_TYPE       $content_type;
uwsgi_param  CONTENT_LENGTH     $content_length;

uwsgi_param  REQUEST_URI        $request_uri;
uwsgi_param  PATH_INFO          $document_uri;
uwsgi_param  DOCUMENT_ROOT      $document_root;
uwsgi_param  SERVER_PROTOCOL    $server_protocol;
uwsgi_param  REQUEST_SCHEME     $scheme;
uwsgi_param  HTTPS              $https if_not_empty;

uwsgi_param  REMOTE_ADDR        $remote_addr;
uwsgi_param  REMOTE_PORT        $remote_port;
uwsgi_param  SERVER_PORT        $server_port;
uwsgi_param  SERVER_NAME        $server_name;

Nginxの設定を追加していきます。
sudo vim /etc/nginx/sites-available/mysite_nginx.confを実行します。

# the upstream component nginx needs to connect to
upstream django {
   server unix:///var/mysite/project.sock; # for a file socket
   # server 127.0.0.1:8001; # for a web port socket (we'll use this first)
}

# configuration of the server
server {
   # the port your site will be served on
   # listen      8000;
   # the domain name it will serve for
   server_name [サーバーのIPアドレス]; # substitute your machine's IP address or FQDN
   charset     utf-8;

   # max upload size
   client_max_body_size 75M;   # adjust to taste

   # Django media
   location /media  {
       alias /var/mysite/media;  # your Django project's media files - amend as required
   }

   location /static {
       alias /var/mysite/static; # your Django project's static files - amend as required
   }

   # Finally, send all non-media requests to the Django server.
   location / {
       uwsgi_pass  django;
       include     /var/mysite/uwsgi_params; # the uwsgi_params file you installed
   }
}

unix:///var/mysite/project.sockはuWSGIと通信するためのインターフェースとなるものです。
後ほど、uWSGIの設定ファイルにもproject.sockを記載します。

シンボリックリンクを貼ります。

sudo ln -s /etc/nginx/sites-available/mysite_nginx.conf /etc/nginx/sites-enabled/

ここでNginxを再起動します。

sudo systemctl restart nginx

uWSGIに実行オプションを渡すためのファイルを設定します。
[mysite]ディレクトリでvim mysite_uwsgi.iniを実行して下記を追加してください。

# mysite_uwsgi.ini file
[uwsgi]

# Django-related settings
# the base directory (full path)
chdir           = /var/mysite
# Django's wsgi file
module          = project.wsgi
# the virtualenv (full path)
home            = /var/mysite/env

# process-related settings
# master
master          = true
# maximum number of worker processes
processes       = 10
# the socket (use the full path to be safe
socket          = /var/mysite/project.sock
# ... with appropriate permissions - may be needed
# chmod-socket    = 664
chmod-socket    = 666
# clear environment on exit
vacuum          = true

Nginxの設定と同じように、ここでもproject.sockを設定しました。
これでNginxとuWSGIを連携させることが可能となります。

設定後uwsgi --ini mysite_uwsgi.iniを実行し、ブラウザでサーバーのIPアドレスを指定するとDjangoが起動しているのがわかります。

おそらく、DisallowedHost at / とエラー分が表示されていると思います。
Djgnaoのホストアドレスを設定する必要があるので、mysite/project/settings.pyを開いて編集します。

ALLOWED_HOSTS = []という設定があるので、[]の中にサーバーのIPアドレスを入れます。
下記のように設定してください。

ALLOWED_HOSTS = ['xxx.xxx.xxx.xxx']

このような画面が表示されたらDjangoの立ち上げは完了です。
おつかれさまでした!

スクリーンショット 2021-06-14 3.34.17

uWSGI自動起動の設定

このままだとNginxと同じようにuWSGIもサーバー再起動のときなどに自動起動ができないので、設定していきます。

sudo vim /etc/systemd/system/uwsgi.serviceでファイルを開き、下記を追記してください。

[Unit]
Description = uWSGI
After = syslog.target

[Service]
ExecStart = /var/mysite/env/bin/uwsgi --ini /var/mysite/mysite_uwsgi.ini
Restart = 5s
Restart=always
KillSignal=SIGQUIT
Type=notify
StandardError=syslog
NotifyAccess=all

[Install]
WantedBy=multi-user.target

下記を実行してください。

sudo systemctl start uwsgi
sudo systemctl status uwsgi

active (running)と表示されたらuWSGIの起動が確認できます。

ドメインの設定

ドメインはすでに取得している前提で進めます。
まだの方は先に取得してから進めましょう。

お名前.comの空きドメイン検索サイトのリンクを置いておきます。
ドメインを取得していない方はぜひご参照ください。
https://www.onamae.com/advanced/

設定はサーバーのホスティングとドメインのホスティングの両方とも行います。

まずは、サーバーを使用していホスティングの管理画面からDNSの設定を行います。
今回はConoHaを使用しているので、ConoHaの画面で説明していきます。
他のホスティングを使用している方も、同じように設定できると思うので本記事を参考にしつつ設定してください。

ConoHa管理画面のサイドバーからDNSを選び、右上のドメインと書かれた部分をクリックします。

スクリーンショット 2021-06-14 9.51.01

このような画面になると思うので、ドメイン名を入力し保存を押下します。

スクリーンショット 2021-06-14 9.57.43

ドメインリストに追加したドメインが表示されるので、そのドメインをクリックします。

スクリーンショット 2021-06-14 10.15.15

3つのネームサーバーの情報が表示されていれば問題ありません。
右端にある青いペンのマークをクリックすると下にレコードが追加されるので名称に@、TTLに300、値にサーバーのIPアドレスを入れてください。

TTLについてはDNSの設定を早くするために300にしているので、後で3600に戻すことを忘れないようにしましょう。

スクリーンショット 2021-06-14 10.35.23

画面はそのまま、ドメインホスティングの管理画面を開きます。

ドメイン側の設定はお名前.comを使って説明しますが、お名前.com以外をお使いの方も同じように設定できると思うので適宜設定してください。

ネームサーバーの設定画面に行きます。

スクリーンショット 2021-06-14 9.49.59

ネームサーバーを3つまで登録できる設定画面があると思うので、ここに先ほどConoHaで表示されていたネームサーバーの値を3つとも入れて確定を押してください。

スクリーンショット 2021-06-14 9.54.50

これでDNSの設定が完了しました。
このままではドメインにアクセスしてもDjangoアプリケーションは表示されないので、再びサーバーにアクセスしNginxとDjangoの設定を行なっていきます。

/etc/nginx/sites-available/mysite_nginx.confを開きserver_nameを変更します。
サーバーのIPアドレスを入れていると思うので、取得したドメイン名に変更してください。

# the upstream component nginx needs to connect to
upstream django {
   server unix:///var/mysite/project.sock; # for a file socket
   # server 127.0.0.1:8001; # for a web port socket (we'll use this first)
}

# configuration of the server
server {
   # the port your site will be served on
   # listen      8000;
   # the domain name it will serve for
   server_name [ドメイン名]; # substitute your machine's IP address or FQDN
   charset     utf-8;

   # max upload size
   client_max_body_size 75M;   # adjust to taste

   # Django media
   location /media  {
       alias /var/mysite/media;  # your Django project's media files - amend as required
   }

   location /static {
       alias /var/mysite/static; # your Django project's static files - amend as required
   }

   # Finally, send all non-media requests to the Django server.
   location / {
       uwsgi_pass  django;
       include     /var/mysite/uwsgi_params; # the uwsgi_params file you installed
   }
}

Djangoのsettings.pyにもサーバーのIPアドレスを指定していたので、ここもドメイン名に変更します。

ALLOWED_HOSTS = ['ドメイン名']

NginxとuWSGIを再起動して、取得したドメインにブラウザからアクセスしてみましょう。
同じくこのような画面が表示されれば大成功です!

スクリーンショット 2021-06-14 10.52.45

Successful !

ここで、300に設定していたTTLを3600にしておきましょう。

SSL化設定

このままだとセキュアな通信ではないので、SSL化して通信を暗号化させます。
サイトのSSL化はエチケットなので、必ず実施しましょう。

SSLにはLet’s Encryptという認証局が発行している無料の証明書を利用します。
有効期間は90日間ですが、certbotという証明書管理ツールを入れておくと自動更新が可能です。
更新のタイミングは有効期間が30日を切った時点となっています。

下記コマンドを実行してください。

sudo apt install certbot python3-certbot-nginx
sudo certbot # 証明書発行の初期設定

最初に
Enter email address (used for urgent renewal and security notices) (Enter 'c' to cancel):
と尋ねられるので、お使いのメールアドレスを入力します。

利用規約に同意(Agrree)し、次の質問はNoで構いません。

スクリーンショット 2021-06-14 11.06.08

次に
Which names would you like to activate HTTPS for?
と尋ねられるので、そのままエンターしてください。

こちらの質問はHTTPへのアクセスをHTTPSにリダイレクトをするかの設定です。
とくに事情などない限りリダイレクトしましょう。
2で設定できます。

スクリーンショット 2021-06-14 11.10.05

ブラウザで再び取得したドメインをhttp形式でアクセスしてみてください。
httpsにリダイレクトされたら大成功です。

また、certbotの自動更新が起動しているか確認します。
下記コマンドを実行してください。

sudo systemctl status certbot.timer
スクリーンショット 2021-06-14 11.30.55

active (waiting)と表示されているかもしれませんが、自動更新が待機中となっているのでwaitingは正しい表示です。

これでSSL化の設定は終了です。
無事に本番運用可能なDjango環境が構築できました。
おつかれさまでした!

誤字脱字や間違いの説明はご指摘いただけると幸いです。
最後までご覧いただきありがとうございます!


この記事が気に入ったらサポートをしてみませんか?