英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论