# Palette
Palette is a fast, self-hosted pastebin. One Go binary, a SQLite database, and
a web UI for sharing text and small files.
> [!NOTE]
>
|
> ✨ This project was built by AI — GLM 5.3 Flash on the Hermes Agent harness, with a human in the loop.
> |
## Features
- Text pastes and cans (multiple items in one share)
- File attachments (one file per paste, up to 25 MB)
- Password protected pastes
- Expire after a specified time
- Burn after a number of views
- Custom URLs
- Syntax highlighting with language auto-detection (go-enry)
- Public paste listing with search, sort and pagination
- Cookie based saved pastes and settings
- Five base themes (midnight, smooth, pastel-lavender, pastel-peach, pastel-cloud), each with a dark and light variant
- Dark mode toggle in the topbar and settings, with a configurable default
- Polished code viewer: line-number gutter sized to the widest number and pinned during horizontal scroll, optional line wrap, jump-to-top/bottom buttons, and theme-aware scrollbars
## Screenshots
| | |
|---|---|
|  |  |
|  |  |
## Get Started
### Docker
```bash
docker run -p 8080:8080 -v palette-data:/data git.archfox.org/poslop/palette
```
The SQLite database lives in the `/data` volume inside the container.
## Docker Compose
See [docker-compose.yml](docker-compose.yml) for a ready-to-use example with
every environment variable documented, including which are required (only the
/data volume) and which are optional.
### Build from source
Requires Go 1.27+.
```bash
go build -o palette ./cmd/palette
./palette
# open http://localhost:8080
```
## Configuration
| Setting | Default | Description |
|---|---|---|
| `PALETTE_ADDR` | `:8080` | Listen address |
| `PALETTE_DB` | `palette.db` | SQLite database path |
| `PALETTE_MAX_TEXT` | `5242880` | Max paste size in bytes (5 MB) |
| `PALETTE_MAX_ITEM` | `26214400` | Max can item / file attachment size in bytes (25 MB) |
| `PALETTE_ADMIN_KEY` | generated | Admin key; if unset a 32-char hex key is generated and persisted to `/admin-key` (0600) |
| `PALETTE_DEFAULT_DARK` | dark on | Default dark mode for new visitors. Set `false`, `0`, or `off` to default to light mode. Visitors who toggle dark mode keep their choice in their browser. |
| `PALETTE_UNLOCK_SECRET` | random per start | HMAC secret for password-unlock cookies. Set a fixed value to keep unlock sessions across restarts or across replicas. |
| `PALETTE_TRUSTED_IP_HEADER` | unset | Name of a proxy-controlled client-IP header to key API rate limits on (e.g. `CF-Connecting-IP` when Cloudflare is the ingress; Cloudflare strips any client-supplied value). Unset: rate limits key on the peer address only, and all client-supplied IP headers (X-Forwarded-For, X-Real-Ip) are ignored. (#280) |
An `/admin` page exists for runtime settings, protected by a key set at
install (`PALETTE_ADMIN_KEY` env var) and resettable locally. See
[API](https://git.archfox.org/poslop/palette/wiki/API) and the [design docs](https://git.archfox.org/poslop/palette/wiki/Home) in the wiki for details.
## API
Full REST API: [wiki/API](https://git.archfox.org/poslop/palette/wiki/API). One example:
```bash
curl -X POST http://localhost:8080/api/pastes -d '{"content":"hello"}'
```
Design docs: [wiki/design](https://git.archfox.org/poslop/palette/wiki/design-attachments-storage) (e2e encryption, attachments & storage, cookie preferences).
## License
Palette is licensed under the GNU Affero General Public License v3.0
(AGPL-3.0-only). See [LICENSE](LICENSE).
The software is provided AS IS, without warranty of any kind, express or
implied, including merchantability and fitness for a particular purpose.
In no event shall the authors be liable for any claim, damages, or other
liability, including without limitation any security vulnerabilities,
data loss, or legal issues arising from use of the software. You use it
at your own risk.
If you run a modified version of Palette as a network service, the AGPL
requires you to offer your modified source code to its users.