This has always been a big question after someone writes their application with Go — — “how can I restart the Go app I just wrote, when it crashes?” Because you can not just keep it running like this
go run main.go or
./main and then when the program crashes it will restart itself.
A common and good solution for this problem is using Docker. But setting up Docker and configuring your app for the container takes time, specially — if your program interact with server/process like MySQL, Redis. For a big or a long term project that’s definitely the right choice — without a doubt. But if you have a small application and you want to just deploy it real quick and check it on a live server. You may consider a different option.
Another option is creating a Daemon on your Linux server and run it as a service but that requires a bit of extra work. And not an easy thing if you don’t have good knowledge on Linux system and service work. So, here come the easiest solution — using Supervisor for you Go app. And it’ll handle the rest of the work for you. It’s a tool that’ll help you to monitor and your application and restart if it crashes.
Installing Supervisor is fairly simple, on Ubuntu this command will install the Supervisor on your system.
$ sudo apt install supervisor
Then you need to add Supervisor to the system user group.
$ sudo addgroup --system supervisor
Now before creating the Supervisor configuration file let’s write a simple Go program which will read configuration form .env file and interact with MySQL database. The code looks like this:
For the purpose of this demonstration, we would keep the code simple
Now, if we want to run it with Supervisor — we need to build the binary file of the application we want to run. Also create a .env file in the root of the project directory — if you are following along. And make those variables in the .env file we are reading for MySQL database.
Clone the repo in your server where you want to run it. Make sure you follow the Golang directory path convention.
$ go build .
In Go this command eventually creates the binary file with the name project’s root directory, So if the project root is myapp it creates the file name with the name myapp
Now, in your server where you want to run the app, create the configuration file for Supervisor
$ sudo vim /etc/supervisor/conf.d/myapp.conf
And put this this content in that file.
The directory and command variables are very important here, it should be where theproject root is, because the program will try to read the .env file or any other config file the app needs to read from the value provided for the directory variable. The autorestart variable is set to
true so it’ll restart the program if it crashes.
Now reload Supervisor with the following command.
$ sudo supervisorctl reload
Lets check the status for it.
$ sudo supervisorctl status`
Everything is configured properly, you should see something like this
myapp RUNNING pid 2023, uptime 0:00:03
Our Golang server called myapp is now running in the background.
Now make some request to the API we made. Firstly check if the rootHandler is working. Then try to send a request with an invalid JSON formatted input data to the the
/user endpoint. This is suppose to crash the server. But there is no log stored in the server, right? Because we haven’t implemented the feature for logging?
Wait a sec, actually Supervisor handles the log rotation for us. So if you go to
/var/log/ and look into the mayapp.log file. You would see that, it has the request URI path for the request has been made to the server.
$ cat /var/log/myapp.log
Same goes for the error log. And that’s it, our server is up and running — it restarts if it crashes, it logs every request and error messages. Which I think we did it in 5 minutes or so? ( — whatever :)). But the point stands, it’s very easy to deploy and monitor your Golang application with Supervisor.
What’s your thought on this? Make a reply without a hesitation. Have a good weekend.