Skip to content
This repository was archived by the owner on Sep 26, 2025. It is now read-only.

Commit befaea6

Browse files
authored
Bump functions docker image to 0.1.1 (#295)
* Set default start timeout to 10 minutes * Bump nhost/functions to 0.1.1 * Start "functions" container first and provide feedback to a user if it takes too long * Measure the time taken to start in debug mode * Remove unnecessary volume
1 parent 5050ac1 commit befaea6

3 files changed

Lines changed: 70 additions & 23 deletions

File tree

cmd/dev.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ func init() {
269269
devCmd.PersistentFlags().Uint32(nhost.PortSMTP, defaultSMTPPort, "Port for smtp server")
270270
devCmd.PersistentFlags().Uint32(nhost.PortMinioS3, defaultS3MinioPort, "S3 port for minio")
271271
devCmd.PersistentFlags().Uint32(nhost.PortMailhog, defaultMailhogPort, "Port for mailhog UI")
272-
devCmd.PersistentFlags().Duration(startTimeoutFlag, 5*time.Minute, "Timeout for starting services")
272+
devCmd.PersistentFlags().Duration(startTimeoutFlag, 10*time.Minute, "Timeout for starting services")
273273
devCmd.PersistentFlags().BoolVar(&noBrowser, "no-browser", false, "Don't open browser windows automatically")
274274

275275
devCmd.PersistentFlags().StringVar(&userDefinedHasuraCli, userDefinedHasuraCliFlag, viper.GetString(userDefinedHasuraCliFlag), "User-defined path for hasura-cli binary")

nhost/compose/config.go

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ const (
4141
svcPostgresDefaultImage = "nhost/postgres:12-v0.0.6"
4242
svcAuthDefaultImage = "nhost/hasura-auth:0.10.0"
4343
svcStorageDefaultImage = "nhost/hasura-storage:0.2.3"
44-
svcFunctionsDefaultImage = "nhost/functions:0.0.4"
44+
svcFunctionsDefaultImage = "nhost/functions:0.1.1"
4545
svcMinioDefaultImage = "minio/minio:RELEASE.2022-07-08T00-05-23Z"
4646
svcMailhogDefaultImage = "mailhog/mailhog"
4747
svcHasuraDefaultImage = "hasura/graphql-engine:v2.10.1"
@@ -148,11 +148,6 @@ func (c *Config) build() *types.Config {
148148
}
149149
}
150150

151-
// set volumes
152-
config.Volumes = types.Volumes{
153-
"functions_node_modules": types.VolumeConfig{},
154-
}
155-
156151
c.composeConfig = config
157152

158153
return config
@@ -360,18 +355,16 @@ func (c Config) functionsService() *types.ServiceConfig {
360355
Restart: types.RestartPolicyAlways,
361356
Expose: []string{"3000"},
362357
Environment: c.functionsServiceEnvs().dockerServiceConfigEnv(),
363-
HealthCheck: c.functionsServiceHealthcheck(time.Second*3, time.Minute*5),
358+
HealthCheck: c.functionsServiceHealthcheck(time.Second*1, time.Minute*30), // 30 minutes is the maximum allowed time for a "functions" service to start, see more below
359+
// Probe failure during that period will not be counted towards the maximum number of retries
360+
// However, if a health check succeeds during the start period, the container is considered started and all
361+
// consecutive failures will be counted towards the maximum number of retries.
364362
Volumes: []types.ServiceVolumeConfig{
365363
{
366364
Type: types.VolumeTypeBind,
367365
Source: "..",
368366
Target: "/opt/project",
369367
},
370-
{
371-
Type: types.VolumeTypeVolume,
372-
Source: "functions_node_modules",
373-
Target: "/opt/project/node_modules",
374-
},
375368
},
376369
}
377370
}
@@ -561,9 +554,6 @@ func (c Config) hasuraService() *types.ServiceConfig {
561554
SvcPostgres: {
562555
Condition: types.ServiceConditionHealthy,
563556
},
564-
SvcFunctions: {
565-
Condition: types.ServiceConditionHealthy,
566-
},
567557
},
568558
Restart: types.RestartPolicyAlways,
569559
}

nhost/service/manager.go

Lines changed: 64 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ import (
1919
"time"
2020
)
2121

