Repository: supabase/cli

Issue #1977: Services getting exposed on network instead of only on localhost
Created: 2024-02-21T10:13:23Z
When running supabase start or supabase db start it looks like some services are getting exposed on the network, such as the postgres database. I believe this is because when we start containers they bind to all network interfaces instead of just localhost

  
    
      cli/internal/db/start/start.go
    
    
        Lines 101 to 150
      in
      7abddb0
    
  
  
    

        
          
           func NewHostConfig() container.HostConfig { 
        

        
          
           	hostPort := strconv.FormatUint(uint64(utils.Config.Db.Port), 10) 
        

        
          
           	hostConfig := WithSyslogConfig(container.HostConfig{ 
        

        
          
           		PortBindings:  nat.PortMap{"5432/tcp": []nat.PortBinding{{HostPort: hostPort}}}, 
        

        
          
           		RestartPolicy: container.RestartPolicy{Name: "always"}, 
        

        
          
           		Binds: []string{ 
        

        
          
           			utils.DbId + ":/var/lib/postgresql/data", 
        

        
          
           			utils.ConfigId + ":/etc/postgresql-custom", 
        

        
          
           		}, 
        

        
          
           		ExtraHosts: []string{"host.docker.internal:host-gateway"}, 
        

        
          
           	}) 
        

        
          
           	return hostConfig 
        

        
          
           } 
        

        
          
            
        

        
          
           func StartDatabase(ctx context.Context, fsys afero.Fs, w io.Writer, options ...func(*pgx.ConnConfig)) error { 
        

        
          
           	config := NewContainerConfig() 
        

        
          
           	hostConfig := NewHostConfig() 
        

        
          
           	networkingConfig := network.NetworkingConfig{ 
        

        
          
           		EndpointsConfig: map[string]*network.EndpointSettings{ 
        

        
          
           			utils.NetId: { 
        

        
          
           				Aliases: utils.DbAliases, 
        

        
          
           			}, 
        

        
          
           		}, 
        

        
          
           	} 
        

        
          
           	if utils.Config.Db.MajorVersion <= 14 { 
        

        
          
           		config.Entrypoint = nil 
        

        
          
           		hostConfig.Tmpfs = map[string]string{"/docker-entrypoint-initdb.d": ""} 
        

        
          
           	} 
        

        
          
           	// Creating volume will not override existing volume, so we must inspect explicitly 
        

        
          
           	_, err := utils.Docker.VolumeInspect(ctx, utils.DbId) 
        

        
          
           	utils.NoBackupVolume = client.IsErrNotFound(err) 
        

        
          
           	if utils.NoBackupVolume { 
        

        
          
           		fmt.Fprintln(w, "Starting database...") 
        

        
          
           	} else { 
        

        
          
           		fmt.Fprintln(w, "Starting database from backup...") 
        

        
          
           	} 
        

        
          
           	if _, err := utils.DockerStart(ctx, config, hostConfig, networkingConfig, utils.DbId); err != nil { 
        

        
          
           		return err 
        

        
          
           	} 
        

        
          
           	if !WaitForHealthyService(ctx, utils.DbId, HealthTimeout) { 
        

        
          
           		return errors.New(ErrDatabase) 
        

        
          
           	} 
        

        
          
           	// Initialize if we are on PG14 and there's no existing db volume 
        

        
          
           	if utils.NoBackupVolume { 
        

        
          
           		if err := setupDatabase(ctx, fsys, w, options...); err != nil { 
        

        
          
           			return err 
        

        
          
           		} 
        

        
          
           	} 
        

        
          
           	return initCurrentBranch(fsys) 
        

        
          
           } 
        
    
  


This is both unexpected and a bit dangerous to suddenly have services exposed publicly in the network.
Ideally we'd expose services only on localhost - the equivalent of
docker run -p 127.0.0.1:54322:54322

In case there are use cases where we really want to expose services publicly then what about we add a flag to the cli that changes the host from localhost to 0.0.0.0?
System information

OS: Linux
Version of CLI: 1.145.4 (latest)

