随着容器技术的出现,我们的开发方式也在发生着变化,以前使用C/C++进行开发时,一般都是开发本地应用,后面发展到本地开发,远程编译部署。如今容器的出现,又有一种新的开发方式,就是在容器中进行编译部署。

一、安装远程容器

笔者使用的远程容器包括Docker和Podman,Ubuntu可以使用apt或者snap命令来安装,CentOS可以使用yum命令来安装,这里就不详述了。

二、安装与配置容器仓库

1.安装与配置

参见:使用nexus3作为Docker镜像仓库

2.安装证书

配置好容器仓库后,为了让开发机(笔者的为Windows,与容器仓库所在主机不为同一机器)能够正常以https的方式访问,需要把安装容器仓库所生成的证书复制到Windows进行安装,即把上前文中的ca.crt文件复制到Windows,然后双击它,在弹出的对话框中选择“安装证书”进行安装。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

三、准备项目

我们这里还是如使用podman容器配置gitlab一文中的GoDemo类似,准备几个文件,main.go,Dockerfile
main.go的内容如下:

package main

import (
	"net/http"
)

func main() {
	http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
		writer.Write([]byte("Hello, 这是一个Docker测试!"))
	})

	http.ListenAndServe(":8000", nil)
}

Dockerfile内容如下:

# 编译使用的镜像
FROM golang:1.16 as build-env

COPY . /dockerdev
WORKDIR /dockerdev

RUN go mod init demo && go build -o /demo

# 最终使用的镜像
FROM ubuntu:latest

# 暴露的端口
EXPOSE 8000

WORKDIR /
COPY --from=build-env /demo /

CMD ["/demo"]

该Dockerfile使用了多阶段构建的方式,即将编译阶段与构建容器的最终阶段分开,这样可以让我们在最终能生成最小的Docker镜像。

四、运行

1.开启容器远程服务

为了让项目在远程容器中运行,需要先打开容器的远程服务,如果是podman来作为容器服务,在服务器上运行如下命令:

sudo podman system service --time=0 tcp:0.0.0.0:2979

如果是docker需要修改docker服务文件,笔者使用的ubuntu系统,路径为:
/lib/systemd/system/docker.service

在ExecStart的命令行中添加

-H tcp://0.0.0.0:2979

如下图所示:
在这里插入图片描述
然后重新加载配置并重启服务:

 systemctl daemon-reload
 systemctl restart docker

注意:如果系统开启了防火墙,需要允许使用到的所有端口。如果是在内网测试,也可以直接关闭防火墙。

2.添加运行配置

在Goland中打开前面的Dockerfile文件,第一个from ……命令的前面会有一个绿色箭头,点它运行“新建运行配置”:
在这里插入图片描述

在服务器一栏中选择“新建…”
在这里插入图片描述
在新建Docker连接对话框中,连接方式中选择TCP套接字,URL填写容器服务器地址及端口:

tcp://192.168.1.8:2979

在这里插入图片描述
填写好后,Goland会自动连接,下面会有连接成功与否的提示。
选择配置好的Docker服务器,填写镜像标记,比如mydemo:v1;容器名称,比如mydemo。
由于我们的项目需要使用到8000端口,对外提供服务,所以需要添加绑定端口,将端口暴露出来。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
填写好后,运行,可以看到运行的容器,构建的镜像,网络、卷等信息,选中运行的容器,可以在构建日志中看到构建过程:
在这里插入图片描述
打开浏览器测试:
在这里插入图片描述
成功运行。

五、推送镜像

能够成功运行的镜像,我们可以将其推送到镜像仓库中。

1.连接镜像仓库

在开发机导入容器库访问证书后,就可以连接容器镜像库(注册表)了,打开Goland设置界面,如下图所示,打开“构建、执行、部署”中的Docker注册表,添加一个注册表

  • 名称,自定义
  • 地址,填写前面配置的容器仓库地址,笔者的为192.168.1.8:5051
  • 用户名,填写Nexus中的用户名
  • 密码,填写Nexus中的用户名对应的密码
    在这里插入图片描述
    填写好后,Goland会自动连接,如果连接成功,下面会给出“连接成功”提示,如果失败,也会给出提示。

2. 推送镜像

选择刚才构建的镜像,右键选择“推送镜像”
在这里插入图片描述
在推送镜像界面选择头面连接的注册表,填写仓库名和标签,确定。

