网上相关的文章很少有用JB家自带的Run Targets功能实现远程运行的,这个功能在2021版本就出来了,但官方的文档主要围绕Goland和Docker在同一台机器上的情况进行配置,故通过本文章记录一下踩坑过程。
官网介绍如下
可以直接从 IntelliJ IDEA (Goland也一样) 在另一个环境(如云或 Docker 容器)中运行代码。
对于某些运行/调试配置,您可以直接从 IntelliJ IDEA 在另一个环境(如云或 Docker 容器)中运行代码。
为了在目标上运行代码,只需在通常用于本地运行的运行/调试配置中定义目标执行环境即可。完成此操作后,在目标上启动应用与在本地启动应用没有什么不同。
main.go
package main
import (
"fmt"
)
func main() {
fmt.Println("Hello, World!")
}
go.mod
module targetTest
go 1.21
这里 Golang 1.21 采用 Go Modules 而不是 GOPATH
请自行测试是否能在本机运行,这里不再赘述
Docker Desktop(windows)
是基于WSL2 (Windows Subsystem for Linux)
的
Docker并没有办法直接读取Windows文件系统中的文件
需要将文件映射到Linux系统(Docker
宿主机)后,再映射到容器内部
为了更方便理解,我们从windows docker开始
在同一台电脑上安装Goland和Docker Desktop
如果你只想在Linux上操作,可以读完本文后自行尝试
编写完代码后
添加Run/Debug Configuration
跟在平常本机Go运行一样,选择Go Build
与本机运行不同,这里我们选择Docker
如果安装了Docker Desktop(Windows),这里会直接识别
选择 Docker windows (即 Docker Desktop)
因为Docker和Goland在同一台机器,这里虚拟路径可以不用设置
回到上一级,设置image tag,这就是我们平常用的docker pull拉取
直接从网上拉golang的最新golang:latest镜像
如果要映射容器相关接口,可以在下面的Run options中使用
-p 8080:8080
这里--entrypoint= --rm
代表在容器停止后删除它,方便我们多次调试
点击Next将开始拉取,如果慢可以进行docker换源,不再赘述
拉取完毕后点击Next,什么都不用动直接Create
经测试这里的 Project path on target
不影响我们后续配置
如果Docker和Goland在一台机器上,那么还是非常简单的
到这里基本就完成了,Configuration保持默认配置就行
注意 这里的 Package Path
应该是和你的go.mod
第一行的module targetTest
对应,不懂的可以去补习一下Go Modules,一般默认的就是对的
运行测试,正常输出
顺利跑通,但是大多数情况下我们的Docker和Goland不是在一台机器上,也不都是Windows系统,下面我们分析已有的容器来进行进一步学习。
到docker desktop中查看容器运行记录以及相关信息
以下命令和映射都是Goland自动创建的
/usr/local/go/bin/go
是golang容器中的go主程序build -o xxx
在xxx目录下构建我们代码的可执行文件这里这个/tmp/4a3bb我们不用深究,是build的临时输出目录
我们只需要执行这个目录中build完的可执行go程序即可
但是有一个/tmp目录我们要注意
可以看见 Goland 创建了一个 Mounts
这个项目绑定到了我们 Docker 宿主机的“D盘”中
我们在这里可以看到
Goland 创建的 Mounts 并不是我们Windows下的项目目录
D:\Projects\Goland_Projects\targetTest
而是Linux样式的
/d/Projects/Goland_Projects/targetTest?
这是因为新Docker Desktop是基于WSL2的,可以直接访问到windows下的文件,这样就可以在Docker容器中编译Windows硬盘上的文件了。
在了解了Goland自动创建的相关配置和映射方式后,我们尝试在Targets中添加我们服务器上的docker
这里我采用SSH的方式直接连接到Linux服务器(Docker宿主机)
可以观察是否连接成功
与Docker Windows不同,这里可以配置一个映射目录。
本人在这里卡了很长时间,才发现:
这个映射目录并不是指的我们
Docker容器
中的目录
而是从本地(Goland
)映射到Docker宿主机
的
重点来了,这里默认的路径映射需要修改为Linux对应风格的路径
这里的路径和WSL2(Docker Desktop)中是对应的
可以推断Goland在生成cmd的时候是默认根据WSL风格来进行的
如果不映射则会定位不到项目目录,后面详细介绍。
此时如果我们以默认参数运行,可能会出现以下错误
tmp/***/___go_build_targetTest__1_.exe:
未找到
出现这类错误,同时带有exe,这是因为Goland默认还是本地编译的。
值得一提的是,如果使用前面的Docker Windows在本机运行是不会出现错误的,因为WSL已经帮我们完成了路径映射
但是我们现在希望在远程容器Linux内编译并运行,需要加上这个勾
此外,你还可能碰到另一个错误,这与我们设置目录映射有关。
我们回去继续分析Goland启动的容器,可以发现
"WorkingDir": "/tmp/1f56aabb-e787-444b-8ad0-4e6751954c41"
指定了一个工作目录,也就是我们平常执行go build时所cd到的目录
继续查找可以发现,这个目录是绑定到我们Docker宿主机的"D盘"中
这个目录跟我们之前分析的项目目录是一样的。
所以,如果使用SSH远程调用服务器上的Docker进行build,一定要记得设置Docker选项卡中的目录映射
因为远程服务器并不像WSL一样会帮我们自动映射。
直接在WorkingDir
中go guild,会找不到源代码,所以编译不成功
再次检查SSH/Docker的目录映射
这里其实完成了两次映射,在使用WSL时,第一次映射自动完成。
D:\Projects\Goland_Projects\targetTest
/d/Projects/Goland_Projects/targetTest?
/tmp/xxxxxxx
至此,我们才能完成go build。
Run Target的在自动配置Docker时没有将自动生成的配置暴露出来,这导致当Docker运行在本机上时运行非常完美,但一旦迁移到远程Docker时,会存在一些不透明的错误。
这与我们在前面提到的,Docker无法读取Windows文件系统下的文件有关
JetBrains的IDE提供了一个将Windows文件映射到Linux的table
在远程(SSH)情况下会有所不同,图中的
蓝色Host
为我们运行Goland的Windows电脑红色Linux virtual machine
为我们的远程服务器(Docker宿主机)绿色Docker Engine
为我们常用的Docker引擎
本文通过分析Run Target自动拉取并生成命令的容器进行分析,探究了Docker容器的自动部署原理。
本文仅作学习记录
JB起初这么设计肯定有他的道理,可能只是为了解决Windows运行Docker的问题。
在实际生产中,我们可以使用dockerfile进行容器自定义配置
或者在本机Docker上测试完毕后再打包迁移到其他平台
如果你在Linux环境下开发(运行Goland)则没有这些问题
This table is not available on a Linux host, where Docker runs natively and you can mount any directory to the container.