如何将命令行选项传递给我的容器化的GoLang程序?

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

How can I pass command line options to my dockerized GoLang program?

问题

我有一个简单的 Docker 化的 Golang 程序,我想在运行容器时能够向其发送命令行选项。

我的 Dockerfile 如下所示:

FROM golang:onbuild
RUN go get [我的程序]
英文:

I have a simple dockerized golang program and I want to be able to send command line options to it when I run the container.

My Dockerfile looks like this:

FROM golang:onbuild
RUN go get [MY PROGRAM]

答案1

得分: 3

只要你的应用程序按照Go的约定编译为单个二进制文件,你就可以使用下面这个简单的两行代码,在ENTRYPOINT指令中将任何后续的标志作为类似数组的参数传递。

FROM golang:onbuild
ENTRYPOINT ["/go/bin/app", "-name=foo", "-title=bar"]
英文:

As long as your app compiles to a single binary per Go convention you should be able to use this simple two liner below, passing any subsequent flags as array-like parameters in the ENTRYPOINT instruction.

FROM golang:onbuild
ENTRYPOINT ["/go/bin/app", "-name=foo", "-title=bar"]

答案2

得分: 2

现在你只是在运行容器中获取源代码,然后退出。
你需要实际运行你的程序,并使用所需的参数来构建它或者运行一个 shell,从中调用你的程序。
我希望我提供的 Dockerfile 能作为一个指南帮助你。

我本地有一个 bashrc 文件,其中导出了 GOPATH、GOBIN 和 PATH,你可以使用 Dockerfile 中的 ENV 语句。我通常会在构建镜像的位置检出一个工作副本,并将其复制到容器中。这个设置只是为了给你解决未来问题的思路。

export GOPATH="/root/go"
export GOBIN="/root/go/bin"
export PATH="/root/go/bin:$PATH"

然后我的 Dockerfile 如下:

FROM ubuntu:14.04
MAINTAINER foo, bar@baz.org
COPY bashrc /root/.bashrc
COPY MYPROGRAM /root/go/src/MYPROGRAM
ENV GOBIN /root/go/bin
ENV GOPATH /root/go
ENV PATH /root/go/bin:$PATH
ENV HOME /root
WORKDIR /root
RUN \
  apt-get update && \
  apt-get install -y golang git && \
  mkdir -p /root/go/src && \
  mkdir -p /root/go/bin && \
  go get DEPENDENCIES

RUN go install /root/go/src/MYPROGRAM/program.go
ENTRYPOINT ["program"]

现在容器的入口点是你的程序,你可以这样运行:

docker run img args-to-your-prog

你也可以在 ENTRYPOINT 语句中添加参数,例如:

ENTRYPOINT["program", "arg1", ...]

或者你可以使用 bash 作为入口点,并将你的程序作为参数传递:

docker run img program arg1 ...

ENTRYPOINT 是正在执行的程序,如果设置了 CMD,CMD 将作为参数传递给它。CMD 是容器的默认参数。如果没有设置 ENTRYPOINT,那么 CMD 将直接执行命令。

英文:

Right now you are only getting your source in the running container and then it exits.
You need to actually RUN your program with the desired arguments once you build it or RUN a shell from which you will call your program.
i hope this Dockerfile that i'm providing will help as a guide.

i have locally a bashrc that exports GOPATH GOBIN and PATH or you can
use the ENV statements in the dockerfile. i also usually have checked out
a working copy of my program where i'm building the image and i copy that in the container. This setup is just to give you ideas to solve future problems.

export GOPATH="/root/go"
export GOBIN="/root/go/bin"
export PATH="/root/go/bin:$PATH"

then my Dockerfile is

FROM ubuntu:14.04
MAINTAINER foo, bar@baz.org
COPY bashrc /root/.bashrc
COPY MYPROGRAM /root/go/src/MYPROGRAM
ENV GOBIN /root/go/bin
ENV GOPATH /root/go
ENV PATH /root/go/bin:$PATH
ENV HOME /root
WORKDIR /root
RUN \
  apt-get update && \
  apt-get install -y golang git && \
  mkdir -p /root/go/src && \
  mkdir -p /root/go/bin && \
  go get DEPENDENCIES

RUN go install /root/go/src/MYPROGRAM/program.go
ENTRYPOINT ["program"]

now that the entry point of the container is your program you can

docker run img args-to-your-prog

you can also add the args to the ENTRYPOINT statement like

ENTRYPOINT["program", "arg1", ...]

or you can use bash as an entry point and get your program as an argument

docker run img program arg1 ...

ENTRYPOINT is the program being executed and if it is set CMD will be
the args passed to it. CMD is the default argument to the container. if
ENTRYPOINT is not set them CMD will be the command executed directly.

答案3

得分: 0

添加以下行应该可以工作:
ENTRYPOINT ["go", "run", "yourapp"],参见Docker文档Go命令行示例

然后,您只需在docker run调用的末尾放置go程序的参数,例如docker run mygoapp arg1 arg2。然后,参数将传递给您的go程序。

英文:

Adding the following line should work:
ENTRYPOINT ["go", "run", "yourapp"], see Docker Doc and Go commandline example.

Then you just put the arguments for your go program at the end of the docker run call, e.g. docker run mygoapp arg1 arg2. The arguments should then be passed to your go program.

答案4

得分: -1

这是我使用的简化版本的配方:

Dockerfile:

FROM golang:1.12.7
WORKDIR /go/src/hello
COPY . .
RUN go get -d -v ./...
RUN go install -v ./...
ENTRYPOINT ["hello"]

hello.go:

package main

