I often wondered, whilst typing the full phrase, ln -s /etc/nginx/sites… to enable a site and undoubtedly getting them the wrong way around, “Surely there must be a better way?”

Of course, Apache has a2ensite, which can be quite easily replicated in a bash script.

After a quick Google to a Server Fault question (like Stack Overflow, but for server-peeps), I stumbled across a script that goes one better.

Called nginx-modsite, it provides a full suite of tools to list enabled sites, available sites, and enable/disable those sites.


First, download the version you need from GitHub:

  • ubuntu is for Ubuntu and Debian-based distros.
  • homebrew is for macOS pros.
  • main is for everything else (based on Linux) that might work.

Installation is fairly straightforward on *nix (Linux and Unix-type, including macOS) machines. The bash script simply needs to be saved in /usr/local/bin, as nginx-modsite, or anything easier for you to remember (provided the name doesn’t clash with an existing command).

The file then needs to be made executable, with sudo chmod +=x.


Using the command nginx-modsite, or whatever you named the script file on install, you have a few options:

  • -l lists all available and enabled sites.
  • -e SITE enables the site SITE.
  • -d SITE disables the site SITE
  • -r reloads the Nginx server, for when you have manually edited config files.
  • -h displays help.

If you miss out the SITE, you will be presented with a number of options:

root@ajsalkeld:/etc/nginx# nginx-modsite -e
0:	example
1:	another-example
Enter number for website:

Then, just hit the number of the one you want, and enter.

After enabling/disabling a site, the script will ask you if you want to reload Nginx now, or you fancy doing it manually later.

Quite simple, really, and far more powerful and feature filled than a2ensite.

How does it work, then?

Again, quite simple, really.

The bash file is simply a list of functions, which can read the sites-available and sites-enabled folders, make links from sites-available to sites-enabled with ln -sf, and remove them.

You can, of course, read the latest script on the repo at GitHub, but I have included the script below, though this may become out of date:

# Default Settings

NGINX_CONF_FILE="$(awk -F= -v RS=' ' '/conf-path/ {print $2}' <<< $(nginx -V 2>&1))"

# Script Functions

ngx_enable_site() {
	[[ ! "$SELECTED_SITE" ]] &&
		ngx_select_site "not_enabled"

		ngx_error "Site does not appear to exist."
		ngx_error "Site appears to already be enabled"


ngx_disable_site() {
	[[ ! "$SELECTED_SITE" ]] &&
		ngx_select_site "is_enabled"

		ngx_error "Site does not appear to be \'available\'. - Not Removing"
		ngx_error "Site does not appear to be enabled."


ngx_list_site() {
	echo "Available sites:"
	ngx_sites "available"
	echo "Enabled Sites"
	ngx_sites "enabled"

# Helper Functions

ngx_select_site() {

	case "$1" in
		not_enabled) sites=$(comm -13 <(printf "%s\n" $se) <(printf "%s\n" $sa));;
		is_enabled) sites=$(comm -12 <(printf "%s\n" $se) <(printf "%s\n" $sa));;

	ngx_prompt "$sites"

ngx_prompt() {

	for site in ${sites[@]}; do
		echo -e "$i:\t${sites[$i]}"

	read -p "Enter number for website: " i

ngx_sites() {
	case "$1" in
		available) dir="$NGINX_SITES_AVAILABLE";;
		enabled) dir="$NGINX_SITES_ENABLED";;

	for file in $dir/*; do
		echo -e "\t${file#*$dir/}"

ngx_reload() {
	read -p "Would you like to reload the Nginx configuration now? (Y/n) " reload
    [[ "$reload" != "n" && "$reload" != "N" ]] && invoke-rc.d nginx reload

ngx_reload_now() {
	invoke-rc.d nginx reload

ngx_error() {
	echo -e "${0##*/}: ERROR: $1"
	[[ "$2" ]] && ngx_help
	exit 1

ngx_help() {
	echo "Usage: ${0##*/} [options]"
	echo "Options:"
	echo -e "\t<-e|--enable> <site>\tEnable site"
	echo -e "\t<-d|--disable> <site>\tDisable site"
	echo -e "\t<-l|--list>\t\tList sites"
	echo -e "\t<-h|--help>\t\tDisplay help"
	echo -e "\n\tIf <site> is left out a selection of options will be presented."
	echo -e "\tIt is assumed you are using the default sites-enabled and"
	echo -e "\tsites-disabled located at $NGINX_CONF_DIR."

# Core Piece

case "$1" in
	-e|--enable)	ngx_enable_site;;
	-d|--disable)	ngx_disable_site;;
	-r|--reload) ngx_reload_now;;
	-l|--list)	ngx_list_site;;
	-h|--help)	ngx_help;;
	*)		ngx_error "No Options Selected" 1; ngx_help;;

Cool! Who wrote it?

Not me. A guy called “Michael Lustfield” is named in the confusing copyright bit, but pyghassen is the original GitHubber.

Then, gabrielwolf ported it for Homebrew on macOS, and made a few improvements.

What I’ve done is add the option -r (about 2 lines’ work), ported the code back to Linux (about one line’s work), changed the name from nginx_modsite to nginx-modsite because I think it works better, and provided branches for Ubuntu and Homebrew.

View on GitHub!