Dapatkah saya menggunakan variabel lingkungan nginx dalam file statis yang dilayani nginx?

10

Jika saya menggunakan variabel lingkungan di konfigurasi nginx, dan nginx dikonfigurasi untuk hanya melayani file statis (html, js, css - misalnya aplikasi AngularJs), apakah ada cara saya dapat menggunakan variabel lingkungan dalam file JS yang dilayani nginx ? Atau satu-satunya cara untuk melakukan ini untuk menjalankan server non-statis, misalnya io.js, php, dll.


Btw Anda tidak dapat menggunakan variabel lingkungan secara asli di konfigurasi nginx.

Ketika saya berbicara tentang lingkungan vars di konfigurasi nginx yang saya maksud seperti di posting ini: Bagaimana saya bisa menggunakan variabel lingkungan di Nginx.conf di mana mereka menggunakan env APP_WEB_1_PORT_5000_TCP_ADDR;dan$ENV{"APP_WEB_1_PORT_5000_TCP_ADDR"};


Jelaskan kasus penggunaan Anda dengan tepat

Kasus penggunaan khusus saya adalah bahwa saya memiliki aplikasi AngularJS bertenaga nginx dalam wadah buruh pelabuhan. Aplikasi ini adalah "Aplikasi Satu Halaman" yang menggunakan API yang berjalan pada sistem lain secara bersamaan. Saat ini saya menjalankan wadah buruh pelabuhan yang berbeda antara produksi dan pementasan karena aplikasi memiliki beberapa konfigurasi yang berbeda, misalnya kode Google-Analtyics. Data khusus lingkungan ini disimpan dalam config.jsfile dan nilai saat ini hardcoded, satu nilai untuk mastercabang di git, dan nilai yang berbeda untuk stagingcabang. Saya ingin mengubah desain sehingga saya dapat menggunakan wadah yang sama untuk produksi dan pementasan. Saya ingin melewatkan var ENV ke dalam wadah ketika saya menjalankannya ( docker run -e GACODE=UA-12345-6 ...) dan minta nginx menggunakan var ENV (via env GACODE;dan $ENV{"GACODE"}jadiconfig.jsfile dapat menggunakan kode GoogleAnaltyics yang diteruskan, daripada meng-hardcoding mereka). Saya tidak tahu apakah ini mungkin atau tidak (maka pertanyaannya;)). Dengan hanya menggunakan nginx menjadikan wadah saya sebuah proses tunggal, sedangkan jika saya harus menggunakan io.js maka saya akan membutuhkan beberapa wadah yang terhubung dan lebih banyak bagian yang bergerak lebih kompleks).

Tom
sumber
Apa ?! Jelaskan persis use case Anda karena tampaknya Anda melihatnya di sisi yang salah. Btw Anda tidak dapat menggunakan variabel lingkungan secara asli di konfigurasi nginx.
Xavier Lucas
Terima kasih @XavierLucas - Saya memperbarui pertanyaan untuk mencoba menjelaskan lebih lanjut.
Tom

Jawaban:

4

sub_filter

Jika Anda ingin penggantian string sederhana, Anda dapat menggunakan sub_filter . Sebagai contoh:

server {
    sub_filter "REPLACE_THIS" "with this";
    sub_filter_once off; # Don't stop at the first match, replace all of them
    sub_filter_types "text/javascript" "application/json"; # Apply to these mime types in addition to text/html 

    # Everything else
}

Namun tidak mungkin untuk membaca variabel lingkungan di nginx config - Anda tentu saja dapat menulis skrip nginx config dengan cara apa pun yang Anda perlukan / ingin menghasilkan file konfigurasi yang valid dan kemudian memuat ulang nginx.

AD7six
sumber
4

Saya bereksperimen dengan menggunakan variabel lingkungan sub_filter dan nginx tetapi menyimpulkan bahwa itu tidak mungkin .

Misalnya, ini menunjukkan eksperimen saya dan menunjukkan menggunakan ENV yang diteruskan ke nginx tidak berfungsi di dalam serverblok:

env TOMTEST1; # OK - makes $ENV{"TOMTEST1"} available but NOT in server block.

http {

    server {

        # set $TOMTEST1 $ENV{"TOMTEST1"};    # KO - DOES NOT WORK - NGINX WONT START
        set $TOMTEST2   'tomtest2 Var';      # OK - THIS DOES WORK OK

        sub_filter 'TOM_TEST2' $TOMTEST2;       # OK - but not useful to me.
        sub_filter 'TOM_TEST3' 'tomtest3 Var';  # OK - but not useful to me.
        sub_filter_once off;                    # Don't stop at the first match, replace all of them
        sub_filter_types "text/javascript" "application/json"; # Apply to these mime types in addition to text/html

        # Serve static files
        location / {
           try_files $uri /index.html =404;
        }
        ...

di mana file config.json statis yang saya sajikan memiliki berbagai string uji seperti berikut:

{
    "environment": "local",
    "test1": "$ENV{"TOMTEST1"}",
    "test3": "TOM_TEST2",
    "test4": "TOM_TEST3",
}

Seperti @ AD7six sebutkan, cara untuk melanjutkan adalah memiliki skrip yang berjalan sebelum nginx mulai menghasilkan file konfigurasi yang valid dari placeholder. Tapi ini menimbulkan pertanyaan, jika skrip akan dijalankan sebelum nginx dimulai, saya mungkin juga mengatur isi config.jsonfile saya di skrip itu dan tidak repot sub_filtersama sekali.

Tom
sumber
2
Jika itu untuk satu file statis - tentu saja masuk akal untuk tidak melakukannya melalui nginx config, saya berasumsi bahwa usecase Anda sedikit lebih luas dari itu. Untuk info / kontras saya gunakan sub_filter "example.com" "example.dev";dalam setup dev untuk mengganti semua dan semua referensi ke domain produksi ke lingkungan lokal karena referensi tersebut berasal dari respons api pihak ke-3 / kode aplikasi / js / db dumps / etc. - Yaitu untuk nginx bisa di mana saja dalam respon html / js / json. +1
AD7six
3

Saya telah mencari untuk menyelesaikan masalah yang sama dengan OP dan posting ini muncul dalam pencarian Google, jadi saya pikir saya akan menambahkan solusi potensial.

Posting ini menguraikan bagaimana Anda dapat mengekspos variabel lingkungan dalam nginx config: https://blog.doismellburning.co.uk/environment-variables-in-nginx-config/

Dan Anda dapat mengembalikan konten tanpa memiliki file di sistem file: Balas dengan 200 dari konfigurasi Nginx tanpa menyajikan file

Menyatukan dua hal ini, kita berakhir dengan yang berikut:

env MY_ENV_VAR;

# Snip

http {
    # Snip

    server {
        # Snip

        location ~ ^/config.js$ {
            add_header Content-Type text/javascript;
            set_by_lua $env_var 'return os.getenv("MY_ENV_VAR")';
            return 200 'const MY_ENV_VAR = \'$env_var\'';
        }
    }
}

Ini berhasil bagi saya di lingkungan pengujian. Agak rumit (tidak yakin itu lebih baik daripada membuat file secara otomatis pada peluncuran Docker yang berisi vars yang Anda butuhkan).

Semoga itu bisa membantu.

Hibah
sumber