服务器部署Go项目

最近在研究服务器部署项目,用了好几种办法成功部署。这些方法互有利弊,本文就逐一详细演示说明:
 

目录

1.服务器下载Go环境,直接将项目代码放到服务器上运行

2.服务器不下载Go环境,本地将项目打包成可执行的二进制文件,放到服务器上运行

3.服务器安装Docker,项目编写Dockerfile文件

 (1)Dockerfile 文件基于golang:alpine 直接构建

 (2)Dockerfile 文件基于golang:alpine 分阶段构建

 (3)Dockerfile 文件基于centos 环境直接构建


1.服务器下载Go环境,直接将项目代码放到服务器上运行

步骤:

一、首先服务器安装Go环境,如果不会的大家可以参考(5条消息) 在Linux云服务器上搭建golang运行环境_屎山搬运工的博客-CSDN博客

注意大家在服务器的Go环境版本一定要和本地的Go环境版本一致,不然可能会出现一些问题。

二、Go环境安装成功后,我们就需要使用文件传输的工具(Xftp,WinSCP等),将我们本地项目都移动到服务器上。

三、移动成功后,进入项目路径下,我们只需跟本地跑项目一样,输入go run main.go 即可,如果想让服务后台运行,只需要在前面加上nohup即可。

优点:

几乎没有优点,可能就是简单吧

缺点:

满满的缺点,比如可能会出现服务器与本地的Go环境不一致而导致出问题,这就是最大的问题。

推荐指数:⭐

2.服务器不下载Go环境,本地将项目打包成可执行的二进制文件,放到服务器上运行

步骤:

一、在本地修改项目的一些配置

set GOOS=linux  //设置编译目标系统为Linux
set GOARCH=amd64 //设置编译目标的指令集架构为64位 x86架构

修改后,一定不要忘了go env 看一看到底改变了没,本人修改了好几次才成功,推荐用cmd 到项目路径下在修改。

二、打包,将打完包的文件和项目的配置文件一起传到服务器上

go build -o 打完包的名字

上传后,结构是这样的

服务器部署Go项目_第1张图片

注意,配置文件的位置一定要和项目里写的一致。否则会出现启动错误的情况。

start.sh 是一个脚本文件,文件内容如下

kill -9 "$(pgrep -f 打包成的二进制文件名)" #杀死之前的进程
chmod +x /项目的全路径/打包的二进制文件名 # 给目标文件加权 ,项目路径可以用 pwd 命令来看
nohup /项目的全路径/打包的二进制文件名 -c /配置文件的全路径/config.yaml > start.log  2>&1 & # 使用nohup后台运行,

三、项目第一次运行时,要先赋予二进制文件权限,不然第一次没法执行

可以使用 chmod +x 二进制文件名 的命令来赋予权限,成功后先  ./二进制文件 让它先前台运行,然后 sh start.sh 命令,让它执行脚本文件里的内容,后台运行。

优点:

服务器不用下载Go了,直接就可以执行。小项目方便又快捷

对于几乎不需要改动的项目,这个非常方便。

缺点:

当项目需要更新时,还需要重新在本地打包再使用文件传输工具上传上去,再操作。比较麻烦

推荐指数:⭐⭐⭐

3.服务器安装Docker,项目编写Dockerfile文件

服务器安装Docker,可以看(5条消息) Docker安装指南——如何在Linux中安装Docker?(最新2022-2 for centOS stream 8)_linux安装docker_Mymel_晗的博客-CSDN博客

 (1)Dockerfile 文件基于golang:alpine 直接构建

步骤:

  项目编写 Dockerfile 文件,文件内容如下

# 项目基于go语言环境
FROM golang:alpine

# 为我们的镜像设置必要的环境变量
ENV GO111MODULE=on \
    GOPROXY=https://goproxy.cn,direct \
    CGO_ENABLED=0 \
    GOOS=linux \
    GOARCH=amd64

# 移动到工作目录:/build
WORKDIR /build

# 将代码复制到容器中
COPY . .

# 将我们的代码编译成二进制可执行文件name
RUN go build -o name .

# 声明服务端口
EXPOSE 8080

# 启动容器时运行的命令,工作目录+二进制文件名
CMD ["/build/name"]

 然后将项目用文件传输工具挪到服务器上,进入项目路径下,然后开始构建项目镜像

docker build . -t 镜像名称

构建成功后是这个样子的

服务器部署Go项目_第2张图片

此时可以输入命令 docker images 来看看构建成的镜像

服务器部署Go项目_第3张图片

 test 是我构建成的镜像,此时可以输入命令

docker run -d -p 宿主机端口:容器端口 --name 容器名称 镜像名称

此时项目就跑起来了,可以看看网络情况 netstat -nltp ,如果映射的宿主机端口跑起来的话就说明项目启动成功了。

优点:

不会出现go版本不适用的情况,且用docker占用的空间比直接在服务器上要小

缺点:

生成的镜像比较大,而且项目打包成二进制文件后就不需要再用go环境了。

不适用于需要频繁更新项目的情况

推荐指数:⭐⭐

(2)Dockerfile 文件基于golang:alpine 分阶段构建

步骤:

同上,只是Dockerfile文件内容做了改动

FROM golang:alpine AS builder