在这里插入图片描述
在这里插入图片描述
成功后就可以在nexue中查看到刚才推送的镜像。
在这里插入图片描述

六、调试

我们将运行环境放在容器中运行后,如果有问题,如何调试呢?

1.修改Dockerfile

还是以前面的项目为示例,我们修改Dockerfile为:

# 编译使用的镜像
FROM golang:1.16 as build-env

RUN export GO111MODULE="on" && export GOPROXY="https://goproxy.cn,direct" && go get github.com/go-delve/delve/cmd/dlv

COPY . /dockerdev
WORKDIR /dockerdev

RUN go build -gcflags="all=-N -l" -o /demo


# 最终使用的镜像
FROM ubuntu:latest

# 暴露的端口
EXPOSE 8000 40000

WORKDIR /
COPY --from=build-env /go/bin/dlv /
COPY --from=build-env /demo /

CMD ["/dlv", "--listen=:40000", "--headless=true", "--api-version=2", "--accept-multiclient", "exec", "/demo"]

该Dockerfile文件在编译阶段,下载并编译生成dlv调试器,由于国内下载源码比较慢,所以需要修改GOPROXY值设置代理,并打开GO111MODULE。
在执行容器时,是以dlv调试器来打开我们的项目执行文件demo,并监听40000端口。

提示:
如果不想更改原始的Dockerfile文件,可以改名为Dockerfile.debug。如果之前从未使用过.debug的文件,Goland会询问如何关联该类型的文件。
在这里插入图片描述

2.在Goland中新建模块文件go.mod

在项目中添加go.mod文件
在这里插入图片描述
内容如下:

module demo

go 1.16

也可以在本机使用

go mod init demo
go mod tidy

命令来自动生成go.mod以及go.sum文件。

注意:如果不在项目中先添加go.mod,直接在Dockerfile中编译前使用go mod init demo指令来生成会导致调试时找不到路径,这点很奇怪。
在这里插入图片描述

3.添加容器的运行/调试配置

添加Dockerfile运行/调试配置
在这里插入图片描述
然后设置运行配置:

  • Dockerfile,填写Dockerfile
  • 镜像标记,设置为mydemo-dbg:v1
  • 容器名称,设置为mydemo-dbg
  • 绑定端口,需要添加40000端口,设置为8000与40000
  • 添加运行选项:--security-opt="apparmor=unconfined" --cap-add=SYS_PTRACE

如下图所示:
在这里插入图片描述

配置好后,运行配置,开始构建镜像并运行容器。
在这里插入图片描述

如果出现未连接docker的问题:
在这里插入图片描述
先断开Docker,再重新连接
在这里插入图片描述
在这里插入图片描述

4.添加Go远程运行/调试配置

在这里插入图片描述
然后填写主机地址以及端口号:
在这里插入图片描述
配置好后,执行调试:
在这里插入图片描述

5.调试

我们在main.go中的输出语句打断点:
在这里插入图片描述
在浏览器中打开http://192.168.1.8:8000/,可以看到断点命中了。
在这里插入图片描述
也可以使用Goland新建一个http请求文件,命名为test
在这里插入图片描述
在这里插入图片描述
内容为:

GET http://192.168.1.8:8000

然后点击前面的绿色箭头,运行,也会命中断点。
在这里插入图片描述

6.优化

前面的用于调试的Dockerfile中,在编译阶段,每次都需要下载dlv调试器,可以自己制作一个带dlv调试的go容器,这样就不用每次都去下载了。

在Go容器中运行:

export GO111MODULE="on" && export GOPROXY="https://goproxy.cn,direct" && go get github.com/go-delve/delve/cmd/dlv

下载dlv调试器,然后使用命令提交

podman commit go-dlv 127.0.0.1:5000/go-dlv:1.16

如果有镜像仓库,使用下面的命令推送到仓库:

podman push 127.0.0.1:5000/go-dlv:1.16

参考链接:
https://blog.jetbrains.com/go/2020/05/04/go-development-with-docker-containers/
https://blog.jetbrains.com/go/2020/05/06/debugging-a-go-application-inside-a-docker-container/
https://www.jetbrains.com/help/idea/podman.html#tutorial-run-podman-in-a-virtual-machine

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