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

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]

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.

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.

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"]

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
", 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 -it --rm hw
hello, world
[sorens | ~/src/go/hello> docker run -it --rm hw there
hello, there

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