66 lines
1.7 KiB
Go
66 lines
1.7 KiB
Go
package deployer
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
|
|
"github.com/docker/docker/api/types"
|
|
"github.com/docker/docker/api/types/container"
|
|
"github.com/docker/docker/client"
|
|
"github.com/docker/go-connections/nat"
|
|
)
|
|
|
|
type Deployer struct {
|
|
cli *client.Client
|
|
}
|
|
|
|
func NewDeployer() (*Deployer, error) {
|
|
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to create docker client: %w", err)
|
|
}
|
|
return &Deployer{cli: cli}, nil
|
|
}
|
|
|
|
func (d *Deployer) RunContainer(ctx context.Context, imageName, appName string, hostPort int, envVars []string) (string, error) {
|
|
config := &container.Config{
|
|
Image: imageName,
|
|
ExposedPorts: nat.PortSet{
|
|
"3000/tcp": struct{}{},
|
|
},
|
|
Env: envVars,
|
|
}
|
|
|
|
hostConfig := &container.HostConfig{
|
|
PortBindings: nat.PortMap{
|
|
"3000/tcp": []nat.PortBinding{
|
|
{
|
|
HostIP: "0.0.0.0",
|
|
HostPort: fmt.Sprintf("%d", hostPort),
|
|
},
|
|
},
|
|
},
|
|
RestartPolicy: container.RestartPolicy{
|
|
Name: "unless-stopped",
|
|
},
|
|
}
|
|
|
|
_ = d.cli.ContainerRemove(ctx, appName, types.ContainerRemoveOptions{Force: true})
|
|
|
|
resp, err := d.cli.ContainerCreate(ctx, config, hostConfig, nil, nil, appName)
|
|
if err != nil {
|
|
return "", fmt.Errorf("failed to create container: %w", err)
|
|
}
|
|
|
|
if err := d.cli.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{}); err != nil {
|
|
return "", fmt.Errorf("failed to start container: %w", err)
|
|
}
|
|
|
|
return resp.ID, nil
|
|
}
|
|
|
|
func (d *Deployer) StreamLogs(ctx context.Context, containerID string) (io.ReadCloser, error) {
|
|
return d.cli.ContainerLogs(ctx, containerID, types.ContainerLogsOptions{ShowStdout: true, ShowStderr: true, Follow: true})
|
|
}
|