diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index a4fcc4d..57dfc88 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -14,4 +14,5 @@ jobs: git init -q . && git fetch -q --depth 1 "https://git.rehbock.xyz/${{ github.repository }}.git" "${{ github.sha }}" && git checkout -q FETCH_HEAD - run: bun install --frozen-lockfile - run: bun run typecheck + - run: bun run build:web - run: bun test server diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..cc96c16 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,16 @@ +FROM oven/bun:1 AS build +WORKDIR /app +COPY package.json bun.lock* ./ +COPY server/package.json server/ +COPY web/package.json web/ +COPY shared/package.json shared/ +RUN bun install --frozen-lockfile +COPY . . +RUN bun run build:web + +FROM oven/bun:1-slim +WORKDIR /app +COPY --from=build /app /app +ENV DATA_DIR=/data +EXPOSE 3000 +CMD ["bun", "server/src/index.ts"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..32e98b9 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,8 @@ +services: + helios: + build: . + ports: + - "3000:3000" + volumes: + - ./data:/data + restart: unless-stopped diff --git a/docs/deploy.md b/docs/deploy.md new file mode 100644 index 0000000..f6f23b6 --- /dev/null +++ b/docs/deploy.md @@ -0,0 +1,17 @@ +# Deploying Helios + + git clone https://git.rehbock.xyz/marcus/helios.git && cd helios + docker compose up -d + +Open http://your-host:3000 and create the instance password. + +Back up the `./data` directory — it holds the SQLite DB, uploads, and +`secret.key`. Without `secret.key` your stored API keys are unrecoverable. +Run the host disk encrypted; Helios encrypts credentials column-level but +not the whole DB file. + +## Reverse proxy (Caddy) + + helios.example.com { + reverse_proxy localhost:3000 + } diff --git a/server/src/app.ts b/server/src/app.ts index 4f2cb51..da2b03d 100644 --- a/server/src/app.ts +++ b/server/src/app.ts @@ -1,5 +1,6 @@ import { Hono } from "hono"; import { getCookie } from "hono/cookie"; +import { serveStatic } from "hono/bun"; import type { Db } from "./db"; import { authRoutes, isAuthenticated } from "./routes/auth"; import { settingsRoutes } from "./routes/settings"; @@ -20,5 +21,7 @@ export function createApp(deps: Deps) { app.route("/api", authRoutes({ db: deps.db })); app.route("/api", settingsRoutes(deps)); // Later route groups (connectors, chat) mount here. + app.use("/*", serveStatic({ root: "./web/dist" })); + app.get("/*", serveStatic({ path: "./web/dist/index.html" })); return app; }