Tôi có thể sử dụng các biến môi trường nginx trong các tệp tĩnh mà nginx phục vụ không?


10

Nếu tôi sử dụng biến môi trường trong cấu hình nginx và nginx được định cấu hình để chỉ phục vụ các tệp tĩnh (html, js, css - ví dụ: ứng dụng AngularJs), có cách nào tôi có thể sử dụng biến môi trường trong tệp JS mà nginx phục vụ ? Hoặc là cách duy nhất để làm điều này để chạy một máy chủ không tĩnh, ví dụ: io.js, php, v.v.


Btw bạn không thể sử dụng các biến môi trường tự nhiên trong cấu hình của nginx.

Khi tôi nói về các vars môi trường trong cấu hình nginx, ý tôi là như trong bài viết này: Làm thế nào tôi có thể sử dụng các biến môi trường trong Nginx.conf nơi họ sử dụng env APP_WEB_1_PORT_5000_TCP_ADDR;$ENV{"APP_WEB_1_PORT_5000_TCP_ADDR"};


Giải thích chính xác trường hợp sử dụng của bạn

Trường hợp sử dụng cụ thể của tôi là tôi có ứng dụng AngularJS được hỗ trợ bởi nginx trong một container docker. Ứng dụng này là "Ứng dụng một trang" tiêu thụ API chạy trên một hệ thống khác hoàn toàn. Hiện tại tôi chạy một bộ chứa docker khác nhau giữa sản xuất và dàn dựng vì ứng dụng có một số cấu hình khác nhau, ví dụ mã Google-Analtyics. Dữ liệu dành riêng cho môi trường này được lưu giữ trong một config.jstệp và các giá trị hiện được mã hóa cứng, một giá trị cho masternhánh trong git và giá trị khác nhau cho stagingnhánh. Tôi muốn thay đổi thiết kế để tôi có thể sử dụng cùng một container cho cả sản xuất và dàn dựng. Tôi muốn chuyển var ENV vào container khi tôi chạy nó ( docker run -e GACODE=UA-12345-6 ...) và nginx sử dụng var ENV (thông qua env GACODE;$ENV{"GACODE"}vì vậyconfig.jstệp có thể sử dụng mã GoogleAnaltyics được truyền vào, thay vì mã hóa chúng). Tôi không biết liệu điều này có thể hay không (do đó là câu hỏi;)). Chỉ sử dụng nginx làm cho bộ chứa của tôi trở thành một quy trình đơn lẻ, trong khi nếu tôi phải sử dụng io.js thì tôi sẽ cần nhiều bộ chứa được liên kết và nhiều bộ phận chuyển động phức tạp hơn).


Gì ?! Giải thích chính xác trường hợp sử dụng của bạn kể từ khi nó xuất hiện bạn đang nhìn vào mặt sai. Btw bạn không thể sử dụng các biến môi trường tự nhiên trong cấu hình của nginx.
Xavier Lucas

Cảm ơn @XavierLucas - Tôi đã cập nhật câu hỏi để cố gắng giải thích thêm.
Tom

Câu trả lời:


4

bộ lọc phụ

Nếu bạn muốn thay thế chuỗi đơn giản, bạn có thể sử dụng sub_filter . Ví dụ:

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
}

Tuy nhiên , không thể đọc biến môi trường trong cấu hình nginx - tất nhiên bạn có thể viết tập lệnh viết tệp cấu hình nginx theo bất kỳ cách nào bạn cần / muốn tạo tệp cấu hình hợp lệ và sau đó tải lại nginx.


4

Tôi đã thử nghiệm sử dụng các biến môi trường sub_filter và nginx nhưng kết luận rằng điều đó là không thể .

Ví dụ: điều này cho thấy các thử nghiệm và chương trình của tôi sử dụng ENV được truyền cho nginx không hoạt động trong một serverkhối:

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;
        }
        ...

trong đó tệp config.json tĩnh mà tôi đang phục vụ có các chuỗi thử nghiệm khác nhau như sau:

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

Như @ AD7six đã đề cập, cách tiến hành là có một tập lệnh chạy trước khi nginx bắt đầu tạo tệp cấu hình hợp lệ từ trình giữ chỗ. Nhưng điều này đặt ra câu hỏi, nếu một kịch bản sẽ chạy trước khi nginx bắt đầu, tôi cũng có thể đặt nội dung config.jsontệp của mình trong tập lệnh đó và không bận tâm gì sub_filtercả.


2
Nếu đó là cho một tệp tĩnh - chắc chắn không có ý nghĩa gì khi không thực hiện thông qua cấu hình nginx, tôi cho rằng usecase của bạn rộng hơn thế một chút. Để biết thông tin / độ tương phản, tôi sử dụng sub_filter "example.com" "example.dev";trong thiết lập dev để thay thế bất kỳ và tất cả các tham chiếu đến miền sản xuất sang môi trường cục bộ vì các tham chiếu đó đến từ phản hồi api của bên thứ 3 / mã ứng dụng / js / db dumps / v.v. - tức là đối với nginx, nó có thể ở bất kỳ đâu trong bất kỳ phản hồi html / js / json nào. +1
AD7six

3

Tôi đã xem xét giải quyết vấn đề tương tự như OP và bài đăng này xuất hiện trong tìm kiếm của Google, vì vậy tôi nghĩ rằng tôi sẽ thêm một giải pháp tiềm năng.

Bài đăng này phác thảo cách bạn có thể hiển thị một biến môi trường trong cấu hình nginx: https://blog.doismellburning.co.uk/en môi-biến-in-nginx-config /

Và bạn có thể trả lại nội dung mà không cần có tệp trong hệ thống tệp: Trả lời 200 từ cấu hình Nginx mà không phục vụ tệp

Đặt hai thứ này lại với nhau, chúng ta sẽ có những điều sau đây:

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\'';
        }
    }
}

Điều này đã làm việc cho tôi trong một môi trường thử nghiệm. Nó hơi cồng kềnh (không chắc nó tốt hơn việc tự động tạo một tệp khi khởi chạy Docker có chứa các vars bạn cần).

Mong rằng sẽ giúp.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.