59
58

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.

nginx, Dockerで動的プロキシ環境

Last updated at Posted at 2014-06-06

nginxで動的プロキシ環境を作ります

バックエンドのアプリはdockerを使用してバックエンドで動くwebサーバーコンテナを立ててそれを動的にプロキシしてみます。

システム構成

OS

ubuntu 14.04 LTS

Middleware

nginx

リクエストを受けてバックエンドへプロキシします

docker

バックエンドのアプリを動かす環境として使用します

redis

ドメインとバックエンドのアプリのポートを紐付けます

lua

nginxの設定ファイルの中でredisに接続して動的に値を返す役割


まずはubuntuの設定

# アップデート
apt-get -y update && apt-get -y upgrade

# 必要なパッケージをインストールします
apt-get install -y build-essential autoconf libssl-dev curl libcurl4-gnutls-dev zlib1g zlib1g-dev libxml2 libxml2-dev libxslt-dev libreadline6-dev

# redisサーバーをインストール
apt-get install -y redis-server

# luaをインストール
apt-get install -y lua5.1 liblua5.1-0 liblua5.1-0-dev
ln -s /usr/lib/x86_64-linux-gnu/liblua5.1.so /usr/lib/liblua.so

# luaのソケットライブラリをインストール
apt-get install -y lua-svn

# nginxはluaモジュールを使用するためコンパイルします。

mkdir -p /tmp/src
cd /tmp/src

wget -O "nginx-1.7.0.tar.gz" "http://nginx.org/download/nginx-1.7.0.tar.gz"
wget -O "pcre-8.35.tar.gz" "ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.35.tar.gz"
wget -O "zlib-1.2.8.tar.gz" "http://zlib.net/zlib-1.2.8.tar.gz"
wget -O "openssl-1.0.1g.tar.gz" "http://www.openssl.org/source/openssl-1.0.1g.tar.gz"
wget -O "nginx_devkit.tar.gz" "https://github.com/simpl/ngx_devel_kit/archive/v0.2.19.tar.gz"
wget -O "nginx_lua.tar.gz" "https://github.com/openresty/lua-nginx-module/archive/v0.9.7.tar.gz"

tar zxf nginx-1.7.0.tar.gz
tar zxf pcre-8.35.tar.gz
tar zxf zlib-1.2.8.tar.gz
tar zxf openssl-1.0.1g.tar.gz
tar zxf nginx_devkit.tar.gz
tar zxf nginx_lua.tar.gz

# opensslのコンパイルはdocの生成で失敗するのでpatchを当てます
wget https://gist.githubusercontent.com/martensms/10107481/raw/e6bf3488f476e7eb1dc4a5f182a75641f7615380/1.0.1g-docfixes-diff.patch
patch -p0 < 1.0.1g-docfixes-diff.patch

# configure
cd nginx-1.7.0
export LUA_LIB=/usr/lib
export LUA_INC=/usr/include/lua5.1

./configure --prefix=/usr/local/nginx \
            --with-http_gzip_static_module \
            --with-http_ssl_module \
            --with-http_stub_status_module \
            --with-zlib=../zlib-1.2.8 \
            --with-pcre=../pcre-8.35 \
            --with-openssl=../openssl-1.0.1g \
            --add-module=../ngx_devel_kit-0.2.19 \
            --add-module=../lua-nginx-module-0.9.7

# コンパイル
make && make install

# luaのredisスクリプト
mkdir -p /usr/local/lib/lua/5.1
cd /usr/local/lib/lua/5.1
wget https://raw.github.com/nrk/redis-lua/version-2.0/src/redis.lua

nginxの設定ファイル

