Disable hugo server automatically assigning a port when the port is taken

My use case is that I have a cronjob running every minute or so to restart the server if it goes down for any reason, which is a technique I’ve used for webservers in the past.

I’ve rewritten a site using hugo (my first using hugo!) and I had assumed that by setting --port=12345 it will only try to use that port, but on discovering that I’m leaking many process after deploying it I found it not to be the case.

Is there a way to cause hugo to exit with error when the port specified is already taken? I feel like in most cases if someone specifies a port it’s the only one that’d work for the process, such as in a shared hosting environment or container.

Hugo contains a web server as a convenience. It’s not intended for production usage.

What exactly is it doing? Grabbing another port every time it starts?

These are the commands I’m using to start it locally on my mac:

It nails it every time. I never have a problem with ports, except when the server is improperly shut down. If something crashes, sometimes I have that hugo already running on that port, and when I run the command again, it starts on a different port. If I use the recommended ctrl-c to shut down, it shuts down fine, every time.

But as @michael_henderson said, it’s not designed for production use. You’d have to build all the various start/stop init scripts around it to make it work (for instance, getting its pid and shutting down gracefully based on that pid), and, it’s just not got the featureset. You’re better off just pushing your generated /public to a folder being served by apache or ngnix.

by the way @zaichang a cron script like that either a) assumes the target (binary or etc) will fail gracefully or b) contains the logic to make sure the target gets shut down before any restarting.

I can comment if you show me the cronjob and associated script.

Thanks for clarifying that hugo server is not designed for production.

@michael_henderson Right it is self-assigning a new port of the specified port is taken:

ERROR: 2016/02/25 port 47572 already in use, attempting to use an available port

I guess my question here is what is the use case for assigning a new port if the specified port is already taken? If a port is specified it seems it’s because the user wants to use that exact port for a reason.

@RickCogley Thanks for your suggestion and sample script

In the end instead of serving static files from nginx I adapted a init.d style script I have elsewhere to manage the process, storing the pid into a file, etc. This is mostly to avoid having to change the application record for my hosting … in the future I might still serve generated files but for now this script seems to suffice (but not guaranteed to be bug-free).

#! /bin/bash
#
# /etc/init.d/hugo
#

SITE_URL=http://www.zaiadesign.com/
SITE_PORT=47572

APPNAME="hugo"
WORKDIR=/home/zaia/webapps/zaiadesign
COMMAND="hugo server --baseURL=$SITE_URL --port=$SITE_PORT \
                     --appendPort=false \
                     --watch --disableLiveReload"
PIDFILE=$WORKDIR/$APPNAME.pid

case "$1" in
  start)
        # Start
        printf "%s … " "Starting $APPNAME"
        if [ -f $PIDFILE ]; then
            PID=`cat $PIDFILE`
            if [ -z "`ps ax | grep ${PID} | grep -v grep`" ]; then
                printf "%s\n" "Process dead but pidfile exists"
            else
                echo "Process is already running"
                exit 0
            fi
        fi

        cd $WORKDIR
        nohup $COMMAND &
        PID=`echo $!`
        echo "PID=$PID"
        if [ -z $PID ]; then
            printf "%s\n" "Unable to start process"
        else
            echo $PID > $PIDFILE
            printf "$APPNAME started successfully with PID $PID\n"
        fi
        ;;
  status)
        # Status
        printf "%s … " "Checking $APPNAME"
        if [ -f $PIDFILE ]; then
            PID=`cat $PIDFILE`
            if [ -z "`ps ax | grep ${PID} | grep -v grep`" ]; then
                printf "%s\n" "Process dead but pidfile exists"
            else
                echo "Running"
            fi
        else
            printf "%s\n" "$APPNAME not running"
        fi
        ;;
  stop)
        printf "%s … " "Stopping $APPNAME"
        if [ -f $PIDFILE ]; then
            PID=`cat $PIDFILE`
            kill $PID
            printf "%s\n" "Ok"
            rm -f $PIDFILE
            printf "%s\n" "$APPNAME stopped"
        else
            printf "%s\n" "$APPNAME was not running"
        fi
        ;;
  restart)
  	    $0 stop
  	    $0 start
        ;;

  *)
        echo "Usage: /etc/init.d/hugo {start|stop|status|restart}"
        exit 1
        ;;
esac

exit 0

Would you mind creating an issue for this in the Hogo Github page? It does seem like it shouldn’t do as you described.

@zaichang, yeah, that init script is what you’d have to do. Are you using cron to run it with the start arg repeatedly?

@michael_henderson I’ve created an issue as you suggested: https://github.com/spf13/hugo/issues/1901

@RickCogley Yes precisely. The cronjob looks like this, so if the server dies for any reason at most it is down for 60 seconds:

*/1 * * * * cd /home/zaia/webapps/zaiadesign/; ./hugo.sh start

As a side note in this thread https://github.com/spf13/hugo/issues/852 Steve did mention that “Hugo’s server is more than powerful enough for production usage and I know of a lot of people using it as such…” as such maybe it’ll evolve into a production-ready alternative.

1 Like