Docker is running, ContainerExecCreate creates a container, but ContainerExecAttach returns: Cannot connect to the Docker daemon at unix: ///var/run/docker.sock in response. Is the docker daemon running?
What could be the problem.
import (
"archive/tar"
"bytes"
"context"
"fmt"
"io"
"io/ioutil"
"log"
"net"
"os"
"strconv"
"strings"
"time"
client "docker.io/go-docker"
"docker.io/go-docker/api/types"
"docker.io/go-docker/api/types/container"
"docker.io/go-docker/api/types/network"
"docker.io/go-docker/api/types/swarm"
"docker.io/go-docker/api/types/volume"
"github.com/containerd/containerd/reference"
"github.com/play-with-docker/play-with-docker/config"
)
func (d *docker) ExecAttach(instanceName string, command []string, out io.Writer) (int, error) {
e, err := d.c.ContainerExecCreate(context.Background(), instanceName, types.ExecConfig{Cmd: command, AttachStdout: true, AttachStderr: true, Tty: true})
if err != nil {
return 0, err
}
resp, err := d.c.ContainerExecAttach(context.Background(), e.ID, types.ExecConfig{AttachStdout: true, AttachStderr: true, Tty: true})
if err != nil {
return 0, err
}
}
It looks normal. May depend on the state of the docker at the time of the call. It is possible to check docker via Ping or just wait one second.
Related
I'm using a docker client with golang; in the following script, I'm trying to pass an environmental variable when a container is going to start.
package main
import (
"context"
"fmt"
"os/user"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/client"
)
func main() {
dockerClient, _ := client.NewClientWithOpts(client.FromEnv)
env := []string{}
for key, value := range map[string]string{"hi": "hoo"} {
env = append(env, fmt.Sprintf("%s=%s", key, value))
}
user, err := user.Current()
if err != nil {
fmt.Println(err)
}
config := container.Config{
User: fmt.Sprintf("%s:%s", user.Uid, user.Gid),
Image: "675d8442a90f",
Env: env,
}
response, err := dockerClient.ContainerCreate(context.Background(), &config, nil, nil, nil, "")
if err != nil {
fmt.Println(err)
}
if err = dockerClient.ContainerStart(context.Background(), response.ID, types.ContainerStartOptions{}); err != nil {
fmt.Println(err)
}
}
and my docker file is a simple one which I try to echo the hi env:
# Filename: Dockerfile
FROM ubuntu:latest
COPY . .
CMD ["echo", "$hi"]
When I built the image and passed the id to the script, it didn't echo the variable. Do you have any idea how I can use the environmental variables in the dockerfile, which are sent to the container by docker golang client?
On host machine I have docker-compose stack that have a service called
transactions-db
its a PostgreSQL container
I want to create a backup service using Golang to be able to create .sql to be used for restores later on
docker-compose.yml for backup service
version: "3.8"
services:
backup-service:
build:
context: .
dockerfile: Dockerfile
image: backup-service
container_name: backup-service
volumes:
- .:/app
- /var/run/docker.sock:/var/run/docker.sock
main.go
package main
import (
"context"
"fmt"
"os"
)
func main () {
result, err := ExecuteCommandOnContainer(context.Background(), ConnectToDocker(), "transactions-db")
if err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Println(result.ExitCode)
}
docker.go
package main
import (
"context"
"fmt"
"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
)
func ConnectToDocker() *client.Client {
cli, err := client.NewClientWithOpts()
if err != nil {
fmt .Println(err)
}
return cli
}
func ExecuteCommandOnContainer(ctx context.Context, cli *client.Client, containerID string) (types.ContainerExecInspect, error) {
command := []string{"pg_dumpall", "-c", "-U", "user", "|", "gzip", ">", "backup/tr.sql"}
execConfig := types.ExecConfig{
Tty: true,
AttachStdin: true,
AttachStderr: true,
AttachStdout: true,
Cmd: command,
}
create, err := cli.ContainerExecCreate(ctx, containerID, execConfig)
if err != nil {
fmt .Println(err)
}
inspect, err := cli.ContainerExecInspect(ctx, create.ID)
if err != nil {
fmt .Println(err)
}
return inspect, nil
}
basically nothing happens when I run this code. I only get the following:
backup-service | 0
backup-service exited with code 0
I tried to normally run: go run .
I've also tried using my docker-compose up
same result
note: I've tested listing container it works but when trying to execute a command nothing
I use golang to develop application . I want get container in application.I hava tired by shell.But I want to get container by go. thanks
You can use docker/client
https://godoc.org/github.com/docker/docker/client
Example code:
# listcontainers.go
package main
import (
"context"
"fmt"
"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
)
func main() {
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
panic(err)
}
containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{})
if err != nil {
panic(err)
}
for _, container := range containers {
fmt.Printf("%s %s\n", container.ID[:10], container.Image)
}
}
Then execute it like this
DOCKER_API_VERSION=1.35 go run listcontainers.go
More about docker engine SDKs and API
https://docs.docker.com/develop/sdk/
I need to know Docker Daemon API version and setup the environment variable of DOCKER_API_VERSION when I have to create Docker client with NewEnvClient(), if not I will get an error about:
Error response from daemon: client version 1.36 is too new. Maximum supported API version is 1.35
If you are executing your code in the same docker host you can use the following approach to get the API version. It execute docker version command and get the API version from that output.
package main
import (
"os/exec"
"bytes"
"os"
"github.com/docker/docker/client"
"golang.org/x/net/context"
"github.com/docker/docker/api/types"
"strings"
)
func main() {
cmd := exec.Command("docker", "version", "--format", "{{.Server.APIVersion}}")
cmdOutput := &bytes.Buffer{}
cmd.Stdout = cmdOutput
err := cmd.Run()
if err != nil {
panic(err)
}
apiVersion := strings.TrimSpace(string(cmdOutput.Bytes()))
// TODO: (optional) verify the api version is in the correct format(a.b)
os.Setenv("DOCKER_API_VERSION", apiVersion)
// execute docker commands
ctx := context.Background()
cli, err := client.NewEnvClient()
if err != nil {
panic(err)
}
_, err = cli.ImagePull(ctx, "alpine", types.ImagePullOptions{})
if err != nil {
panic(err)
}
}
I am looking forward to do something below like this using docker golang api
cmd : docker run -t -i -p 8989:8080 "image-name" /bin/bash
Also I am using golang sdk https://github.com/moby/moby/client or https://godoc.org/github.com/moby/moby/client and my docker api version is 1.30 (Client & Server both)
Here is the piece of code I am using
package main
import (
"fmt"
"github.com/docker/docker/client"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"golang.org/x/net/context"
"github.com/docker/go-connections/nat"
//"github.com/docker/docker/vendor/github.com/docker/go-connections/nat"
)
func check(err error) {
if err != nil {
panic(err)
}
}
func main(){
ctx := context.Background()
cli, err := client.NewEnvClient()
check(err)
config := &container.Config{
Image : image-name,
ExposedPorts: nat.PortSet{
"8080/tcp": struct{}{},
},
Cmd : [] string {"sh","-c","while true; do sleep always; done","/bin/bash"},
}
host_config := &container.HostConfig{
PortBindings: nat.PortMap{
"8080/tcp": []nat.PortBinding{
{
HostIP: "0.0.0.0",
HostPort: "8989",
},
},
},
}
resp, err := cli.ContainerCreate(ctx,config,host_config, nil,"")
check(err)
if err := cli.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{});
err != nil {
panic(err)
}
}
After Compiling this code I get the following error
# command-line-arguments
src\main\createcontainer1.go:53: cannot use "github.com/docker/go-connections/nat".PortSet literal (type "github.com/docker/go-connections/nat".PortSet) as type "github.com/docker/docker/vendor/github.com/docker/go-connections/nat".PortSet in field value
src\main\createcontainer1.go:65: cannot use "github.com/docker/go-connections/nat".PortMap literal (type "github.com/docker/go-connections/nat".PortMap) as type "github.com/docker/docker/vendor/github.com/docker/go-connections/nat".PortMap in field value
If somebody knows what could be the problem and how to fix it.
Please answer to it as I am beginner with docker.
This is a Golang issue with how vendor/ works.
Remove the nested vendor directory:
rm -rf vendor/github.com/docker/docker/vendor
If you are using glide, you should use glide install -v when installing the dependency.
For more details, check this reported issue
My solution for OSX:
mv /Users/<user>/go/src/github.com/docker/docker/vendor/github.com/docker/go-connections/{nat,nat.old}