Introduction
Hey, hey! 👋 Another interesting article about deploy and Golang is here.
Let's imagine that we need to run an application written on Go on a remote server, but configure Docker too long (or just lazy).
What should we do? Learn from this article! 😉
📝 Table of contents
- Why may I need this?
- The basis of our service
- Creating
systemd
service - Setting up a reverse proxy server
- Final result
Why may I need this?
First, it is just important to know how service applications work on GNU/Linux. Also, it will be interesting for very small projects, that are too early to think about Docker and deployment automation (startups, REST API micro services, etc).
The basis of our service
Okay, time to write a simple web service, that will give us something, when sending a request to it. For example, I'll take my favorite web framework Fiber (v2), which works extremely fast and easy to learn.
If you are not yet familiar with it, follow the comments in the code:
package main
import (
"log"
"github.com/gofiber/fiber/v2"
)
func main() {
// Create new Fiber instance
app := fiber.New()
// Make path with some content
app.Get("/hello", func(c *fiber.Ctx) error {
// Return a string with a dummy text
return c.SendString("Hello, World 👋!")
})
// Start server on http://localhost:3000 or error
log.Fatal(app.Listen(":3000"))
}
Save this file as main.go
and build binary for GNU/Linux x64 within a similar folder with hello_world
name:
GOOS=linux GOARCH=amd64 go build main.go -o ./hello_world
OK. Now, just copy this binary to your remote server inside /root/go
folder.
A few words about Fiber
Perhaps, you are asking yourself, so why do I love Fiber web framework so much? The answer is in its main features:
- Robust routing
- Extreme performance
- API-ready web framework
- Flexible middleware support
- Low memory footprint
And, especially, I'd like to mention the extremely friendly community in Discord and detailed documentation (translated into different World languages)!
Creating systemd
service
The systemd
is a software suite that provides an array of system components for Linux operating systems.
[...] Its main aim is to unify service configuration and behavior across Linux distributions; systemd's primary component is a "system and service manager"—an init system used to bootstrap user space and manage user processes.
— Wikipedia
Perfect! Now let's create a new service.
- Connect to your remote server as
root
(super user) - Create a file with the extension
*.service
within thesystemd
folder:
nano /etc/systemd/system/hello_world.service
- Copy this code to it:
[Unit]
Description=Go sample web app
After=multi-user.target
[Service]
User=root
Group=root
ExecStart=/root/go/hello_world
[Install]
WantedBy=multi-user.target
- Hit
Ctrl+O
to save andCtrl+X
for close editor - Next, start and enable this service:
systemctl start hello_world.service
systemctl enable hello_world.service
☝️ Service will start automatically, even after the remote server reboots.
Setting up a reverse proxy server
I will use Nginx as a reverse proxy server, but you can choose any other one.
- Install
nginx
using the package manager. For Debian-like systems it will look like this:
apt install nginx -y
- Start
nginx
service:
systemctl start nginx
- Create a config in
/etc/nginx/sites-available/hello_world
file:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
location /root/go/hello_world {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
- Create a symbolic link of our config file to the
sites-enabled
folder:
ln -s /etc/nginx/sites-available/hello_world /etc/nginx/sites-enabled
- Finally, reload
nginx
to apply config:
nginx -t && nginx -s reload
🔥 Sometimes it can be a problem that port
3000
is not available on your remote server. Please check the firewall settings.
Final result
Yep, that's it! Go to http://your_server_ip:3000
and see result 🎉
Photos by
- Simon Abrams https://unsplash.com/@flysi3000
P.S.
If you want more articles (like this) on this blog, then post a comment below and subscribe to me. Thanks! 😻
❗️ You can support me on Boosty, both on a permanent and on a one-time basis. All proceeds from this way will go to support my OSS projects and will energize me to create new products and articles for the community.
And of course, you can help me make developers' lives even better! Just connect to one of my projects as a contributor. It's easy!
My main projects that need your help (and stars) 👇
- 🔥 gowebly: A next-generation CLI tool that makes it easy to create amazing web applications with Go on the backend, using htmx, hyperscript or Alpine.js and the most popular CSS frameworks on the frontend.
- ✨ create-go-app: Create a new production-ready project with Go backend, frontend and deploy automation by running one CLI command.
Top comments (2)
I find it easier to run Go programs with pm2, together with Node.js programs.
As for the reverse proxy, I use nginx mostly but am doing trial deployments with Caddy.
If the service doesn't need to be on port 443 (backend API), I may skip the reverse proxy altogether and let the Go program listen on port 8443 of an IPv6 address using a self-signed certificate, and then enable Cloudflare in front of it.
Hello! Yes, of course, you can choose this path.
In this article I showed you a way to do this on the built-in tools (almost every distribution already has Nginx installed, for example) and with a minimum of configuration effort... 😉