feat: single Docker image with frontend served from backend

- Dockerfile: 3-stage build (frontend npm build → backend go build → alpine runtime)
- Frontend dist files served from disk at /app/frontend/dist
- server.go: catch-all GET handler serves static files with SPA fallback to index.html
- config.go: new server.frontend_dir option (env: SUB_STORE_SERVER_FRONTEND_DIR)
- API routes (/api/*), download routes, and /health take priority over static serving
This commit is contained in:
2026-07-28 14:52:53 +08:00
parent de9ac92ede
commit 3671c39b7c
3 changed files with 52 additions and 2 deletions
+2
View File
@@ -22,6 +22,7 @@ type ServerConfig struct {
ReadTimeout time.Duration `mapstructure:"read_timeout"`
WriteTimeout time.Duration `mapstructure:"write_timeout"`
BodyLimit int `mapstructure:"body_limit"`
FrontendDir string `mapstructure:"frontend_dir"`
}
type DatabaseConfig struct {
@@ -62,6 +63,7 @@ func defaults() {
viper.SetDefault("server.read_timeout", 30*time.Second)
viper.SetDefault("server.write_timeout", 60*time.Second)
viper.SetDefault("server.body_limit", 4*1024*1024)
viper.SetDefault("server.frontend_dir", "./frontend/dist")
viper.SetDefault("database.path", "./data/sub-store.db")
viper.SetDefault("auth.admin_token", "")
viper.SetDefault("auth.download_token", "")