Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can "include" directive be used within upstream block of nginx?

Tags:

include

nginx

My site uses two app server, namely app1 and app2, so in the configuration I have something like this:

upstream cluster {
    server app1:8080;
    server app2:8080;
}

Since every time I update the code I need to restart both server processes and I want the service undisturbed, I will follow these steps manually:

  1. Comment app1 within upstream block so to modify it into:

    upstream cluster {
        #server app1:8080;
        server app2:8080;
    }
    
  2. Run nginx -s reload

  3. Update code at app1 and restart the server program, and then uncomment app1 in upstream block

  4. Do steps 1-3 for app2

I wish to write a script to spare this tedious work, so what I hope to do is this:

  1. Have a folder named "available" which contains app1.conf and app2.conf in form as

    server app1:8080;  
    
  2. Have another folder named "enabled" to contain the soft links of app1.conf and app2.conf

  3. Modify the upstream cluster into

    upstream cluster {
        include /usr/local/nginx/conf/enabled/*;
    }
    

    So every time I need to disable any app server I can just remove the corresponding soft link from the "enabled" folder, and later can restore it by running ln -s

However this approach didn't work well as I got an error message from nginx saying:

[emerg]: "include" directive is not allowed here in ....

Is that so include cannot not be put into the upstream block? and I'd imagine I'm not alone in this kind of scenario, disabling and enabling server at times, how other folks normally deal with it?

like image 363
Jie Avatar asked Nov 12 '10 13:11

Jie


2 Answers

Unfortunately, nginx can't handle include directive inside upstream,. But you can use this script to manage your upstream servers:

somewhere in http section of nginx.conf:

include /usr/local/nginx/conf/upstream.conf

create empty file:

touch /usr/local/nginx/conf/upstream.conf

use this script to manage upstream servers(upstreamctl.sh):

#!/bin/bash
if [ -n "$1" -a -n "$2" ]; then
    action="$1";
    target="$2";
else
    echo "Usage: $0 (add|rm) server:port"
    exit 0;
fi;
# Path to nginx binary
BIN="/usr/local/nginx/sbin/nginx"
# Path to upstream config file
CONF="/usr/local/nginx/conf/upstream.conf"

SERVERS=`cat $CONF | grep server`

output="upstream cluster {"


if [ $action == "add" ]; then
    echo -e "$output" > $CONF
    if $( echo $SERVERS | grep --quiet $target ); then
        echo "Warning: Server is already enabled."
    else 
        SERVERS="$SERVERS\n\tserver $target;"
    fi
    echo -e "$SERVERS" >> $CONF
    echo "}" >> $CONF

elif [ $action == "rm" ]; then 
    sed -i "/$target/d" $CONF
else 
    echo "Unknown action"
fi

# Check changes:
$BIN -t

In your case you may run:

./upstreamctl.sh add app1:8080

and

./upstreamctl.sh rm app2:8080
like image 151
Sergei Lomakov Avatar answered Nov 24 '22 05:11

Sergei Lomakov


Just putting this here in case we can help others:

Include directive can be used in upstream block in later versions of nginx.

Example:

/etc/nginx/upstream.conf

server ip:port;
server ip:port;

/etc/nginx/conf.d/default.conf

upstream cluster {
    include /etc/nginx/upstream.conf;
}
server {
    listen       80;
    server_name  localhost;
    location / {
        proxy_pass http://cluster;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}
like image 24
Farhad Farahi Avatar answered Nov 24 '22 04:11

Farhad Farahi