OpenRestyにて、nginx.confでincludeしているバーチャルホストの設定からLuaで環境変数を参照したかった
OpenRestyにて、nginx.confでincludeしているバーチャルホストの設定からLuaで環境変数を参照したかった
現在、PHPで動作するアプリケーションを、OpenRestyコンテナとPHP−FPMコンテナを利用して構築しています。
稼働環境として、運用環境はAWS ECS、開発環境はdocker-composeを利用しています。
Docker ComposeとECSでは、Nginxの設定が以下の箇所が異なるため、環境変数で差分を埋められないかと考えました。
- proxy_pass
- サイトマップファイル等、ドメインが同一である必要があるファイルを、CDNに問い合わせて返却させたい
- fastcgi_pass
- ECSでは
localhost
、docker-composeではphp-fpm
としたい
- ECSでは
Nginxの設定ファイルから環境変数を参照する方法として、以下の方法を見つけました。
- テンプレートファイルを作成し、
envsubst
で設定ファイルを生成 - set_by_luaで環境変数を取得
1の方法を採用したくなかった理由は以下です。
- ビルド時にテンプレートから設定を生成するする方法では、ビルド環境に環境変数を指定する必要があり複雑さに繋がると考えた
- コンテナ起動時にテンプレートから設定を生成する方法では、ENTRYPOINT上書きが少し邪道に思えた
そこで、set_by_lua
で何とかしたかったのですが、以下の点でつまづきました。
- includeしているバーチャルホスト設定では、envディレクトリを利用できないため、luaから
eturn os.getenv
してもnil
が返却される- nginx.confでenvディレクティブを指定しても結果は同様
- includeしているバーチャルホスト設定の内容を、nginx.confの
http
に入れれば解決するかと考えたが、どうもPHP-FPMに実行を問い合わせできていない- 静的ファイルは返却できたのだが。。。
もう諦めて envsubst
を利用しようかとは思っているのですが、調査にそれなりに時間をかけた事もあり、不可能か可能かだけでも知りたい思いです。
設定ファイル
以下、一部変更していますが、設定ファイルです。
一旦proxy_pass部分のみ、このようにしたいという形で置いています。
user nginx;
pid /var/run/nginx.pid;
worker_processes auto;
worker_rlimit_nofile 100000;
error_log /usr/local/openresty/nginx/logs/error.log;
access_log /usr/local/openresty/nginx/logs/access.log;
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 2048;
multi_accept on;
accept_mutex_delay 100ms;
}
env SITEMAP_URL; # ここでしか指定できないけどinclude先では効いてないっぽい
http {
include /etc/nginx/mime.types;
server_tokens off;
charset UTF-8;
sendfile on;
default_type application/octet-stream;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 50;
types_hash_max_size 4096;
gzip on;
gzip_http_version 1.0;
gzip_disable "msie6";
gzip_proxied any;
gzip_min_length 1024;
gzip_comp_level 6;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript;
open_file_cache max=1000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
include /etc/nginx/conf.d/*.conf;
}
server {
listen 80 default_server;
server_name localhost
index index.php index.html;
root /src/app/webroot;
client_max_body_size 100M;
location ~ \.(html|css|js|jpe?g|png|gif|svg|mpg|flv|swf|woff|eot|ttf)$ {
expires 1m;
break;
}
### サイトマップはCDN上の内容を返却 <- ここがうまくいかない
location /sitemap.xml {
resolver 8.8.8.8;
set_by_lua $SITEMAP_URL 'return os.getenv("SITEMAP_URL")';
proxy_pass $SITEMAP_URL;
}
location / {
try_files $uri /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php-fpm:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
結果
ダメポ...
結局、設定ファイルをテンプレート化してenvsubstすることにしました。
正直すこし強引な印象もあるので、ローカルとECSで同じ設定ファイルを利用する方法、もうすこし方法をしらべてみたいところです
021/04/23 13:29:08 [error] 7#7: *1 invalid URL prefix in "", client: 172.xx.0.1, server: localhost, request: "GET /sitemap.xml HTTP/1.1", host: "localhost:80"