# 为我们的镜像设置必要的环境变量
ENV GO111MODULE=on \
    GOPROXY=https://goproxy.cn,direct \
    CGO_ENABLED=0 \
    GOOS=linux \
    GOARCH=amd64

# 移动到工作目录:/build
WORKDIR /build

# 将代码复制到容器中
COPY . .

# 下载依赖信息
RUN go mod download

# 将我们的代码编译成二进制可执行文件 bubble
RUN go build -o interviewpush .

###################
# 接下来创建一个小镜像
###################
FROM scratch

# 从builder镜像中把配置文件拷贝到当前目录
COPY ./config.yaml /

# 从builder镜像中把/dist/app 拷贝到当前目录
COPY --from=builder /build/打包后的文件名 /

# 需要运行的命令
ENTRYPOINT ["/打包后的文件", "/项目配置文件.yaml"]

构建完之后大家可以看看大小

同样是一个项目,不分完阶段构建是分阶段构建的 30倍左右。 

优点:

极大缩小了镜像的空间,物尽其用

缺点:

不适用于需要频繁更新项目的情况

推荐指数:⭐⭐⭐

(3)Dockerfile 文件基于centos 环境直接构建

步骤:

Dockerfile文件内容如下

FROM centos:7.9.2009
FROM centos:7.9.2009
ENV MYPATH /root/project
WORKDIR  $MYPATH
RUN yum -y update \
&& yum -y install vim \
&& yum -y install git \
&& yum install -y gcc-c++ \
&& yum -y install wget \
&& wget -P /root/ https://dl.google.com/go/go1.18.3.linux-amd64.tar.gz \
&& tar -zxvf /root/go1.18.3.linux-amd64.tar.gz -C /usr/local \
&& echo export PATH=$PATH:/usr/local/go/bin >> /etc/profile \
&& source /etc/profile && go version \
&& echo "source /etc/profile" >> /root/.bashrc \
&& go env -w GOPROXY=https://goproxy.cn,direct \
&& go env -w GO111MODULE=on \

这个基本上只需要修改一下golang 的安装版本即可,在go官网可以查看所有go的版本All releases - The Go Programming Language (google.cn)

一定要和本地的一致,不然容易出问题。

然后步骤同上,构建成镜像后,docker images查看一下

 运行容器

docker run -it -v /root/project/:/root/project/ --name home centos_go:7.9.2009 /bin/bash

--name 为容器指定一个名称
-v 将宿主机目录挂载到容器内  ;格式:宿主机目录:容器目录
-e 设置环境变量,该环境变量看覆盖Dockerfile中的ENV环境变量
-p 需要手动指定一个或多个映射端口号,格式为:主机(宿主)端口:容器端口 -p 80:8080
-P Docker会随机映射一个 49000~49900 的端口到内部容器开放的网络端口
-it 其中,-i以交互模式运行容器 ;-t为容器重新分配一个伪输入终端
-d 后台运行容器,并返回容器ID (没有此参数,容器在前台窗口运行,窗口关,随之关)

-it 开启新的终端,以交互方式进入容器内部(尾部要指定/bin/bash方式);和-d一起使用后,将不会进入容器内部。

注:该写法相当于把docker run命令和docker exec -it 命令合并的效果(区别是:前者run的同时,进入了容器内部,如果exit退出容器,容器状态(通过docker ps -a查看)立马会变成Exited状态;后者就不一样了,以此方式进入容器,然后exit退出容器,不会主动影响容器的原有状态)。


运行之后,将项目和Dockerfile文件一起放在宿主机对应的目录下,这样在容器内部对应挂载的位置也有了,此时就可以使用服务器的两种方式将其运行成功。

但是这样存在的缺点就是:我们虽然集成了这么大的一个环境,干的确实和那小镜像干的活一样。还是不能实现直接拉最新代码然后直接重启项目。

解决方法:

我们在构建镜像的时候添加Git,想实现在容器内实现项目重新部署,而不需要像之前那两种都需要重新生成镜像然后再启动容器。

我们可以进入到容器内和宿主机挂载的目录下,然后连接远程仓库,git clone 远程仓库链接。

此时,如果你用的是HTTPS,那么你每次都要输入远程仓库的账号密码,如果你用的是SSH,那么就需要配置一个个人公钥,这个公钥可以让你在这个容器内拉代码的时候,不用输入密码,详细的可以看配置 SSH 公钥 - 什么是 DevOps? DevOps 介绍 | CODING DevOps

配置成功后,使用git clone 拉取成功后,进入项目路径下,编写一个脚本文件,update.sh

文件内容如下

docker pull origin 分支名
go build -o 打包二进制文件名
kill -9 "$(pgrep -f 打包二进制文件名)" #杀死之前的进程
chmod +x /二进制文件全路径 # 给目标文件加权
nohup /二进制文件全路径 -c /项目配置文件全路径 > start.log  2>&1 & # 使用nohup后台运行

第一次先执行打完包的文件名,然后每次输入 sh update.sh 即可重新部署项目了。

优点:

完美解决了以上四种方式的问题,重新部署的不方便

容器里就像个小centos系统,很多命令都能集成进去,操作也方便

缺点:

缺点就是没有缺点。

推荐指数:⭐⭐⭐⭐⭐

码字不易,看到这的小伙伴给个点赞再走呗。

你可能感兴趣的:(服务器,golang,运维)