From 272027d1019e2668ed6cf5cc1a8d473bc2167920 Mon Sep 17 00:00:00 2001 From: Han Qiao Date: Wed, 17 Jan 2024 01:54:54 +0800 Subject: [PATCH] fix(db): make local hostname configurable for docker-in-docker (#1852) --- internal/db/diff/migra.go | 8 +++++++- internal/db/start/start.go | 4 ++-- internal/migration/squash/squash.go | 3 ++- internal/start/start.go | 16 +++++++++------- internal/start/templates/kong.yml | 2 +- internal/status/status.go | 16 ++++++++-------- internal/utils/config.go | 2 ++ internal/utils/connect.go | 2 +- internal/utils/flags/db_url.go | 2 +- internal/utils/misc.go | 11 +++++++++++ 10 files changed, 44 insertions(+), 22 deletions(-) diff --git a/internal/db/diff/migra.go b/internal/db/diff/migra.go index 68e51e080..9a4aed983 100644 --- a/internal/db/diff/migra.go +++ b/internal/db/diff/migra.go @@ -195,7 +195,13 @@ func DiffDatabase(ctx context.Context, schema []string, config pgconn.Config, w return "", err } fmt.Fprintln(w, "Diffing schemas:", strings.Join(schema, ",")) - source := fmt.Sprintf("postgresql://postgres:postgres@127.0.0.1:%d/postgres", utils.Config.Db.ShadowPort) + source := utils.ToPostgresURL(pgconn.Config{ + Host: utils.Config.Hostname, + Port: uint16(utils.Config.Db.ShadowPort), + User: "postgres", + Password: utils.Config.Db.Password, + Database: "postgres", + }) target := utils.ToPostgresURL(config) return DiffSchemaMigra(ctx, source, target, schema) } diff --git a/internal/db/start/start.go b/internal/db/start/start.go index 8adb00745..d11ea1072 100644 --- a/internal/db/start/start.go +++ b/internal/db/start/start.go @@ -173,7 +173,7 @@ func WithSyslogConfig(hostConfig container.HostConfig) container.HostConfig { if utils.Config.Analytics.Enabled { hostConfig.LogConfig.Type = "syslog" hostConfig.LogConfig.Config = map[string]string{ - "syslog-address": fmt.Sprintf("tcp://127.0.0.1:%d", utils.Config.Analytics.VectorPort), + "syslog-address": fmt.Sprintf("tcp://%s:%d", utils.Config.Hostname, utils.Config.Analytics.VectorPort), "tag": "{{.Name}}", } } @@ -222,7 +222,7 @@ func initSchema15(ctx context.Context, host string) error { return err } return utils.DockerRunOnceWithStream(ctx, utils.Config.Auth.Image, []string{ - fmt.Sprintf("API_EXTERNAL_URL=http://127.0.0.1:%v", utils.Config.Api.Port), + fmt.Sprintf("API_EXTERNAL_URL=http://%s:%d", host, utils.Config.Api.Port), "GOTRUE_LOG_LEVEL=error", "GOTRUE_DB_DRIVER=postgres", fmt.Sprintf("GOTRUE_DB_DATABASE_URL=postgresql://supabase_auth_admin:%s@%s:5432/postgres", utils.Config.Db.Password, host), diff --git a/internal/migration/squash/squash.go b/internal/migration/squash/squash.go index c4ea854d6..fa9259b96 100644 --- a/internal/migration/squash/squash.go +++ b/internal/migration/squash/squash.go @@ -91,10 +91,11 @@ func squashMigrations(ctx context.Context, migrations []string, fsys afero.Fs, o } defer f.Close() config := pgconn.Config{ - Host: "127.0.0.1", + Host: utils.Config.Hostname, Port: uint16(utils.Config.Db.ShadowPort), User: "postgres", Password: utils.Config.Db.Password, + Database: "postgres", } return dump.DumpSchema(ctx, config, nil, false, false, f) } diff --git a/internal/start/start.go b/internal/start/start.go index e3190542c..9e7623379 100644 --- a/internal/start/start.go +++ b/internal/start/start.go @@ -100,6 +100,7 @@ type kongConfig struct { PgmetaId string EdgeRuntimeId string LogflareId string + ApiHost string ApiPort uint } @@ -305,6 +306,7 @@ EOF PgmetaId: utils.PgmetaId, EdgeRuntimeId: utils.EdgeRuntimeId, LogflareId: utils.LogflareId, + ApiHost: utils.Config.Hostname, ApiPort: utils.Config.Api.Port, }); err != nil { return errors.Errorf("failed to exec template: %w", err) @@ -377,7 +379,7 @@ EOF } env := []string{ - fmt.Sprintf("API_EXTERNAL_URL=http://127.0.0.1:%v", utils.Config.Api.Port), + fmt.Sprintf("API_EXTERNAL_URL=http://%s:%d", utils.Config.Hostname, utils.Config.Api.Port), "GOTRUE_API_HOST=0.0.0.0", "GOTRUE_API_PORT=9999", @@ -394,7 +396,7 @@ EOF "GOTRUE_JWT_DEFAULT_GROUP_NAME=authenticated", fmt.Sprintf("GOTRUE_JWT_EXP=%v", utils.Config.Auth.JwtExpiry), "GOTRUE_JWT_SECRET=" + utils.Config.Auth.JwtSecret, - fmt.Sprintf("GOTRUE_JWT_ISSUER=http://127.0.0.1:%v/auth/v1", utils.Config.Api.Port), + fmt.Sprintf("GOTRUE_JWT_ISSUER=http://%s:%d/auth/v1", utils.Config.Hostname, utils.Config.Api.Port), fmt.Sprintf("GOTRUE_EXTERNAL_EMAIL_ENABLED=%v", utils.Config.Auth.Email.EnableSignup), fmt.Sprintf("GOTRUE_MAILER_SECURE_EMAIL_CHANGE_ENABLED=%v", utils.Config.Auth.Email.DoubleConfirmChanges), @@ -407,10 +409,10 @@ EOF // TODO: To be reverted to `/auth/v1/verify` once // https://github.com/supabase/supabase/issues/16100 // is fixed on upstream GoTrue. - fmt.Sprintf("GOTRUE_MAILER_URLPATHS_INVITE=http://127.0.0.1:%v/auth/v1/verify", utils.Config.Api.Port), - fmt.Sprintf("GOTRUE_MAILER_URLPATHS_CONFIRMATION=http://127.0.0.1:%v/auth/v1/verify", utils.Config.Api.Port), - fmt.Sprintf("GOTRUE_MAILER_URLPATHS_RECOVERY=http://127.0.0.1:%v/auth/v1/verify", utils.Config.Api.Port), - fmt.Sprintf("GOTRUE_MAILER_URLPATHS_EMAIL_CHANGE=http://127.0.0.1:%v/auth/v1/verify", utils.Config.Api.Port), + fmt.Sprintf("GOTRUE_MAILER_URLPATHS_INVITE=http://%s:%d/auth/v1/verify", utils.Config.Hostname, utils.Config.Api.Port), + fmt.Sprintf("GOTRUE_MAILER_URLPATHS_CONFIRMATION=http://%s:%d/auth/v1/verify", utils.Config.Hostname, utils.Config.Api.Port), + fmt.Sprintf("GOTRUE_MAILER_URLPATHS_RECOVERY=http://%s:%d/auth/v1/verify", utils.Config.Hostname, utils.Config.Api.Port), + fmt.Sprintf("GOTRUE_MAILER_URLPATHS_EMAIL_CHANGE=http://%s:%d/auth/v1/verify", utils.Config.Hostname, utils.Config.Api.Port), "GOTRUE_RATE_LIMIT_EMAIL_SENT=360000", fmt.Sprintf("GOTRUE_EXTERNAL_PHONE_ENABLED=%v", utils.Config.Auth.Sms.EnableSignup), @@ -501,7 +503,7 @@ EOF ) } else { env = append(env, - fmt.Sprintf("GOTRUE_EXTERNAL_%s_REDIRECT_URI=http://127.0.0.1:%v/auth/v1/callback", strings.ToUpper(name), utils.Config.Api.Port), + fmt.Sprintf("GOTRUE_EXTERNAL_%s_REDIRECT_URI=http://%s:%d/auth/v1/callback", strings.ToUpper(name), utils.Config.Hostname, utils.Config.Api.Port), ) } diff --git a/internal/start/templates/kong.yml b/internal/start/templates/kong.yml index b6d70d5f0..3e477291c 100644 --- a/internal/start/templates/kong.yml +++ b/internal/start/templates/kong.yml @@ -99,7 +99,7 @@ services: config: add: headers: - - "Forwarded: host=127.0.0.1:{{ .ApiPort }}/storage/v1;proto=http" + - "Forwarded: host={{ .ApiHost }}:{{ .ApiPort }}/storage/v1;proto=http" - name: pg-meta _comment: "pg-meta: /pg/* -> http://pg-meta:8080/*" url: http://{{ .PgmetaId }}:8080/ diff --git a/internal/status/status.go b/internal/status/status.go index 33271bb7a..7656e3249 100644 --- a/internal/status/status.go +++ b/internal/status/status.go @@ -5,6 +5,7 @@ import ( "fmt" "io" "net/http" + "net/url" "os" "reflect" @@ -27,14 +28,14 @@ type CustomName struct { func (c *CustomName) toValues(exclude ...string) map[string]string { values := map[string]string{ - c.DbURL: fmt.Sprintf("postgresql://postgres:%s@127.0.0.1:%d/postgres", utils.Config.Db.Password, utils.Config.Db.Port), + c.DbURL: fmt.Sprintf("postgresql://%s@%s:%d/postgres", url.UserPassword("postgres", utils.Config.Db.Password), utils.Config.Hostname, utils.Config.Db.Port), } if utils.Config.Api.Enabled && !utils.SliceContains(exclude, utils.RestId) && !utils.SliceContains(exclude, utils.ShortContainerImageName(utils.Config.Api.Image)) { - values[c.ApiURL] = fmt.Sprintf("http://127.0.0.1:%d", utils.Config.Api.Port) - values[c.GraphqlURL] = fmt.Sprintf("http://127.0.0.1:%d/graphql/v1", utils.Config.Api.Port) + values[c.ApiURL] = fmt.Sprintf("http://%s:%d", utils.Config.Hostname, utils.Config.Api.Port) + values[c.GraphqlURL] = fmt.Sprintf("http://%s:%d/graphql/v1", utils.Config.Hostname, utils.Config.Api.Port) } if utils.Config.Studio.Enabled && !utils.SliceContains(exclude, utils.StudioId) && !utils.SliceContains(exclude, utils.ShortContainerImageName(utils.StudioImage)) { - values[c.StudioURL] = fmt.Sprintf("http://127.0.0.1:%d", utils.Config.Studio.Port) + values[c.StudioURL] = fmt.Sprintf("http://%s:%d", utils.Config.Hostname, utils.Config.Studio.Port) } if !utils.SliceContains(exclude, utils.GotrueId) && !utils.SliceContains(exclude, utils.ShortContainerImageName(utils.Config.Auth.Image)) { values[c.JWTSecret] = utils.Config.Auth.JwtSecret @@ -42,7 +43,7 @@ func (c *CustomName) toValues(exclude ...string) map[string]string { values[c.ServiceRoleKey] = utils.Config.Auth.ServiceRoleKey } if utils.Config.Inbucket.Enabled && !utils.SliceContains(exclude, utils.InbucketId) && !utils.SliceContains(exclude, utils.ShortContainerImageName(utils.InbucketImage)) { - values[c.InbucketURL] = fmt.Sprintf("http://127.0.0.1:%d", utils.Config.Inbucket.Port) + values[c.InbucketURL] = fmt.Sprintf("http://%s:%d", utils.Config.Hostname, utils.Config.Inbucket.Port) } return values } @@ -119,13 +120,13 @@ func IsServiceReady(ctx context.Context, container string) bool { func isPostgRESTHealthy(ctx context.Context) bool { // PostgREST does not support native health checks - restUrl := fmt.Sprintf("http://127.0.0.1:%d/rest-admin/v1/ready", utils.Config.Api.Port) + restUrl := fmt.Sprintf("http://%s:%d/rest-admin/v1/ready", utils.Config.Hostname, utils.Config.Api.Port) return checkHTTPHead(ctx, restUrl) } func isEdgeRuntimeHealthy(ctx context.Context) bool { // Native health check logs too much hyper::Error(IncompleteMessage) - restUrl := fmt.Sprintf("http://127.0.0.1:%d/functions/v1/_internal/health", utils.Config.Api.Port) + restUrl := fmt.Sprintf("http://%s:%d/functions/v1/_internal/health", utils.Config.Hostname, utils.Config.Api.Port) return checkHTTPHead(ctx, restUrl) } @@ -141,7 +142,6 @@ func checkHTTPHead(ctx context.Context, url string) bool { func printStatus(names CustomName, format string, w io.Writer, exclude ...string) (err error) { values := names.toValues(exclude...) - return utils.EncodeOutput(format, w, values) } diff --git a/internal/utils/config.go b/internal/utils/config.go index 6703c86f9..4eca0fbff 100644 --- a/internal/utils/config.go +++ b/internal/utils/config.go @@ -233,6 +233,7 @@ var Config = config{ type ( config struct { ProjectId string `toml:"project_id"` + Hostname string `toml:"-"` Api api `toml:"api"` Db db `toml:"db" mapstructure:"db"` Realtime realtime `toml:"realtime"` @@ -463,6 +464,7 @@ func LoadConfigFS(fsys afero.Fs) error { if Config.ProjectId == "" { return errors.New("Missing required field in config: project_id") } + Config.Hostname = GetHostname() UpdateDockerIds() // Validate api config if Config.Api.Port == 0 { diff --git a/internal/utils/connect.go b/internal/utils/connect.go index e66b91cb8..1509d3ecc 100644 --- a/internal/utils/connect.go +++ b/internal/utils/connect.go @@ -91,7 +91,7 @@ func getPoolerConfig(dbConfig pgconn.Config) *pgconn.Config { // Connnect to local Postgres with optimised settings. The caller is responsible for closing the connection returned. func ConnectLocalPostgres(ctx context.Context, config pgconn.Config, options ...func(*pgx.ConnConfig)) (*pgx.Conn, error) { if len(config.Host) == 0 { - config.Host = "127.0.0.1" + config.Host = Config.Hostname } if config.Port == 0 { config.Port = uint16(Config.Db.Port) diff --git a/internal/utils/flags/db_url.go b/internal/utils/flags/db_url.go index 66f7a5a93..ec96d39f9 100644 --- a/internal/utils/flags/db_url.go +++ b/internal/utils/flags/db_url.go @@ -56,7 +56,7 @@ func ParseDatabaseConfig(flagSet *pflag.FlagSet, fsys afero.Fs) error { if err := utils.LoadConfigFS(fsys); err != nil { return err } - DbConfig.Host = "127.0.0.1" + DbConfig.Host = utils.Config.Hostname DbConfig.Port = uint16(utils.Config.Db.Port) DbConfig.User = "postgres" DbConfig.Password = utils.Config.Db.Password diff --git a/internal/utils/misc.go b/internal/utils/misc.go index 1569b73e9..f5d2bc466 100644 --- a/internal/utils/misc.go +++ b/internal/utils/misc.go @@ -3,6 +3,7 @@ package utils import ( "context" _ "embed" + "net" "os" "path/filepath" "regexp" @@ -300,3 +301,13 @@ func ValidateFunctionSlug(slug string) error { func Ptr[T any](v T) *T { return &v } + +func GetHostname() string { + host := Docker.DaemonHost() + if parsed, err := client.ParseHostURL(host); err == nil && parsed.Scheme == "tcp" { + if host, _, err := net.SplitHostPort(parsed.Host); err == nil { + return host + } + } + return "127.0.0.1" +}