Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion cmd/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,15 @@ var (
excludedContainers []string
ignoreHealthCheck bool
preview bool
foreground bool

startCmd = &cobra.Command{
GroupID: groupLocalDev,
Use: "start",
Short: "Start containers for Supabase local development",
RunE: func(cmd *cobra.Command, args []string) error {
validateExcludedContainers(excludedContainers)
return start.Run(cmd.Context(), afero.NewOsFs(), excludedContainers, ignoreHealthCheck)
return start.Run(cmd.Context(), afero.NewOsFs(), excludedContainers, ignoreHealthCheck, foreground)
},
}
)
Expand All @@ -58,6 +59,7 @@ func init() {
flags.StringSliceVarP(&excludedContainers, "exclude", "x", []string{}, "Names of containers to not start. ["+names+"]")
flags.BoolVar(&ignoreHealthCheck, "ignore-health-check", false, "Ignore unhealthy services and exit 0")
flags.BoolVar(&preview, "preview", false, "Connect to feature preview branch")
flags.BoolVarP(&foreground, "foreground", "f", false, "Run in foreground and stop services on exit")
cobra.CheckErr(flags.MarkHidden("preview"))
rootCmd.AddCommand(startCmd)
}
2 changes: 2 additions & 0 deletions docs/supabase/start.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ All service containers are started by default. You can exclude those not needed
> It is recommended to have at least 7GB of RAM to start all services.

Health checks are automatically added to verify the started containers. Use `--ignore-health-check` flag to ignore these errors.

By default, `supabase start` starts the services and exits. Use `-f` or `--foreground` flag to run in foreground mode, which keeps the command running and automatically stops services when the terminal is closed or interrupted.
25 changes: 24 additions & 1 deletion internal/start/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@
"net"
"net/url"
"os"
"os/signal"
"path"
"path/filepath"
"slices"
"strconv"
"strings"
"syscall"
"text/template"
"time"

Expand All @@ -38,12 +40,13 @@
"github.com/supabase/cli/internal/seed/buckets"
"github.com/supabase/cli/internal/services"
"github.com/supabase/cli/internal/status"
"github.com/supabase/cli/internal/stop"
"github.com/supabase/cli/internal/utils"
"github.com/supabase/cli/internal/utils/flags"
"github.com/supabase/cli/pkg/config"
)

func Run(ctx context.Context, fsys afero.Fs, excludedContainers []string, ignoreHealthCheck bool) error {
func Run(ctx context.Context, fsys afero.Fs, excludedContainers []string, ignoreHealthCheck bool, foreground bool) error {
// Sanity checks.
{
if err := flags.LoadConfig(fsys); err != nil {
Expand Down Expand Up @@ -81,6 +84,10 @@

fmt.Fprintf(os.Stderr, "Started %s local development setup.\n\n", utils.Aqua("supabase"))
status.PrettyPrint(os.Stdout, excludedContainers...)

if foreground {
return runForeground(ctx, fsys)
}
return nil
}

Expand Down Expand Up @@ -1304,6 +1311,22 @@
return names
}

func runForeground(ctx context.Context, fsys afero.Fs) error {
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM, syscall.SIGHUP)

fmt.Fprintln(os.Stderr, "Running in foreground. Press Ctrl+C to stop services.")

select {
case sig := <-sigChan:
fmt.Fprintf(os.Stderr, "\nReceived signal %v, stopping services...\n", sig)
case <-ctx.Done():
fmt.Fprintln(os.Stderr, "\nContext cancelled, stopping services...")
}

return stop.Run(ctx, true, "", false, fsys) // backup=true, no specific project, not all

Check failure on line 1327 in internal/start/start.go

View workflow job for this annotation

GitHub Actions / Lint

File is not properly formatted (gofmt)
}

func formatMapForEnvConfig(input map[string]string, output *bytes.Buffer) {
numOfKeyPairs := len(input)
i := 0
Expand Down
6 changes: 3 additions & 3 deletions internal/start/start_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func TestStartCommand(t *testing.T) {
fsys := afero.NewMemMapFs()
require.NoError(t, afero.WriteFile(fsys, utils.ConfigPath, []byte("malformed"), 0644))
// Run test
err := Run(context.Background(), fsys, []string{}, false)
err := Run(context.Background(), fsys, []string{}, false, false)
// Check error
assert.ErrorContains(t, err, "toml: expected = after a key, but the document ends there")
})
Expand All @@ -47,7 +47,7 @@ func TestStartCommand(t *testing.T) {
Get("/v" + utils.Docker.ClientVersion() + "/containers").
ReplyError(errors.New("network error"))
// Run test
err := Run(context.Background(), fsys, []string{}, false)
err := Run(context.Background(), fsys, []string{}, false, false)
// Check error
assert.ErrorContains(t, err, "network error")
assert.Empty(t, apitest.ListUnmatchedRequests())
Expand Down Expand Up @@ -84,7 +84,7 @@ func TestStartCommand(t *testing.T) {
Reply(http.StatusOK).
JSON(running)
// Run test
err := Run(context.Background(), fsys, []string{}, false)
err := Run(context.Background(), fsys, []string{}, false, false)
// Check error
assert.NoError(t, err)
assert.Empty(t, apitest.ListUnmatchedRequests())
Expand Down
Loading