package main import ( "context" "fmt" "log" "os" "time" "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/mount" "github.com/docker/docker/api/types/network" "github.com/docker/docker/client" ) const ( fixedDockerVersion = "1.38" ) var ( dockerCtx context.Context dockerCLI *client.Client ) func setupContext() { if dockerCtx == nil { dockerCtx = context.Background() } } func setupDockerCLI() (err error) { os.Setenv("DOCKER_API_VERSION", "1.27") if dockerCLI == nil { dockerCLI, err = client.NewEnvClient() } return err } func spawnCompanion(username string, accesscode string) { log.Println("Spwaning a new companion container") // setup the context and the docker cli connection setupContext() setupDockerCLI() sessionSalt := generateSessionSalt() vpnRemoteAddress := "127.0.0.1" vpnRemotePort := "1193" log.Println("Generating the container config") Config := &container.Config{ Image: "circus-companion:latest", Cmd: []string{fmt.Sprintf("-username %s -accesscode %s -sessionSalt %s -vpnRemoteAddress %s -vpnRemotePort %s", username, accesscode, sessionSalt, vpnRemoteAddress, vpnRemotePort)}, // Container labels used by traefik Labels: map[string]string{ "traefik.enable": "true", "traefik.http.routers.companion.entrypoints": "web", "traefik.http.routers.companion.rule": "Host(`companion.docker.localhost`)", "traefik.http.services.companion.loadbalancer.server.port": "8080", }, } HostConfig := &container.HostConfig{ Mounts: []mount.Mount{ { Type: mount.TypeBind, Source: "/var/run/docker.sock", Target: "/var/run/docker.sock", }, { Type: mount.TypeBind, Source: "/etc/companion.json", Target: "/etc/companion.json", }, }, } containerNetworkID, err := setupNetwork("circus", true) NetworkingConfig := &network.NetworkingConfig{ EndpointsConfig: map[string]*network.EndpointSettings{ "circus": { NetworkID: containerNetworkID, }, }, } log.Println("Starting the container") _, err := dockerCLI.ContainerCreate(dockerCtx, Config, HostConfig, NetworkingConfig, "") if err != nil { panic(err) } log.Println("Container started") } func generateSessionSalt() string { return fmt.Sprintf("%d", time.Now().UnixNano()) }