This paper takes the Go Web program as an example to introduce several methods of deploying the Go language program on CentOS7 server.

Independent deployment

Go supports cross-compilation, which means you can write code on Windows or Mac platforms and compile it into programs that run on Linux AMD64 servers.

For simple projects, we usually just copy the compiled binaries to the server and set them up to run as background daemons.

compile

Compilation can be done by the following command or by writing a makefile.

CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o ./bin/bluebell
Copy the code

The following assumes that we upload locally compiled Bluebell binaries, configuration files and static files to /data/app/ Bluebell directory on the server.

In addition, if you don’t like the size of the compiled binary, you can add the -ldFlags “-s-w” parameter at compile time to remove the symbol table and debug information, and generally reduce the size by 20%.

CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags "-s -w" -o ./bin/bluebell
Copy the code

If this is too large, you can continue to compress binary executables using the UPX tool.

After compiling bluebell project, the directory structure of relevant necessary files is as follows:

├ ─ ─ bin │ └ ─ ─ bluebell ├ ─ ─ the conf │ └ ─ ─ config. The yaml ├ ─ ─ the static │ ├ ─ ─ CSS │ │ └ ─ ─ app. 0 afe9dae. CSS │ ├ ─ ─ the favicon. Ico │ ├ ─ ─ │ ├─ ├─ ├─ ├─ avatar.7b0a9835. Img │ │ ├─ ├─ │ ├─ avatar.7b0a9835 └ ─ ─ js │ ├ ─ ─ app. 9 f3efa6d. Js │ ├ ─ ─ app. 9 f3efa6d. Js. Map │ ├ ─ ─ the chunk - vendors. 57 f9e9d6. Js │ └ ─ ─ Chunk-impress.57f9e9d6.js. Map ├ ── index.htmlCopy the code

nohup

Nohup is used to run commands in the background of the system without hanging up, which means that the terminal that executes the command exits without affecting the running of the program.

We can use the nohup command to run the application as a background daemon. Since the nohup command tool is installed by default on major Linux distributions, we can simply type the following command to start our project:

sudo nohup ./bin/bluebell conf/config.yaml > nohup_bluebell.log 2>&1 &
Copy the code

Among them:

  • ./bluebell conf/config.yamlIs the start command for our application
  • nohup ... &The startup command of the application is executed without hanging up in the background
  • > nohup_bluebell.logRedirects the standard output of the command to the nohup_bluebell.log file
  • 2 > &1Nohup_bluebell.log redirects standard error output to nohup_bluebell.log

The preceding command returns the process ID

[1], 6338Copy the code

Of course, we can also check bluebell related activity process through the following command:

ps -ef | grep bluebell
Copy the code

Output:

root      6338  4048  0 08:43 pts/0    00:00:00 ./bin/bluebell conf/config.yaml
root      6376  4048  0 08:43 pts/0    00:00:00 grep --color=auto bluebell
Copy the code

In this case, you can open the browser and enter http://server public IP address: port to view the application program display effect.

supervisor

Supervisor is a universal process manager popular in the industry. It changes a common command line process into a background daemon, monitors the running status of the process, and automatically restarts the process when it abnormally exits.

First use yum to install the Supervisor:

If you have not already installed EPEL, you can do so by running the following command, or skip this step if you have:

sudo yum install epel-release
Copy the code

The installation supervisor

sudo yum install supervisor
Copy the code

The Supervisor configuration file is: Conf, the configuration file for the application that is managed by the Supervisor is placed in the /etc/supervisor. d/ directory, which can be configured in the include container in the supervisor.conf file.

