Golang live-reload with Virtualbox shared folders



This week I was looking into a live reload solution for a golang project I was working on. The project is targeted at linux only.
My development machine is running Windows 10 and I am building and debugging the Go project on a Virtualbox VM running Ubuntu 18.10 with the project source code shared to the VM via virtualbox shared folders.

Due to using a virtualbox shared folder, filesystem events from Windows 10 are not picked up in the guest linux virtual machine. There are a few existing live reload utilities but none of them supported legacy polling (as far as I know) and so they didnt work for me. I came across Nodemon which does support legacy polling.

These are my notes on a live-reload solution using nodemon and a bash script when using virtualbox shared folders.

1. Install Nodemon

 $ npm install -g nodemon 

2. Create the Nodemon config file

Add a file called nodemon.json in the root of your project and paste the following code. This is assuming your main.go is sitting in cmd/myproject.
Replace myproject with your project name.
The watch array contains all the directories that will watched for file changes.
The ignore array contains all the directories that will ignore.
You can refer to the Nodemon documention for further info.

 
{
  "restartable": "rs",
  "verbose": true,
  "events": {
       "restart": "./dev_kill_server.sh"
  },
  "watch": [
    "cmd/myproject/",
    "internal/",
    "templates/"
  ],
  "ignore": [
    ".git",
    "web/node_modules/**/node_modules",
    "docs",
    "logs",
    "public",
    "test"
  ],
  "env": {
    "NODE_ENV": "development"
  },
  "delay": "1",
  "ext": "go,gohtml"
}
 

2. Create the bash script to kill the running Go http server. This will be called by nodemon.

Create a bash script called dev_kill_server.sh in your project root and add the following code.
Change :8080 to whatever port number you are using.
This basically finds the process id using the specified port and kills the process.

 
#!/bin/bash

PID=$(sudo lsof -t -i :8080 | tr '\\n' ' '); 
if [[ -n $PID ]]; 
then 
    echo "killing PID(s): $PID"; 
    sudo kill -KILL $PID 2> /dev/null; 
fi
 

3. Run nodemon to watch for changes and run the Go server.

The following command will call nodemon to watch for changes to any files, restart the golang server via the dev_kill_server.sh script and execute go run thereafter.
The -L flag enables legacy polling, needed when using a virtualbox file share due to filesystem events generated on Windows 10 not being picked up in the guest linux vm.

 $ nodemon -L  --exec "go run" ./cmd/myproject 

Copyright (c) 2021 Julien Dcruz