প্রশ্ন আমি কিভাবে Nginx.conf এ পরিবেশ ভেরিয়েবল ব্যবহার করতে পারি


[ক্রস পোস্ট এবং নিচে থেকে সম্পাদনা https://stackoverflow.com/questions/21933955 স্ট্যাকঅভারফ্লোের জন্য এটি খুব সিএসএসডমিন-মত বিবেচিত হয়েছিল।]

আমি Nginx চলমান একটি ডকার কনটেইনার আছে, যে অন্য docker ধারক লিঙ্ক। দ্বিতীয় কন্টেইনারের হোস্ট নাম এবং আইপি ঠিকানাটি Nginx কন্টেইনারে স্টার্টআপে পরিবেশের ভেরিয়েবল হিসাবে লোড করা হয় তবে তা আগে থেকেই জানা নেই (এটি গতিশীল)। আমি চাই আমার nginx.conf এই মান ব্যবহার করতে - যেমন।

upstream gunicorn {
    server $APP_HOST_NAME:$APP_HOST_PORT;
}

কিভাবে আমি প্রারম্ভে Nginx কনফিগারেশন মধ্যে পরিবেশ ভেরিয়েবল পেতে পারি?

সম্পাদনা করুন 1

নীচের প্রস্তাবিত উত্তরের পরে এটি সম্পূর্ণ ফাইল:

env APP_WEB_1_PORT_5000_TCP_ADDR;
# Nginx host configuration for django_app

# Django app is served by Gunicorn, running under port 5000 (via Foreman)
upstream gunicorn {
    server $ENV{"APP_WEB_1_PORT_5000_TCP_ADDR"}:5000;
}

server {
    listen 80;

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    location /static/ {
        alias /app/static/;
    }
    location /media/ {
        alias /app/media/;
    }
    location / {
        proxy_pass http://gunicorn;
    }
}

তারপর nginx পুনরায় লোড হচ্ছে ত্রুটি:

$ nginx -s reload
nginx: [emerg] unknown directive "env" in /etc/nginx/sites-enabled/default:1

সম্পাদনা 2: আরো বিস্তারিত

বর্তমান পরিবেশ ভেরিয়েবল

root@87ede56e0b11:/# env | grep APP_WEB_1
APP_WEB_1_NAME=/furious_turing/app_web_1
APP_WEB_1_PORT=tcp://172.17.0.63:5000
APP_WEB_1_PORT_5000_TCP=tcp://172.17.0.63:5000
APP_WEB_1_PORT_5000_TCP_PROTO=tcp
APP_WEB_1_PORT_5000_TCP_PORT=5000
APP_WEB_1_PORT_5000_TCP_ADDR=172.17.0.63

Root nginx.conf:

root@87ede56e0b11:/# head /etc/nginx/nginx.conf
user www-data;
worker_processes 4;
pid /var/run/nginx.pid;
env APP_WEB_1_PORT_5000_TCP_ADDR;

সাইট nginx কনফিগারেশন:

root@87ede56e0b11:/# head /etc/nginx/sites-available/default
# Django app is served by Gunicorn, running under port 5000 (via Foreman)
upstream gunicorn {
    server $ENV{"APP_WEB_1_PORT_5000_TCP_ADDR"}:5000;
}

server {
    listen 80;

Nginx কনফিগারেশন পুনরায় লোড করুন:

root@87ede56e0b11:/# nginx -s reload
nginx: [emerg] directive "server" is not terminated by ";" in /etc/nginx/sites-enabled/default:3

143
2018-02-21 15:02


উত্স


এটি পরিবেশ ভেরিয়েবলগুলির জন্য একটি জেনেরিক সমাধান নয়, তবে আপস্ট্রিম সার্ভারগুলির হোস্টনাম / আইপি ঠিকানাগুলির জন্য পরিবেশ ভেরিয়েবল ব্যবহার করতে চাইলে, নোট করুন (কমপক্ষে সাম্প্রতিক সংস্করণগুলিতে) আপনার জন্য / etc / হোস্টগুলি সংশোধন করে। দেখ docs.docker.com/userguide/dockerlinks    এর মানে হল, যদি আপনার সংযুক্ত কন্টেইনারকে 'app_web_1' বলা হয়, ডকার আপনার Nginx কন্টেইনারে / etc / হোস্টগুলিতে একটি লাইন তৈরি করবে। সুতরাং আপনি শুধু প্রতিস্থাপন করতে পারেন server $ENV{"APP_WEB_1_PORT_5000_TCP_ADDR"}:5000;    সঙ্গে server app_web_1:5000; - mozz100
ধন্যবাদ @ মজজ 100 - এটি অবিশ্বাস্যভাবে দরকারী - / etc / হোস্ট এন্ট্রিগুলি এই ক্ষেত্রে env vars এর চেয়ে অনেক বেশি কার্যকর। আপস্ট্রিম কন্টেইনারটি পুনরায় আরম্ভ করা হলে এবং এটির জন্য একটি নতুন আইপি অর্জন করলেই কেবলমাত্র বিট অনুপস্থিত। আমি ধারনা করছি যে সন্তানের পাত্রে এখনও মূল আইপি নির্দেশ করবে, নতুন নয়? - Hugo Rodger-Brown
হ্যাঁ, আপনি পুনরায় আরম্ভ করা হলে app_web_1 এটি একটি নতুন আইপি ঠিকানা পাবেন, তাই আপনাকে আপনার nginx ধারক পুনরায় চালু করতে হবে। ডকার একটি আপডেট সঙ্গে এটি পুনরায় আরম্ভ হবে /etc/hosts তাই আপনি nginx কনফিগারেশন ফাইল (গুলি) পরিবর্তন করতে হবে না। - mozz100


উত্তর:


যদি আপনি একটি লিঙ্ক ব্যবহার করেন, ডকার পরিবেশ পরিবর্তনশীল সেট আপ করে এবং সংযুক্ত ধারকটির জন্য একটি উপনাম যুক্ত করে /etc/hosts। আপনি যদি পোর্ট হার্ড কোডটি সক্ষম করতে সক্ষম হন (অথবা এটি কেবল পোর্ট 80 হলে) আপনি কেবল তা করতে পারেন:

upstream gunicorn {
    server linked-hostname:5000;
}

পোর্ট শুধুমাত্র একটি পরিবেশগত পরিবর্তনশীল পাওয়া যায়, যা ব্যবহার করা যাবে না upstream মডিউল, না সার্ভার বা অবস্থান ব্লক। তারা শুধুমাত্র প্রধান কনফিগারেশন উল্লেখ করা যেতে পারে, যা আপনাকে সাহায্য করে না। আপনি এই সঙ্গে করতে পারে openresty বান্ডিল যে Lua অন্তর্ভুক্ত।

আপনি যদি Openresty / Lua ব্যবহার করতে চান না, অন্য বিকল্পটি ধারক প্রারম্ভে কিছু প্রতিস্থাপন করতে হয়। তোমার docker run কমান্ডটি লিঙ্কটি তৈরি করতে পারে তখন যথাযথ প্রতিস্থাপন সম্পাদনকারী একটি মোড়ানো স্ক্রিপ্ট চালায়:

#!/bin/bash
/usr/bin/sed -i "s/server<gunicorn_server_placeholder>/${APP_WEB_1_PORT_5000_TCP_ADDR}/" default
start nginx

56
2018-03-18 06:14



Yup - বর্তমান (কাজ) সমাধান ঠিক এই। শুধু একটু হ্যাকি মনে হচ্ছে। (যে বলেন, এটি শুধুমাত্র একটি স্থানীয় dev পরিবেশ, তাই হ্যাকিং একটি বিশাল সমস্যা নয়।) - Hugo Rodger-Brown
আমি এই মধ্যে দৌড়ে, তাই আমি একটি সামান্য আরো জেনেরিক তৈরি nginx ধারক যে স্বয়ংক্রিয়ভাবে কনফিগারেশন পরিবেশ পরিবর্তনশীল বিস্তৃত। - Shepmaster


থেকে অফিসিয়াল Nginx ডকার ফাইল:

Nginx কনফিগারেশন এ পরিবেশ ভেরিয়েবল ব্যবহার করে:

আউট অফ দ্য বাক্স, Nginx পরিবেশ ভেরিয়েবল ব্যবহার করে সমর্থন করে না   অধিকাংশ কনফিগারেশন ব্লক ভিতরে।

কিন্তু envsubst একটি হিসাবে ব্যবহার করা যেতে পারে   আপনার nginx কনফিগারেশন জেনারেট করার প্রয়োজন হলে workaround   গতিশীলভাবে nginx শুরু করার আগে।

এখানে docker-compose.yml ব্যবহার করে একটি উদাহরণ:

image: nginx
volumes:
 - ./mysite.template:/etc/nginx/conf.d/mysite.template
ports:
 - "8080:80"
environment:
 - NGINX_HOST=foobar.com
 - NGINX_PORT=80
command: /bin/bash -c "envsubst < /etc/nginx/conf.d/mysite.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'" 

তারপর mysite.template ফাইলের মত পরিবর্তনশীল রেফারেন্স থাকতে পারে   এই :

listen ${NGINX_PORT};

হালনাগাদ:

কিন্তু আপনি এটি এর মতো Nginx ভেরিয়েবলের কারণে এটি জানেন:

proxy_set_header        X-Forwarded-Host $host;

ক্ষতিগ্রস্ত:

proxy_set_header        X-Forwarded-Host ;

সুতরাং, এটি রোধ করতে, আমি এই কৌশলটি ব্যবহার করি:

আমি Nginx চালানোর জন্য একটি স্ক্রিপ্ট আছে, যে ব্যবহৃত docker-compose Nginx সার্ভারের জন্য কমান্ড বিকল্প হিসাবে ফাইল, আমি এটি নামকরণ run_nginx.sh:

#!/usr/bin/env bash
export DOLLAR='$'
envsubst < nginx.conf.template > /etc/nginx/nginx.conf
nginx -g "daemon off;"

এবং কারণ সংজ্ঞায়িত নতুন DOLLAR পরিবর্তনশীল উপর run_nginx.sh স্ক্রিপ্ট, এখন আমার কন্টেন্ট nginx.conf.template Nginx নিজেই পরিবর্তনশীল জন্য ফাইল এই মত হল:

proxy_set_header        X-Forwarded-Host ${DOLLAR}host;

এবং আমার সংজ্ঞায়িত পরিবর্তনশীল জন্য এই মত হল:

server_name  ${WEB_DOMAIN} www.${WEB_DOMAIN};

এছাড়াও এখানে, যে জন্য আমার বাস্তব ব্যবহার ক্ষেত্রে আছে।


62
2018-02-11 12:39



যে nginx হত্যা করে মত হত্যা proxy_set_header Host $http_host; - shredding
@ শ্রেডডিং আপনি ভেরিয়েবল নামগুলি প্রতিস্থাপিত করতে পারেন - অন্যদের স্পর্শ করা হয় না: command: /bin/bash -c "envsubst '$VAR1 $VAR2' < /etc/nginx/conf.d/mysite.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'" আমার জন্য কাজ b / c আমি জানি তারা কি বলা হয় ... - pkyeck
ঠিক আছে, পালাতে ভুলে গেছি $, হতে হবে command: /bin/bash -c "envsubst '\$VAR1 \$VAR2' < /etc/nginx/conf.d/mysite.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'" - pkyeck
আপনার নিজের Dockerfile এ এই কাজগুলি থেকে পালানোর জন্য বিবেচনার সাথে: CMD ["/bin/sh","-c", "if [ -n \"${SOME_ENV}\" ]; then echo envsubst '${SOME_ENV}' with ${SOME_ENV} && envsubst '${SOME_ENV}' < /etc/nginx/conf.d/default.template > /etc/nginx/conf.d/default.conf; fi ; nginx -g 'daemon off;'"] - KCD
এটি একটি মহান সমাধান। ধন্যবাদ। এছাড়াও উপরে উল্লিখিত লিঙ্ক github.com/docker-library/docs/issues/496 সমস্যাটির জন্য একটি মহান সমাধান আছে। - kabirbaidhya


লুয়া সঙ্গে এই কাজটি শব্দটি তুলনায় উল্লেখযোগ্যভাবে সহজ:

server {
    set_by_lua $server_name 'return os.getenv("NGINX_SERVERNAME")';
}

আমি এখানে পাওয়া যে:

https://docs.apitools.com/blog/2014/07/02/using-environment-variables-in-nginx-conf.html

সম্পাদনা:

দৃশ্যত এই lua মডিউল ইনস্টল করার প্রয়োজন: https://github.com/openresty/lua-nginx-module

সম্পাদনা 2:

উল্লেখ্য যে এই পদ্ধতির সাথে আপনাকে সংজ্ঞায়িত করতে হবে env Nginx পরিবর্তনশীল:

env ENVIRONMENT_VARIABLE_NAME

আপনি inplevel প্রসঙ্গে এই কাজ আছে nginx.conf অথবা এটা কাজ করবে না! সার্ভার ব্লক বা কিছু সাইটে কনফিগার করা হয় না /etc/nginx/sites-availableকারণ এটি দ্বারা অন্তর্ভুক্ত করা হয় nginx.conf মধ্যে http প্রসঙ্গ (যা শীর্ষ স্তরের প্রসঙ্গ নয়)।

এছাড়াও যদি আপনি একটি পুনঃনির্দেশ তৈরি করার চেষ্টা করেন তবে এই পদ্ধতির সাথে মনে রাখবেন .:

server {
    listen 80;
    server_name $server_name;
    return 301 https://$server_name$request_uri;
}

এটি ভাল কাজ করবে না:

2016/08/30 14:49:35 [emerg] 1#0: the duplicate "server_name" variable in /etc/nginx/sites-enabled/default:8

এবং যদি আপনি এটিতে একটি পৃথক পরিবর্তনশীল নাম দেন:

set_by_lua $server_name_from_env 'return os.getenv("NGINX_SERVERNAME")';

server {
    listen 80;
    server_name $server_name_from_env;
    return 301 https://$server_name$request_uri;
}

nginx এটা ব্যাখ্যা করবে না এবং আপনাকে পুনঃনির্দেশিত করা হবে https://%24server_name_from_env/


26
2017-12-01 16:26



তোমার দরকার হতে পারে env NGINX_SERVERNAME কোথাও আপনার nginx.conf। - hiroshi
এটি আমার জন্য কাজ করে না, যদিও আমার Nginx ডকার ইমেজ lua মডিউল আছে। এই আমার nginx.conf মধ্যে একটি কনফিগার ফাইল অন্তর্ভুক্ত করা যেতে পারে যে সম্পর্কিত হতে পারে? আমি চেষ্টা করছিলাম set_by_lua কনফিগারেশন ফাইল অন্তর্ভুক্ত পরিবর্তনশীল, যখন env MY_VAR ঘোষণা প্রধান nginx.conf ছিল, প্রস্তাবিত। কি লজ্জা, এই পরিষ্কার সমাধান হয়েছে! - pederpansen
কেউ এই পদ্ধতি ব্যবহার করার জন্য pros / cons জানেন envsubst? আমি অনুমান আপনি প্রো চালানোর প্রয়োজন হয় না envsubstr সার্ভার শুরু করার আগে কমান্ড এবং কনটেন্টটি আপনাকে lua মডিউল ইনস্টল করতে হবে? আমি কোন পদ্ধতির উপর কোনো নিরাপত্তা প্রভাব আছে কিনা ভাবছি? - Mark Winterbottom
@ মার্ক উইন্টার্টারবটম এখনো এটি পরীক্ষা করে নিচ্ছেন না তবে মনে হচ্ছে আপনাকে nginx কনফিগারেশন ফাইলগুলিতে লেখার অ্যাক্সেস প্রদান করতে হবে না, যা আপনাকে ব্যবহার করতে হবে envsubst এবং যা আমার ক্ষেত্রে একটি যেতে হয় - Griddo


আমি এমন কিছু লিখেছিলাম যা সহায়ক হতে পারে বা পারে না: https://github.com/yawn/envplate

এটি ইনলাইন কনফিগারেশন ফাইলগুলি $ {key} রেফারেন্সগুলির সাথে পরিবেশ ভেরিয়েবলগুলির সম্পাদনা করে, বিকল্পভাবে ব্যাকআপগুলি / এটি কী করে লগিং করে। এটি Go তে লেখা হয়েছে এবং ফলে স্ট্যাটিক বাইনারিটি কেবল লিনাক্স এবং ম্যাকোসগুলির জন্য রিলিজ ট্যাবে ডাউনলোড করা যেতে পারে।

এটি কার্যকর () প্রসেস, ডিফল্ট বিকল্প, লগ এবং বুদ্ধিমান ব্যর্থতা semantics আছে।


14
2017-11-15 16:02





আমি কি ব্যবহার ছিল ERB!

cat nginx.conf  | grep -i error_log

error_log <%= ENV["APP_ROOT"] %>/nginx/logs/error.log;

- erb ব্যবহার করার পরে

export APP_ROOT=/tmp

erb nginx.conf  | grep -i error_log

error_log /tmp/nginx/logs/error.log;

এই ব্যবহার করা হয় Cloudfoundry staticfile-buildpack

নমুনা nginx কনফিগারেশন: https://github.com/cloudfoundry/staticfile-buildpack/blob/master/conf/nginx.conf

আপনার ক্ষেত্রে

head /etc/nginx/nginx.conf
user www-data;
worker_processes 4;
pid /var/run/nginx.pid;
env APP_WEB_1_PORT_5000_TCP_ADDR;
upstream gunicorn {
    server $APP_HOST_NAME:$APP_HOST_PORT;
}

পরিণত

head /etc/nginx/nginx.conf
user www-data;
worker_processes 4;
pid /var/run/nginx.pid;
env <%= ENV["APP_WEB_1_PORT_5000_TCP_ADDR"] %>
upstream gunicorn {
    server <%= ENV["APP_HOST_NAME"] %>:<%= ENV["APP_HOST_PORT"] %>
}

#After applying erb

export APP_WEB_1_PORT_5000_TCP_ADDR=12.12.12.12
export APP_HOST_NAME=test
export APP_HOST_PORT=7089 

erb /etc/nginx/nginx.conf

head /etc/nginx/nginx.conf
user www-data;
worker_processes 4;
pid /var/run/nginx.pid;
env 12.12.12.12
upstream gunicorn {
    server test: 7089
}

5
2018-02-20 00:11



আপনি এই উত্তর প্রসারিত করতে পারেন? উপরের প্রশ্নের এই প্রশ্নটি ইতিমধ্যেই গ্রহণযোগ্য উত্তর আছে তা মূল্যায়ন করা ভাল, তবে যদি আপনার মনে হয় যে আপনার উত্তরটি এর মান যোগ করে তবে দয়া করে এটিকে প্রসারিত করুন। - BE77Y


Erb ব্যবহার করার উত্তরটি উল্লেখ করে, এটি নীচের হিসাবে করা যেতে পারে।

NGINX কনফিগারেশন ফাইলটি একটি এনআরবি ফাইল হিসাবে পরিবেশ পরিবর্তনশীল ধারণকারী লিখুন, এবং একটি সাধারণ কনফিগারেশন ফাইলের মধ্যে erb কমান্ড ব্যবহার করে এটি মূল্যায়ন করুন।

erb nginx.conf.erb > nginx.conf

Nginx.conf.erb ফাইলের সার্ভার ব্লকের ভিতরে থাকতে পারে

listen <%= ENV["PORT"] %>;

4
2017-08-01 11:39



তাহলে কি রুবি ইন্সটল করতে হবে কনটেইনারে? (যদি না হয়, কিভাবে হয় erb পরিবর্তনশীল প্রতিস্থাপন করতে সক্ষম ... কন্টেইনার শুরু করার পরে, ডান?) - erb এই রুবি স্টাফ ডান: stuartellis.name/articles/erb - KajMagnus
এটি একটি কমান্ড লাইন সরঞ্জাম যা রুবি ইনস্টলেশনের সাথে আসে। কনটেইনারে না থাকলে অন্য বিকল্পগুলি চেষ্টা করুন। - Ruifeng Ma
ঠিক আছে, ব্যাখ্যা করার জন্য ধন্যবাদ - KajMagnus


আমি জানি এটি একটি পুরানো প্রশ্ন, কিন্তু যদি কেউ এই (যেমন আমি এখন আছে) উপর stumbles, এই কাজ করার আরো ভাল উপায় আছে। Docker / etc / হোস্টগুলিতে সংযুক্ত ধারক এর উদ্বোধন সন্নিবেশ করান, আপনি কেবল তা করতে পারেন

upstream upstream_name {
    server docker_link_alias;
}

আপনার ডকার কমান্ড অনুমান মত কিছু docker run --link othercontainer:docker_link_alias nginx_container


3
2018-03-17 05:16



আপনি এই পদ্ধতি ব্যবহার করে হোস্ট পেতে পারেন কিন্তু পোর্ট না। আপনাকে অবশ্যই পোর্ট হার্ড কোডটি বা পোর্ট 80 ব্যবহার করে অনুমান করতে হবে। - Ben Whaley