Hi guys! I’m trying to run a container programmatically from golang using API.
The run docker command is like this:
docker container run -a stdout -a stderr --stop-timeout 0 --rm -v sourceDir:destDir --network none -m 1GB my-image:latest args1 args2 args3
Below is a code that I am trying to make run the container and it doesn’t work as expected
package main
import (
"context"
"fmt"
"os/exec"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/client"
)
func main() {
cli, err := client.NewClientWithOpts()
if err != nil {
fmt.Println("Unable to create docker client")
panic(err)
}
ctx := context.Background()
cont, err := cli.ContainerCreate(
ctx,
&container.Config{
Image: "my-image:latest",
AttachStdout: true,
AttachStderr: true,
Volumes: map[string]struct{}{
"sourceDir:destDir": {},
},
Entrypoint: []string{
"arg1", "arg2", "arg3",
},
StopTimeout: new(int),
NetworkDisabled: true,
},
nil,
nil,
nil,
"",
)
if err != nil {
panic(err)
}
cli.ContainerStart(ctx, cont.ID, types.ContainerStartOptions{})
cli.ContainerRemove(ctx, cont.ID, types.ContainerRemoveOptions{Force: true})
}
Any suggestion on what can be wrong?
Ps: Not happens exceptions. Just not working… I have doubt if volumes and args are mapped correctly
Deivisson:
I’m trying to run a container programmatically from golang using API.
The run docker command is like this:
docker container run -a stdout -a stderr --stop-timeout 0 --rm -v sourceDir:destDir --network none -m 1GB my-image:latest args1 args2 args3
Below is a code that I am trying to make run the container and it doesn’t work as expected
package main
import (
"context"
"fmt"
"os/exec"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/client"
)
func main() {
cli, err := client.NewClientWithOpts()
if err != nil {
fmt.Println("Unable to create docker client")
panic(err)
}
ctx := context.Background()
cont, err := cli.ContainerCreate(
ctx,
&container.Config{
Image: "my-image:latest",
AttachStdout: true,
AttachStderr: true,
Volumes: map[string]struct{}{
"sourceDir:destDir": {},
},
Entrypoint: []string{
"arg1", "arg2", "arg3",
},
StopTimeout: new(int),
NetworkDisabled: true,
},
nil,
nil,
nil,
"",
)
if err != nil {
panic(err)
}
cli.ContainerStart(ctx, cont.ID, types.ContainerStartOptions{})
cli.ContainerRemove(ctx, cont.ID, types.ContainerRemoveOptions{Force: true})
}
Any suggestion on what can be wrong?
There are a few issues with the code you had posted:
The AttachStdout
and AttachStderr
fields in the container.Config
struct should be set to false
, not true
. Setting these fields to true
will attach the container’s standard output and error streams to the host’s standard output and error streams, respectively.
The Volumes
field in the container.Config
struct should be a map of strings to *mount.Mount
, not a map of strings to empty structs. You can use the mount.New
function from the github.com/docker/docker/api/types/mount
package to create a *mount.Mount
for the volume.
The StopTimeout
field in the container.Config
struct should be set to a pointer to a *int
with a value of 0
, not a pointer to a *int
with a nil
value.
The cli.ContainerStart
function should be called with a types.ContainerStartOptions
struct as its second argument, not a types.ContainerStartOptions{}
.
The cli.ContainerRemove
function should be called with a types.ContainerRemoveOptions
struct as its third argument, not a types.ContainerRemoveOptions{Force: true}
.
Here an updated version of your code with these changes applied:
package main
import (
"context"
"fmt"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/mount"
"github.com/docker/docker/client"
)
func main() {
cli, err := client.NewClientWithOpts()
if err != nil {
fmt.Println("Unable to create docker client")
panic(err)
}
ctx := context.Background()
cont, err := cli.ContainerCreate(
ctx,
&container.Config{
Image: "my-image:latest",
AttachStdout: false,
AttachStderr: false,
Volumes: map[string]*mount.Mount{
"sourceDir:destDir": mount.New("sourceDir", "destDir", false),
},
Entrypoint: []string{
"arg1", "arg2", "arg3",
},
StopTimeout: new(int),
NetworkDisabled: true,
},
nil,
nil,
nil,
"",
)
if err != nil {
panic(err)
}
cli.ContainerStart(ctx, cont.ID, types.ContainerStartOptions{})
cli.ContainerRemove(ctx, cont.ID, types.ContainerRemoveOptions{Force: true})
}