DockerとNginxとLet's Encryptで雑に静的サイトを配信する


ホストOS側のメンテが地味に面倒になってきてVPSからFirebase Hostingへ移行するので備忘録。ホスト側にDocker Compose、certbot(Let's Encrypt)が入っている事が前提

compose.yml
version: '2'
services:
  http:
    container_name: http
    build:
      context: ./
      dockerfile: NginxDockerfile
    volumes:
      - "../public:/usr/share/nginx/html:ro"
      - "./nginx.conf:/etc/nginx/nginx.conf:ro"
      - "./nginx.vh.default.conf:/etc/nginx/conf.d/default.conf:ro"
      - "/etc/nginx/ssl/dhparam.pem:/etc/nginx/ssl/dhparam.pem:ro"
      - "/etc/letsencrypt:/etc/letsencrypt:ro"
      - "/etc/localtime:/etc/localtime:ro"
    ports:
      - "80:80"
      - "443:443"

今はversion3とかになってるらしいですね。設定ファイルや証明書周りはホスト(CentOS)側からべったりマウントしてる。../publicが公開ディレクトリ。静的コンテンツ自体もここらへんの設定ファイルと一緒にgithubのprivate repositoryからcloneしてきている。

nginx.vh.default.conf
server {
    listen 80;
    listen [::]:80;
    return 301 https://$host$request_uri;
}

server {
    listen        443 ssl http2;
    listen        [::]:443 ssl http2;
      ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    server_name   ${serverName};

    ssl_certificate           /etc/letsencrypt/live/${serverName}/fullchain.pem;
    ssl_certificate_key       /etc/letsencrypt/live/${serverName}/privkey.pem;
    ssl_prefer_server_ciphers on;
    ssl_ciphers               ECDHE+RSAGCM:ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:!aNULL!eNull:!EXPORT:!DES:!3DES:!MD5:!DSS;

    ssl_dhparam          /etc/nginx/ssl/dhparam.pem;
    add_header           Strict-Transport-Security 'max-age=31536000; includeSubDomains;';
    client_max_body_size 64M;

    ssl_stapling            on;
    ssl_stapling_verify     on;
    ssl_trusted_certificate /etc/letsencrypt/live/${serverName}/fullchain.pem;
    resolver                8.8.8.8;

    charset UTF-8;
    charset_types text/css;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

合わせて読みたい:https://qiita.com/harukasan/items/fe37f3bab8a5ca3f4f92

ssl_ciphersの関係で古すぎるIEからのアクセスは出来なくなる設定だった気がする。うろ覚えだけどたぶん。

あとStrict-Transport-Security(HSTS)をincludeSubDomains付きで有効にしているので、サブドメインを運用する場合はそっちもHSTSの影響を受ける事を忘れないようにしましょう、などの教訓がある。

HSTSというのが何なのかというと、いきなりHTTPSのExpiresヘッダみたいなものです。ワイルドステーキの付け合わせをコーンからブロッコリーに変えて、塩胡椒で食べるのが好きです。

NginxDockerfile
FROM nginx:mainline-alpine

まっさら。

crontab
docker-compose down
certbot renew
docker images -aq | xargs docker rmi -f
docker-compose build --no-cache
docker-compose up -d

crontabから起動しているシェルスクリプト。証明書の更新ついでにイメージを再生成してる。その間はサイトがダウンする。