tag:crieit.net,2005:https://crieit.net/tags/nginx/feed
「nginx」の記事 - Crieit
Crieitでタグ「nginx」に投稿された最近の記事
2022-02-24T23:44:23+09:00
https://crieit.net/tags/nginx/feed
tag:crieit.net,2005:PublicArticle/18124
2022-02-24T23:29:56+09:00
2022-02-24T23:44:23+09:00
https://crieit.net/posts/Gitlab-push-buffalo
【障害切り分けのコツはまずは森を見ること!】Gitlabのpushエラー、原因は(恐らく?)buffalo製ルータだった話
<p>お久しぶりですにゃ。<br />
やらなきゃいけない事があるからと、”<strong>優先度の低いものをする時間をマストタスクに割り当てよう</strong>”と考えながら<br />
、<strong>結局マスト作業も先延ばしになり帳尻合わせが大変になる</strong>時空を生きて21年目の私です😢</p>
<p>実はこの間に、所属している会社のブログも1ページながら担当させていただきましたねこ!業務内容とおすすめ焼酎4選という内容なので、<br />
良かったら探してみて欲しいぎょぴ!!<br />
(さすがにネコ語は自重しましたぎょぴぼー)<br />
貴重な経験をさせてくださった弊社の担当者様、ありがとうございますにゃー!</p>
<p>久しぶりの投稿ということで前置きが長くなってしまいましたが、<br />
<strong>今回は自宅で特定の通信がハングアップしてしまったときのこと</strong>を綴りますぴょん。<br />
※解決法とういうよりは、ハチャメチャに慌ててる私をご覧いただく記事となります。</p>
<hr />
<h4 id="v目次にゃv"><a href="#v%E7%9B%AE%E6%AC%A1%E3%81%AB%E3%82%83v">v目次にゃv</a></h4>
<p>1.今回起こった問題<br />
2.一旦バックグラウンド<br />
3.対処1<br />
4.対処2<br />
5. 切り分け<br />
6. 今回の件から私が得るべき教訓は…<br />
7. エンドタイトル</p>
<hr />
<h4 id="今回起こった問題"><a href="#%E4%BB%8A%E5%9B%9E%E8%B5%B7%E3%81%93%E3%81%A3%E3%81%9F%E5%95%8F%E9%A1%8C">今回起こった問題</a></h4>
<p>自宅クライアントPCからドメインでGitlabへ200MB付近の容量ファイルをgit pushすると</p>
<blockquote>
<p>error: RPC failed; curl 56 Recv failure: Connection was reset<br />
fatal: The remote end hung up unexpectedly</p>
</blockquote>
<p>とのエラーが出てpushできない。※今回は19MBのサイズでエラー出ました<br />
どうやら<strong>サイズ制限にかかり、正常にpushできていない</strong>みたい。<br />
※ファイルサイズが小さいものは問題なくpushできます。</p>
<p>〇 5KB<br />
✖ 19MB</p>
<hr />
<h4 id="一旦バックグラウンド"><a href="#%E4%B8%80%E6%97%A6%E3%83%90%E3%83%83%E3%82%AF%E3%82%B0%E3%83%A9%E3%82%A6%E3%83%B3%E3%83%89">一旦バックグラウンド</a></h4>
<p>唐突ですが、当時の自宅の簡単な構成を…<br />
<a href="https://crieit.now.sh/upload_images/c8e3813e38831a16492d64162853d8f062177aebea260.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/c8e3813e38831a16492d64162853d8f062177aebea260.png?mw=700" alt="image.png" /></a></p>
<p>Windowsサーバより外の構成は私関与していなかったので、聞き伝えでの図ですが…<br />
今回、外部からWebサーバにアクセスできるように<strong>buffaloルータでポート開放</strong>されていますうさぎ~。</p>
<p>また、CentOS内部では、80番ポートはプロジェクト管理ソフトWebGUIへ(Apache)<br />
GitLabはパッケージ内包のNginxで動いています。<br />
<strong>hoge/projects</strong>と<strong>hoge/gitlab</strong>で<strong>サブディレクトリ</strong>にして、<strong>Apaceでリバースプロキシ設定で運用</strong>していますきんぎょ~。<br />
今回アクセスする経路はドメイン指定するので<strong>1度インターネット抜けしてからLAN内にあるサーバに戻ってくる</strong>形です。(混乱する要因の1つ)<br />
この辺の詳細は省きます。わけわかランボルギーニ~(^^♪<ふんっ!ふんっ!</p>
<hr />
<h4 id="対処1"><a href="#%E5%AF%BE%E5%87%A6%EF%BC%91">対処1</a></h4>
<p>原因を調べたところ、GItLab側(Nginx)で<strong>一定値を超えるものは制限</strong>をかけているらしい。(そもそも大容量通信を想定していない)<br />
早速、ネットに記載されていた対処法を試すねこ!</p>
<p>まずは<strong>クライアント側でバッファを増やす設定</strong>をするにゃ</p>
<pre><code>git config --global http.postBuffer 524288000
</code></pre>
<p>次に<strong>サーバ側のGitlabのサイズ制限を変更す</strong>るために、Nginxのconfigに追記するぎょぴぼー。</p>
<pre><code>client_max_body_size 200M
</code></pre>
<p>その後、各ソフトとサーバーを<strong>再起動</strong>っぽ!<br />
。<br />
。<br />
。<br />
同じエラーが返ってくる…</p>
<hr />
<h4 id="対処2"><a href="#%E5%AF%BE%E5%87%A6%EF%BC%92">対処2</a></h4>
<p>根気強くネットで解決策をさがすと、”<strong>プロキシを挟まずに直でGitlabにつないだらいけた</strong>!!”との記事を発見!<br />
バックグラウンドを見ていただくと分かると思いますが、自宅構成では<br />
<strong>クライアントからGitlabに行く際に、リバースプロキシを介しています</strong>。<br />
しかし、リバースプロキシを使わないと、Gitlabかプロジェクト管理GUIのどちらか一方しかアクセス出来なくなりますぴょん…<br />
もちろん、URLでポート指定すればよいのですが、ユーザ側の負担が増えるため却下ですにゃ…<br />
というか、そもそも<strong>Apacheにデフォルトでサイズ制限はない</strong>らしい!!(もしかしたらという事もあるので一応設定をいろいろ試しました)</p>
<hr />
<h4 id="切り分け"><a href="#%E5%88%87%E3%82%8A%E5%88%86%E3%81%91">切り分け</a></h4>
<p>ここまで、サーバ側、もしくはクライアントの設定を疑い試行錯誤してきましたが、一向に解決しないため、<br />
サーバ内だけでなく全体を見て切り分けを行いましたきんぎょ。<br />
通常なら切り分けを最初にするべきですが、ネット上に同じ問題に直面している方がおり、<br />
さらに解決策まで載っているという事で<strong>先入観を持ってしまったのが私の敗因</strong>ですねこ…</p>
<p>まずはリバースプロキシが原因かどうかを確認するため、<br />
新しくテスト仮想サーバをつくり、Gitlabだけ構築します。<br />
Gitlabは設定を変更せず、リポジトリだけ作成し、大容量push時にエラーを返す状態を再現します。<br />
ドメインを紐づけるのはめんどくさかったので、プライベートIPで開くようにしました。</p>
<p>↓リポジトリパス↓</p>
<blockquote>
<p>http:\192.168.100.101/gitlab/piyopiyo.git</p>
</blockquote>
<pre><code>###push 結果↓
〇 5KBのデータ ←小さいファイルはOKですね
〇 19MBのデータ ←え!?pushできた!!!!
</code></pre>
<p>ということは、<strong>GitlabやNginxは問題なし</strong>。リバースプロキシが怪しい…<br />
前段階でリバースプロキシは違うと踏んでただけに驚きました。</p>
<p>より本番環境に近い(外部からのアクセス)挙動も確認したいので、一応ドメインとIPを紐づける(もちろん本番環境のIPは重複を避け変更しておく)<br />
クライアント側でリポジトリのパスをドメイン指定に変更<br />
↓リポジトリパス↓</p>
<blockquote>
<p>http:\hogehoge.nk/gitlab.piyopiyo.git</p>
</blockquote>
<pre><code>###push 結果↓
〇 5KBのデータ ←小さいファイルはOK
✖ 19MBのデータ ←あれ、いつものエラーで通らない…💦
</code></pre>
<p>小さいファイルは通っているのでDNSの根本的な間違えはなさそう…<br />
今回はリバースプロキシは設定していないので、リバースプロキシのせいでエラーが出るわけではなさそう<br />
もしや、<strong>wanを抜ける過程で失敗している</strong>??</p>
<hr />
<p>テスト仮想サーバを閉じ、本番サーバのIPとドメインを紐づけ直して再度検証</p>
<pre><code>###push 結果↓
〇 5KBのデータ ←小さいのは通った!
✖ 19MBのデータ ←通らない
</code></pre>
<p>この場合、以下の2つ範囲で考えることが出来ますね。<br />
<strong>①プロバイダ側で何かしら制限がある(これだったらお手上げです😢)<br />
②自分の管轄範囲のNWで問題がある</strong></p>
<p><del><strong>想定できる原因</strong></del><br />
<del>・大容量通信は弾いている<br />
→Youtube等の大容量のデータはup,down共に正常に疎通可能。おそらく違う。</del></p>
<p><del>・特定プロトコルの大容量データを弾いている<br />
→gitの仕様詳細まで分からず、未検証。(今回はサイズによらずHTTPを使っているはず)</del></p>
<p><del>・十分な帯域が確保できず、通信量を絞っている<br />
→サーバ側のタイムアウト時間も延長したがダメ</del></p>
<p>Lanでは繋がり、Wanでは繋がらない(小さいデータは繋がるが)という事で、私の手が届く1番Wan側のbuffaloルータを詳しく見てみます。<br />
設定を覗いた感じ、QoSが設定してあるわけでもなく、問題はなさそう。<br />
<strong>機器固有の設定は不明</strong>なので、我が家にある<strong>FortiGateに置き換えることにした</strong>にゃ!<br />
<a href="https://crieit.now.sh/upload_images/c8e3813e38831a16492d64162853d8f0621774bb13a10.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/c8e3813e38831a16492d64162853d8f0621774bb13a10.png?mw=700" alt="image.png" /></a><br />
ついでなので、セグメント別けしました。(NW図の構成が甘くてすみません)</p>
<p>FortiGateの設定を行い、接続確認をしました。<br />
↓リポジトリパス↓</p>
<blockquote>
<p>http:\hogehoge.nk/gitlab.piyopiyo.git</p>
</blockquote>
<pre><code>###push 結果↓
〇 5KBのデータ ←小さいファイルはOK
〇 19MBのデータ ←無事に通った!
</code></pre>
<p><strong>通常利用が想定されるWanを介しての大小データのpushに成功したのにゃ!!</strong></p>
<hr />
<h4 id="今回の件から私が得るべき教訓は…"><a href="#%E4%BB%8A%E5%9B%9E%E3%81%AE%E4%BB%B6%E3%81%8B%E3%82%89%E7%A7%81%E3%81%8C%E5%BE%97%E3%82%8B%E3%81%B9%E3%81%8D%E6%95%99%E8%A8%93%E3%81%AF%E2%80%A6">今回の件から私が得るべき教訓は…</a></h4>
<p>まずは、今回、問題解決に至るまでのネックポイント<br />
・ネット記事に、同一サーバにWebサーバを同時導入(リバースプロキシ使用)例が少ない<br />
・GitHubの方がユーザが多くGitlabはどちらかといえば少数派なため、なぜかGithubの記事に案内される<br />
・Hyper-vよりDockerを使用している例が多いため、解決法がマッチしない<br />
・buffaloルータの仕様を理解できていない</p>
<p>以上を踏まえ、<strong>今回の件から私が得るべき教訓は、全体を見て切り分けをしっかりしよう!ということだ。</strong></p>
<p>↓今回の切り分け例↓<br />
<strong>サーバサイド</strong><br />
・リバースプロキシがおかしい<br />
・Gitlabがおかしい<br />
・Nginxがおかしい<br />
・ポートやファイアウォールの設定がうまく機能していない<br />
<strong>その他物理</strong><br />
・クライアントの設定ミス<br />
・物理機器の故障、謎仕様<br />
<strong>ネットワークサイド</strong><br />
・Wan側がおかしい<br />
・Lan側がおかしい<br />
・NW境界部がうまく機能していない</p>
<p>てっきりサーバ側だと思い込んでそちらばかり対応にあたったのがダメでした。<br />
今回は<strong>ネットワークサイド、NW境界部(buffaloルータの仕様なのかな?)があたり</strong>でしたね…<br />
結局、最たる原因は仕様が不明のため、buffaloさんには問い合わせて回答をいただく予定です。</p>
<h4 id="エンドタイトル"><a href="#%E3%82%A8%E3%83%B3%E3%83%89%E3%82%BF%E3%82%A4%E3%83%88%E3%83%AB">エンドタイトル</a></h4>
<p>今回は個人的にいろいろな事象が複雑に面倒くさく絡まっていたのが、解決への道を妨げるものでした。<br />
リソースの関係上仕方がないとはいえ、シンプルな設計の重要さを身をもって学びました。み〇ほ銀行のジャングルシステムがいい例ですね。いや、悪い例か…<br />
複雑なものをどのようにまとめようか思考しながら筆をとった結果、語尾も中途半端になる始末…(しかも非常に読みづらくて申し訳ない)</p>
<p>今回はここまで🐾<br />
自宅にて、焼酎のお湯割りを飲みながら…。</p>
<p>次回も頑張るきんぎょー…</p>
<h5 id="編集後記"><a href="#%E7%B7%A8%E9%9B%86%E5%BE%8C%E8%A8%98">編集後記</a></h5>
<p>私のCrieit記事では、私個人の思ったことや考えを色濃く記事に出しています。qiitaやStack Overflowのような解決を求める記事や、参考となる記事とは違い、実際に困難(?)に直面しているへっぽこ技術者の狭い視野やドキドキを臨場感のある雰囲気を含め楽しんで屍を越えて下されば幸いです。</p>
<p>せっかくなので、次回あたりFortiGateの設定などもご紹介できればよいですにゃ~…</p>
keito_woood
tag:crieit.net,2005:PublicArticle/16587
2021-01-13T15:45:49+09:00
2021-01-13T18:21:58+09:00
https://crieit.net/posts/2021-1-13
nginx + uWSGI + Flask で python webアプリを立ち上げる
<h1 id="nginx + uWSGI + Flask で python webアプリを立ち上げる"><a href="#nginx+%2B+uWSGI+%2B+Flask+%E3%81%A7+python+web%E3%82%A2%E3%83%97%E3%83%AA%E3%82%92%E7%AB%8B%E3%81%A1%E4%B8%8A%E3%81%92%E3%82%8B">nginx + uWSGI + Flask で python webアプリを立ち上げる</a></h1>
<p>開発中は Flask の dev server で良いのだけれど、リリース時にはフロントのHTTPサーバを用意する必要がある。</p>
<p>Deployment は選択肢がいくつかあるけれど、今回はUbuntu上で、HTTPサーバに nginx、Flaskで作ったPython Webアプリを動かす WSGIコンテナに uWSGI を使った構成の設定例。</p>
<h2 id="インストール"><a href="#%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB">インストール</a></h2>
<p>nginx, uwsgi, Flask をインストールする。uwsgi と Flask は venv 環境で。</p>
<pre><code class="shell">$ uname -a
Linux hoge-machine 5.4.0-52-generic #57~18.04.1-Ubuntu SMP Thu Oct 15 14:04:49 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
$ sudo apt install nginx
$ python3 -V
Python 3.6.9
$ mkdir venv; cd venv
$ python3 -m venv flaskapp
$ source ~/venv/flaskapp/bin/activate
(flaskapp) $ pip install -U pip
(flaskapp) $ pip install flask uwsgi
</code></pre>
<h2 id="nginx の設定ファイル"><a href="#nginx+%E3%81%AE%E8%A8%AD%E5%AE%9A%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB">nginx の設定ファイル</a></h2>
<p><a target="_blank" rel="nofollow noopener" href="https://flask.palletsprojects.com/en/1.1.x/deploying/uwsgi/#configuring-nginx">https://flask.palletsprojects.com/en/1.1.x/deploying/uwsgi/#configuring-nginx</a></p>
<p>flask で uwsgi を使う場合の nginx 設定ファイル例は上に載っているので、それを参考に。<br />
アプリ名を <code>nginx_yourapp</code> とか <code>your_application</code> とかにしているが適当に変える。</p>
<p>nginx_yourapp.conf</p>
<pre><code class="conf">server {
listen 80;
listen [::]:80;
server_name hoge-machine.com;
root /var/www/example.com;
index index.html;
location = /your_application { rewrite ^ /your_application/; }
location /your_application {
try_files $uri @your_application;
}
location @your_application {
include uwsgi_params;
uwsgi_pass unix:/tmp/your_application.sock;
}
}
</code></pre>
<p>nginx の設定ファイルは <code>/etc/nginx/sites-available</code> 下に置いて、<code>/etc/nginx/sites-enabled</code> 下に<br />
シンボリックリンクを張り、サービス再起動する。Permission 関係はよしなに。</p>
<pre><code class="shell">$ mkdir -p ~/path/to/nginx_yourapp; cd ~/path/to/nginx_yourapp
$ vim nginx_yourapp.conf
(上記の設定ファイルを作る)
$ cp nginx_yourapp.conf /etc/nginx/sites-available/
$ ln -s /etc/nginx/sites-available/nginx_yourapp.conf /etc/nginx/sites-enabled/nginx_yourapp.conf
$ systemctl restart nginx
</code></pre>
<h2 id="webアプリの準備"><a href="#web%E3%82%A2%E3%83%97%E3%83%AA%E3%81%AE%E6%BA%96%E5%82%99">webアプリの準備</a></h2>
<p><a target="_blank" rel="nofollow noopener" href="https://flask.palletsprojects.com/en/1.1.x/quickstart/#a-minimal-application">https://flask.palletsprojects.com/en/1.1.x/quickstart/#a-minimal-application</a></p>
<p>Flask の HelloWorld。</p>
<p>index.py</p>
<pre><code class="python">from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello_world():
return "Hello, World!"
</code></pre>
<h2 id="uwsgi の起動コマンド"><a href="#uwsgi+%E3%81%AE%E8%B5%B7%E5%8B%95%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89">uwsgi の起動コマンド</a></h2>
<ul>
<li>ソケットファイルは nginx の設定ファイルと合わせること</li>
<li><code>--chmod-socket=666</code> はパーミッション関連でこけたら</li>
<li><code>--mount</code> はアプリパスと実行するスクリプト名:Flask appオブジェクト名を正しく指定する</li>
<li><code>--virtualenv</code> は venv で作ったPython仮想環境を正しく指定する。</li>
</ul>
<pre><code class="shell">$ uwsgi -s /tmp/nginx_yourapp.sock --chmod-socket=666 --manage-script-name --mount /nginx_yourapp=index:app --virtualenv ~/venv/flaskapp
</code></pre>
<p>後はブラウザから <code>http://<サーバのIPアドレス>/nginx_yourapp/</code> にアクセスすれば <code>Hello World</code> が表示される。</p>
<h2 id="FAQ"><a href="#FAQ">FAQ</a></h2>
<h3 id="502 Bad Gateway が出る"><a href="#502+Bad+Gateway+%E3%81%8C%E5%87%BA%E3%82%8B">502 Bad Gateway が出る</a></h3>
<p>ソケットファイルの permission 関連がおかしいかも。<br />
<code>/var/log/nginx/error.log</code> あたりを覗くとヒントがあるかも。</p>
<h3 id="404 Not Found が出る"><a href="#404+Not+Found+%E3%81%8C%E5%87%BA%E3%82%8B">404 Not Found が出る</a></h3>
<p>アプリパス指定が正しくないかも。</p>
<h3 id="接続できない"><a href="#%E6%8E%A5%E7%B6%9A%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84">接続できない</a></h3>
<p>nginx が正しく動いているなら、 <code>http://<サーバのIPアドレス>/</code> で何かが開けるはず。<br />
ダメならnginxが正しく起動できていないか、そもそもサーバに到達できてないか、<br />
サーバが外からのリクエストを受け付けていないので、そちらの方面でなんとかする。</p>
keyangu
tag:crieit.net,2005:PublicArticle/15557
2019-11-21T23:48:51+09:00
2019-11-21T23:48:51+09:00
https://crieit.net/posts/MQTT
MQTTを使ってみよう
<h1 id="MQTT(MQ Telemetry Transport)とは?"><a href="#MQTT%28MQ+Telemetry+Transport%29%E3%81%A8%E3%81%AF%EF%BC%9F">MQTT(MQ Telemetry Transport)とは?</a></h1>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://ja.wikipedia.org/wiki/MQ_Telemetry_Transport">wikipedia</a></li>
</ul>
<p>通信プロトコルの一種でPub/Sub型のデータ配信モデル。<br />
軽量プロトコルのため、主にIoTの分野で使われていることが多いです。</p>
<h2 id="Pub/Sub型"><a href="#Pub%2FSub%E5%9E%8B">Pub/Sub型</a></h2>
<p>Pub/Sub型に関わるのは次の3者。</p>
<ul>
<li>Publisher メッセージを出す人</li>
<li>Subscriber メッセージを読む人</li>
<li>Broker 配送業者(中継サーバ)</li>
</ul>
<p>履歴の残らないLINE、という感じでしょうか。</p>
<h1 id="中継サーバを立ててみよう"><a href="#%E4%B8%AD%E7%B6%99%E3%82%B5%E3%83%BC%E3%83%90%E3%82%92%E7%AB%8B%E3%81%A6%E3%81%A6%E3%81%BF%E3%82%88%E3%81%86">中継サーバを立ててみよう</a></h1>
<p><a target="_blank" rel="nofollow noopener" href="https://hub.docker.com/_/eclipse-mosquitto">eclipse-mosquitto</a>というMQTTサーバのdockerイメージが配布されています。</p>
<p>今回はホストの1883番ポートにmosquittoサーバを公開します。<br />
さらにリバースプロキシの後ろに配置するため、nginxと同じnetwork(ここでは<strong>default</strong>)に接続します。</p>
<p><strong>docker-compose.yml(抜粋)</strong></p>
<pre><code class="yml"> mosquitto:
image: eclipse-mosquitto
hostname: mosquitto
container_name: mosquitto
ports:
- "1883:1883"
volumes:
- ./mosquitto.conf:/mosquitto/config/mosquitto.conf
networks:
- default
</code></pre>
<p><strong>moquitto.conf(一部)</strong></p>
<pre><code class="conf"># ========================================================
# Default listener
# ========================================================
# Port to use for the default listener.
port 1883
# Choose the protocol to use when listening.
protocol websockets
# listener port-number [ip address/host name]
listener 9001
</code></pre>
<p><strong>nginx.conf(listen 443)</strong></p>
<pre><code> location /mqtt {
proxy_pass http://mosquitto:1883/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
</code></pre>
<h1 id="クライアント(react)側実装"><a href="#%E3%82%AF%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%B3%E3%83%88%28react%29%E5%81%B4%E5%AE%9F%E8%A3%85">クライアント(react)側実装</a></h1>
<pre><code class="javascript">import PahoMQTT from "paho-mqtt";
const uuidv4 = require('uuid/v4');
//wssを利用する
const client = new PahoMQTT.Client(
'******',443,uuidv4()
);
export const connect=()=>{
client.connect({
userName: "******",
password: "********",
useSSL: true,
onSuccess,
onFailure
});
client.onMessageArrived = onMessageArrived;
client.onConnectionLost = onConnectionLost;
}
const onSuccess=()=>{
client.subscribe(TOPIC);
}
const onFailure=()=>{
console.log('connect failed.')
}
export const onMessageArrived=(message)=>{
console.log(message.payloadString);
}
export const send=(message)=>{
client.send(TOPIC, message, 0, false);
}
function onConnectionLost(responseObject) {
if (responseObject.errorCode !== 0) {
connect();
}
}
</code></pre>
<h1 id="アドベントカレンダー"><a href="#%E3%82%A2%E3%83%89%E3%83%99%E3%83%B3%E3%83%88%E3%82%AB%E3%83%AC%E3%83%B3%E3%83%80%E3%83%BC">アドベントカレンダー</a></h1>
<ul>
<li><a href="https://crieit.net/advent-calendars/2019/crieit">crieitアドベントカレンダー「なんでも」</a></li>
</ul>
<p>2日目に登板予定です。<br />
MQTTを基礎技術に使ったアプリを作る予定です。</p>
ckoshien
tag:crieit.net,2005:PublicArticle/15538
2019-11-11T10:57:24+09:00
2019-11-11T10:57:24+09:00
https://crieit.net/posts/Oracle-Django-Nginx-uWSGI
Oracle無料ティアでDjango+Nginx+uWSGIでサーバを立ててみる
<p>Oracle Cloudで常時無料サービスが開始されたので使ってみた。<br />
構成は、Django+nginx+uWSGI+Oracle Database+Oracle Linux</p>
<p>以下の3つの環境を作ってみたので、その時の備忘録。</p>
<ul>
<li>ローカルの開発環境</li>
<li>ローカルでDockerを使った開発環境</li>
<li>コンピュート・インスタンスでの本番環境</li>
</ul>
<p>とりあえず、Djangoの雛形アプリにアクセスできるまでの簡易なので、<br />
SSL対応などは省いてます。</p>
<h3 id="Oracle Cloudの常時無料サービス(無料ティア)について"><a href="#Oracle+Cloud%E3%81%AE%E5%B8%B8%E6%99%82%E7%84%A1%E6%96%99%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%28%E7%84%A1%E6%96%99%E3%83%86%E3%82%A3%E3%82%A2%29%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6">Oracle Cloudの常時無料サービス(無料ティア)について</a></h3>
<p>新しく常時無料で利用できるようになったサービスたち。<br />
・<a target="_blank" rel="nofollow noopener" href="https://www.oracle.com/jp/cloud/free/">Oracle Cloud無償ティア | オラクル | Oracle 日本</a></p>
<p>利用できるのは、以下のようなもの。</p>
<ul>
<li>データベース ... 20GBを2つまで</li>
<li>コンピュート ... 仮想マシン。1/8 OCPU・1GBを2つまで</li>
<li>ストレージ ... 合計100GBの2つのブロック・ボリューム。10GBのオブジェクト・ストレージ</li>
</ul>
<p>ほかにもロードバランサや監視・通知などある。</p>
<p>仮想マシンもデータベースも1アカウントにつき2つまでなので、<br />
1サービスであれば、ステージング環境と本番環境を用意できそう。</p>
<hr />
<h3 id="とりあえずDBを作ってみる"><a href="#%E3%81%A8%E3%82%8A%E3%81%82%E3%81%88%E3%81%9ADB%E3%82%92%E4%BD%9C%E3%81%A3%E3%81%A6%E3%81%BF%E3%82%8B">とりあえずDBを作ってみる</a></h3>
<p>トップ画面から。</p>
<p><img width="1367" alt="oracle_1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/dde42040-2f99-5a2a-4824-5894bd4ce59d.png"></p>
<p>名前とAdminのパスワードを設定する。<br />
Always FreeもONにしておく。</p>
<p><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/ce050658-f517-7338-ef93-cd0d07893e16.png" alt="oracle_2.png" /></p>
<p>「Autonomous Databaseの作成」をクリックすると、プロビジョンがはじまる。<br />
プロビジョンが終わるとこんな感じに。</p>
<p><img width="1436" alt="スクリーンショット 2019-11-10 15.59.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/0df9b110-5004-76cd-f942-10780d1c1e39.png"></p>
<h5 id="WebブラウザでDBにアクセスしてみる"><a href="#Web%E3%83%96%E3%83%A9%E3%82%A6%E3%82%B6%E3%81%A7DB%E3%81%AB%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B">WebブラウザでDBにアクセスしてみる</a></h5>
<p>SQL Developer Webからアクセスできる。</p>
<p>「DB接続」>「アプリケーション接続」>「SQL Developer Web」にある。<br />
「アクセスURL」をコピーして、ブラウザに貼り付け。</p>
<p><img width="742" alt="oracle_3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/8795616a-9ab4-87a2-cc78-460e9680f30d.png"></p>
<p>ログイン画面が表示されるので、DBを作ったときのパスワードを入力。<br />
アカウントは「admin」</p>
<p><img width="490" alt="スクリーンショット 2019-11-10 16.00.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/003a489d-23f3-3f50-4cff-a49f674fe002.png"></p>
<p>ログインできるとこんな感じ</p>
<p><img width="843" alt="スクリーンショット 2019-11-10 16.01.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/485c6462-de41-ad35-6829-33292cce2129.png"></p>
<hr />
<h3 id="ローカルの開発環境を作ってみる"><a href="#%E3%83%AD%E3%83%BC%E3%82%AB%E3%83%AB%E3%81%AE%E9%96%8B%E7%99%BA%E7%92%B0%E5%A2%83%E3%82%92%E4%BD%9C%E3%81%A3%E3%81%A6%E3%81%BF%E3%82%8B">ローカルの開発環境を作ってみる</a></h3>
<p>とりあえず、開発用にローカル環境で<code>python manage.py runserver</code>できるようにする。<br />
ローカルの環境はmacOS Mojave(10.14.6)</p>
<h4 id="まずは、Djangoの雛形を作成する"><a href="#%E3%81%BE%E3%81%9A%E3%81%AF%E3%80%81Django%E3%81%AE%E9%9B%9B%E5%BD%A2%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B">まずは、Djangoの雛形を作成する</a></h4>
<pre><code class="shell"># 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
</code></pre>
<p>これでとりあえず、デフォルトのデータベース(SQLite)で立ち上がるとこまで完成。</p>
<p><img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/e2a487cd-a318-d09c-e9f3-899f598eee09.png" /></p>
<h4 id="ローカルでOracleDBを使えるようにする"><a href="#%E3%83%AD%E3%83%BC%E3%82%AB%E3%83%AB%E3%81%A7OracleDB%E3%82%92%E4%BD%BF%E3%81%88%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%E3%81%99%E3%82%8B">ローカルでOracleDBを使えるようにする</a></h4>
<h5 id="Oracle Instant Clientのインストール"><a href="#Oracle+Instant+Client%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB">Oracle Instant Clientのインストール</a></h5>
<p>OracleDBを使うためには、Oracle Instant Clientが必要なので、<br />
以下からダウンロードしてインストールする。<br />
・<a target="_blank" rel="nofollow noopener" href="https://www.oracle.com/database/technologies/instant-client/downloads.html">Oracle Instant Client Downloads</a></p>
<p>Macだったので、「<a target="_blank" rel="nofollow noopener" href="https://www.oracle.com/database/technologies/instant-client/macos-intel-x86-downloads.html">Instant Client for macOS (Intel x86)</a>」の「Basic Light Package」を選択</p>
<pre><code class="sh">## インストールするディレクトリを作成
$ 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/
</code></pre>
<h5 id="環境変数にインストールした場所を設定"><a href="#%E7%92%B0%E5%A2%83%E5%A4%89%E6%95%B0%E3%81%AB%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%97%E3%81%9F%E5%A0%B4%E6%89%80%E3%82%92%E8%A8%AD%E5%AE%9A">環境変数にインストールした場所を設定</a></h5>
<pre><code class="shell">echo "export ORACLE_HOME=/opt/oracle/instantclient_19_3" >> ~/.bashrc
source ~/.bashrc
</code></pre>
<h5 id="認証情報の配置"><a href="#%E8%AA%8D%E8%A8%BC%E6%83%85%E5%A0%B1%E3%81%AE%E9%85%8D%E7%BD%AE">認証情報の配置</a></h5>
<p>Oracle Cloudの「Autonomous Database」>「Autonomous Databaseの詳細」にある<br />
「DB接続」からウォレットをダウンロードしてくる。</p>
<p><img width="753" alt="oracle_4.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/6b23b62d-623d-2fad-ea3b-a95c11d4d605.png"></p>
<p>ファイル名は「<code>Wallet_<データベース名>.zip</code>」。<br />
今回はデータベース名が<code>sample</code>なので、<code>Wallet_sample.zip</code>となる。</p>
<pre><code class="shell">## 認証ファイルを配置するディレクトリを作成
$ 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
</code></pre>
<h5 id="cx_Oracle(pythonライブラリ)のインストール"><a href="#cx_Oracle%28python%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%29%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB">cx_Oracle(pythonライブラリ)のインストール</a></h5>
<p>Oracle Databaseのpythonライブラリをインストールする</p>
<pre><code>$ pip install cx_Oracle
</code></pre>
<h5 id="settings.pyの設定"><a href="#settings.py%E3%81%AE%E8%A8%AD%E5%AE%9A">settings.pyの設定</a></h5>
<p>settings.pyをOracleように変更。<br />
<code>NAME</code>には、TNS名のどれかを指定する。</p>
<p><img width="753" alt="oracle_4.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/6b23b62d-623d-2fad-ea3b-a95c11d4d605.png"></p>
<p>今回は一番上の<code>sample_HIGH</code>を選択。</p>
<pre><code class="python">DATABASES = {
'default': {
'ENGINE': 'django.db.backends.oracle',
'NAME': 'sample_HIGH',
'USER': 'admin',
'PASSWORD': '<DB作成時に入力したパスワード>',
}
}
</code></pre>
<p>マイグレーションをもう一度実行してみて、接続できるか確認。</p>
<pre><code class="shell">$ python manage.py migrate
</code></pre>
<p>マイグレーションが成功すると、Webブラウザ上のSQL Developerでも確認できる。</p>
<p><img width="926" alt="スクリーンショット 2019-11-10 16.35.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/53393a83-0772-2f8e-9814-6d2ddbe203bd.png"></p>
<p>これで、とりあえず、開発できるようになった(<em>´ω`</em>)</p>
<hr />
<h3 id="ローカルでDockerを使った開発環境を作ってみる"><a href="#%E3%83%AD%E3%83%BC%E3%82%AB%E3%83%AB%E3%81%A7Docker%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%9F%E9%96%8B%E7%99%BA%E7%92%B0%E5%A2%83%E3%82%92%E4%BD%9C%E3%81%A3%E3%81%A6%E3%81%BF%E3%82%8B">ローカルでDockerを使った開発環境を作ってみる</a></h3>
<p>実際にデプロイする際は、NginxとuWSGIを利用するので、<br />
それを試せる環境をDockerで構築する。</p>
<h4 id="Django側の変更"><a href="#Django%E5%81%B4%E3%81%AE%E5%A4%89%E6%9B%B4">Django側の変更</a></h4>
<p>nginx+uWSGIで動かすために、いくつか変更。</p>
<h5 id="1. STATIC_ROOTとALLOWED_HOSTS設定"><a href="#1.+STATIC_ROOT%E3%81%A8ALLOWED_HOSTS%E8%A8%AD%E5%AE%9A">1. STATIC_ROOTとALLOWED_HOSTS設定</a></h5>
<p>settings.pyを以下の感じに変更。<br />
ログファイルも出るように変更。</p>
<pre><code class="diff">-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,
+ },
+ },
+}
</code></pre>
<h5 id="2. staticディレクトリを作成&配置"><a href="#2.+static%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E3%82%92%E4%BD%9C%E6%88%90%26amp%3B%E9%85%8D%E7%BD%AE">2. staticディレクトリを作成&配置</a></h5>
<p>manage.pyと同じ場所に作成し、<br />
django-adminのcssとかを配置</p>
<pre><code class="shell">$ mkdir static
$ python manage.py collectstatic
</code></pre>
<h4 id="Docker用の資材を配置"><a href="#Docker%E7%94%A8%E3%81%AE%E8%B3%87%E6%9D%90%E3%82%92%E9%85%8D%E7%BD%AE">Docker用の資材を配置</a></h4>
<pre><code class="shell"># 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
</code></pre>
<p>ディレクトリ的にはこんな感じ。</p>
<pre><code>.
├── 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
</code></pre>
<p>各ファイルの中身は以下の感じ。</p>
<h5 id="docker-compose.yml"><a href="#docker-compose.yml">docker-compose.yml</a></h5>
<pre><code class="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
</code></pre>
<h5 id="docker/Dockerfile"><a href="#docker%2FDockerfile">docker/Dockerfile</a></h5>
<pre><code class="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
</code></pre>
<h5 id="docker/conf/requirements.txt"><a href="#docker%2Fconf%2Frequirements.txt">docker/conf/requirements.txt</a></h5>
<pre><code class="txt">Django==2.2.7
cx-Oracle==7.2.3
uWSGI==2.0.18
</code></pre>
<h5 id="docker/conf/myproject_nginx.conf"><a href="#docker%2Fconf%2Fmyproject_nginx.conf">docker/conf/myproject_nginx.conf</a></h5>
<pre><code class="nginx"># 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;
}
}
</code></pre>
<h5 id="docker/conf/myproject_uwsgi.ini"><a href="#docker%2Fconf%2Fmyproject_uwsgi.ini">docker/conf/myproject_uwsgi.ini</a></h5>
<pre><code class="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
</code></pre>
<h5 id="docker/conf/uwsgi.service"><a href="#docker%2Fconf%2Fuwsgi.service">docker/conf/uwsgi.service</a></h5>
<pre><code>[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
</code></pre>
<h4 id="Dockerを起動"><a href="#Docker%E3%82%92%E8%B5%B7%E5%8B%95">Dockerを起動</a></h4>
<pre><code class="shell"># dockerを立ち上げ
$ docker-compose up -d
</code></pre>
<p>これでうまくビルドされて立ち上がれば、<br />
<code>http://127.0.0.1</code>にアクセスできる。</p>
<p><code>myproject_nginx.conf</code>の<code>server_name</code>で、<code>127.0.0.1</code>を指定しているので、<br />
<code>http://127.0.0.1</code>じゃないとDjangoアプリにアクセスできないので注意。</p>
<p><code>http://localhost</code>だと、<code>myproject_nginx.conf</code>の設定が適用されず、<br />
nginxのデフォルトページが表示される。</p>
<h5 id="よく使うログインとか停止とかはこんな感じ。"><a href="#%E3%82%88%E3%81%8F%E4%BD%BF%E3%81%86%E3%83%AD%E3%82%B0%E3%82%A4%E3%83%B3%E3%81%A8%E3%81%8B%E5%81%9C%E6%AD%A2%E3%81%A8%E3%81%8B%E3%81%AF%E3%81%93%E3%82%93%E3%81%AA%E6%84%9F%E3%81%98%E3%80%82">よく使うログインとか停止とかはこんな感じ。</a></h5>
<pre><code class="shell"># コンテナにログイン
$ 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`
</code></pre>
<h5 id="うまくいかないときにみるところ"><a href="#%E3%81%86%E3%81%BE%E3%81%8F%E3%81%84%E3%81%8B%E3%81%AA%E3%81%84%E3%81%A8%E3%81%8D%E3%81%AB%E3%81%BF%E3%82%8B%E3%81%A8%E3%81%93%E3%82%8D">うまくいかないときにみるところ</a></h5>
<p>以下の場所にログファイルが出力されるので見てみる。</p>
<ul>
<li><code>/var/log/messages</code> ... systemdのログ</li>
<li><code>/var/log/nginx/error.log</code> ... nginxのエラーログ</li>
<li><code>/var/log/uwsgi/emperor.log</code> ... uWSGI Emperorのログ</li>
<li><code>/var/log/uwsgi/myproject_uwsgi.log</code> ... myproject_uwsgi.iniのログ</li>
<li><code>/var/www/myproject/django.log</code> ... Djangoプロジェクトのログ</li>
</ul>
<p>あとは、「パスが正しいか」「権限、オーナーが正しいか」などを見てみるといいかも。</p>
<hr />
<h3 id="コンピュート・インスタンスで公開してみる"><a href="#%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%83%88%E3%83%BB%E3%82%A4%E3%83%B3%E3%82%B9%E3%82%BF%E3%83%B3%E3%82%B9%E3%81%A7%E5%85%AC%E9%96%8B%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B">コンピュート・インスタンスで公開してみる</a></h3>
<h4 id="仮想インスタンスの作成"><a href="#%E4%BB%AE%E6%83%B3%E3%82%A4%E3%83%B3%E3%82%B9%E3%82%BF%E3%83%B3%E3%82%B9%E3%81%AE%E4%BD%9C%E6%88%90">仮想インスタンスの作成</a></h4>
<p>ここから選択。</p>
<p><img width="1367" alt="oracle_5.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/58f5c6f6-a84b-435e-eadf-96a795fe8ba8.png"></p>
<p>こんな感じで入力。<br />
「<strong>パブリックIPアドレスの割当</strong>」を選択しておく。</p>
<p><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/71e54b71-dad2-9b33-3120-73ef26aae734.png" alt="oracle_6.png" /></p>
<p>ちゃんと「パブリックIPアドレスの割当」を選択していると、<br />
ここにIPアドレスが表示される</p>
<p><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/2a714a85-2389-506d-4a8c-9197fb9ca208.png" alt="oracle_7.png" /></p>
<p>デフォルトのユーザは<code>opc</code>なので、<br />
こんな感じで、sshでログインできる。</p>
<pre><code class="shell">$ ssh opc@<IPアドレス>
</code></pre>
<h4 id="セキュリティルールを設定"><a href="#%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3%E3%83%AB%E3%83%BC%E3%83%AB%E3%82%92%E8%A8%AD%E5%AE%9A">セキュリティルールを設定</a></h4>
<p>HTTP(ポート80)でアクセスできるようにセキュリティルールを設定する<br />
ただ、セキュリティルールを設定する場所は少しわかりにくい。。</p>
<p>仮想インスタンスの詳細にアクセスして、<br />
「仮想クラウド・ネットワーク」を選択</p>
<p><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/8c83e806-cb22-481f-a7c4-1903c7766685.png" alt="oracle_8.png" /></p>
<p>左下に「ネットワーク・セキュリティ・グループ」を選択。<br />
「ネットワーク・セキュリティ・グループの作成」を選択すると、追加できるようになる。</p>
<p><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/107254d4-5c9f-155d-5fb2-f9ba13c9d621.png" alt="oracle_9.png" /></p>
<p>「名前」と「コンパートメント」に作成を設定</p>
<p><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/4464efc9-a245-3858-707c-811f12a166d9.png" alt="oracle_10.png" /></p>
<p>ルールの追加を以下のように設定して、「作成」をクリック</p>
<p><img width="1404" alt="oracle_11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/f604553d-7ea4-925d-944b-2410bd920e91.png"></p>
<p>これで作成できたので、仮想インスタンスの詳細にもどって、<br />
「ネットワーク・セキュリティ・グループ」の「編集」を選択</p>
<p><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/8c96405c-539f-9197-40b0-782c30b85079.png" alt="oracle_12.png" /></p>
<p>さっき作ったセキュリティグループを設定</p>
<p><img width="783" alt="スクリーンショット 2019-11-11 0.19.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/12823048-83d2-1278-68a6-dcd45dace136.png"></p>
<h4 id="環境構築"><a href="#%E7%92%B0%E5%A2%83%E6%A7%8B%E7%AF%89">環境構築</a></h4>
<p>Dockerfileでやったような感じで、<br />
Django+nginx+uWSGIな環境を構築してく。</p>
<p>DockerイメージのOracleLinuxとは違い、</p>
<ol>
<li>リポジトリが最初から有効化されている</li>
<li>SELinuxが有効化されている</li>
</ol>
<p>という感じなので、ちょっと変更が必要。</p>
<h5 id="資材を仮想インスタンスに送る"><a href="#%E8%B3%87%E6%9D%90%E3%82%92%E4%BB%AE%E6%83%B3%E3%82%A4%E3%83%B3%E3%82%B9%E3%82%BF%E3%83%B3%E3%82%B9%E3%81%AB%E9%80%81%E3%82%8B">資材を仮想インスタンスに送る</a></h5>
<p>Dockerのときに使った資材を仮想インスタンスに送る。</p>
<pre><code class="shell">$ scp -r docker opc@<IPアドレス>:~/
$ scp -r myproject/ opc@<IPアドレス>:~/
</code></pre>
<p>送信したら、ログインして確認。</p>
<pre><code class="shell">$ ssh opc@<IPアドレス>
$ pwd
/home/opc
$ ls
docker myproject
</code></pre>
<p>ログイン後のディレクトリ構成はこんな感じ</p>
<pre><code>/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
</code></pre>
<h5 id="設定ファイルの変更"><a href="#%E8%A8%AD%E5%AE%9A%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E5%A4%89%E6%9B%B4">設定ファイルの変更</a></h5>
<p>IPアドレスと<code>127.0.0.1</code>にしていたので変更する。</p>
<h6 id="~/docker/conf/myproject_nginx.conf"><a href="#%7E%2Fdocker%2Fconf%2Fmyproject_nginx.conf">~/docker/conf/myproject_nginx.conf</a></h6>
<pre><code class="diff"> server {
- server_name 127.0.0.1;
+ server_name <IPアドレス>;
}
</code></pre>
<h6 id="~/myproject/myproject/settings.py"><a href="#%7E%2Fmyproject%2Fmyproject%2Fsettings.py">~/myproject/myproject/settings.py</a></h6>
<pre><code class="diff">-ALLOWED_HOSTS = ["127.0.0.1"]
+ALLOWED_HOSTS = ["<IPアドレス>"]
</code></pre>
<h5 id="環境構築の実施"><a href="#%E7%92%B0%E5%A2%83%E6%A7%8B%E7%AF%89%E3%81%AE%E5%AE%9F%E6%96%BD">環境構築の実施</a></h5>
<pre><code class="shell">$ 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
</code></pre>
<p>一度、<code>http://<IPアドレス></code>にアクセスして確認してみる。<br />
エラーページが出ていたら、以下を実行</p>
<pre><code class="shell"># 監査ログを確認
$ cat /var/log/audit/audit.log | grep nginx | audit2allow -m nginx
# ポリシーファイルを作成
$ cat /var/log/audit/audit.log | audit2allow -M nginx
# ポリシーファイルを適用
$ semodule -i nginx.pp
</code></pre>
<p>これで、<code>http://<IPアドレス></code>にアクセスして、<br />
Djangoの画面が表示されて、django-adminの画面が操作できればOK</p>
<h1 id="おわりに"><a href="#%E3%81%8A%E3%82%8F%E3%82%8A%E3%81%AB">おわりに</a></h1>
<p>とりあえず、ローカルとインスタンス上の環境が作れたので、<br />
色々することはできそう(<em>´ω`</em>)</p>
<p>SSL対応、権限周りなど、本番としては足りないところがあるので、<br />
そのあたりは他の記事を参照ください〜ヽ(=´▽`=)ノ</p>
<h2 id="こんなのつくってます!!"><a href="#%E3%81%93%E3%82%93%E3%81%AA%E3%81%AE%E3%81%A4%E3%81%8F%E3%81%A3%E3%81%A6%E3%81%BE%E3%81%99%21%21">こんなのつくってます!!</a></h2>
<p>積読用の読書管理アプリ 『積読ハウマッチ』をリリースしました!<br />
<a target="_blank" rel="nofollow noopener" href="https://tsundoku.site">積読ハウマッチ</a>は、Nuxt.js+Firebaseで開発してます!</p>
<p><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/572d4947-f40b-e4dc-1c9c-bc584cd2a66c.png" width="200"/></p>
<p>もしよかったら、遊んでみてくださいヽ(=´▽`=)ノ</p>
<p>要望・感想・アドバイスなどあれば、<br />
公式アカウント(<a target="_blank" rel="nofollow noopener" href="https://twitter.com/MemoryLoverz">@MemoryLoverz</a>)や開発者(<a target="_blank" rel="nofollow noopener" href="https://twitter.com/kira_puka">@kira_puka</a>)まで♪</p>
<h1 id="参考にしたサイトさま"><a href="#%E5%8F%82%E8%80%83%E3%81%AB%E3%81%97%E3%81%9F%E3%82%B5%E3%82%A4%E3%83%88%E3%81%95%E3%81%BE">参考にしたサイトさま</a></h1>
<ul>
<li><a target="_blank" rel="nofollow noopener" href="https://docs.djangoproject.com/ja/2.2/ref/databases/#oracle-notes">データベース | Django ドキュメント | Django</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://oracle.github.io/python-cx_Oracle/">cx_Oracle - Python Interface for Oracle Database</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://cx-oracle.readthedocs.io/en/latest/user_guide/installation.html">cx_Oracle 7 Installation — cx_Oracle 7.3.0-dev documentation</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://www.oracle.com/database/technologies/instant-client/macos-intel-x86-downloads.html#ic_osx_inst">Instant Client for macOS (Intel x86)</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://oracle.github.io/odpi/doc/installation.html#macos">ODPI-C Installation — ODPI-C v3.2.2</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://shase428.hatenablog.jp/entry/2018/01/31/201543">Macでsqlplus使えるようにするメモ - ビットの海</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://github.com/oracle/python-cx_Oracle/issues/56">trouble running Oracle_cx on macOS · Issue #56 · oracle/python-cx_Oracle</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://docs.oracle.com/cd/E83857_01/iaas/compute-iaas-cloud/stcsg/accessing-oracle-linux-instance-using-ssh.html#GUID-D313B1A1-FB67-42C7-A7CC-958656A5207F">SSHを使用したOracle Linuxインスタンスへのアクセス</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://cloudii.atomitech.jp/entry/20190417/1555464532">コンピュート・インスタンスに予約済パブリックIPを付与する - Cloudii blog</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/chi9rin/items/af532d0dd9237cc65741#selinux-%E3%81%AE%E5%8B%95%E4%BD%9C%E3%83%A2%E3%83%BC%E3%83%89">SELinux を使おう.使ってくれ. - Qiita</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://serverfault.com/questions/413397/how-to-set-environment-variable-in-systemd-service">arch linux - How to set environment variable in systemd service? - Server Fault</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/cof123/items/6c9d4b01f0057a9a8de0">EC2にnginx+uwsgi+python でHello World - Qiita</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/takahirono7/items/fd6f9239f0f88eb65a7c">uwsgiのsystemd化(pyenv環境) - Qiita</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/yasunori/items/64606e63b36b396cf695#%E3%83%AD%E3%82%B0%E3%83%AD%E3%83%BC%E3%83%86%E3%83%BC%E3%83%88%E3%81%A7%E3%83%AD%E3%82%B0%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E8%A6%8B%E5%A4%B1%E3%82%8F%E3%81%AA%E3%81%84">ちゃんと運用するときのuWSGI設定メモ - Qiita</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://www.saintsouth.net/blog/setup-django-app-with-uwsgi-and-nginx/#toc-9">Nginx に uWSGI + Django アプリ を組み込む | SaintSouth.NET</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/5t111111/items/e170fead91261621b054#uwsgi-emperor">Ubuntu 12.04でpyenvを利用して速攻でPython3.4 + Nginx + uWSGI + FlaskなWebアプリケーション実行環境を作る - Qiita</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://www.mathpython.com/ja/django-nginx-conf/">nginxでDjangoを使うときの設定ファイル:クライアント、nginx、uwsgiの流れを整理しよう - MathPython</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://uwsgi-docs.readthedocs.io/en/latest/tutorials/Django_and_nginx.html">Setting up Django and your web server with uWSGI and nginx — uWSGI 2.0 documentation</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://pythonspeed.com/articles/activate-virtualenv-dockerfile/">Elegantly activating a virtualenv in a Dockerfile</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/hana_shin/items/bd9ba363ba06882e1fab">firewall-cmdコマンドの使い方 - Qiita</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/yakumo/items/8ac195337414aabd39c0">Oracle Cloud で Compute にWebサーバーを立てたメモ - Qiita</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/fiftystorm36/items/b2fd47cf32c7694adc2e">venv: Python 仮想環境管理 - Qiita</a></li>
<li><a target="_blank" rel="nofollow noopener" href="http://blog.higty.xyz/archives/242/">SELinux + Nginx ポリシー設定 - URAGAMI</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://www.blog.umentu.work/centos7nginx-selinux%E3%82%92%E8%A8%AD%E5%AE%9A%E3%81%97%E3%83%9B%E3%83%BC%E3%83%A0%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E9%85%8D%E4%B8%8B%E3%81%AEweb%E3%82%B3%E3%83%B3%E3%83%86/">[CentOS7][Nginx] SELinuxを設定しホームディレクトリ配下のWebコンテンツを公開を許可 | from umentu import stupid</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/tifa2chan/items/e9aa408244687a63a0ae#%E5%81%9C%E6%AD%A2%E3%81%97%E3%81%A6%E3%81%84%E3%82%8B%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E3%81%AE%E7%A2%BA%E8%AA%8D">Dockerイメージとコンテナの削除方法 - Qiita</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/gold-kou/items/44860fbda1a34a001fc1#rm">いまさらDockerに入門したので分かりやすくまとめます - Qiita</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/okhrn/items/d8580e66546d166f489a">Dockerネットワーク設定 - Qiita</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/zembutsu/items/9e9d80e05e36e882caaa">Docker Compose - docker-compose.yml リファレンス - Qiita</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/tifa2chan/items/e9aa408244687a63a0ae">Dockerイメージとコンテナの削除方法 - Qiita</a></li>
<li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/prgseek/items/e557a371d7bd1f57b9b1#-docker-composeyml">Docker Compose で複数コンテナ構築&管理 - Qiita</a></li>
</ul>
きらぷか@積読ハウマッチ/SSSAPIなど
tag:crieit.net,2005:PublicArticle/14776
2019-02-02T09:32:29+09:00
2019-02-02T09:34:19+09:00
https://crieit.net/posts/KUSANAGI-PHP7-nginx
KUSANAGI で PHP7 + nginx を利用している際のタイムアウト時間設定
<h1 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h1>
<p>デフォルトでファイルが複数あって迷うので、備忘録です。<br />
以下はタイムアウト時間が1時間(3600秒)の場合の例です。</p>
<p>必要な設定箇所は 3 (4) ファイルです。</p>
<h1 id="PHP7"><a href="#PHP7">PHP7</a></h1>
<h2 id="php.ini"><a href="#php.ini">php.ini</a></h2>
<p>/etc/php7.d/php.ini</p>
<pre><code>max_execution_time = 3600
</code></pre>
<h2 id="PHP-FPM"><a href="#PHP-FPM">PHP-FPM</a></h2>
<p>/etc/php7-fpm.d/www.conf</p>
<pre><code>request_terminate_timeout = 3600
</code></pre>
<h1 id="nginx"><a href="#nginx">nginx</a></h1>
<h2 id="SSL"><a href="#SSL">SSL</a></h2>
<p>location ディレクティブブロック <code>location ~ [^/]\.php(/|$) {}</code> 内に記載があります。</p>
<p>/etc/nginx/conf.d/kusanagi_html_ssl.conf</p>
<pre><code>fastcgi_read_timeout 3600s
</code></pre>
<h2 id="HTTP"><a href="#HTTP">HTTP</a></h2>
<p>SSL を用いている場合は不要ですが念の為。</p>
<p>/etc/nginx/conf.d/kusanagi_html_http.conf</p>
<pre><code>fastcgi_read_timeout 3600s
</code></pre>
<h1 id="最後に"><a href="#%E6%9C%80%E5%BE%8C%E3%81%AB">最後に</a></h1>
<p>PHP (PHP-FPM), nginx の再起動を忘れずに。<br />
KUSNAGAI の場合は、以下のコマンドで PHP (PHP-FPM), nginx の再起動を同時に行ってくれます。</p>
<pre><code>sudo kusanagi restart
</code></pre>
sola