[include]
files = /etc/supervisord.d/*.conf
Copy the code

Start the Supervisor service:

sudo supervisord -c /etc/supervisord.conf
Copy the code

We created a configuration file called bluebell.conf in the /etc/supervisord.d directory, which is detailed below.

[program:bluebell] ; User =root; Execution of user command = / data/app/bluebell/bin/bluebell/data/app/bluebell/conf/config. The yaml. Directory =/data/app/bluebell/; Stopsignal =TERM; Signal sent during restart autostart=true Autorestart =true; Whether to automatically restart stdout_logfile=/var/log/bluebell-stdout.log; Stderr_logfile =/var/log/bluebell-stderr.log; stderr_logfile=/var/log/bluebell-stderr.log; Standard error log locationCopy the code

After the configuration file is created, restart the Supervisor service

The sudo supervisorCTL update # is designed to update the configuration file and restart the programCopy the code

Check the running status of Bluebell:

sudo supervisorctl status bluebell
Copy the code

Output:

bluebell                         RUNNING   pid 10918, uptime 0:05:46
Copy the code

And finally, the common supervisory command it is handling is:

The container is designed for the small container that the container is designed for. The container is designed for the small container that the container is designed for Disables the task supervisorctl ReloadCopy the code

The next step is to open your browser to see if the site works.

With nginx deployment

In the need for static file separation, the need to configure multiple domain names and certificates, the need to build their own load balancing layer and other slightly complex scenarios, we generally need to deploy our programs with third-party Web servers (Nginx, Apache).

Forward proxy and reverse proxy

A forward proxy is simply a proxy on the client side. The one you use to access a web site outside the wall is a forward proxy.

Reverse proxy can be simply understood as the proxy of the server, usually said Nginx and Apache belong to the reverse proxy.

Nginx is a free, open source, high-performance HTTP and reverse proxy service that loads heavily visited sites. Nginx can be used as a standalone Web service or as a reverse proxy for Apache or other Web services. Nginx can handle more concurrent connections than Apache, and the memory footprint per connection is very small.

Install nginx using yum

There are installation packages for Nginx in the EPEL warehouse. If you have not already installed EPEL, you can do so by running the following command:

sudo yum install epel-release
Copy the code

Install nginx

sudo yum install nginx
Copy the code

After the installation is complete, run the following command to set up Nginx startup:

sudo systemctl enable nginx
Copy the code

Start the Nginx

sudo systemctl start nginx
Copy the code

Nginx running status

sudo systemctl status nginx
Copy the code

Nginx configuration file

If you install nginx using the above method, all relevant configuration files are in the /etc/nginx/ directory. The main configuration file for Nginx is /etc/nginx/nginx.conf.

There is also a sample nginx.conf.default configuration file for your reference. You can create different configuration files for multiple services (it is recommended to create a separate configuration file for each service (domain name)), and each separate Nginx service configuration file must end in.conf and be stored in the /etc/nginx/conf.d directory.

Nginx common commands

Add several common Nginx commands.

Nginx -s reload # reloading the configuration file nginx -s quit # smooth stop the nginx service nginx -t # test the configuration file is correctCopy the code

Nginx reverse proxy deployment

We recommend using Nginx as a reverse proxy to deploy our program and modify the nginx configuration file as follows.

worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server { listen 80; server_name localhost; access_log /var/log/bluebell-access.log; error_log /var/log/bluebell-error.log; Location / {proxy_pass http://127.0.0.1:8084; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }}}Copy the code

Run the following command to check the syntax of the configuration file:

nginx -t
Copy the code

Run the following command to reload the configuration file:

nginx -s reload
Copy the code

The next step is to open your browser to see if the site works.

You can also use the upstream configuration of Nginx to add multiple server addresses for load balancing.

worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; Upstream Backend {server 127.0.0.1:8084; Backend1.example.com; backend1.example.com; #server backend2.example.com; } server { listen 80; server_name localhost; access_log /var/log/bluebell-access.log; error_log /var/log/bluebell-error.log; location / { proxy_pass http://backend/; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }}}Copy the code

Nginx separates static file requests

The configuration above simply uses Nginx as a reverse proxy to process all requests and forward them to our Go program. In fact, we can optionally use Nginx directly for static file requests and forward the API class dynamic processing requests to the back-end Go program for processing.

Let’s go ahead and modify our nginx configuration file to do this.

worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server { listen 80; server_name bluebell; access_log /var/log/bluebell-access.log; error_log /var/log/bluebell-error.log; # static file request location ~. * \. (GIF | JPG | jpeg | PNG | js | | CSS eot | the vera.ttf | woff | SVG | otf) ${access_log off; expires 1d; root /data/app/bluebell; # #} index. The HTML page request because it is a single page application used here try_files processing, to avoid the problem of there was a 404 page refresh the location / {root/data/app/bluebell/templates; index index.html; try_files $uri $uri/ /index.html; } # API request location/API {proxy_pass http://127.0.0.1:8084; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }}}Copy the code

The front and rear ends are deployed separately

The front-end and back-end code does not need to be deployed on the same server, but can also be deployed on different servers. The following diagram shows how the front-end service forwards API requests to the back-end service.

In the preceding deployment, all browser requests directly access the front-end service, whereas in the deployment mode, the browser directly accesses the back-end API service, as shown in the following figure.

In this case, the front end and back end are often not in the same domain, and we also need to add cross-domain support to the back-end code.

Here use github.com/gin-contrib… Library to support cross-domain requests.

The simplest configuration to allow cross-domain is to use cers.default (), which allows all cross-domain requests by Default.

func main() {
	router := gin.Default()
	// same as
	// config := cors.DefaultConfig()
	// config.AllowAllOrigins = true
	// router.Use(cors.New(config))
	router.Use(cors.Default())
	router.Run()
}
Copy the code

In addition, specific cross-domain request-related configuration items can be customized using cers.config:

package main

import (
	"time"

	"github.com/gin-contrib/cors"
	"github.com/gin-gonic/gin"
)

func main() {
	router := gin.Default()
	// CORS for https://foo.com and https://github.com origins, allowing:
	// - PUT and PATCH methods
	// - Origin header
	// - Credentials share
	// - Preflight requests cached for 12 hours
	router.Use(cors.New(cors.Config{
		AllowOrigins:     []string{"https://foo.com"},
		AllowMethods:     []string{"PUT", "PATCH"},
		AllowHeaders:     []string{"Origin"},
		ExposeHeaders:    []string{"Content-Length"},
		AllowCredentials: true,
		AllowOriginFunc: func(origin string) bool {
			return origin == "https://github.com"
		},
		MaxAge: 12 * time.Hour,
	}))
	router.Run()
}
Copy the code

Container deployment

Container deployment scenarios will be covered in a separate blog post that I won’t go into here.

The above is about deploying the Go project, if you want to know more, please visit the “Go keyboard man” public number, exchange and learn together, ^_^!

Recommended articles:

Network programming in Go (dry stuff!)