Duplicate issue #1977: Services getting exposed on network instead of only on localhost
Created: 2024-02-21T10:13:23Z
When running supabase start or supabase db start it looks like some services are getting exposed on the network, such as the postgres database. I believe this is because when we start containers they bind to all network interfaces instead of just localhost

  
    
      cli/internal/db/start/start.go
    
    
        Lines 101 to 150
      in
      7abddb0
    
  
  
    

        
          
           func NewHostConfig() container.HostConfig { 
        

        
          
           	hostPort := strconv.FormatUint(uint64(utils.Config.Db.Port), 10) 
        

        
          
           	hostConfig := WithSyslogConfig(container.HostConfig{ 
        

        
          
           		PortBindings:  nat.PortMap{"5432/tcp": []nat.PortBinding{{HostPort: hostPort}}}, 
        

        
          
           		RestartPolicy: container.RestartPolicy{Name: "always"}, 
        

        
          
           		Binds: []string{ 
        

        
          
           			utils.DbId + ":/var/lib/postgresql/data", 
        

        
          
           			utils.ConfigId + ":/etc/postgresql-custom", 
        

        
          
           		}, 
        

        
          
           		ExtraHosts: []string{"host.docker.internal:host-gateway"}, 
        

        
          
           	}) 
        

        
          
           	return hostConfig 
        

        
          
           } 
        

        
          
            
        

        
          
           func StartDatabase(ctx context.Context, fsys afero.Fs, w io.Writer, options ...func(*pgx.ConnConfig)) error { 
        

        
          
           	config := NewContainerConfig() 
        

        
          
           	hostConfig := NewHostConfig() 
        

        
          
           	networkingConfig := network.NetworkingConfig{ 
        

        
          
           		EndpointsConfig: map[string]*network.EndpointSettings{ 
        

        
          
           			utils.NetId: { 
        

        
          
           				Aliases: utils.DbAliases, 
        

        
          
           			}, 
        

        
          
           		}, 
        

        
          
           	} 
        

        
          
           	if utils.Config.Db.MajorVersion <= 14 { 
        

        
          
           		config.Entrypoint = nil 
        

        
          
           		hostConfig.Tmpfs = map[string]string{"/docker-entrypoint-initdb.d": ""} 
        

        
          
           	} 
        

        
          
           	// Creating volume will not override existing volume, so we must inspect explicitly 
        

        
          
           	_, err := utils.Docker.VolumeInspect(ctx, utils.DbId) 
        

        
          
           	utils.NoBackupVolume = client.IsErrNotFound(err) 
        

        
          
           	if utils.NoBackupVolume { 
        

        
          
           		fmt.Fprintln(w, "Starting database...") 
        

        
          
           	} else { 
        

        
          
           		fmt.Fprintln(w, "Starting database from backup...") 
        

        
          
           	} 
        

        
          
           	if _, err := utils.DockerStart(ctx, config, hostConfig, networkingConfig, utils.DbId); err != nil { 
        

        
          
           		return err 
        

        
          
           	} 
        

        
          
           	if !WaitForHealthyService(ctx, utils.DbId, HealthTimeout) { 
        

        
          
           		return errors.New(ErrDatabase) 
        

        
          
           	} 
        

        
          
           	// Initialize if we are on PG14 and there's no existing db volume 
        

        
          
           	if utils.NoBackupVolume { 
        

        
          
           		if err := setupDatabase(ctx, fsys, w, options...); err != nil { 
        

        
          
           			return err 
        

        
          
           		} 
        

        
          
           	} 
        

        
          
           	return initCurrentBranch(fsys) 
        

        
          
           } 
        
    
  


This is both unexpected and a bit dangerous to suddenly have services exposed publicly in the network.
Ideally we'd expose services only on localhost - the equivalent of
docker run -p 127.0.0.1:54322:54322

In case there are use cases where we really want to expose services publicly then what about we add a flag to the cli that changes the host from localhost to 0.0.0.0?
System information

OS: Linux
Version of CLI: 1.145.4 (latest)

Closing comment (2024-02-23T07:50:14Z): I will close this as a duplicate of #1977
Feel free to upvote the issue to bump its priority.