API and Database Deployment Update
This commit is contained in:
@@ -1,28 +1,26 @@
|
||||
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 (d *Deployer) RemoveContainer(ctx context.Context, containerID string) error {
|
||||
return d.cli.ContainerRemove(ctx, containerID, types.ContainerRemoveOptions{Force: true})
|
||||
}
|
||||
func NewDeployer() (*Deployer, error) {
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithVersion("1.44"))
|
||||
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,
|
||||
@@ -31,7 +29,6 @@ func (d *Deployer) RunContainer(ctx context.Context, imageName, appName string,
|
||||
},
|
||||
Env: envVars,
|
||||
}
|
||||
|
||||
hostConfig := &container.HostConfig{
|
||||
PortBindings: nat.PortMap{
|
||||
"3000/tcp": []nat.PortBinding{
|
||||
@@ -45,21 +42,96 @@ func (d *Deployer) RunContainer(ctx context.Context, imageName, appName string,
|
||||
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) GetContainerEnv(ctx context.Context, containerID string) ([]string, error) {
|
||||
info, err := d.cli.ContainerInspect(ctx, containerID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return info.Config.Env, 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})
|
||||
}
|
||||
func (d *Deployer) StartDatabaseContainer(ctx context.Context, image, name string, port int, volumePath string, envVars []string) (string, error) {
|
||||
_, err := d.cli.ImagePull(ctx, image, types.ImagePullOptions{})
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to pull image %s: %v\n", image, err)
|
||||
}
|
||||
config := &container.Config{
|
||||
Image: image,
|
||||
ExposedPorts: nat.PortSet{
|
||||
"27017/tcp": struct{}{},
|
||||
},
|
||||
Env: envVars,
|
||||
}
|
||||
hostConfig := &container.HostConfig{
|
||||
PortBindings: nat.PortMap{
|
||||
"27017/tcp": []nat.PortBinding{
|
||||
{
|
||||
HostIP: "0.0.0.0",
|
||||
HostPort: fmt.Sprintf("%d", port),
|
||||
},
|
||||
},
|
||||
},
|
||||
Binds: []string{
|
||||
fmt.Sprintf("%s:/data/db", volumePath),
|
||||
},
|
||||
RestartPolicy: container.RestartPolicy{
|
||||
Name: "unless-stopped",
|
||||
},
|
||||
}
|
||||
d.cli.ContainerRemove(ctx, name, types.ContainerRemoveOptions{Force: true})
|
||||
resp, err := d.cli.ContainerCreate(ctx, config, hostConfig, nil, nil, name)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to create db container: %w", err)
|
||||
}
|
||||
if err := d.cli.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{}); err != nil {
|
||||
return "", fmt.Errorf("failed to start db container: %w", err)
|
||||
}
|
||||
return resp.ID, nil
|
||||
}
|
||||
func (d *Deployer) ExecContainer(ctx context.Context, containerID string, cmd []string) error {
|
||||
execConfig := types.ExecConfig{
|
||||
Cmd: cmd,
|
||||
AttachStdout: true,
|
||||
AttachStderr: true,
|
||||
}
|
||||
resp, err := d.cli.ContainerExecCreate(ctx, containerID, execConfig)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create exec: %w", err)
|
||||
}
|
||||
execID := resp.ID
|
||||
attachResp, err := d.cli.ContainerExecAttach(ctx, execID, types.ExecStartCheck{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to attach exec: %w", err)
|
||||
}
|
||||
defer attachResp.Close()
|
||||
io.Copy(io.Discard, attachResp.Reader)
|
||||
inspectResp, err := d.cli.ContainerExecInspect(ctx, execID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to inspect exec: %w", err)
|
||||
}
|
||||
if inspectResp.ExitCode != 0 {
|
||||
return fmt.Errorf("command exited with code %d", inspectResp.ExitCode)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (d *Deployer) StopContainer(ctx context.Context, containerID string) error {
|
||||
return d.cli.ContainerStop(ctx, containerID, container.StopOptions{})
|
||||
}
|
||||
func (d *Deployer) StartContainer(ctx context.Context, containerID string) error {
|
||||
return d.cli.ContainerStart(ctx, containerID, types.ContainerStartOptions{})
|
||||
}
|
||||
func (d *Deployer) RestartContainer(ctx context.Context, containerID string) error {
|
||||
return d.cli.ContainerRestart(ctx, containerID, container.StopOptions{})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user