最近在研究服务器部署项目,用了好几种办法成功部署。这些方法互有利弊,本文就逐一详细演示说明:
目录
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 打完包的名字
上传后,结构是这样的
注意,配置文件的位置一定要和项目里写的一致。否则会出现启动错误的情况。
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 镜像名称
构建成功后是这个样子的
此时可以输入命令 docker images 来看看构建成的镜像
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系统,很多命令都能集成进去,操作也方便
缺点:
缺点就是没有缺点。
推荐指数:⭐⭐⭐⭐⭐
码字不易,看到这的小伙伴给个点赞再走呗。