010. 代理部署:使用 nginx supervisor 部署 go web 应用 |《gx1 golang 五分钟视频》| go 技术论坛-江南app体育官方入口
提示: 希望我讲某方面的视频,请前往 提交建议。
前置声明
ubuntu 20.04 64 位系统下演示。
使用 项目来做演示。
三种部署方式
go web 程序一般来讲有三种部署方式:
- 独立部署
- 代理部署
- 容器部署
独立部署就是将监听端口直接设置为 80/443 端口,使用 nohup myapi &
后台运行。缺点很明显,服务器上只能部署一站点。
代理部署是将使用 nginx 来将动态请求迭代给 go 程序。好处有一机多站点,动静分离,负载均衡等。
容器部署是将所有依赖程序,如 mysql , nginx, supervisor 等都打包到一个 docker 镜像里,具有隔离应用,方便集群部署的好处。
详见:
本视频我们重点讲解代理部署,容器部署也是需要依赖代理部署的相关知识,后面还有有容器部署的视频。
代理部署
需要安装几个软件:
- nginx —— 代理服务器,请确保安装;
- supervisor —— 进程管理,请确保安装;
- mysql —— 数据库,请确保安装。
软件安装这里就不做演示。
开始部署
开始部署
1. 创建 web 目录
ssh 连接到服务器上,创建 web 目录。
我的目录一般会放在 /data/www 下,服务器上有多个项目,每个项目会创建网站域名对应的 web 目录。
假如我们要部署的域名是 goblog.com
使用以下命令:
$ mkdir -p /data/www/goblog.com
2. 编译可执行文件
根目录使用下面的指令可以静态编译 linux
平台 amd64
架构的可执行文件。
mac 或 linux 系统:
$ cgo_enabled=0 goos=linux goarch=amd64 go build -o goblog
winows 依次执行以下四个命令:
set cgo_enabled=0
set goos=linux
set goarch=amd64
go build -o goblog
命令详解:
- cgo_enabled :设置是否在 go 代码中调用 c 代码。0 为关闭,采用纯静态编译;
- goos : 目标操作系统
- goarch : 目标操作系统的架构
-o
是产出的目标文件名称
通过如下命令可查看 go 支持 os 和平台列表:
$ go tool dist list
aix/ppc64
android/386
android/amd64
android/arm
android/arm64
darwin/amd64
darwin/arm64
dragonfly/amd64
freebsd/386
freebsd/amd64
freebsd/arm
freebsd/arm64
illumos/amd64
ios/amd64
ios/arm64
js/wasm
linux/386
linux/amd64
linux/arm
linux/arm64
linux/mips
linux/mips64
.
.
.
windows/386
windows/amd64
windows/arm
windows/arm64
3. 上传文件
上面的命令执行完成后,会在根目录下产生一个 goblog
的可执行文件,使用 scp 命令将其上传到服务器 web 目录:
$ scp goblog root@117.50.你的ip.25:/data/www/goblog.com/
scp 命令使用的是 ssh 连接,安全稳定。当然你也可以通过 sftp 或者 ftp 将文件上传到 /data/www/goblog.com/
目录下。
在服务器的 /data/www/goblog.com/
下创建 .env 文件,并做相应修改,请修改以下的数据库连接信息、app_key 和 app_url,其他信息有必要也可以做修改:
.env
app_name=goblog
app_env=local
app_key=33446a9dcf9ea033a0a6532b166da32f304af0de
app_debug=true
app_url=http://goblog.com
app_log_level=debug
app_port=3000
db_connection=mysql
db_host=127.0.0.1
db_port=3306
db_database=goblog
db_username=xxxxxx
db_password=xxxxxxxxxxxxxxxx
session_driver=cookie
session_name=goblog-session
注意此时 goblog 可执行文件与 .env 文件是在同一个目录下 —— /data/www/goblog.com/
。
创建数据库:
create database goblog character set utf8mb4 collate utf8mb4_unicode_ci;
4. 运行项目
服务器上,进入 /data/www/goblog.com/
目录,并允许我们的项目:
$ cd /data/www/goblog.com/
$ ./goblog
此时如果我们的 goblog 数据库里面没有表,应该会在命令行输出创建表的信息,这是 gorm 在做自动迁移。
服务器上使用以下命令测试一下:
$ curl http://localhost:3000
一切正常的话,会打印出:
<!doctype html>
<html lang="en">
<head>
<title>
所有文章 —— 我的技术博客
</title>
<link href="/css/bootstrap.min.css" rel="stylesheet">
<link href="/css/app.css" rel="stylesheet">
</head>
.
.
.
此时我们的程序已经可以正常运行。
5. 绑定 hosts
为方便调试,我们来修改本机的 hosts 。
假设以下:
- 域名是 goblog.com
- ip 是 173.20.20.20 (请换为你的服务器 ip )
定位 hosts 文件:
- mac 或 linux 下,文件在
/etc/hosts
中,使用sudo vi /etc/hosts
命令编辑; - windows 下是
c:\windows\system32\drivers\etc\hosts
,不懂请百度一下。
修改 hosts 文件,最后面添加一行:
173.20.20.20 goblog.com
然后保存。
使用 ping 测试一下:
$ ping goblog.com
返回的第一行跟我们绑定的域名是一致的就行了:
ping goblog.com (173.20.20.20): 56 data bytes
.
.
.
6. 配置 nginx
我的服务器上有多个站点,nginx.conf 里配置了:
http {
.
.
.
include /etc/nginx/sites-enabled/*;
}
目录 /etc/nginx/sites-enabled
下是所有的站点配置,以域名区分。goblog 项目域名就使用 goblog.com 命名,配置如下:
/etc/nginx/sites-enabled/goblog.com
server {
listen 80;
server_name goblog.com;
access_log /data/log/nginx/goblog/access.log;
error_log /data/log/nginx/goblog/error.log;
location / {
proxy_pass http://127.0.0.1:3000;
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;
}
}
日志目录 /data/log/nginx/goblog
也请确保存在,不存在的话运行以下:
$ mkdir -p /data/log/nginx/goblog
配置完成后,使用以下命令确保 nginx 配置正确:
$ nginx -t
-t
是 test 的意思,输出以下即代表正确:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
现在可以让 nginx 加载我们的 goblog.com 配置:
$ service nginx reload
浏览器访问 goblog.com ,应该可以看到:
现在 nginx 配置成功。
7. 配置 supervisor
目前我们的 goblog 还是通过命令行运行的方式,一但退出命令行 goblog.com 将无法打开。
所以一般我们会使用进程管理工具来管理 go 应用,使其在后台运行,且出错时可自动重启。
开始之前我们先在服务器上,将之前监听的 3000 端口的 goblog 程序关闭:
$ kill -9 $(lsof -ti:3000)
接下来我们在 /etc/supervisor/conf.d
目录中创建一个新的配置:
/etc/supervisor/conf.d/goblog.conf
[program:goblog]
directory=/data/www/goblog.com
command=/data/www/goblog.com/goblog
stopsignal=term
autostart=true
autorestart=true
user=www-data
stdout_logfile=/data/log/supervisor/goblog/stdout.log
stderr_logfile=/data/log/supervisor/goblog/stderr.log
以下是配置信息详解:
配置项 | 说明 |
---|---|
[program:goblog] | 程序名称,stop start 等管理时使用 |
directory=/data/www/goblog.com | 进入该目录运行命令,确保了 .env 的正确加载 |
command=/data/www/goblog.com/goblog | 执行 goblog 项目 |
stopsignal=term | 重启时发送的信号,确保端口正常关闭 |
autostart=true | 是否自启动 |
autorestart=true | 是否自动重启 |
user=www-data | 执行程序的用户 |
stdout_logfile=/data/log/supervisor/goblog/stdout.log | 输出日志位置 |
stderr_logfile=/data/log/supervisor/goblog/stderr.log | 错误输出日志 |
请确保 /data/log/supervisor/goblog
目录存在,不存在的话使用以下命令创建:
$ mkdir -p /data/log/supervisor/goblog
最后,保存文件。
现在运行以下命令让 supervisor 重新加载配置文件:
$ supervisorctl reload
运行 status
命令,加上我们的 goblog 程序名称来查看状态:
$ supervisorctl status goblog
goblog running pid 36184, uptime 0:17:49
一切正常。
supervisor 还有以下的几个常见操作:
命令 | 说明 |
---|---|
supervisorctl reload | 重启 supervisor |
supervisorctl status 程序名 | 查看状态,后面不加程序名的话是所有任务状态 |
supervisorctl shutdown | 关闭所有任务 |
supervisorctl start 程序名 | 启动任务 |
supervisorctl stop 程序名 | 关闭任务 |
浏览器访问 goblog.com ,可以看到:
随着 supervisor 的配置成功,我们的 goblog 项目也成功部署上线了。