LoginSignup
16
11

WebサーバーのHTTP/3対応をNginxのリバースプロキシでするためのDockerイメージが出来ました

Last updated at Posted at 2019-11-04

やりたいこと

好きなWebサーバーをHTTP/3に対応させたいです。
HTTP/3はGoogleやCloudflareなどで使われ徐々に普及しています。HTTP/3では
UDPで通信が行われ、HTTP/1.xやHTTP/2やより高速に通信することができるようになります。詳しくは「HTTP/3が出るらしいという話を雑に書く - Qiita」などが参考になります。

今回はNginx + HTTP/3をDockerイメージにしてすぐに手軽にHTTP/3対応が出来るようにしました。Docker Composeで手軽にHTTP/3対応できるサンプルも載せたいと思います。

Cloudflare Quiche

CDNや1.1.1.1やWarpなどで活躍しているCloudflareからQuicheというQUICやHTTP/3のためのOSSがリリースされています。Cloudflare公式がNginxをHTTP/3対応する記事があり、それを元にDockerイメージを作成しました。

Nginx + HTTP/3のDockerイメージ

docker pull nwtgck/nginx-http3でDockerイメージが手に入ります。
Dockerfileの内容はhttps://github.com/nwtgck/docker-nginx-http3/blob/master/Dockerfileです。
Dockerfileは公式のGitHubにあるNginx + HTTP/3をする説明を(quiche/extras/nginx at master · cloudflare/quiche)を元に作成しました。

Docker Hub上でのサイズは47MBでnginx:latestと同じくらいのサイズです。

例: docker run

docker runで起動させる例についてです。
以下のnginx.confを今いるディレクトリに作成します。

./nginx.conf
worker_processes  1;

events {
    worker_connections  1024;
}

http {
    server {
        # Enable QUIC and HTTP/3.
        listen 443 quic reuseport;

        # Enable HTTP/2 (optional).
        listen 443 ssl http2;

        ssl_certificate      /etc/ssl/certs/server.crt;
        ssl_certificate_key  /etc/ssl/private/server.key;

        # Enable all TLS versions (TLSv1.3 is required for QUIC).
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;

        # Add Alt-Svc header to negotiate HTTP/3.
        add_header alt-svc 'h3-23=":443"; ma=86400';
    }
}

以下のようにHTTP/3ではUDPも使うため-p 443:443/udpでUDPも解放します。

docker run -it -p 443:443 -p 443:443/udp \
  -v $PWD/nginx.conf:/usr/local/nginx/conf/nginx.conf \
  -v /etc/letsencrypt/live/nwtgck-nginx-http3.tk/fullchain.pem:/etc/ssl/certs/server.crt \
  -v /etc/letsencrypt/live/nwtgck-nginx-http3.tk/privkey.pem:/etc/ssl/private/server.key \
  nwtgck/nginx-http3

上記はLet's Encryptの証明書を指定してます。.../fullchain.pem.../privkey.pemは適切に存在しているものを指定してください。最初はローカル環境で自己証明書を使いたかったのですが、後述のChromeでHTTP/3対応の確認が出来なかったのでLet's Encryptを使いました。

好きなWebサーバーをリバースプロキシしてHTTP/3対応するには

上記のように好きにnginx.confが書けるためlocation / {proxy_pass ...}などを使ってリバースプロキシの設定すれば良いと思います。
docker run --net=host ...を使って起動すればホスト環境で起動している他のWebサーバーのリバースプロキシを作れると思います。
Docker Composeでリバースプロキシする例は後述します。

HTTP/3対応できているか確認する

image.png

このCloudflareの公式ブログ「HTTP/3: the past, the present, and the future」で触れられている方法を使ってHTTP/3の対応を確認します。Chrome Canaryに--enable-quic --quic-version=h3-23フラグを付けて起動します。

Macユーザーは以下のコマンドで起動できます。

/Applications/Google\ Chrome\ Canary.app/Contents/MacOS/Google\ Chrome\ Canary --enable-quic --quic-version=h3-23

以下のように開発者ツールのネットワークタブでhttp/2+quic/99となっていてHTTP/3で通信できていることが確認できました。
image.png

Chrome CanaryはVersion 80.0.3959.0 (Official Build) canary (64-bit)を使いました。GUIのChrome CanaryではなくCLIで確認したいときは以下の方法が使えるかも知れません。
http3-client - HTTP/3 Docs

Docker Composeを使った例

HTTP/3の対応するのはGhostというOSSのブログのプラットフォームです。https://hub.docker.com/_/ghost/でDockerイメージが配布されています。

このGitHubリポジトリhttps://github.com/nwtgck/ghost-nginx-http3-docker-composeに例を作りました。

docker-compose.ymlnginx.confがあるだけのシンプルな構成で内容は以下のとおりです。

docker-compose.yml
version: '3.1'
services:
  nginx:
    image: nwtgck/nginx-http3
    ports:
      - '80:80'
      - '443:443'
      - '443:443/udp'
    depends_on:
      - ghost
    restart: always
    volumes:
      - ./nginx.conf:/usr/local/nginx/conf/nginx.conf
      # 適切に証明書のパスを指定してください。
      - /etc/letsencrypt/live/nwtgck-nginx-http3.tk/fullchain.pem:/etc/ssl/certs/server.crt
      - /etc/letsencrypt/live/nwtgck-nginx-http3.tk/privkey.pem:/etc/ssl/private/server.key

  ghost:
    image: ghost
    restart: always
    expose:
      - "2368"
nginx.conf
worker_processes  1;

events {
    worker_connections  1024;
}


http {
    server {
        listen       80;
        server_name  localhost;

        location / {
            proxy_pass http://ghost:2368;
        }
    }

    server {
        # Enable QUIC and HTTP/3.
        listen 443 quic reuseport;

        # Enable HTTP/2 (optional).
        listen 443 ssl http2;

        ssl_certificate      /etc/ssl/certs/server.crt;
        ssl_certificate_key  /etc/ssl/private/server.key;

        # Enable all TLS versions (TLSv1.3 is required for QUIC).
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;

        location / {
            proxy_pass http://ghost:2368;
        }

        # Add Alt-Svc header to negotiate HTTP/3.
        add_header alt-svc 'h3-23=":443"; ma=86400';
    }
}

自分の環境で試す方法

# リポジトリをクローンする
git clone https://github.com/nwtgck/ghost-nginx-http3-docker-compose.git
cd ghost-nginx-http3-docker-compose

<docker-compose.ymlの...fullchain.pemと...privkey.pemのパスを適切に書き換える>

# サーバーを起動する
docker-compose up

Chrome Canaryの開発者ツールのネットワークタブで確認するとhttps://nwtgck-nginx-http3.tk/...のリクエストがhttp/2+quic/99となっていてHTTP/3で通信されていることが分かります。
image.png

おまけ

以下にNginx + HTTP/3でビルドしたり、Dockerイメージにするために少し苦労したことなどを書きました。
Nginx + HTTP/3 (Quiche)のDockerイメージを生成するためにしたこと - nwtgck / Ryo Ota

16
11
1

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
16
11