Oracle Cloudで常時無料サービスが開始されたので使ってみた。
構成は、Django+nginx+uWSGI+Oracle Database+Oracle Linux
以下の3つの環境を作ってみたので、その時の備忘録。
- ローカルの開発環境
- ローカルでDockerを使った開発環境
- コンピュート・インスタンスでの本番環境
とりあえず、Djangoの雛形アプリにアクセスできるまでの簡易なので、
SSL対応などは省いてます。
Oracle Cloudの常時無料サービス(無料ティア)について
新しく常時無料で利用できるようになったサービスたち。
・Oracle Cloud無償ティア | オラクル | Oracle 日本
利用できるのは、以下のようなもの。
- データベース ... 20GBを2つまで
- コンピュート ... 仮想マシン。1/8 OCPU・1GBを2つまで
- ストレージ ... 合計100GBの2つのブロック・ボリューム。10GBのオブジェクト・ストレージ
ほかにもロードバランサや監視・通知などある。
仮想マシンもデータベースも1アカウントにつき2つまでなので、
1サービスであれば、ステージング環境と本番環境を用意できそう。
とりあえずDBを作ってみる
トップ画面から。
名前とAdminのパスワードを設定する。
Always FreeもONにしておく。
「Autonomous Databaseの作成」をクリックすると、プロビジョンがはじまる。
プロビジョンが終わるとこんな感じに。
WebブラウザでDBにアクセスしてみる
SQL Developer Webからアクセスできる。
「DB接続」>「アプリケーション接続」>「SQL Developer Web」にある。
「アクセスURL」をコピーして、ブラウザに貼り付け。
ログイン画面が表示されるので、DBを作ったときのパスワードを入力。
アカウントは「admin」
ログインできるとこんな感じ
ローカルの開発環境を作ってみる
とりあえず、開発用にローカル環境でpython manage.py runserver
できるようにする。
ローカルの環境はmacOS Mojave(10.14.6)
まずは、Djangoの雛形を作成する
# pythonのバージョンは3.7.3
$ python3 -V
Python 3.7.3
# ディレクトリの作成
$ mkdir sample
$ cd sample/
# 仮想環境の作成
$ python3 -m venv venv
$ source venv/bin/activate
# djangoのインストール
$ pip install --upgrade pip
$ pip install django
# djangoプロジェクトの作成
$ django-admin startproject myproject
$ cd myproject
$ python manage.py migrate
# 起動
$ python manage.py runserver
これでとりあえず、デフォルトのデータベース(SQLite)で立ち上がるとこまで完成。
ローカルでOracleDBを使えるようにする
Oracle Instant Clientのインストール
OracleDBを使うためには、Oracle Instant Clientが必要なので、
以下からダウンロードしてインストールする。
・Oracle Instant Client Downloads
Macだったので、「Instant Client for macOS (Intel x86)」の「Basic Light Package」を選択
## インストールするディレクトリを作成
$ sudo mkdir -p /opt/oracle
## インストールしたファイルを展開
$ sudo unzip ~/Downloads/instantclient-basiclite-macos.x64-19.3.0.0.0dbru.zip -d /opt/oracle
## ライブラリを参照できるように${HOME}/libにリンクを追加
$ mkdir ~/lib
$ ls -s /opt/oracle/instantclient_19_3/libclntsh.dylib ~/lib/
$ cp /opt/oracle/instantclient_19_3/lib* ~/lib/
環境変数にインストールした場所を設定
echo "export ORACLE_HOME=/opt/oracle/instantclient_19_3" >> ~/.bashrc
source ~/.bashrc
認証情報の配置
Oracle Cloudの「Autonomous Database」>「Autonomous Databaseの詳細」にある
「DB接続」からウォレットをダウンロードしてくる。
ファイル名は「Wallet_<データベース名>.zip
」。
今回はデータベース名がsample
なので、Wallet_sample.zip
となる。
## 認証ファイルを配置するディレクトリを作成
$ mkdir -p /opt/oracle/instantclient_19_3/network/admin
## ダウンロードしたウォレットを展開して配置
$ sudo unzip ~/Downloads/Wallet_sample.zip -d ${ORACLE_HOME}/network/admin
Archive: ~/Downloads/Wallet_sample.zip
inflating: /opt/oracle/instantclient_19_3/network/admin/cwallet.sso
inflating: /opt/oracle/instantclient_19_3/network/admin/tnsnames.ora
inflating: /opt/oracle/instantclient_19_3/network/admin/truststore.jks
inflating: /opt/oracle/instantclient_19_3/network/admin/ojdbc.properties
inflating: /opt/oracle/instantclient_19_3/network/admin/sqlnet.ora
inflating: /opt/oracle/instantclient_19_3/network/admin/ewallet.p12
inflating: /opt/oracle/instantclient_19_3/network/admin/keystore.jks
cx_Oracle(pythonライブラリ)のインストール
Oracle Databaseのpythonライブラリをインストールする
$ pip install cx_Oracle
settings.pyの設定
settings.pyをOracleように変更。
NAME
には、TNS名のどれかを指定する。
今回は一番上のsample_HIGH
を選択。
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.oracle',
'NAME': 'sample_HIGH',
'USER': 'admin',
'PASSWORD': '<DB作成時に入力したパスワード>',
}
}
マイグレーションをもう一度実行してみて、接続できるか確認。
$ python manage.py migrate
マイグレーションが成功すると、Webブラウザ上のSQL Developerでも確認できる。
これで、とりあえず、開発できるようになった(´ω`)
ローカルでDockerを使った開発環境を作ってみる
実際にデプロイする際は、NginxとuWSGIを利用するので、
それを試せる環境をDockerで構築する。
Django側の変更
nginx+uWSGIで動かすために、いくつか変更。
1. STATIC_ROOTとALLOWED_HOSTS設定
settings.pyを以下の感じに変更。
ログファイルも出るように変更。
-ALLOWED_HOSTS = []
+ALLOWED_HOSTS = ["127.0.0.1"]
...
STATIC_URL = '/static/'
+STATIC_ROOT = os.path.join(BASE_DIR, "static/")
+# for logging
+LOGGING = {
+ 'version': 1,
+ 'disable_existing_loggers': False,
+
+ 'formatters': {
+ 'standard': {
+ 'format': "[%(asctime)s] %(levelname)s [%(name)s:%(lineno)s] %(message)s",
+ 'datefmt': "%d/%b/%Y %H:%M:%S"
+ },
+ },
+ 'handlers': {
+ 'file': {
+ 'level': 'INFO',
+ 'class': 'logging.handlers.RotatingFileHandler',
+ 'filename': 'django.log',
+ 'maxBytes': 50000,
+ 'backupCount': 2,
+ 'formatter': 'standard',
+ },
+ },
+ 'loggers': {
+ 'django': {
+ 'handlers': ['file'],
+ 'level': 'DEBUG',
+ 'propagate': True,
+ },
+ },
+}
2. staticディレクトリを作成&配置
manage.pyと同じ場所に作成し、
django-adminのcssとかを配置
$ mkdir static
$ python manage.py collectstatic
Docker用の資材を配置
# Docker用の資材の配置場所を作成
$ mkdir docker
# 資格情報の配置
$ mkdir docker/wallet
$ unzip ~/Downloads/Wallet_sample.zip -d docker/wallet/
Archive: ~/Downloads/Wallet_sample.zip
inflating: wallet/cwallet.sso
inflating: wallet/tnsnames.ora
inflating: wallet/truststore.jks
inflating: wallet/ojdbc.properties
inflating: wallet/sqlnet.ora
inflating: wallet/ewallet.p12
inflating: wallet/keystore.jks
# NginxやuWSGIの設定ファイルは以下に配置
$ mkdir docker/conf
$ touch docker/conf/requirements.txt
$ touch docker/conf/myproject_nginx.conf
$ touch docker/conf/myproject_uwsgi.ini
$ touch docker/conf/uwsgi.service
# Dockerfireとdocker-compose.ymlを配置
$ touch docker/Dockerfile
$ touch docker-compose.yml
ディレクトリ的にはこんな感じ。
.
├── docker/
│ ├── conf/
│ │ ├── myproject_nginx.conf
│ │ ├── myproject_uwsgi.ini
│ │ └── uwsgi.service
│ ├── wallet
│ │ ├── ...
│ │ └── tnsnames.ora
│ ├── Dockerfile
│ └── requirements.txt
├── myproject/
│ ├── myproject/
│ │ ├── settings.py
│ │ └── wsgi.py
│ ├── static/
│ └── manage.py
├── venv/
└── docker-compose.yml
各ファイルの中身は以下の感じ。
docker-compose.yml
version: '2'
services:
web:
build: "./docker"
volumes: # djangoアプリを/var/www配下にマウント
- ./myproject:/var/www/myproject
ports: # 80および8000ポートを開けておく
- "80:80"
- "8000:8000"
# systemctlを使うので特権を有効にしておく
privileged: true
command: /sbin/init
docker/Dockerfile
# Oracle Cloud Infrastructureでも
# OracleLinuxを使うのでoraclelinuxのイメージを使う
FROM oraclelinux:7
### ENV
ENV ORACLE_HOME "/usr/lib/oracle/18.3"
### INSTALL ORACLE DATABASE
# oracle-instantclientを利用するために、2つリポジトリを有効化
RUN yum install -y oracle-release-el7 oracle-softwarecollection-release-el7
RUN yum install -y oracle-instantclient18.3-basiclite
RUN echo /usr/lib/oracle/18.3/client64/lib > /etc/ld.so.conf.d/oracle-instantclient.conf
RUN mkdir -p ${ORACLE_HOME}/network/admin
COPY wallet/* ${ORACLE_HOME}/network/admin/
### INSTALL PYTHON
# python3-develを利用するために、ol7_optional_latestを有効化
RUN yum-config-manager --enable ol7_optional_latest
RUN yum install -y python3 python3-devel gcc
### CREATE VIRTUAL ENV
RUN mkdir /var/www/
RUN mkdir /var/www/myproject
WORKDIR /var/www/
RUN python3 -m venv venv
# 作成した仮想環境(venv)にactivateする
ENV PATH="/var/www/venv/bin:$PATH"
COPY requirements.txt /var/www/
RUN pip install -r requirements.txt
#### INSTALL NGINX
RUN yum install -y nginx
COPY conf/myproject_nginx.conf /etc/nginx/conf.d/
RUN systemctl enable nginx
RUN chown -R nginx.nginx /var/www
RUN chmod 755 /var/www
### SETUP uWSGI Emperor mode
RUN mkdir /etc/uwsgi
RUN mkdir /etc/uwsgi/vassals
COPY conf/myproject_uwsgi.ini /etc/uwsgi/vassals
# uWSGIのログディレクトリを作成
RUN mkdir /var/log/uwsgi
RUN chown -R nginx:nginx /var/log/uwsgi
# uWSGIをサービスに登録
COPY conf/uwsgi.service /etc/systemd/system/
RUN systemctl enable uwsgi
docker/conf/requirements.txt
Django==2.2.7
cx-Oracle==7.2.3
uWSGI==2.0.18
docker/conf/myproject_nginx.conf
# the upstream component nginx needs to connect to
upstream django {
# myproject_uwsgi.iniで設定したsocketファイルを指定
# unix://<socketファイルのパス>
server unix:///var/www/myproject.sock;
}
# configuration of the server
server {
listen 80;
# IPアドレスを指定。ローカルなので、127.0.0.1を設定
server_name 127.0.0.1;
charset utf-8;
# Django static
location /static {
alias /var/www/myproject/static;
}
# Finally, send all non-media requests to the Django server.
location / {
include uwsgi_params;
uwsgi_pass django;
}
}
docker/conf/myproject_uwsgi.ini
[uwsgi]
# Djangoプロジェクトのパスを指定
chdir = /var/www/myproject
# Djangoプロジェクトのwsgi.pyを指定
module = myproject.wsgi
# venvのパスを指定
home = /var/www/venv
# process-related settings: master
master = true
# maximum number of worker processes
processes = 10
# socketファイルののパス
socket = /var/www/myproject.sock
# socketファイルのユーザと権限を設定
chown-socket = nginx:nginx
chmod-socket = 666
# clear environment on exit
vacuum = true
# logfile
logto = /var/log/uwsgi/%n.log
docker/conf/uwsgi.service
[Unit]
Description=uWSGI Emperor
After=syslog.target
[Service]
User=nginx
Group=nginx
# 環境変数の設定
Environment="ORACLE_HOME=/usr/lib/oracle/18.3"
Environment="LD_LIBRARY_PAT=${ORACLE_HOME}/client64/lib:$LD_LIBRARY_PATH"
Environment="PATH=$PATH:${ORACLE_HOME}/client64/lib"
# EmperorモードでuWSGIを実行。venvにあるuwsgiを使う
ExecStart=/var/www/venv/bin/uwsgi --master --emperor /etc/uwsgi/vassals --die-on-term --uid nginx --gid nginx --logto /var/log/uwsgi/emperor.log
Restart=always
KillSignal=SIGQUIT
Type=notify
StandardError=syslog
NotifyAccess=all
[Install]
WantedBy=multi-user.target
Dockerを起動
# dockerを立ち上げ
$ docker-compose up -d
これでうまくビルドされて立ち上がれば、
http://127.0.0.1
にアクセスできる。
myproject_nginx.conf
のserver_name
で、127.0.0.1
を指定しているので、
http://127.0.0.1
じゃないとDjangoアプリにアクセスできないので注意。
http://localhost
だと、myproject_nginx.conf
の設定が適用されず、
nginxのデフォルトページが表示される。
よく使うログインとか停止とかはこんな感じ。
# コンテナにログイン
$ docker-compose exec web /bin/bash
# 停止
$ docker-compose stop
# 削除
$ docker-compose rm
# Dockerfile ビルド
$ docker-compose build
# Dockerfile ビルド(キャッシュなし)
$ docker-compose build --no-cache
# コンテナをせんぶ削除
$ docker rm `docker ps -a -q`
うまくいかないときにみるところ
以下の場所にログファイルが出力されるので見てみる。
-
/var/log/messages
... systemdのログ -
/var/log/nginx/error.log
... nginxのエラーログ -
/var/log/uwsgi/emperor.log
... uWSGI Emperorのログ -
/var/log/uwsgi/myproject_uwsgi.log
... myproject_uwsgi.iniのログ -
/var/www/myproject/django.log
... Djangoプロジェクトのログ
あとは、「パスが正しいか」「権限、オーナーが正しいか」などを見てみるといいかも。
コンピュート・インスタンスで公開してみる
仮想インスタンスの作成
ここから選択。
こんな感じで入力。
「パブリックIPアドレスの割当」を選択しておく。
ちゃんと「パブリックIPアドレスの割当」を選択していると、
ここにIPアドレスが表示される
デフォルトのユーザはopc
なので、
こんな感じで、sshでログインできる。
$ ssh opc@<IPアドレス>
セキュリティルールを設定
HTTP(ポート80)でアクセスできるようにセキュリティルールを設定する
ただ、セキュリティルールを設定する場所は少しわかりにくい。。
仮想インスタンスの詳細にアクセスして、
「仮想クラウド・ネットワーク」を選択
左下に「ネットワーク・セキュリティ・グループ」を選択。
「ネットワーク・セキュリティ・グループの作成」を選択すると、追加できるようになる。
「名前」と「コンパートメント」に作成を設定
ルールの追加を以下のように設定して、「作成」をクリック
これで作成できたので、仮想インスタンスの詳細にもどって、
「ネットワーク・セキュリティ・グループ」の「編集」を選択
さっき作ったセキュリティグループを設定
環境構築
Dockerfileでやったような感じで、
Django+nginx+uWSGIな環境を構築してく。
DockerイメージのOracleLinuxとは違い、
- リポジトリが最初から有効化されている
- SELinuxが有効化されている
という感じなので、ちょっと変更が必要。
資材を仮想インスタンスに送る
Dockerのときに使った資材を仮想インスタンスに送る。
$ scp -r docker opc@<IPアドレス>:~/
$ scp -r myproject/ opc@<IPアドレス>:~/
送信したら、ログインして確認。
$ ssh opc@<IPアドレス>
$ pwd
/home/opc
$ ls
docker myproject
ログイン後のディレクトリ構成はこんな感じ
/home/opc
├── docker/
│ ├── conf/
│ │ ├── myproject_nginx.conf
│ │ ├── myproject_uwsgi.ini
│ │ └── uwsgi.service
│ ├── wallet
│ │ ├── ...
│ │ └── tnsnames.ora
│ ├── Dockerfile
│ └── requirements.txt
├── myproject/
│ ├── myproject/
│ │ ├── settings.py
│ │ └── wsgi.py
│ ├── static/
│ └── manage.py
├── venv/
└── docker-compose.yml
設定ファイルの変更
IPアドレスと127.0.0.1
にしていたので変更する。
~/docker/conf/myproject_nginx.conf
server {
- server_name 127.0.0.1;
+ server_name <IPアドレス>;
}
~/myproject/myproject/settings.py
-ALLOWED_HOSTS = ["127.0.0.1"]
+ALLOWED_HOSTS = ["<IPアドレス>"]
環境構築の実施
$ sudo -s
### INSTALL ORACLE DATABASE
$ yum install -y oracle-instantclient18.3-basiclite
$ echo /usr/lib/oracle/18.3/client64/lib > /etc/ld.so.conf.d/oracle-instantclient.conf
$ mkdir -p /usr/lib/oracle/18.3/network/admin
$ /home/opc/docker/wallet/* /usr/lib/oracle/18.3/network/admin/
### INSTALL PYTHON
$ yum install -y python3 python3-devel gcc
### CREATE VIRTUAL ENV
$ mkdir /var/www/
$ cp -r /home/opc/myproject /var/www
$ cd /var/www/
$ python3 -m venv venv
# 作成した仮想環境(venv)にactivateする
$ source venv/bin/activate
$ pip install -r /home/opc/docker/requirements.txt
#### INSTALL NGINX
$ yum install -y nginx
$ cp /home/opc/docker/conf/myproject_nginx.conf /etc/nginx/conf.d/
$ systemctl enable nginx
$ chown -R nginx.nginx /var/www
# $ chmod 755 /var/www
### SETUP uWSGI Emperor mode
$ mkdir -p /etc/uwsgi/vassals
$ cp /home/opc/docker/conf/myproject_uwsgi.ini /etc/uwsgi/vassals
# uWSGIのログディレクトリを作成
$ mkdir /var/log/uwsgi
$ chown -R nginx:nginx /var/log/uwsgi
# uWSGIをサービスに登録
$ cp /home/opc/docker/conf/uwsgi.service /etc/systemd/system/
$ systemctl enable uwsgi
##### ここから仮想インスタンス独自の設定
### Firewallの設定
# httpを追加する
$ firewall-cmd --permanent --add-service=http
# firewallを再起動して変更を反映
$ systemctl restart firewalld.service
### SELinuxの設定
$ restorecon -RF /var/www
### サービスの起動
$ systemctl restart nginx
$ systemctl restart uwsgi
一度、http://<IPアドレス>
にアクセスして確認してみる。
エラーページが出ていたら、以下を実行
# 監査ログを確認
$ cat /var/log/audit/audit.log | grep nginx | audit2allow -m nginx
# ポリシーファイルを作成
$ cat /var/log/audit/audit.log | audit2allow -M nginx
# ポリシーファイルを適用
$ semodule -i nginx.pp
これで、http://<IPアドレス>
にアクセスして、
Djangoの画面が表示されて、django-adminの画面が操作できればOK
おわりに
とりあえず、ローカルとインスタンス上の環境が作れたので、
色々することはできそう(´ω`)
SSL対応、権限周りなど、本番としては足りないところがあるので、
そのあたりは他の記事を参照ください〜ヽ(=´▽`=)ノ
こんなのつくってます!!
積読用の読書管理アプリ 『積読ハウマッチ』をリリースしました!
積読ハウマッチは、Nuxt.js+Firebaseで開発してます!
もしよかったら、遊んでみてくださいヽ(=´▽`=)ノ
要望・感想・アドバイスなどあれば、
公式アカウント(@MemoryLoverz)や開発者(@kira_puka)まで♪
参考にしたサイトさま
- データベース | Django ドキュメント | Django
- cx_Oracle - Python Interface for Oracle Database
- cx_Oracle 7 Installation — cx_Oracle 7.3.0-dev documentation
- Instant Client for macOS (Intel x86)
- ODPI-C Installation — ODPI-C v3.2.2
- Macでsqlplus使えるようにするメモ - ビットの海
- trouble running Oracle_cx on macOS · Issue #56 · oracle/python-cx_Oracle
- SSHを使用したOracle Linuxインスタンスへのアクセス
- コンピュート・インスタンスに予約済パブリックIPを付与する - Cloudii blog
- SELinux を使おう.使ってくれ. - Qiita
- arch linux - How to set environment variable in systemd service? - Server Fault
- EC2にnginx+uwsgi+python でHello World - Qiita
- uwsgiのsystemd化(pyenv環境) - Qiita
- ちゃんと運用するときのuWSGI設定メモ - Qiita
- Nginx に uWSGI + Django アプリ を組み込む | SaintSouth.NET
- Ubuntu 12.04でpyenvを利用して速攻でPython3.4 + Nginx + uWSGI + FlaskなWebアプリケーション実行環境を作る - Qiita
- nginxでDjangoを使うときの設定ファイル:クライアント、nginx、uwsgiの流れを整理しよう - MathPython
- Setting up Django and your web server with uWSGI and nginx — uWSGI 2.0 documentation
- Elegantly activating a virtualenv in a Dockerfile
- firewall-cmdコマンドの使い方 - Qiita
- Oracle Cloud で Compute にWebサーバーを立てたメモ - Qiita
- venv: Python 仮想環境管理 - Qiita
- SELinux + Nginx ポリシー設定 - URAGAMI
- [CentOS7][Nginx] SELinuxを設定しホームディレクトリ配下のWebコンテンツを公開を許可 | from umentu import stupid
- Dockerイメージとコンテナの削除方法 - Qiita
- いまさらDockerに入門したので分かりやすくまとめます - Qiita
- Dockerネットワーク設定 - Qiita
- Docker Compose - docker-compose.yml リファレンス - Qiita
- Dockerイメージとコンテナの削除方法 - Qiita
- Docker Compose で複数コンテナ構築&管理 - Qiita