🐺

ミニPCでマルチサーバー構築 [Nginxコンテナ]

2024/05/19に公開


ミニPCでマルチサーバー構築シリーズのNginxコンテナ構築の記録メモです。

シリーズ

  1. N100搭載ミニPCでマルチサーバーの構想と構築準備
  2. ミニPCでマルチサーバー構築 [OS等インストール]
  3. ミニPCでマルチサーバー構築 [Sambaコンテナ]
  4. ミニPCでマルチサーバー構築 [PostgreSQLコンテナ]
  5. ミニPCでマルチサーバー構築 [Nginxコンテナ] この記事
  6. ミニPCでマルチサーバー構築 [Immichコンテナ]
  7. ミニPCでマルチサーバー構築 [VaultwardenコンテナとTailscale]
  8. ミニPCでマルチサーバー構築 [AdGuard Homeコンテナ]
  9. ミニPCでマルチサーバー構築 [GUI環境整備]

簡単な要件

  • Port80で通信する
  • Nginx上の/にアクセスしても何もしない
  • Nginx上の/musicへのアクセスはWebDAVを使用可能にする
  • アクセス時にPAM認証を行う

コンテナ化

検討事項

  • Nginx公式のDocker imageは存在するがWebDAVに対応していない
    • イメージの前提等調べるのが面倒
  • そのためOSイメージから自分で構築することにした
    • alpineが好ましいが不慣れなため不採用
    • 意外にも現時点で容量がより少ないubuntu:latestを採用
      • ubuntu:latest 27.53MB (d21429c46353 linux/amd64)
      • debian:stable-slim 27.8MB (04a4090043d8 linux/amd64)

Dockerfile

Dockerfileではタイムゾーン設定とNginx等インストールのみ実施。

Dockerfile
FROM ubuntu:latest
ARG DEBIAN_FRONTEND=noninteractive
RUN echo Asia/Tokyo > /etc/timezone \
    && apt update && apt install -y \
        nginx \
        nginx-extras \
        libnginx-mod-http-dav-ext \
    && rm -rf /var/lib/apt/lists/*

Docker Compose周り作成

ディレクトリ構成

$ tree .
.
├── compose.yaml
└── nginx
    ├── Dockerfile
    ├── entrypoint.sh
    └── etc
        ├── nginx.conf
        ├── pam.d
        │   └── nginx
        └── sites-enabled
            └── music

compose.yaml

compose.yaml
services:
  nginx:
    build:
      context: ./nginx
      dockerfile: Dockerfile
    init: true
    restart: unless-stopped
    ports:
      - "80:80"
    configs:
      - source: common-user
        target: /etc/passwd
      - source: common-group
        target: /etc/group
      - source: common-shadow
        target: /etc/shadow
      - source: nginx-pam
        target: /etc/pam.d/nginx
      - source: nginx-config
        target: /etc/nginx/nginx.conf
      - source: nginx-sites
        target: /etc/nginx/sites-enabled
      - source: nginx-entrypoint
        target: /run/entrypoint.sh
    environment:
      - TZ=Asia/Tokyo
    volumes:
      - /mnt/ssd1/music:/srv/nginx/private/music
      - /var/log/nginx:/var/log/nginx
    networks:
      - nginxnet
    command: /bin/sh -c "/run/entrypoint.sh"

configs:
  common-user:
    file: /etc/passwd
  common-group:
    file: /etc/group
  common-shadow:
    file: /etc/shadow
  nginx-entrypoint:
    file: ./nginx/entrypoint.sh
  nginx-config:
    file: ./nginx/etc/nginx.conf
  nginx-sites:
    file: ./nginx/etc/sites-enabled
  nginx-pam:
    file: ./nginx/etc/pam.d/nginx

networks:
  nginxnet:

Entrypoint

entrypoint.sh
#!/bin/sh
if [ -f /run/nginx.pid ]; then
    rm -f /run/nginx.pid
fi

nginx -g "daemon off;"

pam.d/nginx

auth required pam_unix.so
account required pam_unix.so

設定

実際の設定ファイル

有効項目を抜粋

nginx.conf
user www-data;
worker_processes auto;
pid /run/nginx.pid;
error_log /var/log/nginx/error.log;
include /etc/nginx/modules-enabled/*.conf;

events {
    worker_connections 512;
    multi_accept on;
}

http {
    sendfile on;
    tcp_nopush on;
    types_hash_max_size 2048;

    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;

    access_log /var/log/nginx/access.log;
    gzip on;

    include /etc/nginx/sites-enabled/*;
}
sites-enabled
server {
    listen 80 default_server;
    listen [::]:80 default_server;
    root /srv/nginx;
    index index.html index.nginx-debian.html;
    server_name _;

    location /music {
        alias /srv/nginx/private;
        dav_access user:rw group:r all:r;
        dav_methods PUT DELETE MKCOL COPY MOVE;
        dav_ext_methods PROPFIND OPTIONS;

        client_max_body_size 0;
        create_full_put_path on;
        client_body_temp_path /tmp/;

        auth_pam "Restricted area";
        auth_pam_service_name "nginx";
    }
}

mainコンテキスト

  • user: 実行ユーザはデフォルト値www-data
  • worker_processes: プロセス数もデフォルト値auto
  • pid: プロセスIDファイルもデフォルト値/run/nginx.pid

eventsコンテキスト

  • worker_connections: 最大コネクション数デフォルト値512
  • multi_accept: 個人用のため省資源になるon

httpコンテキスト

  • sendfile: 特に問題が起きていないためon
  • tcp_nopush: 効率よく送るためon
  • types_hash_max_size: 特に警告も出ていないため2048
    • /etc/nginx/mime.typesに多数のタイプが含まれると警告が出るらしい
  • include /etc/nginx/mime.types: デフォルト値
  • default_type: デフォルト値application/octet-stream
  • ssl_protocols: 使用予定はないがTLSv1.2TLSv1.3に制限
  • ssl_prefer_server_ciphers: サーバー設定値に限定するためon
  • gzip: 使用する予定はないが一応on
    • Debian系OSでSSL通信する場合、onだと不具合があるらしい
    • 以下デフォルト設定ファイルのコメントアウト部抜粋

    Note: You should disable gzip for SSL traffic.
    See: https://bugs.debian.org/773332

serverコンテキスト

  • listen: 80番ポート使用かつ1サーバーのため80 default_server
  • root: コンテンツのルートディレクトリ
  • index: インデックスファイル名 デフォルト値
  • server_name: 無効なドメイン名としての値_
  • location: /musicへのアクセスのみ有効にするため/music
  • alias: パスを個別に指定するためこの項目を使用
  • dav_access: PUTした際の権限,使用予定はないが設定
  • dav_methods: 許可するDAVメソッドPUT DELETE MKCOL COPY MOVE
    • 標準ではPROPFIND,OPTIONSは対応していない
  • dav_ext_methods: 許可する追加的DAVメソッドPROPFIND OPTIONS
  • client_max_body_size: 制限無効化のため0
  • create_full_put_path: 使用予定ないが必要Dir作成のためon
  • client_body_temp_path: client_body_buffer_size超過時に使用する場所
  • auth_pam: PAM認証ダイアログに表示する文字列
  • auth_pam_service_name: /etc/pam.d内で使用するファイル名

認証準備

  • PAM認証を使用するためNginxのユーザをshadowグループに追加する必要がある
    • sudo usermod -aG shadow www-data

参考文献

Discussion