github.com/defang-io/defang/src@v0.0.0-20240505002154-bdf411911834/pkg/docker/run.go (about) 1 package docker 2 3 import ( 4 "context" 5 "strings" 6 7 "github.com/docker/docker/api/types" 8 "github.com/docker/docker/api/types/container" 9 v1 "github.com/opencontainers/image-spec/specs-go/v1" 10 ) 11 12 func (d Docker) Run(ctx context.Context, env map[string]string, cmd ...string) (ContainerID, error) { 13 resp, err := d.ContainerCreate(ctx, &container.Config{ 14 Image: d.image, 15 Env: mapToSlice(env), 16 Cmd: cmd, 17 }, &container.HostConfig{ 18 AutoRemove: true, // --rm; FIXME: this causes "No such container" if the container exits early 19 PublishAllPorts: true, // -P 20 Resources: container.Resources{ 21 Memory: int64(d.memory), 22 }, 23 }, nil, parsePlatform(d.platform), "") 24 if err != nil { 25 return nil, err 26 } 27 28 return &resp.ID, d.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{}) 29 } 30 31 func mapToSlice(m map[string]string) []string { 32 s := make([]string, 0, len(m)) 33 for k, v := range m { 34 // Ensure no = in key 35 if strings.ContainsRune(k, '=') { 36 panic("invalid environment variable key") 37 } 38 s = append(s, k+"="+v) 39 } 40 return s 41 } 42 43 func parsePlatform(platform string) *v1.Platform { 44 parts := strings.Split(platform, "/") 45 var p = &v1.Platform{} 46 switch len(parts) { 47 case 3: 48 p.Variant = parts[2] 49 fallthrough 50 case 2: 51 p.OS = parts[0] 52 p.Architecture = parts[1] 53 case 1: 54 p.Architecture = parts[0] 55 default: 56 panic("invalid platform: " + platform) 57 } 58 return p 59 }