diff --git a/.dockerignore b/.dockerignore
index 317f5d4..44cd24c 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -2,7 +2,6 @@
.github
docs
node_modules
-frontend/dist
backend/filetree
backend/filetree.exe
*.md
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 8a7d916..c4b89bd 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -2,6 +2,8 @@ name: CI
on:
push:
+ tags:
+ - 'v*'
pull_request:
release:
types: [published]
@@ -105,6 +107,12 @@ jobs:
- name: Build
run: cd frontend && npm run build
+ - name: Upload frontend artifact
+ uses: actions/upload-artifact@v4
+ with:
+ name: frontend-dist
+ path: frontend/dist
+
docker-build:
name: Build
runs-on: ubuntu-latest
@@ -129,14 +137,20 @@ jobs:
docker-push:
name: Push
runs-on: ubuntu-latest
- needs: [docker-build]
- if: (github.event_name == 'push' && github.ref == 'refs/heads/main') || github.event_name == 'release'
+ needs: [docker-build, frontend]
+ if: (github.event_name == 'push' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v'))) || github.event_name == 'release'
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v6
+ - name: Download frontend artifact
+ uses: actions/download-artifact@v4
+ with:
+ name: frontend-dist
+ path: frontend/dist
+
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
@@ -162,10 +176,10 @@ jobs:
type=ref,event=branch
type=sha,prefix=sha-
flavor: |
- latest=${{ github.event_name == 'release' && !github.event.release.prerelease || (github.event_name == 'push' && github.ref == 'refs/heads/main') }}
+ latest=${{ github.event_name == 'release' && !github.event.release.prerelease || (github.event_name == 'push' && (github.ref == 'refs/heads/main' || (startsWith(github.ref, 'refs/tags/v') && !contains(github.ref_name, '-')))) }}
- name: Set platforms
- if: github.event_name == 'release'
+ if: github.event_name == 'release' || (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v'))
run: echo "PLATFORMS=linux/amd64,linux/arm64,linux/arm/v7" >> $GITHUB_ENV
- name: Build and push image
@@ -174,7 +188,7 @@ jobs:
context: .
file: ./Containerfile
push: true
- platforms: ${{ github.event_name == 'release' && env.PLATFORMS || 'linux/amd64' }}
+ platforms: ${{ (github.event_name == 'release' || (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v'))) && env.PLATFORMS || 'linux/amd64' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
diff --git a/Containerfile b/Containerfile
index 3f8b883..5f89fd5 100644
--- a/Containerfile
+++ b/Containerfile
@@ -1,9 +1,8 @@
FROM node:20-alpine AS frontend
WORKDIR /app/frontend
-COPY frontend/package*.json ./
-RUN npm ci
COPY frontend/ ./
-RUN npm run build
+ENV NODE_OPTIONS="--max-old-space-size=4096"
+RUN if [ ! -f dist/index.html ]; then npm ci && npm run build; fi
FROM golang:1.25-alpine AS backend
WORKDIR /app
diff --git a/docs/assets/styles/home.css b/docs/assets/styles/home.css
index eb48ff8..94cefcb 100644
--- a/docs/assets/styles/home.css
+++ b/docs/assets/styles/home.css
@@ -1,6 +1,7 @@
[data-md-color-scheme="default"] {
--md-primary-fg-color: #2a2438;
--md-primary-bg-color: #fff;
+ --md-typeset-a-color: #5488e8;
}
[data-md-color-scheme="slate"] {
diff --git a/docs/getting-started/index.md b/docs/getting-started/index.md
index e67e6b1..4b3b796 100644
--- a/docs/getting-started/index.md
+++ b/docs/getting-started/index.md
@@ -5,47 +5,88 @@ icon: material/rocket-launch
# Getting Started
-You're minutes away from a self-hosted file manager. No database to configure, no cloud sign-up, no vendor lock-in — just a single binary and a config file. Your files stay under your control.
+Filetree is minimalistic, self-hosted file manager. No database to configure, no cloud sign-up, no vendor lock-in — just a single binary and a config file. Your files stay under your control.
-## Why Filetree?
+## From homelab to open source
-- **Minimal setup** — Build once, run anywhere. One process serves both the API and the web UI.
-- **No database** — Everything lives in a YAML or JSON file. Add users, toggle auth providers, and adjust settings without migrations or extra services.
-- **Fast and lightweight** — Built with Go. Starts in milliseconds, uses little memory. Copy the binary and `frontend/dist` to deploy.
-- **Works everywhere** — Responsive interface for desktop, tablet, and mobile. Access your files from any browser.
+Filetree started as a simple homelab project — a way to browse and manage files on my home server without exposing it to the cloud or dealing with heavy, database-backed alternatives. I wanted something minimal: one binary, a config file and control over my own data.
+
+Over time, it grew, I added auth, previews, signed URLs, and an admin UI. What began as a personal tool became something I thought others might find useful. If you're running a homelab, a small team server, or just want your files under your control, Filetree is for you.
-## Prerequisites
+## Features
-- **Go 1.21+** — For the backend
-- **Node.js 18+** — For building the frontend assets (only needed at build time; not required at runtime)
+- **Minimal setup** — Build once, run anywhere. Single binary or a small Container image.
+- **No database** — No complex setup, everything lives in a [config](/configuration) file. Add local users, toggle auth providers, and adjust settings without migrations or extra services.
+- **Fast and lightweight** — Built with Go. Starts in milliseconds, uses little memory.
+- **Works everywhere** — Responsive interface for desktop, tablet, and mobile. Access your files from any browser.
+- **Browse & manage** — Create folders, rename, move, copy, delete (with trash). Drag-and-drop to upload.
+- **Rich previews** — Images, video, audio, PDF, Markdown, JSON, CSV, HTML, text — preview in the browser.
+- **Secure auth** — Sign in with Google, GitHub, or local users. JWT-based sessions.
+- **Signed URLs** — Share short-lived links for previews and downloads. Time-limited, no long-lived links.
+- **Admin UI** — Manage auth providers and users from the Settings page. No config editing required.
## Quick start
-From the project root:
+## Quick start
-```bash
-make build
-ROOT_PATH=./data ./backend/filetree
-```
+=== "Single binary"
-Open **http://localhost:8080**. You'll see the file manager — browse, upload, preview, and manage files from your browser. Drag-and-drop uploads, rich previews for images and documents, and a folder tree for quick navigation.
+ **Download** pre-built binaries from [GitHub Releases](https://github.com/heapoftrash/filetree/releases/latest). Extract the archive, copy `frontend/dist` next to the binary, then:
-## What's next?
+ ```bash
+ ROOT_PATH=./data ./filetree
+ ```
-| Step | What to do |
-|------|------------|
-| [Installation](installation.md) | Choose your path: make, Docker, from source, or development mode with hot reload |
-| [Production](production.md) | Deploy to a server — reverse proxy, HTTPS, and production config |
-| [Configuration](../configuration/index.md) | Set up your config file and environment variables |
-| [Authentication](../authentication/index.md) | Enable Google OAuth, GitHub OAuth, or local username/password |
+ Or build from source:
-## Features at a glance
+ ```bash
+ make build
+ ROOT_PATH=./data ./backend/filetree
+ ```
-- **Browse & manage** — Create folders, rename, move, copy, delete (with trash). Drag-and-drop to upload.
-- **Rich previews** — Images, video, audio, PDF, Markdown, JSON, CSV, HTML, text — preview in the browser.
-- **Secure auth** — Sign in with Google, GitHub, or local users. JWT-based sessions.
-- **Signed URLs** — Share short-lived links for previews and downloads. Time-limited, no long-lived links.
-- **Admin UI** — Manage auth providers and users from the Settings page. No config editing required.
+ For production:
+
+ ```bash
+ ROOT_PATH=/path/to/files CONFIG_FILE=./config.yaml ./filetree
+ ```
+
+=== "Container image recommended"
+
+ The prebuilt OCI complaint container image is a great way to get up and running in a few minutes, as it comes with all dependencies pre-installed.
+ **Pull** the pre-built image from [GitHub Container Registry](https://github.com/heapoftrash/filetree/pkgs/container/filetree):
+
+ ```bash
+ docker pull ghcr.io/heapoftrash/filetree:latest
+ docker run -p 8080:8080 -v /path/to/files:/data ghcr.io/heapoftrash/filetree:latest
+ ```
+
+ Or build from source:
+
+ ```bash
+ docker build -f Containerfile -t filetree .
+ docker run -p 8080:8080 -v /path/to/files:/data filetree
+ ```
+
+ Then open **http://localhost:8080**. Use `ghcr.io/heapoftrash/filetree:v1.0.0` for a specific version.
+
+=== "From git"
+
+ Filetree can be directly used from GitHub by cloning the repository into a subfolder of your project root which might be useful if you want to use the very latest version:
+
+ Clone and build from source:
+ ```bash
+ git clone https://github.com/heapoftrash/filetree.git
+ cd filetree
+ ```
+ Build the frontend and backend:
+ ```bash
+ make build
+ ```
+ Run from the project root:
+ ```bash
+ ROOT_PATH=./data ./backend/filetree
+ ```
+ Then open **http://localhost:8080**.
## Open source