このポストは、Django Advent Calendar 2019 - Qiitaの17日目の記事です。
こんちは!しんせいたろうです。モグモグDjangoの主宰してます。
現在、アーバンデータチャレンジに東東京のアザラシチームの一員として、DRFを頑張っています。
「アーバンデータチャレンジ」とは、地域課題の解決を目的とした地方自治体を中心とする公共データを活用した年間のイベント開催を伴う一般参加型コンテストです。東東京チームは定期的にがやがや会という楽しくもくもくする会を開催していますので、公共データや地域課題解決などに興味があるエンジニアの方、ぜひぜひお越しくださいませ。くわしくはこちら→UDC東東京 - connpass
今回、ある公共データを地図にマッピングするアプリケーションを作成するチームに入っています。そこでGeoDjangoを使うことになり、そのサーバー側の設定を全くわからない状態から始めました。以下、サーバー設定&最初のアプリケーション立ち上げまでの、辛かった道のりでメモしていたので、まとめて書きました。
目次
- Vultr 登録
- インスタンス作成
- ウェブアプリケーションインストール
- データベースインストール
- データベース作成と設定
- Django App 作成
- 独自ドメイン登録
Vultr 登録
今回、Vultrというインスタンス上にDjangoとPostgresを使って、地図アプリを作って見ることにしました。
まずはユーザー登録します。初めての人には50ドル分サービスがありますので、最初の50ドルまでは課金されずにフル機能使うことができます。使ってみてイマイチだな?と思ったらインスタンスをdestroy すれば一切お金はかかりません。
インスタンス作成
作成
インスタンスを選ぶ
今回は、Cloud Compute / Tokyo (region) / Ubuntu 18.04 x64 を選びました。
サーバーサイズについて
今回は、25GBSSDを選びました。料金は、$5/MO $0.007/h です。これは、インスタンスを作っている間は毎時70セントはかかるよ。だけど、Max月5ドルだよ。という意味です。何もしていなくてもインスタンスをDestroyするまでは課金されます。しかし、どんなに使ってもMax5ドルまでということです。
Enter server label に任意の名前をつけたらDeploy Now
shinseitaro という名前をつけてインスタンスを作りました。
Deploy Now
を押すと、インスタンス作成が始まります。
Instance 確認
インスタンスが出来上がったら、下記のようにリストが表示されます。
自分のインスタンスを開きましょう。
パスワードは、目のマークを押すと表示され、コピーマークを押すとコピーされます。
SSH 接続
ローカルマシンから、リモートインスタンスにSSH接続します。(ローカルマシンでSSHが使えることを前提に話しています。)
-
ローカルマシンから、
root@[Your IP Address]
で接続する。IP と password は先ほどのインスタンス確認画面でできます。$ ssh root@xx.xx.xx.xxx The authenticity of host 'xx.xx.xx.xxx (xx.xx.xx.xxx)' can't be established. ECDSA key fingerprint is xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'xx.xx.xx.xxx' (ECDSA) to the list of known hosts. root@xx.xx.xx.xxx's password:
User 追加
- root で作業するのは危険なので、必ずユーザーを作成しましょう (下記例では shinseitaro で作成しています。適宜読み替えてください。)
- 新規ユーザーを作成したあとは、必ず root では SSH 接続できない設定をしましょう。
- パスワードは十分複雑なものにしてください。パスワード生成(パスワード作成)などを使うのが便利です。
- ユーザー作成
-
ssh 接続したターミナルで、
adduser your-new-name
します。user information
を聞かれますが、全部Enterを押して行けばOKですroot@vultr:~# adduser shinseitaro Adding user `shinseitaro' ... Adding new group `shinseitaro' (1000) ... Adding new user `shinseitaro' (1000) with group `shinseitaro' ... Creating home directory `/home/shinseitaro' ... Copying files from `/etc/skel' ... New password: Retype new password: passwd: password updated successfully Changing the user information for shinseitaro Enter the new value, or press ENTER for the default Full Name []: Room Number []: Work Phone []: Home Phone []: Other []: Is the information correct? [Y/n] Y
-
新規ユーザーに sudo 権限を与えます
root@vultr:~# gpasswd -a shinseitaro sudo Adding user shinseitaro to group sudo # いったんログアウト root@vultr:~# exit logout
-
新規ユーザーで ssh
$ ssh shinseitro@xxx.xxx.xxx.xx $ shinseitaro@vultr:~$
-
rootでは SSH で入れないようにします。
/etc/ssh/sshd_config
を修正して root では SSH出来ないようにします。# 私は nano 使ってますが vim でもなんでもいいです shinseitaro@vultr:~$ sudo nano /etc/ssh/sshd_config # ここを yes から no へ変更 PermitRootLogin no
-
変更を反映
shinseitaro@vultr:~$ sudo service ssh restart
SSH 接続を公開鍵で行う(任意)
ターミナルを閉じると、毎回パスワードを確認されるのはめんどくさいので、公開鍵を使ってログインできるようにします。
【注意】:Windowsでの設定はわかりません。だれかコメントしといてくれると嬉しいです。
Vultr インスタンス側:
```
$ mkdir /home/[username]/.ssh
```
ローカルマシン側:
-
ssh-keygenを使って公開/秘密鍵のペアを作成。
$ mkdir $HOME/.ssh $ cd $HOME/.ssh $ ssh-keygen -t rsa -b 4096 -f id_rsa_vultr
ファイル名
id_rsa_vultr
は何でもOKです。 -
Vultr へ 公開鍵を scp で送信する。
$ scp id_rsa_vultr.pub [user_name]@[remote_ip_addr]:/home/[user_name]/.ssh/authorized_keys
-
./ssh/config に設定を追加
$ vi ~/.ssh/config # 下記貼り付け Host hoge HostName xx.xx.xx.xxx User your-username IdentityFile ~/.ssh/id_rsa_vultr ServerAliveInterval 60 ServerAliveCountMax 3
-
Host
は、ssh 接続するときに呼び出す設定名です。何でもOK。 -
HostName
は Vulter インスタンスIP -
User
は、先程追加した新規ユーザ名 -
IdentityFile
は、ssh-keygenしたとき作ったファイル名
-
Vultr インスタンス側:
$ chmod 644 ~/.ssh/authorized_keys
ローカルマシン側:
接続確認。./ssh/config
で Host
に指定した名前でssh接続できます。
$ ssh hoge
Welcome to Ubuntu 18.04.3 LTS (GNU/Linux 4.15.0-55-generic x86_64)
:
:
いろいろインストール
上記までで、インスタンスに関連する設定は終わりです。これからアプリケーション用のインストールや設定にはいります。
- Python (miniconda)
- Django
- Git
- psycopg2 (Python からPostgresSQLに接続するためのライブラリ)
- GDAL (地図データを触るためのライブラリ。)
Python
色々悩んだ結果、miniconda で pythonをインストールすることにしました。(今となっては何に悩んだかさえ忘れました)
miniconda をインストール
$ curl -O https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
$ bash ./Miniconda3-latest-Linux-x86_64.sh
# このあと色々と聞かれる。
Do you accept the license terms? [yes|no]
>>> yes
Miniconda3 will now be installed into this location:
/home/shinseitaro/miniconda3
>>> [Enter]押す
installation finished.
Do you wish the installer to initialize Miniconda3
by running conda init? [yes|no]
[no] >>> yes
# ながなが色々インストールされる。
# これが出たらインストール完了です
Thank you for installing Miniconda3!
python3.7 の仮想環境をつくってアクティベートする。
Pythonのバージョン、および仮想環境名はお好きなものに変えてください。
# bashrc を適用する
$ source ~/.bashrc
# プロンプトが下記の様に(base) yourname@vultrに変わればOK。
(base) shinseitaro@vultr:~$
# python3.7 の仮想環境をつくってアクティベート
(base) shinseitaro@vultr:~$ conda create --name py37 python=3.7 -y
(base) shinseitaro@vultr:~$ conda activate py37
# プロンプトが base から py37 に変わればOK。
(py37) shinseitaro@vultr:~$
# python 起動して3.7か確認
$ python
Python 3.7.4 (default, Aug 9 2019, 18:51:30)
[GCC 7.3.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
# インストール用の miniconda.sh はもういらないので削除
(py37) shinseitaro@vultr:~$ rm Miniconda3-latest-Linux-x86_64.sh
次回起動時からは、デフォルトで py37 が起動するように変更(任意)
この設定をすると、次回 ssh接続したときに、 (base) ではなく (py37) がデフォルトで起動します。
$ nano ~/.bashrc
# 最後の行に追加して保存
source activate py37
Django
$ pip install Django==2.1.11
注意:現在Djangoのバージョン指定を行わないと、3.0がデフォルトでインストールされます。2系以下を選びたいときはバージョンを指定してください。
psycopg2
$ conda install psycopg2 -y
メモ:pip で入れようと試行錯誤したのですが ERROR: Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-install-lefl0f21/psycopg2/
を解決できず、conda にしました。
データベースインストール
PostgreSQL + PostGIS のインストールと設定
GeoDjangoアプリを作りたいので、以下をインストールして、設定していきます。
- PostgreSQL
- PostGIS
- GEOS
- GDAL
- PROJ.4
PostgreSQL
レポジトリキーをインポート
$ apt-get install curl ca-certificates gnupg
$ curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
/etc/apt/sources.list.d/pgdg.list を作成
注意
[bionic]のところは、自分のUBUNTU_CODENAME
を入れてください。cat /etc/os-release
すればわかります。
root@vultr:~# echo "deb http://apt.postgresql.org/pub/repos/apt/ bionic-pgdg main" | sudo tee -a /etc/apt/sources.list.d/pgdg.list
package listsを更新してインストール
$ apt-get update
$ apt-get install postgresql-11 pgadmin4
確認
インストールすると、postgres
ユーザというDB管理用のユーザが、インスタンスに自動で生成されます。postgres
にスイッチしてDBの確認をします。
# shinseitaro から postgres にスイッチ
shinseitaro $ su - postgres
# スイッチしたらDB確認
postgres@vultr:~$ psql -V
psql (PostgreSQL) 11.5 (Ubuntu 11.5-1.pgdg18.04+1)
postgres にパスワードを与える
postgres
にパスワードを与えます。今後は su
するときにこのパスワードを入力します。
$ passwd postgres
New password:
Retype new password:
passwd: password updated successfully
PostGIS
$ apt-get install postgis -y
$ apt install postgresql-11-postgis-2.5
$ apt-get install postgresql-contrib
$ apt install postgresql-11-postgis-2.5-scripts
GEOS
$ apt-get install libgeos-dev -y
PROJ.4
$ apt-get install libproj-dev proj-data proj-bin -y
データベース 作成
新規DBを作成します。postgres
ユーザにスイッチして作業します。
$ su - postgres
postgres@vultr:~$
現在のDBを確認
まったく新しい現時点では下記のようなDBが存在すると思います。
混乱しがちですが、先程新規作成された postgres
ユーザはマシンユーザーです。
このリストに乗っている、Name privileges: postgres
と Owner: postgres
はマシンユーザーのことではなく、データベース名とオーナー名とです。混乱しやすいので注意してください。
# psql に入る
postgres@vultr:~$ psql
# 現時点でのDataBaseリストを出力
postgres=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-------------+-------------+----------+-------------+-------------+-----------------------
postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres +
この オーナーpostgres
にパスワードを与えます。
postgres=# Alter Role postgres with password 'new_password';
postgres=# exit
postgres@vultr:~$
新規DBを作成
データベースとそのオーナーを作成します。
例として shinseitaro
オーナーを作成して testdb1
というデータベースを作り、そのオーナーに指定しています。
# postgres ユーザにログインしている状態。shinseitaro 作成します。
postgres@vultr:~$ createuser shinseitaro
# testdb1を作成。オーナーをshinseitaroに指定。
postgres@vultr:~$ createdb testdb1 --owner shinseitaro
# password 設定
postgres@vultr:~$ psql -c "ALTER USER shinseitaro WITH PASSWORD 'some_pwd'"
ALTER ROLE
pg_hba.conf 編集
では、shinseitaro
で testdb1
にログインしてみます。すると、psql: FATAL: Peer authentication failed
が発生します。
postgres@vultr:~$ psql -U shinseitaro -d testdb1
psql: FATAL: Peer authentication failed for user "shinseitaro"
これは、OS側(ここでは postgres)のユーザ名と、PostgreSQL にログインしようとしているユーザー名( shinseitaro )が一致していないときに起きるエラーです。これをPeer認証と言います。これをパスワード認証に変更して、ログインできるようにします。
この設定は、Web AppとDBが違うマシン上にあるときにも必要です。その場合はIPアドレスを設定する必要があります。
pg_hba.conf 確認
postgres ユーザをexit
postgres@vultr:~$ exit
pg_hba.conf ファイルを探す. わたしの場合はここにありました。このパスで進めます
$ find /etc/ -name pg_hba.conf
/etc/postgresql/11/main/pg_hba.conf
確認
$ cat /etc/postgresql/11/main/pg_hba.conf
# Database administrative login by Unix domain socket
local all postgres peer
# TYPE DATABASE USER ADDRESS METHOD
# "local" is for Unix domain socket connections only
local all all peer
# IPv4 local connections:
host all all 127.0.0.1/32 md5
# IPv6 local connections:
host all all ::1/128 md5
# Allow replication connections from localhost, by a user with the
# replication privilege.
local replication all peer
host replication all 127.0.0.1/32 md5
host replication all ::1/128 md5
pg_hba.conf 編集
現在設定されている、
local all all peer
local replication all peer
peer
を md5
に変更します。
またIPアドレスの指定が必要な場合は、
# IPv4 local connections:
host all all 127.0.0.1/32 md5
ここにIPアドレスを追加していきます。
こうすれば、追加されたインスタンスからこのPostgresサーバー(インスタンス)にアクセスできるようになります。DjangoのMigrationで、Connection refused
やSSL OFF
といったエラーが発生する場合は、ここにIPが追加されていない可能性が高いです。
よって最終的にはこのようになります。
# Database administrative login by Unix domain socket
local all postgres peer
# TYPE DATABASE USER ADDRESS METHOD
# "local" is for Unix domain socket connections only
local all all md5
# IPv4 local connections:
host all all 127.0.0.1/32 md5
host all all xxx.xxx.xxx.xx/32 md5
host all all zzz.zzz.zz.zzz/32 md5
# IPv6 local connections:
host all all ::1/128 md5
# Allow replication connections from localhost, by a user with the
# replication privilege.
local replication all md5
host replication all 127.0.0.1/32 md5
host replication all ::1/128 md5
【注意】postgresは md5 にしないよう注意してください。
local all postgres peer
設定を有効化する
$ service postgresql restart
確認
$ psql -U shinseitaro -d testdb1
testdb1=>
# table表示を試してみる.何も作ってないので無いよ,と言われる.
testdb1=> \d
Did not find any relations.
testdb1=>
postgresql.conf 修正
Web AppとDBが違うマシン上にあるときは、postgresql.conf 修正も必要です。listen_addresses
にIPを追加します。
確認
Postgres がどのアドレスをlistenしてるか確認します。localhost
だけですね。これを変更します。
$ lsof -i :5432
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
postgres 11840 postgres 5u IPv6 490443 0t0 TCP localhost:postgresql (LISTEN)
postgres 11840 postgres 6u IPv4 490444 0t0 TCP localhost:postgresql (LISTEN)
postgresql.confのパスを探す
$ find /etc/ -name postgresql.conf
/etc/postgresql/11/main/postgresql.conf
修正する。ここでは、全てを受け入れる *
にしているが、ちゃんとアドレス書いたほうがいいと思います。
$ nano /etc/postgresql/11/main/postgresql.conf
# listen_addresses を変更する。
#listen_addresses = 'localhost'
listen_addresses = '*'
設定を有効化して確認。さきほどは localhost
だったところが、*
になっていると思います。
$ service postgresql restart
$ lsof -i :5432
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
postgres 15606 postgres 5u IPv4 542478 0t0 TCP *:postgresql (LISTEN)
postgres 15606 postgres 6u IPv6 542479 0t0 TCP *:postgresql (LISTEN)
PostGIS Extention インストール
やっとPostgresの設定が終わりました。しかし空間データをDBで扱うためには、PostgreSQL+PostGISのインストールだけではだめです。拡張機能をインストールする必要があります。
注意
- 拡張機能は、それぞれのDBにインストールします。
-
postgres
ユーザに追加権限があります。 -
postgres
ユーザはpostgres
というDBを所有していますが、このDBには決して拡張機能を追加してはいけません。
例では、データベースtestdb1
に空間データを扱うためのエクステンションを追加しています。
$ su - postgres
# Extention を追加していく。
$ psql -d testdb1 -c "CREATE EXTENSION postgis;"
CREATE EXTENSION
# 以下同じように全部追加
$ psql -d testdb1 -c "CREATE EXTENSION postgis_topology;"
$ psql -d testdb1 -c "CREATE EXTENSION postgis_sfcgal;"
$ psql -d testdb1 -c "CREATE EXTENSION fuzzystrmatch;"
$ psql -d testdb1 -c "CREATE EXTENSION address_standardizer;"
$ psql -d testdb1 -c "CREATE EXTENSION address_standardizer_data_us;"
$ psql -d testdb1 -c "CREATE EXTENSION postgis_tiger_geocoder;"
全部追加したらExtensionを表示してみましょう。
$ psql -U shinseitaro -d testdb1
psql (11.5 (Ubuntu 11.5-1.pgdg18.04+1))
Type "help" for help.
# 拡張機能リストを見る
testdb1=> \dx
List of installed extensions
Name | Version | Schema | Description
------------------------------+---------+------------+---------------------------------------------------------------------------------------------------------------------
address_standardizer | 2.5.2 | public | Used to parse an address into constituent elements. Generally used to support geocoding address normalization step.
address_standardizer_data_us | 2.5.2 | public | Address Standardizer US dataset example
fuzzystrmatch | 1.1 | public | determine similarities and distance between strings
plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language
postgis | 2.5.2 | public | PostGIS geometry, geography, and raster spatial types and functions
postgis_sfcgal | 2.5.2 | public | PostGIS SFCGAL functions
postgis_tiger_geocoder | 2.5.2 | tiger | PostGIS tiger geocoder and reverse geocoder
postgis_topology | 2.5.2 | topology | PostGIS topology spatial types and functions
(8 rows)
Django App 作成
やっとここまで来ましたYo!長すぎて頭おかしくなりそうです。
ここからは、mamix1116さんが以前書いた、GeoDjangoでWeb地図をつくろう!にフォローしてGeoDjangoアプリを作成していきます。やっとDjangoよ!
作業のすすめかた
今回は実験的に、Vultr上に作ったプロジェクトディレクトリを、ローカルマシンにマウントして、コーディングしていくことにします。よって、
- Vultr側にプロジェクトディレクトリ(今回は
code
) - ローカルにマウント用のディレクトリ(今回は
/home/azarashi/vultr
)
を用意して進めます。この方法は、ローカルでコーディングをしてデプロイする普通の作業工程では必要ありません。デプロイする人は無視してください。
また、Vultrで実行するコマンドは、 を、ローカルで実行するときは、
をつけています。ファイルの修正時には何もつけていません。
事前準備
sshfs インストール
sshfs を使ってVultrのディレクトリを,ローカルにマウントします.sshfs のインストール方法は,以下を参照して下さい。
- (Ubuntu):ソフトウェアの管理>sshfs 検索 >インストール
- (Mac):Macでsshfsを使ってローカルからリモートのファイルを触る - Qiita
- (win): Windows10からLinuxにSSHで接続し、ネットワークドライブとしてマウントして使うとすごく便利だった
startproject と startapp
Vultr上でDjangoのプロジェクトを作成して、map
というアプリケーションを作成します。
Vultr
$ mkdir ~/code
$ cd code
$ pwd
/home/shinseitaro/code
# わたしは、あきよこせんせい信者なので、設定ファイルを全部 config 以下に置くように設定します。
$ django-admin startproject config .
$ ls
config manage.py
# 地図用のアプリケーション
$ python manage.py startapp map
$ ls
config manage.py map
Vultrに作ったディレクトリをローカルにマウント(任意)
sshfs コマンドは,sshfs [youname]@[IP-Adress]:./code [Local Directory Path]
です.
Local
$ mkdir /home/azarashi/vultr
$ sshfs shinseitaro@xxx.xxx.xxx.xx:./code /home/azarashi/vultr
# cd して ls すると、先程 Vultr上で作ったDjangoプロジェクトファイルが見えるはずです。
$ cd /home/azarashi/vultr
$ ls
config manage.py map
マウントされたディレクトリに入っているファイル等は、ローカルマシンのファイル等と同じように新規作成、修正、削除できます。
/home/azarashi/vultr
を VSCode や Pycharm で開けば、あたかもローカルで作業しているかのようにインスタンス上のファイルを操作できます。
なお、アンマウントする場合は,fusermount -u
します。
Local
$ fusermount -u /home/azarashi/vultr
もし fusermount
して,【fusermount: failed to unmount Device or resource busy】
といったエラーが出る場合は umount
を試してみてください。
$ sudo umount -l /home/azarashi/vultr
コーディング作業
セッティング
config/settings.py
修正:
INSTALLED_APPS = [
...
'django.contrib.gis', # 追加
'map',# 追加
]
# DBは PostgreSQLに変更
DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
# }
'default': {
'ENGINE': 'django.contrib.gis.db.backends.postgis',
'NAME': 'testdb1',
'USER': 'shinseitaro',
'PASSWORD': 'xxxxxx',
'HOST': 'xxx.xxx.xx.xxx',
'PORT': 5432,
}
}
createsuperuser
Vultr
$ python manage.py migrate
$ python manage.py createsuperuser
$ python manage.py runserver xx.xx.xxx.xx:8000
IPアドレス:8000 にアクセスするとロケットが飛んでいるはずです。
地図データをUploadする
今回は、保育所のデータをサンプルとして作成しました。
map/data
ディレクトリを作成して、このjsonファイルを格納します。
ogrinspect を使って、json 構造から、GeoDjango model クラスを自動作成
ogrinspect
オプションを使って model class を自動生成するには、以下のコマンドを使います。
$ python manage.py ogrinspect --srid=XXXX path/to/geojson modelname
今回の場合は、
$ python manage.py ogrinspect --srid=6668 ./map/data/201810-2-1-hoikusyo.geojson Hoikusho
これを実行すると、
# This is an auto-generated Django model module created by ogrinspect.
from django.contrib.gis.db import models
class Hoikusho(models.Model):
owned = models.CharField(max_length=0)
name = models.CharField(max_length=0)
postalcode = models.CharField(max_length=0)
address = models.CharField(max_length=0)
gcs = models.CharField(max_length=0)
tel = models.CharField(max_length=0)
capacity = models.IntegerField()
geom = models.PointField(srid=6668)
と出力されますので、これを map/models.py
にコピペします。
SRID:
srid に関してはこちらが詳しいので参照してください→空間参照系の概要 - Qiita
どのSRIDを使う必要があるのかは、データを作った人に聞くしかありません。もしわからない場合は、よく使われる上記記事中に出てくる、わが国の陸域でよく使われる空間参照系を一つずつ試して地図に出して、自分が知っている地図上の住所から、「なんとなくこれがあってそうだなー」とあたりをつける、という地道な作業を行うらしいです。なんかもやもやする。。。
モデル
自動出力された model に適切なオプションを追加しながら、map/models.py
にコピペします。
# map/models.py
from django.contrib.gis.db import models
class Hoikusho(models.Model):
owned = models.CharField(max_length=50)
name = models.CharField(max_length=50)
postalcode = models.CharField(max_length=10)
address = models.CharField(max_length=250)
gcs = models.CharField(max_length=10)
tel = models.CharField(max_length=50)
capacity = models.IntegerField()
geom = models.PointField(srid=6668)
def __str__(self):
return self.name
ここでは主に max_length
オプションの変更を行っています。もとの geojsonデータを見て、だいたいの感じでオプションを与えます。
migrations & migrate
Vultr
$ python manage.py makemigrations
Migrations for 'map':
map/migrations/0001_initial.py
- Create model Hoikusho
$ python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, map, sessions
Running migrations:
Applying map.0001_initial... OK
データベースにデータをインポート
django.contrib.gis.utils
の LayerMapping
クラスは、空間データをGeoDjango モデルに適用するツールを提供しています。
geojsonのキーワードと、GeoDjangoのフィールド名をマッピングした辞書を渡すと、データベースにデータをアップロードしてくれます。
今回のgeojsonデータはこういう形で
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [ 139.777421,35.699016 ]
},
"properties": {
"owned":"区市町村",
"name":"いずみこども園",
"postalcode":"101-0024",
"address":"千代田区神田和泉町1",
"gcs":"JGD2011",
"tel":"03-3866-9938",
"capacity":36
}
},
モデルはこういう形なので、
class Hoikusho(models.Model):
owned = models.CharField(max_length=50)
name = models.CharField(max_length=50)
postalcode = models.CharField(max_length=10)
address = models.CharField(max_length=250)
gcs = models.CharField(max_length=10)
tel = models.CharField(max_length=50)
capacity = models.IntegerField()
geom = models.PointField(srid=6668)
下記のような辞書を渡すスクリプトを書きます。スクリプトファイルは map/load_hoikusho.py
にしました。(任意)
# map/load_hoikusho.py
import os
from django.contrib.gis.utils import LayerMapping
from map.models import Hoikusho
mapping = {
"owned": "owned",
"name": "name",
"postalcode": "postalcode",
"address": "address",
"gcs": "gcs",
"tel": "tel",
"capacity": "capacity",
"geom": "Point",
}
# `201810-2-1-hoikusyo.geojson` へのファイルパス
geojson_file = os.path.abspath(
os.path.join(
os.path.dirname(__file__), 'data', '201810-2-1-hoikusyo.geojson'
)
)
# 実行
def run(verbose=True):
lm = LayerMapping(
Hoikusho,
geojson_file,
mapping,
transform=False,
encoding='UTF-8',)
lm.save(strict=True, verbose=verbose)
これをshellで実行します。
Vultr
$ python manage.py shell
>>> from map import load_hoikusho
>>> load_hoikusho.run()
Saved: Hoikusho object (1)
Saved: Hoikusho object (2)
Saved: Hoikusho object (3)
......
Saved: Hoikusho object (2778)
Saved: Hoikusho object (2779)
>>> exit()
管理画面の設定
地図を管理画面で確認できるように設定します。
# map/admin.py
# from django.contrib import admin
from django.contrib.gis import admin
from map.models import Hoikusho
# オープンストリートマップにマッピングする
admin.site.register(Hoikusho, admin.OSMGeoAdmin)
url 設定
# config/urls.py
# from django.contrib import admin
from django.contrib.gis import admin
from django.urls import path
urlpatterns = [
path('admin/', admin.site.urls),
]
表示
Vultr
$ python manage.py runserver xx.xxx.xx.xx:8000
xx.xxx.xx.xx:8000/admin
で地図が表示されていれば成功です!
独自ドメインで表示
いつまでも IP アドレスのままではかっこ悪いので、自分のドメインで表示させるための設定を行います。すでにドメインは持っていることを前提にします。最近よく、porkbun.comでドメインを買っています。ぶたさんがかわいいので。
- Django設定:今回はDjangoの簡易ウェブサーバを使い続けることにしたので変更なし。
- レジストラで Name Server の設定変更
- ns1.vultr.com / ns2.vultr.com を追加してください
- Vultr 設定
-
https://my.vultr.com/dns/ >
Add Domain
ボタン(右上にある)を押す。 - Domainと、自分のインスタンスのIPアドレスを入れる
-
https://my.vultr.com/dns/ >
- firewall設定
- https://my.vultr.com/firewall/
- Add Firewall Group
-
Add Firewall Group
に適当な名前をつける。 -
Action
の+
ボタンを押す - Protocol を
HTTP
Port を80
にして Action の+
ボタンを押す。注意:HTTP を選んでも、表示上はTCP
になる。これでOK。 -
Firewall group updated. It may take up to 120 seconds for these changes to apply.
と出たらOK
-
npam
して確認。80/tcp
が追加されていたら80番ポートが開いたということなのでOKLocal
$ nmap -v xx.xx.xx.xxx Starting Nmap 7.60 ( https://nmap.org ) at 2019-12-14 22:48 JST Initiating Ping Scan at 22:48 Scanning xx.xx.xx.xxx [2 ports] Completed Ping Scan at 22:48, 0.00s elapsed (1 total hosts) Initiating Parallel DNS resolution of 1 host. at 22:48 Completed Parallel DNS resolution of 1 host. at 22:48, 0.00s elapsed Initiating Connect Scan at 22:48 Scanning xx.xx.xx.xxx.vultr.com (xx.xx.xx.xxx) [1000 ports] Discovered open port 22/tcp on xx.xx.xx.xxx Completed Connect Scan at 22:48, 4.41s elapsed (1000 total ports) Nmap scan report for xx.xx.xx.xxx.vultr.com (xx.xx.xx.xxx) Host is up (0.0032s latency). Not shown: 998 filtered ports PORT STATE SERVICE 22/tcp open ssh 80/tcp closed http # ←ここ!
runserver すると
80/tcp closed http
がopen
に変わります。 -
runserver する。ただし sudo をつけてかつ、python へのFull path を指定しなくてはいけない.
Vultr
$ sudo /home/shinseitaro/miniconda3/envs/py37/bin/python manage.py runserver xx.xx.xx.xxx:80
もう一度
nmap
すると open に変わっているはずです。指定したドメインで開いてみてください。
おしまい。
あしたは、@kaizumakiさんです。