diff --git a/build/Dockerfile b/build/Dockerfile index 4e483ca..d9f70eb 100644 --- a/build/Dockerfile +++ b/build/Dockerfile @@ -21,10 +21,7 @@ RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main . # Final stage FROM alpine:latest -ENV PORT=3001 \ - IS_DEVELOPMENT=false \ - TEMPLATES_DIR=web/templates/ \ - STATIC_DIR=./web/static +ENV PORT=3001 WORKDIR /root/ diff --git a/cmd/main.go b/cmd/main.go index 2640777..e75c808 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -3,19 +3,28 @@ package main import ( "context" "fmt" + "log" "os" "os/signal" + "github.com/joho/godotenv" "github.com/tombrereton/go-hot-reload/internal/application" ) func main() { - app := application.NewApp() + err := godotenv.Load() + if err != nil { + log.Println("No .env file found - loading from environment") + } + cfg := application.NewConfigurationBuilder(). + WithPort(os.Getenv("PORT")). + Build() + app := application.NewApp(cfg) ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt) defer cancel() - err := app.Start(ctx) + err = app.Start(ctx) if err == nil { fmt.Println("Shutting down server: %w", err) } diff --git a/go.mod b/go.mod index 3817cb6..6a76920 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/PuerkitoBio/goquery v1.8.1 github.com/a-h/templ v0.2.513 github.com/go-chi/chi/v5 v5.0.11 + github.com/joho/godotenv v1.5.1 github.com/mavolin/go-htmx v1.0.0 ) diff --git a/go.sum b/go.sum index e006c93..2fbec3e 100644 --- a/go.sum +++ b/go.sum @@ -8,6 +8,8 @@ github.com/go-chi/chi/v5 v5.0.11 h1:BnpYbFZ3T3S1WMpD79r7R5ThWX40TaFB7L31Y8xqSwA= github.com/go-chi/chi/v5 v5.0.11/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/mavolin/go-htmx v1.0.0 h1:43rZuemWd23zrMcTU939EsflXjOPxtHy9VraT1CZ6qQ= github.com/mavolin/go-htmx v1.0.0/go.mod h1:r6O09gzKou9kutq3UiDPZ//Q7IeBCMcs8US5/sHFbvg= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= diff --git a/internal/application/app.go b/internal/application/app.go index 985cd70..520a020 100644 --- a/internal/application/app.go +++ b/internal/application/app.go @@ -8,25 +8,26 @@ import ( ) type App struct { + cfg Configuration router http.Handler } -func NewApp() *App { +func NewApp(c Configuration) *App { app := &App{ router: loadRoutes(), + cfg: c, } return app } func (a *App) Start(ctx context.Context) error { - port := "4000" + port := a.cfg.port server := &http.Server{ Addr: ":" + port, Handler: a.router, } - fmt.Printf("Starting server on http://localhost:%s\n", port) ch := make(chan error, 1) go func() { err := server.ListenAndServe() @@ -36,8 +37,9 @@ func (a *App) Start(ctx context.Context) error { close(ch) }() + fmt.Printf("Started server at http://localhost:%s\n", port) select { - case err := <-ch: + case err := <-ch: return err case <-ctx.Done(): timeout, cancel := context.WithTimeout(context.Background(), time.Second*10) diff --git a/internal/application/app_integration_test.go b/internal/application/app_integration_test.go index 1a7a311..6e51d8e 100644 --- a/internal/application/app_integration_test.go +++ b/internal/application/app_integration_test.go @@ -9,7 +9,8 @@ import ( ) func TestApp_Start(t *testing.T) { - app := NewApp() + cfg := NewConfigurationBuilder().WithPort("7000").Build() + app := NewApp(cfg) server := httptest.NewServer(app.router) defer server.Close() diff --git a/internal/application/configuration.go b/internal/application/configuration.go new file mode 100644 index 0000000..7e39eec --- /dev/null +++ b/internal/application/configuration.go @@ -0,0 +1,25 @@ +package application + +type Configuration struct { + port string +} + +type ConfigurationBuilder struct { + configuration Configuration +} + +func NewConfigurationBuilder() *ConfigurationBuilder { + return &ConfigurationBuilder{} +} + +func (b *ConfigurationBuilder) WithPort(port string) *ConfigurationBuilder { + if port == "" { + panic("port cannot be empty") + } + b.configuration.port = port + return b +} + +func (b *ConfigurationBuilder) Build() Configuration { + return b.configuration +}