6
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Heroku上の1つのDockerコンテナでnginxとgunicornを動かす

Posted at

Flaskアプリをgunicornで動かし、nginxの裏で動かしたい。これをDockerコンテナとしてHerokuで動かしてみたいので、Supervisorを用いて1つのコンテナ内でnginxとgunicornの両方を起動できるようにするということを、HerokuでDockerコンテナを動かす時の制約を解決しながらやってみた。

nginxの設定

まずは、nginxを単体でHerokuで動くように設定していく。

gunicornのサイトにあるサンプルのnginx.confを元に作業したので、書き換えが必要な部分だけ記載していく。
http://docs.gunicorn.org/en/latest/deploy.html

ログの出力先変更

Herokuではログをstdoutとstderrに出力したいのでそのように設定する。

nginx.conf
error_log stderr;

http {
  server {
    access_log /dev/stdout;
  }
}

temp_path設定の変更

Herokuではコンテナは非rootユーザで動作するため、client_body_temp_pathなどを書き込める場所に設定する必要がある。

nginx.conf
http {
  client_body_temp_path /tmp/client_body;
  fastcgi_temp_path /tmp/fastcgi_temp;
  proxy_temp_path /tmp/proxy_temp;
  scgi_temp_path /tmp/scgi_temp;
  uwsgi_temp_path /tmp/uwsgi_temp;

PORTの設定

Heroku上のDockerコンテナは環境変数PORTで実行環境から渡されるポート番号をlistenする必要がある。

nginx.confの設定に環境変数を渡す方法としてperl_setなどを使う方法があるが、listenのポート番号に対しては使用できないらしい(参考)。そのためDockerfileのCMDの中で、sedでも使って無理矢理渡すくらいしか方法がなさそうだった。

さらに、前述のとおり実行ユーザの権限によりsedで書き換えたnginx.confの出力先に注意が必要で、その影響で一部の設定変更も必要になる。

Dockerfile
COPY ./nginx.conf /opt/nginx.conf.temp

CMD sed -e "s/ENV_PORT/$PORT/g" nginx.conf.temp > /tmp/nginx.conf && \
    nginx -c /tmp/nginx.conf -g "daemon off;"
nginx.conf
# nginx.confの位置が通常と変わるので変更が必要
#include mime.types;
include /etc/nginx/mime.type;

ここまでで、いったんnginxが立ち上がり、当然まだgunicornは動いていないのでエラーページが表示される。

Supervisor

次にSupervisorを設定し、DockerfileのCMDをsupervisordの起動に変更する。
PORTのためのsedはCMD側に残ることになる。

Dockerfile
COPY ./supervisord.conf /etc/

CMD sed -e "s/ENV_PORT/$PORT/g" nginx.conf.temp > /tmp/nginx.conf && \
    supervisord -c /etc/supervisord.conf

supervisord.confでは、logfileやpidfileを設定しないと、デフォルト設定ではこちらも書き込み権限がなくてエラーになるところにだけ注意。

supervisord.conf
[supervisord]
nodaemon=true
logfile=/dev/null
logfile_maxbytes=0
pidfile=/tmp/supervisord.pid

[program:nginx]
command=nginx -c /tmp/nginx.conf -g "daemon off;"
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0

[program:gunicorn]
command=gunicorn --bind unix:/tmp/gunicorn.sock app:app

以上で、Herokuにデプロイして動作することが確認できた。

6
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?