wails/v3/examples/server/main.go
Lea Anthony 9a363d7be5
feat(v3): add server mode for headless HTTP deployment (#4903)
* feat(v3): add server mode for headless HTTP deployment

Server mode allows Wails applications to run as pure HTTP servers
without native GUI dependencies. Enable with `-tags server` build tag.

Features:
- HTTP server with configurable host/port via ServerOptions
- WAILS_SERVER_HOST and WAILS_SERVER_PORT env var overrides
- WebSocket event broadcasting to connected browsers
- Browser clients represented as BrowserWindow (Window interface)
- Health check endpoint at /health
- Graceful shutdown with configurable timeout
- Docker support with Dockerfile.server template and tasks

Build and run:
  wails3 task build:server
  wails3 task run:server
  wails3 task build:docker
  wails3 task run:docker

Documentation at docs/guides/server-build.mdx

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(v3): add server mode for headless HTTP deployment

Server mode allows Wails applications to run as pure HTTP servers
without native GUI dependencies. Enable with `-tags server` build tag.

Features:
- HTTP server with configurable host/port via ServerOptions
- WAILS_SERVER_HOST and WAILS_SERVER_PORT env var overrides
- WebSocket event broadcasting to connected browsers
- Browser clients represented as BrowserWindow (Window interface)
- Health check endpoint at /health
- Graceful shutdown with configurable timeout
- Docker support with Dockerfile.server template and tasks

Build and run:
  wails3 task build:server
  wails3 task run:server
  wails3 task build:docker
  wails3 task run:docker

Documentation at docs/guides/server-build.mdx

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: address CodeRabbit review comments

- Fix corrupted test file with embedded terminal output
- Fix module name mismatch in gin-routing (was gin-example)
- Fix replace directive version mismatch in gin-service
- Fix placeholder module name in ios example (was changeme)
- Fix Dockerfile COPY path to work from both build contexts
- Fix bare URL in README (MD034 compliance)
- Fix comment accuracy in getScreens (returns error, not empty slice)
- Remove deprecated docker-compose version field
- Add port documentation in Taskfile template

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: address CodeRabbit review comments

- Add note about healthcheck wget not being available in distroless images
- Add !server build constraint to menu_windows.go and menu_darwin.go
- Downgrade window-visibility-test go.mod from 1.25 to 1.24 to match CI

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 14:33:44 +11:00

82 lines
2 KiB
Go

package main
import (
"embed"
"log"
"log/slog"
"os"
"time"
"github.com/wailsapp/wails/v3/pkg/application"
)
//go:embed frontend/dist
var assets embed.FS
// GreetService is a simple service that provides greeting functionality.
type GreetService struct{}
// Greet returns a greeting message.
func (g *GreetService) Greet(name string) string {
if name == "" {
name = "World"
}
return "Hello, " + name + "!"
}
func main() {
// Create a logger for better visibility
logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
Level: slog.LevelInfo,
}))
app := application.New(application.Options{
Name: "Server Mode Example",
Description: "A Wails application running in server mode",
Logger: logger,
LogLevel: slog.LevelInfo,
// Server mode is enabled by building with -tags server
// Host/port can be overridden via WAILS_SERVER_HOST and WAILS_SERVER_PORT env vars
Server: application.ServerOptions{
Host: "localhost",
Port: 8080,
},
// Register services (bindings work the same as desktop mode)
Services: []application.Service{
application.NewService(&GreetService{}),
},
// Serve frontend assets
Assets: application.AssetOptions{
Handler: application.AssetFileServerFS(assets),
},
})
log.Println("Starting Wails application in server mode...")
log.Println("Access at: http://localhost:8080")
log.Println("Health check: http://localhost:8080/health")
log.Println("Press Ctrl+C to stop")
// Listen for broadcast events from browsers
app.Event.On("broadcast", func(event *application.CustomEvent) {
log.Printf("Received broadcast from %s: %v\n", event.Sender, event.Data)
})
// Emit periodic events to test WebSocket broadcasting
go func() {
time.Sleep(2 * time.Second) // Wait for server to start
ticker := time.NewTicker(5 * time.Second)
defer ticker.Stop()
for {
<-ticker.C
app.Event.Emit("server-tick", time.Now().Format(time.RFC3339))
log.Println("Emitted server-tick event")
}
}()
if err := app.Run(); err != nil {
log.Fatal(err)
}
}