feat: add self-hosting support (Docker, NixOS, remote import)#241
Open
Razboy20 wants to merge 6 commits intoschej-it:mainfrom
Open
feat: add self-hosting support (Docker, NixOS, remote import)#241Razboy20 wants to merge 6 commits intoschej-it:mainfrom
Razboy20 wants to merge 6 commits intoschej-it:mainfrom
Conversation
- Add nix/server.nix: buildGoModule for Go server - Add nix/frontend.nix: buildNpmPackage for Vue frontend (Node.js 20) - Add nix/module.nix: NixOS module (systemd service + Podman MongoDB) - Rewrite flake.nix: packages, devShells, formatter, nixosModules - Update DEPLOYMENT.md: flake-based NixOS setup docs - Add flake.lock - Gitignore nix result symlink
.. as superfluous as it might be
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Self-hosting support
Adds first-class support for self-hosting Timeful, with two deployment options documented in
DEPLOYMENT.md.Docker Compose — The primary path. Adds
compose.yaml,Dockerfiles for the server and frontend, and aCaddyfile.examplefor the reverse proxy. The server now handles a missing.envfile gracefully (env vars can be passed directly via Docker), and Cloud Tasks initialization no longer panics if unconfigured — it just disables itself with a log message.NixOS flake — A
nix/directory contains native Nix derivations for the Go server and Vue frontend, plus a NixOS module that wires up a systemd service and a Podman-managed MongoDB instance. Consuming it is a one-liner flake input.Import from remote instance — Adds a "Import from URL" flow (
POST /api/events/import) so users can copy an event from another Timeful instance into their own. Useful when migrating or federating between self-hosted deployments.Infrastructure
compose.yaml— three services:mongo(with healthcheck),frontend(build-only, copies dist to a shared volume),server(waits on both, mounts the dist read-only)server/Dockerfile/frontend/Dockerfile— multi-stage builds; server copies pre-built frontend dist at runtime via Docker volumeCaddyfile.example— reverse proxy to:3002with gzip/zstd, security headers, www redirectserver/main.go— CORS middleware commented out (handled by reverse proxy); frontend dist path now auto-detects./frontend/dist(Docker layout) before falling back to../frontend/dist(local dev); missing frontend dist is a warning, not a fatalnix/server.nix,nix/frontend.nix—buildGoModuleandbuildNpmPackagederivations; client IDs passed as build args so they're baked into the frontend bundlenix/module.nix— NixOS module withservices.timeful.{enable, domain, envFile, enableCaddy, googleClientId, microsoftClientId}options; optionally configures Caddy virtualHost; MongoDB viavirtualisation.oci-containersFrontend
sign_in_utils.js— Google and Microsoft OAuth client IDs moved from hardcoded strings toVUE_APP_GOOGLE_CLIENT_ID/VUE_APP_MICROSOFT_CLIENT_IDenv vars (set at build time via Docker build args or.env)TimefulImportDialog.vue— new dialog: paste a remote event URL, calls/api/events/import, emits the new event ID on successHome.vue— wires up the import dialog behind the existing event-creation menuConfig / server
server/.env.template— template for required env varsserver/routes/events.go— newPOST /api/events/importendpoint: validates URL scheme, fetches the remote event and its responses via the public API, clones them locally under the authenticated userserver/services/gcloud/tasks.go— graceful no-op whenSERVICE_ACCOUNT_KEY_PATHis unset or"?"; initialization failure logs and returns instead of panicking