import "os"
import "fmt"

func main() {
    name := "world"
    if (len(os.Args) > 1) {
        name = os.Args[1]
    }
    fmt.Printf("hello, %s\n", name)
}

在本地编译和运行代码以确保它正常工作:

[sorens | ~/src/go/hello> go build hello.go
[sorens | ~/src/go/hello> ./hello
hello, world
[sorens | ~/src/go/hello> ./hello there
hello, there

现在,在Docker中构建它:

[sorens | ~/src/go/hello> docker build -t hw .
Sending build context to Docker daemon  2.128MB
Step 1/6 : FROM golang:1.12.7
1.12.7: Pulling from library/golang
5ae19949497e: Pull complete
ed3d96a2798e: Pull complete
f12136850781: Pull complete
1a9ad5d5550b: Pull complete
efbd5496b163: Pull complete
c01c378f53ca: Pull complete
c7aef280980d: Pull complete
Digest: sha256:f5486a917b57f8b14be4345604bc4654147416a327d6d63271a0c52c907001c4
Status: Downloaded newer image for golang:1.12.7
 ---> be63d15101cb
Step 2/6 : WORKDIR /go/src/hello
 ---> Running in 4f362ab0be79
Removing intermediate container 4f362ab0be79
 ---> 47a247a9b603
Step 3/6 : COPY . .
 ---> b1e53c8f9166
Step 4/6 : RUN go get -d -v ./...
 ---> Running in 309331f04485
Removing intermediate container 309331f04485
 ---> 088f49d8ee5f
Step 5/6 : RUN go install -v ./...
 ---> Running in 83e5937ece78
hello
Removing intermediate container 83e5937ece78
 ---> 8cd1d6ffefa8
Step 6/6 : ENTRYPOINT ["hello"]
 ---> Running in dae06fb3343e
Removing intermediate container dae06fb3343e
 ---> c04a6307cdc8
Successfully built c04a6307cdc8
Successfully tagged hw:latest

然后运行它:

[sorens | ~/src/go/hello> docker run hw
hello, world
[sorens | ~/src/go/hello> docker run hw there
hello, there

docker run hw 不向Docker容器传递任何参数,因此 hello.go 打印出 hello, world。然而,当你在docker命令的末尾添加 there 时,它被传递给Docker容器和入口点 hello.go,然后分支并显示 hello, there

我在GitHub上发布了它:https://github.com/sorens/cli-golang-via-docker

英文:

Here is a simplified version of the recipe I use:

[sorens | ~/src/go/hello> ls -al
total 16
drwxr-xr-x   4 sorens  staff  128 Aug  1 21:46 .
drwxr-xr-x  11 sorens  staff  352 Jun 25 13:21 ..
-rw-r--r--@  1 sorens  staff  118 Aug  1 21:43 Dockerfile
-rw-r--r--   1 sorens  staff  153 Aug  1 15:42 hello.go

Dockerfile:

FROM golang:1.12.7
WORKDIR /go/src/hello
COPY . .
RUN go get -d -v ./...
RUN go install -v ./...
ENTRYPOINT ["hello"]

hello.go

package main

import "os"
import "fmt"

func main() {
	name := "world"
	if (len(os.Args) > 1) {
		name = os.Args[1]
	}
	fmt.Printf("hello, %s\n", name)
}

Compile and run the code locally to see that it works:

[sorens | ~/src/go/hello> go build hello.go
[sorens | ~/src/go/hello> ./hello
hello, world
[sorens | ~/src/go/hello> ./hello there
hello, there

Now, build it in Docker:

[sorens | ~/src/go/hello> docker build -t hw .
Sending build context to Docker daemon  2.128MB
Step 1/6 : FROM golang:1.12.7
1.12.7: Pulling from library/golang
5ae19949497e: Pull complete 
ed3d96a2798e: Pull complete 
f12136850781: Pull complete 
1a9ad5d5550b: Pull complete 
efbd5496b163: Pull complete 
c01c378f53ca: Pull complete 
c7aef280980d: Pull complete 
Digest: sha256:f5486a917b57f8b14be4345604bc4654147416a327d6d63271a0c52c907001c4
Status: Downloaded newer image for golang:1.12.7
 ---> be63d15101cb
Step 2/6 : WORKDIR /go/src/hello
 ---> Running in 4f362ab0be79
Removing intermediate container 4f362ab0be79
 ---> 47a247a9b603
Step 3/6 : COPY . .
 ---> b1e53c8f9166
Step 4/6 : RUN go get -d -v ./...
 ---> Running in 309331f04485
Removing intermediate container 309331f04485
 ---> 088f49d8ee5f
Step 5/6 : RUN go install -v ./...
 ---> Running in 83e5937ece78
hello
Removing intermediate container 83e5937ece78
 ---> 8cd1d6ffefa8
Step 6/6 : ENTRYPOINT ["hello"]
 ---> Running in dae06fb3343e
Removing intermediate container dae06fb3343e
 ---> c04a6307cdc8
Successfully built c04a6307cdc8
Successfully tagged hw:latest

And run it:

[sorens | ~/src/go/hello> docker run hw
hello, world
[sorens | ~/src/go/hello> docker run hw there
hello, there

docker run hw does not pass any arguments to the docker container and therefore hello.go prints hello, world. However, when you add there to the end of the docker command, that is passed to the docker container and to the entrypoint hello.go which then branches and displays hello, there instead.

I posted it on github: https://github.com/sorens/cli-golang-via-docker

huangapple
  • 本文由 发表于 2015年4月16日 04:19:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/29660108.html
匿名

发表评论

匿名网友

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

确定