server {
  listen 80;
  server_name _;
  server_name_in_redirect off;
  port_in_redirect off;
  root /root/html;

  location / {
    set $upstream "";
    rewrite_by_lua '
      -- load global route cache into current request scope
      -- by default vars are not shared between requests
      local routes = _G.routes

      -- setup routes cache if empty
      if routes == nil then
        routes = {}
        ngx.log(ngx.ALERT, "Route cache is empty.")
      end

      -- try cached route first
      local route = routes[ngx.var.http_host]
      if route == nil then
        local redis  = require "redis"
        local client = redis.connect("localhost", 6379)
        route        = client:get(ngx.var.http_host)
      end

      -- fallback to redis for lookups
      if route ~= nil then
        ngx.var.upstream = route
        routes[ngx.var.http_host] = route
        _G.routes = routes
      else
        ngx.exit(ngx.HTTP_NOT_FOUND)
      end
    ';

    proxy_buffering             off;
    proxy_set_header            Host $host;
    proxy_set_header            X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_redirect              off;
    proxy_connect_timeout       10;
    proxy_send_timeout          30;
    proxy_read_timeout          30;
    proxy_pass                  http://$upstream;
  }
}

こちらのものを使わせてもらっています。


dockerでnginxが起動されるイメージを作成

dockerをインストール

curl -s https://get.docker.io/ubuntu/ | sudo sh

コンテナイメージの作成

Dockerfile

FROM ubuntu

ENV DEBIAN_FRONTEND noninteractive
RUN locale-gen en_US.UTF-8 && update-locale LANG=en_US.UTF-8
ENV LC_ALL C
ENV LC_ALL en_US.UTF-8

RUN echo "deb http://us.archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
RUN apt-get update && apt-get upgrade -y && apt-get install -y nginx supervisor openssh-server && apt-get clean && rm -rf /var/cache/apt/archives/* /var/lib/apt/lists/*

RUN dpkg-divert --local --rename --add /sbin/initctl && rm -f /sbin/initctl && ln -s /bin/true /sbin/initctl

RUN useradd -d /home/docker -m -s /bin/bash docker \
  && echo docker:docker | chpasswd \
  && echo 'docker ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers

# sshd config
RUN sed -i -e '/^UsePAM\s\+yes/d' /etc/ssh/sshd_config \
  && mkdir -p /var/run/sshd \
  && /etc/init.d/ssh start \
  && /etc/init.d/ssh stop

RUN sed -i 's/.*session.*required.*pam_loginuid.so.*/session optional pam_loginuid.so/g' /etc/pam.d/sshd
RUN /bin/echo -e "LANG=\"ja_JP.UTF-8\"" > /etc/default/local

# supervisor
RUN mkdir -p /var/log/supervisor
ADD supervisord.conf /etc/supervisor/conf.d/supervisord.conf

EXPOSE 22 80

CMD ["/usr/bin/supervisord"]

supervisord.conf

[supervisord]
nodaemon=true

[program:sshd]
command=/usr/sbin/sshd -D

[program:nginx]
command=/usr/sbin/nginx -c /etc/nginx/nginx.conf
process_name=%(program_name)s
numprocs=1
stopsignal=QUIT

イメージをビルド

cd <Dockerfileがあるpath>
docker build --no-cache --rm -t test/nginx .

nginxコンテナを起動する

docker run -d -i -p 49153:80 -t test/nginx /usr/bin/supervisord
docker run -d -i -p 49154:80 -t test/nginx /usr/bin/supervisord

2つのコンテナの80番をそれぞれ49153, 49154に割り当てました

redisにドメインとコンテナを紐付けます

user1.example.com49153ポートのコンテナ


user2.example.com49154ポートのコンテナ


に紐付けます

※とりあえずhostsとかでubuntuのIPに向けます。実際使う時はワイルドカードとかでやると思います。

redis-cli =>
SET user1.example.com 127.0.0.1:49153
SET user2.example.com 127.0.0.1:49154

nginxを起動

/usr/local/nginx/sbin/nginx

user1.example.comにアクセスすれば49153のコンテナにプロキシされ


user2.example.comにアクセスすれば49154のコンテナにプロキシされるようになります。

59
58
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
59
58

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?