Railway.appのウェブアプリにBasic認証を追加

2023/09/12に公開

概要

同プロジェクトにあるdockerサービスを利用して、ウェブアプリのコードを修正せずにBasic認証を追加する方法です。
GitHubにも公開してます。
https://github.com/toyjack/railway-nginx-basic-auth

認証情報を作成

作成方法は参考[1]に。
openssl 1.xを利用すれば、-apr1-cryptに修正する必要があります。

gen_passwd.sh
#!/bin/sh

USER_NAME=${USERNAME}
PASSWD=${PASSWORD}

echo "Generating password for user ${USER_NAME}"

CRYPTPASS=`openssl passwd -apr1 ${PASSWD}`

echo "${USER_NAME}:${CRYPTPASS}" >> /etc/nginx/.htpasswd

Dockerfileを用意

Dockerfile
FROM nginx:alpine AS runtime

ARG PROXY_PASS=http://host.docker.internal:3000
ARG PORT=4000
ARG USERNAME=user
ARG PASSWORD=password

RUN echo "proxy_pass: $PROXY_PASS\nport: $PORT\nusername: $USERNAME\npassword: $PASSWORD"

COPY ./nginx.conf.template /etc/nginx/nginx.conf.template
RUN envsubst '$PROXY_PASS $PORT' < /etc/nginx/nginx.conf.template > /etc/nginx/nginx.conf


ENV USERNAME=$USERNAME
ENV PASSWORD=$PASSWORD
RUN apk add --no-cache openssl
COPY ./gen_passwd.sh /etc/nginx/gen_passwd.sh
RUN ["chmod", "+x", "/etc/nginx/gen_passwd.sh"]
RUN /etc/nginx/gen_passwd.sh
EXPOSE ${PORT}

nginxの設定ファイル

特にいう必要がある箇所はなさそうです。

nginx.conf
worker_processes 1;

events {
  worker_connections 1024;
}

http {
  server {
    listen ${PORT};
    server_name _;

    location / {
        auth_basic	"Restricted";
        auth_basic_user_file	/etc/nginx/.htpasswd;
        
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-Nginx-Proxy true;
        proxy_http_version 1.1;
        proxy_pass ${PROXY_PASS};
    }
  }
}

Railwayの環境変数

要注意のは、alpine系のdocker imageを利用すれと、ENABLE_ALPINE_PRIVATE_NETWORKINGの設定が必要です(参考[2])。設定しないと、Railwayのprivate networkを利用できないようです。
また、nginxのポートを指定する必要がある。port的な言葉であれば大丈夫そうです(参考[3])。

env
ENABLE_ALPINE_PRIVATE_NETWORKING=true
PORT=80
USERNAME=user
PASSWORD=pass

参考

  1. OpenSSL コマンドでサーバー上で直接 .htpasswd に ID & パスワードを追加する
  2. Workaround for Alpine-based images
  3. Simple HTML App with NGNIX Docker container doesn't run on Railway.app - Application failed to respond (error-503)

Discussion