22+
const (
23+
slowStartWaitMsg = "It takes more than usual to start the nhost project. Most likely because CLI needs to pull js dependencies inside a container. Please wait..."
24+
)
25+
2226
type Manager interface {
2327
SyncExec(ctx context.Context, f func(ctx context.Context) error) error
2428
Start(ctx context.Context) error
@@ -78,22 +82,59 @@ func (m *dockerComposeManager) SetGitBranch(gitBranch string) {
7882
}
7983

8084
func (m *dockerComposeManager) Start(ctx context.Context) error {
85+
startTime := time.Now()
86+
defer func() {
87+
m.l.Debugf("Start took %s", time.Since(startTime).String())
88+
}()
8189

8290
ds := &compose.DataStreams{}
8391

84-
if err := m.startPostgresGraphqlFunctions(ctx, ds); err != nil {
92+
m.status.Executing("Starting local Nhost project...")
93+
m.l.Debug("Starting docker compose")
94+
95+
// spin up the "functions" container first, because it's the one that's going to take the longest to start
96+
// though we don't wait for it to be healthy, only start
97+
if err := m.startFunctions(ctx, ds); err != nil {
98+
return err
99+
}
100+
101+
if err := m.startPostgresGraphql(ctx, ds); err != nil {
85102
return err
86103
}
87104

88105
if err := m.waitForGraphqlEngine(ctx, time.Millisecond*100, time.Minute*2); err != nil {
89106
return err
90107
}
91108

92-
// start all containers
109+
containersHealthy := make(chan bool)
110+
111+
go func() {
112+
ticker := time.NewTicker(time.Second * 20)
113+
defer ticker.Stop()
114+
115+
showSlowStartMsg := time.After(time.Second * 15)
116+
117+
for {
118+
select {
119+
case <-containersHealthy:
120+
return
121+
case <-ticker.C:
122+
m.status.Executingln("Processing...")
123+
m.l.Debug("Processing...")
124+
case <-showSlowStartMsg:
125+
m.status.Executing(slowStartWaitMsg)
126+
m.l.Debug(slowStartWaitMsg)
127+
}
128+
}
129+
}()
130+
131+
// start all containers, this is where we make sure that all containers are up & running, including "functions"
93132
if err := m.waitForServicesToBeRunningHealthy(ctx, ds); err != nil {
94133
return err
95134
}
96135

136+
containersHealthy <- true
137+
97138
// ensure default bucket `nhost` exists in Minio S3
98139
if err := m.ensureBucketExists(ctx); err != nil {
99140
return err
@@ -131,12 +172,28 @@ func (m *dockerComposeManager) Start(ctx context.Context) error {
131172
return m.applySeeds(ctx)
132173
}
133174

134-
func (m *dockerComposeManager) startPostgresGraphqlFunctions(ctx context.Context, ds *compose.DataStreams) error {
135-
m.status.Executing("Starting local Nhost project...")
136-
m.l.Debug("Starting docker compose")
175+
func (m *dockerComposeManager) startFunctions(ctx context.Context, ds *compose.DataStreams) error {
176+
m.status.Executing("Starting functions...")
177+
m.l.Debug("Starting functions")
178+
179+
cmd, err := compose.WrapperCmd(ctx, []string{"up", "-d", compose.SvcFunctions}, m.composeConfig, ds)
180+
if err != nil {
181+
if ctx.Err() != nil {
182+
return ctx.Err()
183+
}
184+
185+
m.status.Error("Failed to start functions container")
186+
m.l.WithError(err).Debug("Failed to start functions")
187+
return err
188+
}
189+
190+
m.setProcessToStartInItsOwnProcessGroup(cmd)
191+
return nhost.RunCmdAndCaptureStderrIfNotSetup(cmd)
192+
}
137193

138-
m.l.Debugf("Starting %s containers...", strings.Join([]string{compose.SvcPostgres, compose.SvcGraphqlEngine, compose.SvcFunctions}, ", "))
139-
cmd, err := compose.WrapperCmd(ctx, []string{"up", "-d", "--wait", compose.SvcPostgres, compose.SvcGraphqlEngine, compose.SvcFunctions}, m.composeConfig, ds)
194+
func (m *dockerComposeManager) startPostgresGraphql(ctx context.Context, ds *compose.DataStreams) error {
195+
m.l.Debugf("Starting %s containers...", strings.Join([]string{compose.SvcPostgres, compose.SvcGraphqlEngine}, ", "))
196+
cmd, err := compose.WrapperCmd(ctx, []string{"up", "-d", "--wait", compose.SvcPostgres, compose.SvcGraphqlEngine}, m.composeConfig, ds)
140197
if err != nil {
141198
if ctx.Err() != nil {
142199
return ctx.Err()

0 commit comments

Comments
 (0)