2012-01-17 19 views
27

Tôi có một kịch bản Upstart cho máy chủ của tôi trông như thế này:Upstart env đoạn thơ không thiết lập các biến môi trường (như NODE_ENV) cho các ứng dụng Node.js

description "myapp node.js server" 

start on runlevel [2345] 
stop on shutdown 

env NODE_ENV=production 
env CUSTOM=somevalue 
exec sudo -u nodejs /usr/local/bin/node /opt/myapp/app.js >> /var/log/nodejs/myapp.log 2>&1 

post-start script 
    NODE_PID=`status myapp | egrep -oi '([0-9]+)$' | head -n1` 
    echo $NODE_PID > /var/run/nodejs/myapp.pid 
end script 

Tuy nhiên, các ứng dụng không thấy NODE_ENV thiết lập để sản xuất. Trong thực tế, nếu tôi console.log (process.env) trong ứng dụng, tôi không thấy NODE_ENV hoặc CUSTOM. Bất kỳ ý tưởng gì đang xảy ra?

Nhân tiện, NODE_ENV = nút sản xuất app.js hoạt động tốt.

+0

Trả lời bởi Peter Lyons đi sâu và đưa ra một số gợi ý thực hành tốt nhất, nhưng chỉ cần chuyển từ "sudo -u" sang "su -c" mà không cần chạm vào bất cứ điều gì khác có vẻ như giải quyết vấn đề này nếu tôi chuyển sang sử dụng "www-data "người dùng so với người dùng" nodejs "của riêng tôi. Cái sau không hoạt động, nhưng điều đó không liên quan gì đến câu hỏi này. –

+1

Tôi cũng nên đề cập rằng sudo -E (bảo vệ môi trường) có thể được thử, mặc dù tôi đã không thử nghiệm nó bản thân mình. –

Trả lời

38

Từ sudo man page (Ubuntu phiên bản của sudo)

Có hai cách khác nhau để đối phó với các biến môi trường. Theo mặc định, tùy chọn env_reset sudoers được bật. Điều này làm cho các lệnh được thực thi với một môi trường tối thiểu có chứa TERM, PATH, HOME, SHELL, LOGNAME, USER và USERNAME ngoài các biến từ quá trình gọi được cho phép bởi các tùy chọn env_check và env_keep sudoers. Có một danh sách trắng có hiệu quả cho các biến môi trường .

Sudo đang đặt lại môi trường. Đây là một khía cạnh khó chịu khi sử dụng susudo trong các tập lệnh khởi động hoặc init. Các phiên bản gần đây của hỗ trợ mới nổi chỉ định uid/gid mà không sử dụng sudo thông qua các chỉ thị setuid/setgid như trong ví dụ bên dưới. Cũng lưu ý việc sử dụng chdir.

start on filesystem and started networking 
respawn 
chdir /var/www/yourapp 
setuid yourapp 
setgid yourapp 
env NODE_ENV=production 
env PATH=/usr/local/bin:/usr/bin:/bin 
env CUSTOM=somevalue 
exec /usr/local/bin/node app.js | /usr/bin/multilog s1024000 /var/log/yourapp 2>&1 

Đối với các phiên bản cũ hơn mới nổi, dưới đây là những gì tôi thường làm để giải quyết.

description "start and stop the example.com node.js server" 

start on filesystem and started networking 
respawn 

chdir /path/to/your/code 
exec su -c 'PATH=$PWD/node/bin NODE_ENV=$(cat node_env.txt) ./node/bin/node app/server.js' www-data >> tmp/stdout.log 2>&1 

Lưu ý rằng tôi chỉ cần đặt một tập tin node_env.txt trong thư mục gốc ứng dụng của tôi mà bộ phương thức sản xuất, bởi vì I hate environment variables. Bạn chỉ có thể làm NODE_ENV=production ngay tại đó nếu bạn thích.

+0

Một vài câu hỏi: (1) Có gì trong node_env.txt, chỉ cần "sản xuất"? (2) Tại sao bạn đặt PATH thành $ PWD/node/bin? và sử dụng ./node/bin/node. Bạn có cài đặt nút cục bộ cho ứng dụng của mình không? (3) Tại sao sử dụng su -c so với sudo -u? Cảm ơn. –

+0

node_env.txt chỉ chứa một từ "sản xuất" (có dấu dòng mới). Đó là tất cả. Có, tôi cài đặt nút trong thư mục gốc của ứng dụng của tôi, mà tôi xem là thực hành tốt nhất. Tôi có nhiều ứng dụng trên cùng một máy chủ và mỗi ứng dụng cần một phiên bản nút khác nhau. Tôi không bao giờ chia sẻ các phiên bản cho ngăn xếp máy chủ ứng dụng của mình. Bạn nên sử dụng "su" thay vì sudo trong các kịch bản mới nổi bởi vì chúng đã được chạy bởi root bởi hệ điều hành và bạn không cần sudo. "su" là cái thích hợp ở đây - trở thành một người dùng khác. "sudo" là nhiều hơn về việc cho phép người dùng thường xuyên thực hiện các lệnh cụ thể dưới dạng root, không áp dụng ở đây –

+0

Tôi đã chuyển mã để sử dụng lệnh exec su -c '...' nodejs >> ... và bây giờ tôi không thể khởi động quá trình. Nếu tôi chạy lệnh đó theo cách thủ công trong trình bao, tôi được yêu cầu nhập mật khẩu. Tôi đã thử lệnh bằng tay với người dùng www-data và nó yêu cầu mật khẩu. Tôi sau đó sudo su -c ... với www-data và nó hoạt động. Tôi chưa thử sử dụng www-data trong kịch bản Upstart của mình. Tôi đang thiếu gì ở đây về cấu hình người dùng Linux? –

3

Chỉ để lưu nội dung trò chuyện. Số Upstart Cookbook đề xuất the usage of start-stop-daemon thay vì su hoặc sudo khi phiên bản Upstart của bạn thực hiện không triển khai setuid.

Nhưng, trừ khi bạn vẫn đang sử dụng 10.04 LTS (Lucid Lynx) mà chỉ có Upstart phiên bản 0.6.5, bạn nên sử dụng các setuid/setgid chỉ thị.

+0

Điều này không hoàn toàn đúng (bất kỳ chi tiết nào?) Kể từ Upstart 1.4, Upstart có khả năng chạy System Job như một người dùng được chỉ định bằng cách sử dụng các dòng lệnh 'setuid' và' setgid'. – hostmaster

+0

Tôi đã biết điều đó, cảm ơn. Nhưng bạn làm tôi nhận ra rằng câu trả lời có lẽ không đủ rõ ràng. – C2H5OH

1

Điều này đã làm việc cho tôi để đặt các biến env của nút trong quá trình khởi động.

#!upstart 

start on runlevel [2345] 
stop on runlevel [016] 

respawn 

script 
    echo $$ > /var/run/app.pid 
    exec sudo NODE_ENV=production /opt/node/bin/node /opt/myapp/app.js >> /var/log/app.sys.log 2>&1 
end script 
0

visudo có một dòng để xác định các biến môi trường được lưu giữ.

sudo visudo 

và thêm env của bạn để:

Defaults  env_keep="YOUR_ENV ..." 

và khởi động lại.

Các vấn đề liên quan