Golang在Mac OSX上为Docker机器构建

huangapple go评论101阅读模式
英文:

Golang Mac OSX build for Docker machine

问题

我需要在Docker机器上运行Golang应用程序。

我正在使用Mac OSX,并且Docker是在Linux虚拟机上运行的,所以在Mac上构建的二进制文件无法在Docker上运行。

我看到两种方法:

  1. 在Mac上交叉编译二进制文件以供Linux操作系统使用。
  2. 将项目源代码复制到Docker中,在其中运行"go get"和"go build"命令。

第一种方法很困难,因为CGO(它在一些导入的库中使用)。

第二种方法非常慢,因为"go get"操作。

请问,在这种情况下,哪种方法最常见?或者我做错了什么?

英文:

I need to run Golang application on Docker machine.

I'm working on Mac OSX and Docker is working on top of Linux virtual machine, so binaries builded on Mac are not runnable on Docker.

I see two ways here:

  1. cross-compile binaries on Mac for linux OS
  2. copy project sources to docker, run 'go get' and 'go build' on it

First one is hard because of CGO (it is used in some imported libraries).

Second is very slow because of 'go get' operation.

Can you please tell me, which way is the most common in that situation? Or maybe I'm doing something wrong?

答案1

得分: 3

这里有一个解决方案,可以使交叉编译变得非常简单,即使使用CGO也可以。

最近我偶然发现了这个解决方案,在把我的Go应用程序编译到新的Windows构建服务器上花费了很多时间后。现在我只需要在我的Mac上编译它,然后使用它创建一个Linux构建服务器:

https://github.com/karalabe/xgo

非常感谢Péter Szilágyi(化名karalabe)提供的这个真正棒的软件包!

使用方法:

  • 确保Docker正在运行
  • 运行命令:go get github.com/karalabe/xgo
  • 运行命令:xgo --targets=windows/amd64 ./

还有很多其他选项!

-- 编辑 --

将近3年过去了,我不再使用这个方法,但是我在基于Linux的持续交付流水线中构建应用程序的Docker镜像仍然基于xgo中使用的Docker镜像。

英文:

Here a solution to make cross-compile super easy even with CGO.

I stumbled upon it recently after wasting a lot of time getting a new windows build server to build my Go app.
Now I just compile it on my Mac and will create a Linux build server with it:

https://github.com/karalabe/xgo

Many thanks to Péter Szilágyi alias karalabe for this really great package!

How to use:

  • have Docker running
  • go get github.com/karalabe/xgo
  • xgo --targets=windows/amd64 ./

There are lots more options!

-- edit --

Almost 3 Years later I'm not using this any more, but my docker image to build my application in a linux based CD pipeline is still based on the docker images used in xgo.

答案2

得分: 0

我使用第一种方法。这是一个gulp任务,用于构建Go代码。如果设置了生产标志,它将运行GOOS=linux CGO_ENABLED=0 go build,而不是go build。因此,二进制文件将在Docker容器内正常工作。

gulp.task('server:build', function () {
    var build;

    let options = {
        env: {
            'PATH': process.env.PATH,
            'GOPATH': process.env.GOPATH
        }
    }

    if (argv.prod) {
        options.env['GOOS'] = 'linux';
        options.env['CGO_ENABLED'] = '0';
        console.log("Compiling go binarie to run inside Docker container");
    }

    var output = argv.prod ? conf.paths.build + '/prod/bin' : conf.paths.build + '/dev/bin';
    build = child.spawnSync('go', ['build', '-o', output, "src/backend/main.go"], options);
    if (build.stderr.length) {
        var lines = build.stderr.toString()
            .split('\n').filter(function(line) {
                return line.length;
            });
        for (var l in lines)
            util.log(util.colors.red(
                'Error (go install): ' + lines[l]
            ));
        notifier.notify({
            title: 'Error (go install)',
            message: lines
        });
    }
    return build;
});
英文:

I use the first approach. Here its a gulp task the build go code. If the production flag is set, it runs GOOS=linux CGO_ENABLED=0 go build instead go build. So the binary will work inside a docker container

gulp.task('server:build', function () {
	var build;

    let options = {
        env: {
            'PATH': process.env.PATH,
            'GOPATH': process.env.GOPATH
        }
    }

    if (argv.prod) {
        options.env['GOOS'] = 'linux'
        options.env['CGO_ENABLED'] = '0'
        console.log("Compiling go binarie to run inside Docker container")
    }

	var output = argv.prod ? conf.paths.build + '/prod/bin' : conf.paths.build + '/dev/bin';
	build = child.spawnSync('go', ['build', '-o', output, "src/backend/main.go"], options);
	if (build.stderr.length) {
		var lines = build.stderr.toString()
			.split('\n').filter(function(line) {
				return line.length
			});
		for (var l in lines)
			util.log(util.colors.red(
				'Error (go install): ' + lines[l]
			));
		notifier.notify({
			title: 'Error (go install)',
			message: lines
		});
	}
	return build;
});

答案3

得分: 0

你可以根据你需要的可执行文件创建一个来自不同操作系统的Docker容器,并将一个卷映射到你的源代码目录。在容器内部运行并生成可执行文件。这样你就可以在不同的操作系统上运行这个二进制文件了。

英文:

You could create a Docker container from the distinct OS you need for your executable, and map a volume to your src directory. Run the container and make the executable from within the container. You end up with a binary that you can run on the distinct OS.

huangapple
  • 本文由 发表于 2016年3月15日 05:01:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/35997995.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定