package services import ( "fmt" "localenv/utils" "github.com/docker/docker/api/types/mount" "github.com/docker/docker/api/types/swarm" "github.com/docker/docker/client" "golang.org/x/net/context" ) const ( PostgresImageName string = "postgres:13.4-alpine" PostgresServicePort uint32 = 5432 ) type Postgres struct { Service } func NewPostgres(serviceName string) Postgres { var pg Postgres pg.name = fmt.Sprintf("localenv-postgres-%s", serviceName) pg.spec = pg.getServiceSpec( serviceName, WithNetwork(serviceName), WithRestartPolicy(), ) return pg } func (p *Postgres) getServiceSpec(name string, opts ...ServiceOption) swarm.ServiceSpec { spec := swarm.ServiceSpec{ Annotations: swarm.Annotations{ Name: p.name, }, TaskTemplate: swarm.TaskSpec{ ContainerSpec: &swarm.ContainerSpec{ Image: PostgresImageName, Hostname: fmt.Sprintf("pg-%s", name), Env: []string{ "POSTGRES_HOSTNAME=localhost", fmt.Sprintf("POSTGRES_PORT=%d", PostgresServicePort), fmt.Sprintf("POSTGRES_DB=%s", name), "POSTGRES_USER=test", "POSTGRES_PASSWORD=test", }, Mounts: []mount.Mount{ { Type: mount.TypeVolume, Source: p.name, Target: "/var/lib/postgresql/data/", }, }, }, }, Mode: swarm.ServiceMode{ Replicated: &swarm.ReplicatedService{ Replicas: &SwarmServiceReplicas, }, }, } for _, opt := range opts { opt(&spec) } return spec } func (p *Postgres) Deploy(ctx context.Context, cli *client.Client) error { if err := utils.CreateVolume(ctx, cli, p.name); err != nil { return err } if err := utils.CreateService(ctx, cli, &p.spec); err != nil { return err } if err := utils.CheckServiceHealthWithRetry(ctx, cli, p.name); err != nil { return err } return nil }