func RunDockerContainer(cmd string) { herokuClient := HttpClient() request := MakeRequest(appName, "config-vars", "") resp, err := herokuClient.Do(request) if err != nil { panic("do request") } herokuEnv, err := ioutil.ReadAll(resp.Body) if err != nil { panic("read response") } fmt.Println("Heroku Env:", string(herokuEnv)) cwd, _ := os.Getwd() dClient, err := dockerClient.NewClient("unix:///var/run/docker.sock") if err != nil { panic("new client") } var config docker.Config exposedPorts := make(map[docker.Port]struct{}) exposedPorts["80"] = struct{}{} volumes := make(map[string]struct{}) volumes["/app"] = struct{}{} config.Volumes = volumes config.ExposedPorts = exposedPorts config.Cmd = []string{"/bin/bash", "-c", cmd} config.Env = []string{"PORT=80"} config.Image = "heroku-runtime" config.WorkingDir = "/app" container, err := dClient.CreateContainer(dockerClient.CreateContainerOptions{}, &config) if err != nil { panic("create container") } err = dClient.StartContainer(container.ID, &docker.HostConfig{Binds: []string{cwd + "/app:/app"}}) if err != nil { panic("start container") } fmt.Fprintf(os.Stdout, "%s\n", container.ID) }
func (c App) Attach(user string, ws *websocket.Conn) revel.Result { config := docker.Config{} config.Cmd = []string{"/bin/bash"} config.Image = "workshops:" + c.Params.Values.Get("image") config.Tty = true config.AttachStdin = true config.AttachStdout = true config.OpenStdin = true config.StdinOnce = true container, err := c.DockerClient.CreateContainer(&config) if err != nil { fmt.Println(err.Error()) c.Response.Status = 500 return c.RenderText(err.Error()) } id := container.ShortID() err = c.DockerClient.StartContainer(id) if err != nil { fmt.Println(err.Error()) c.Response.Status = 500 return c.RenderText(err.Error()) } endpoint := "ws://127.0.0.1:4243/v1.5/containers/" + id + "/attach/ws?logs=1&stderr=1&stdout=1&stream=1&stdin=1" containerWs, err := websocket.Dial(endpoint, "", "http://localhost") if err != nil { fmt.Println(err.Error()) c.Response.Status = 500 return c.RenderText(err.Error()) } finished := make(chan bool) go func() { defer containerWs.Close() buf := make([]byte, 40*1024) for { n, err := containerWs.Read(buf) if err != nil { break } if n != 0 { ws.Write(buf[0:n]) } } finished <- true }() go func() { defer ws.Close() defer containerWs.Close() buf := make([]byte, 40*1024) for { n, err := ws.Read(buf) if err != nil { break } if n != 0 { containerWs.Write(buf[0:n]) } } finished <- true }() <-finished <-finished return c.RenderText("OK") }