riina-k.net

音楽・小説・プログラミングを手がけるリイナの拠点。

Docker Compose と nginx でリバースプロキシを作ろうとしたお話(出題編)

家から電車で1時間程度のところで開催された OSC 2019 Tokyo/Spring に行ってきました。
さくらインターネットのセッションで Docker Compose が取り上げられていて、めっちゃ興味持ちました。
そこで今回は Docker Compose を使ってバーチャルホストでリバースプロキシにチャレンジしてみました。

完成してないけど、作業ログとして置いておきます。

とりあえず各種インストールは済ませました(ログ取り忘れたとか言わない)

目標は nginx をリバースプロキシにして http://riina-k.me/ で Apache のコンテナが動くようにしたい。
Docker も nginx も触るの初めてなので、あちこちググりながら設定ファイル作ってました。

ホスト側のディレクトリ構成は以下の通り。
今後バーチャルホストを増やしたいので、/var/docker/proxy/vhosts/ 以下にバーチャルホストのコンテナを増やしていきます。

/
+ var/
  + docker/
    + proxy/
      | docker-compose.yml <- Docker Compose 設定ファイル
      + nginx-proxy/
      | | Dockerfile <- nginx コンテナの設定ファイル
      | | nginx.conf <- コンテナにコピーする nginx の設定ファイル
      + vhosts/
        + riina-k.me/
          | Dockerfile <- Apache コンテナの設定ファイル
          | httpd.conf <- コンテナにコピーする Apache の設定ファイル
          | php.ini <- コンテナにコピーする PHP の設定ファイル
          + var/
            + www/
              + html/ <- Apache のドキュメントルート
                | index.html <- <h1>riina-k.me</h1> とだけ書いてある

以下、各種設定ファイル。
(ここまで作るまでに何度 nginx のウェルカムページやら 502 エラーやらを見たことか……)

/var/docker/proxy/docker-compose.yml

version: '3'

services:
  nginx-proxy:
    build: ./nginx-proxy
    restart: on-failure
    container_name: nginx-proxy
    privileged: true
    expose:
      - "80"
    ports:
      - "80:80"
    networks:
      - app-net

  apache.riina-k.me:
    build: ./vhosts/riina-k.me
    restart: on-failure
    container_name: apache.riina-k.me
    environment:
      VIRTUAL_HOST: riina-k.me
      VIRTUAL_PORT: 8080
    expose:
      - "8080"
    ports:
      - "8080:8080"
    volumes:
      - ./vhosts/riina-k.me/var/www/html:/var/www/html
    networks:
      - app-net

networks:
  app-net:
    driver: bridge

/var/docker/proxy/nginx-proxy/Dockerfile

FROM nginx:alpine
COPY ./nginx.conf /etc/nginx/nginx.conf

EXPOSE 80

/var/docker/proxy/nginx-proxy/nginx.conf

user nginx;
worker_processes auto;

events {
    worker_connections 1024;
}

http {
    sendfile on;

    upstream me_servers {
        server riina-k.me:8080;
    }

    server {
        listen 8080;
        server_name riina-k.me;

        location / {
            proxy_pass http://me_servers/;
        }
    }
}

/var/docker/proxy/vhosts/riina-k.me/Dockerfile

FROM centos:latest

RUN yum -y update
RUN yum -y install httpd
RUN rm -f /etc/httpd/conf.d/welcome.conf
RUN yum install -y php | true 
RUN yum install -y net-tools | true

COPY ./httpd.conf /etc/httpd/conf/
COPY ./php.ini /etc/

EXPOSE 8080

CMD /usr/sbin/httpd -DFOREGROUND

/var/docker/proxy/vhosts/riina-k.me/httpd.conf

(略)
Listen 8080
(略)
ServerName riina-k.me:8080
(略)

/var/docker/proxy/vhosts/riina-k.me/php.ini

特に変わったことはしてないので省略


これで SSH から

[root@riina-02 proxy]# docker-compose up -d

いろいろわちゃわちゃログが出てきて起動完了。

[root@riina-02 proxy]# docker ps
CONTAINER ID        IMAGE                     COMMAND                  CREATED             STATUS              PORTS                            NAMES
f6c6df75cd70        proxy_apache.riina-k.me   "/bin/sh -c '/usr/sb…"   6 seconds ago       Up 4 seconds        80/tcp, 0.0.0.0:8080->8080/tcp   apache.riina-k.me
eba3bc0107ce        proxy_nginx-proxy         "nginx -g 'daemon of…"   6 seconds ago       Up 4 seconds        0.0.0.0:80->80/tcp               nginx-proxy

Apache コンテナが 8080 しか listen しないはずなのに 80/tcp ??

[root@riina-02 proxy]# curl riina-k.me
curl: (7) Failed connect to riina-k.me:80; 接続を拒否されました
[root@riina-02 proxy]# curl riina-k.me:8080
<h1>riina-k.me</h1>

んんんん???? 8080 しか通らない。
riina-k.me:80 でアクセスしたら <h1>riina-k.me</h1> が出るようにしたいんだー!!

nginx 詳しい人、教えて……


余談ですが、お名前.com で Let’s Encrypt による無料 SSL サービスがあったので、しれっとこのブログも https にしました。


3/8 18:53 追記

変に空いていたポート 80 は、以下の箇所を変えることで塞げました。

/var/docker/proxy/docker-compose.yml

  apache.riina-k.me:
    build: ./vhosts/riina-k.me
    restart: on-failure
    container_name: apache.riina-k.me
    environment:
      VIRTUAL_HOST: riina-k.me
      VIRTUAL_PORT: 8080 <- この行を削除
    expose:
      - "8080"

3/8 19:13追記

ポート周りが怪しいとあたりをつけていろいろ調整したところ、ちょっと反応が変わりました。

/var/docker/proxy/nginx-proxy/nginx.conf

    server {
        listen 8080;
        listen 80; <- 変更
        server_name riina-k.me;

        location / {
            proxy_pass http://me_servers/;
        }
    }
}

こうすると

[root@riina-02 proxy]# curl riina-k.me
<html>
<head><title>502 Bad Gateway</title></head>
<body>
<center><h1>502 Bad Gateway</h1></center>
<hr><center>nginx/1.15.9</center>
</body>
</html>
[root@riina-02 proxy]# curl riina-k.me:8080
<h1>riina-k.me</h1>

ポート 8080 へのアクセスは変わりませんが、ポート 80 が 502 Bad Gateway に変わりました。徐々に解決の緒が見えてきてるかも? それとも 80 のまま Apache に行っちゃってるのかなぁ……?


3/8 20:45追記

動いたーーーー!!!!

/var/docker/proxy/nginx-proxy/nginx.conf

http {
    sendfile on;

    upstream me_servers {
        server riina-k.me:8080;
        server apache.riina-k.me:8080; <- ホスト名じゃなくコンテナ名
    }

    server {
        listen 80;
        server_name riina-k.me;

        proxy_set_header Host $host; <- 追加

        location / {
            proxy_pass http://me_servers/;
        }
    }
}

upstream のところはホスト名じゃなくコンテナ名を書かなきゃいけないようでした。
紛らわしいコンテナ名つけやがって
これで

[root@riina-02 proxy]# curl riina-k.me
<h1>riina-k.me</h1>
[root@riina-02 proxy]# curl riina-k.me:8080
<h1>riina-k.me</h1>

ポート 8080 が塞がってないけど、これはホスト側の iptables で対応すればいいか……?

これで肝心のバーチャルホストの設定に入れるので、完成したらまたエントリ書きます。

解答編へ続く

  1. コメント 0

  1. トラックバック 0

return top