Chiyogami
Chiyogami is a sleek, modern pastebin with encryption, customizable expiry, private pastes, user accounts and an API for developers.
Screenshots:
β¨ Features
- β Beautiful & Responsive UI β Built with TailwindCSS & DaisyUI for a clean and modern look.
- π Syntax Highlighting β Automatic formatting with HighlightJS.
- π Markdown Rendering β Automatic formatting with Marked.
- β³ Configurable Expiry β Set custom expiration times with API.
- π Secure & Private β Client-side encryption with WebCrypto API for encrypted pastes. No password saved in server.
- π‘ Powerful API β Create and fetch pastes without leaving the terminal.
- π Public Pastes β List & search all public pastes.
- π Private Pastes β Only accessible via a unique, unguessable link for enhanced privacy (use encryption on web UI for ultimate privacy).
- π Local Storage β Uses SQLite for a lightweight, self-hostable database.
- π€ User Accounts β Create & manage your pastes with authentication.
- π Easy Sharing β Share paste links or scan a QR code for instant access.
- π‘ Built-in Rate Limiting β Protects against spam and abuse with smart request throttling.
- π³ Easy self-host with docker.
- π Multi-arch multi-platform builds. Support for AMD64, ARM64 on Windows(AMD64 only), Linux and MacOS.
- π¦
Standalonebinary will runfrontend(client) if project'spublicfolder exists in same directory. Otherwise theAPIjust works! - π§°
Non-standalone(chiyogami) runs thefull-featuredself-containedbinary.
Installation
Docker. Build it or check docker-compose file for example with pre-built images.
Releases contain 2 variants of portable go builds: chiyogami-* and chiyogami-standalone-* both of which will serve the frontend client and API or just the API respectively.
Quick run
docker run -d \
-v "$(pwd)/pastes:/pastes" \
-p 127.0.0.1:8000:8000 \
--restart unless-stopped \
ghcr.io/rhee876527/chiyogami:latest
Environment variables
| Env | Default value | Note |
|---|---|---|
| SECRET_KEY | None | Session key. Keep secure and unique. Recommended example: openssl rand -base64 32. |
| PASTE_DEFAULT_EXPIRATION | 24h | Valid time units are βnsβ, βusβ (or βΒ΅sβ), βmsβ, βsβ, βmβ, βhβ or "Never" |
| MAX_CHAR_CONTENT | 50000 | Maximum characters allowed in content body. Larger limits may offer reduced performance |
| DISABLE_RATE_LIMIT | None | Use 1 to disable rate limit |
| CREATE_PER_MIN | 10 | No of paste creation, register, login, delete account & delete paste requests allowed per minute |
| DATABASE_PATH | None | For local development use. Conflicts with docker volume paths. |
| DELETE_RETENTION | 90 | Number of days to keep soft-deleted pastes. Valid values: 1-99 |
| COMPLEX_PASSWORD | None | Use 1 to activate. Requires complex password on user registration. Valid password: Minimum 8 characters, including at least 1 lowercase, 1 uppercase, 1 number and 1 symbol. |
| ADMIN_CONTACT | None | Accepts email values. May be useful for moderation purposes. |
| PORT | None | Customize default port. Ignored in Docker build. |
Note about exposing /health to public
Since v1.4.3 this healthcheck endpoint was created to actively monitor state of application's database. It has potential for abuse WHEN exposed publicly. Caution is hereby given to protect endpoint (http://localhost:8000/health) from external access as necessary.
If using Traefik as reverse proxy this can be done in the docker-compose file by adding the following middleware:
...
services:
chiyogami:
labels:
- "traefik.http.routers.chiyogami.middlewares=localonly-health"
- "traefik.http.middlewares.localonly-health.replacepathregex.regex=^/health$"
- "traefik.http.middlewares.localonly-health.replacepathregex.replacement=/nonexistent-path"
...
Usage
Web UI is simple & straightforward. Or use the API.
Create paste
FILE
curl http://localhost:8000/paste -T sample.txt
or JSON
curl -X POST \
http://localhost:8000/paste \
-H 'Content-Type: application/json' \
-d '{"content":"Test paste"}'
response: {"title":"OkxI"}
Note: Pastes are created by default with Public visibility. They can be accessed from api or website.
Change this to Private or Unlisted to make the paste undiscoverable. Pastes are also set to expire within 24hrs if expiry is not specified.
You can set a default expiry for new pastes with PASTE_DEFAULT_EXPIRATION.
Create private paste with 48h expiry
curl -X POST \
http://localhost:8000/paste \
-H 'Content-Type: application/json' \
-d '{"content":"Test", "visibility":"Private", "expiration":"48h"}'
response: {"title":"euVa"}
Fetch created paste
curl -X GET http://localhost:8000/paste/bZTR -H "Accept: application/json"
response:
{"ID":22,"CreatedAt":"2025-02-04T19:48:06.747679947Z","UpdatedAt":"2025-02-04T19:48:06.747679947Z","DeletedAt":null,"Title":"bZTR","Content":"test private","Visibility":"Private","Expiration":"2025-02-05T19:48:06.747635027Z","IsEncrypted":false,"UserID":0,"IsUserPaste":false}
Create user account
curl -X POST \
http://localhost:8000/register \
-H 'Content-Type: application/json' \
-d '{"username":"test", "password":"test"}'
response: {"message":"User registered successfully"}
Delete owner paste using session (from cookies)
curl -X DELETE http://localhost:8000/paste/EIKq \
-b "session=MTczNzA2NDI5NXxEWDhFQVFMX2dBQUJFQUVRQUFBZl80QUFBUVp6ZEhKcGJtY01DUUFIZFhObGNsOXBaQVIxYVc1MEJnSUFEQT09fLnhi2OxsN6coY5ZmmBeA0tPXUcsKiii6ECOoJ7yrqNC"
response: {"message":"Paste deleted successfully"}
Get instance configuration
curl http://localhost:8000/info
response: {"ADMIN_CONTACT":"[email protected]","DELETE_RETENTION":90,"MAX_CHAR_CONTENT":50000,"PASTE_DEFAULT_EXPIRATION":"24h"}
COPYRIGHT
This software is free to use in accordance with the license.