diff --git a/Dockerfile b/Dockerfile index 5688cf2..6993488 100644 --- a/Dockerfile +++ b/Dockerfile @@ -21,7 +21,11 @@ RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o warpbox ./cmd/ # Stage 2: Runtime FROM alpine:3.21 -RUN apk add --no-cache ca-certificates tzdata +RUN apk add \ + --no-cache \ + ca-certificates \ + tzdata \ + wget # Create non-root user RUN addgroup -S warpbox && adduser -S warpbox -G warpbox @@ -60,6 +64,9 @@ ENV WARPBOX_DATA_DIR=/app/data \ EXPOSE 8080 +HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \ + CMD wget -qO- http://127.0.0.1:8080/health >/dev/null || exit 1 + VOLUME ["/app/data"] CMD ["./warpbox", "run", "--addr", ":8080"] diff --git a/README.md b/README.md index 06b8280..d284d60 100644 --- a/README.md +++ b/README.md @@ -189,3 +189,25 @@ keeps most behavior easy to follow from the Go handlers and the small browser scripts. For a short implementation overview, see [docs/tech.md](docs/tech.md). + +## Docker / Podman + +If you are using Podman, please pay attention in the [docker-compose.yml](./docker-compose.example.yml) example +file that has been provided, there's comments in regards to differences between the two. + + +When it comes to building the image, please make sure that you basically set the `--format docker` in the podman +build command, otherwise it won't have HealthChecks and other issues might arise. + +Tip: Put the following in `~/.config/containers/containers.conf` +```toml +[engine] +image_default_format = "docker" +``` + +For just running the docker-compose.yml with docker image format: +```bash +BUILDAH_FORMAT=docker podman compose up --build +``` + + diff --git a/lib/routing/routes.go b/lib/routing/routes.go index 8d238b3..e1f1a0b 100644 --- a/lib/routing/routes.go +++ b/lib/routing/routes.go @@ -3,6 +3,7 @@ package routing import "github.com/gin-gonic/gin" type Handlers struct { + Health gin.HandlerFunc Index gin.HandlerFunc ShowBox gin.HandlerFunc BoxLogin gin.HandlerFunc @@ -34,6 +35,7 @@ type Handlers struct { } func Register(router *gin.Engine, handlers Handlers) { + router.GET("/health", handlers.Health) router.GET("/", handlers.Index) router.GET("/box/:id", handlers.ShowBox) diff --git a/lib/server/server.go b/lib/server/server.go index fe4b6a3..d9cfcbf 100644 --- a/lib/server/server.go +++ b/lib/server/server.go @@ -48,6 +48,7 @@ func Run(addr string) error { router.SetHTMLTemplate(htmlTemplates) routing.Register(router, routing.Handlers{ + Health: app.handleHealth, Index: app.handleIndex, ShowBox: app.handleShowBox, BoxLogin: handleBoxLogin, @@ -114,3 +115,9 @@ func applyBoxstoreRuntimeConfig(cfg *config.Config) { boxstore.SetUploadRoot(cfg.UploadsDir) boxstore.SetOneTimeDownloadExpiry(cfg.OneTimeDownloadExpirySeconds) } + +func (app *App) handleHealth(c *gin.Context) { + c.JSON(200, gin.H{ + "status": "healthy", + }) +}