Toshiki's Avatar
A modern, self-hosted, privacy-friendly Gravatar alternative. Serve your own avatars with deterministic mapping, robust API, and zero external dependencies.
1: Introduction
toshi-avatar is a drop-in replacement for Gravatar, designed for privacy and control. Host your own avatar server, map email hashes to images you choose, and integrate seamlessly with any app that supports Gravatar URLs.
1.1: Why?
- Fuck gravatar, despite open source, too hefty and overkill for a avatar server for my blog's comment system (Artalk/Waline/Valine), and it sucks to the oblivion, it makes my stoamch it makes my stomach churn like I just swallowed a bucket of spoiled code wrapped in XML from 2008.
- Many users want custom, themed, or anime avatars.
- This project gives you full control, with a simple, robust Go backend and no external dependencies, in one single binary exectable wihtout extra library, no bullshit, that's it.
2: Features
- Self-hosted: Run anywhere Go runs (Linux, macOS, Windows, Docker, etc.)
- No external dependencies: Pure Go, no C libraries or system image tools required
- Deterministic mapping: Each email hash always maps to the same avatar
- Custom avatar pool: Use your own images (anime, icons, etc.)
- Gravatar-compatible API: Works as a drop-in replacement
- Multiple formats: PNG and JPEG output
- Image resizing:
?s=<size>query for dynamic resizing - JSON metadata:
?format=jsonorAccept: application/json - Health check endpoint:
/healthzfor monitoring - Robust CLI: Helpful flags, error handling, and usage info
- Modular codebase: Easy to extend and maintain
3: Architecture
┌────────────┐ ┌──────────────┐ ┌──────────────┐
│ Client │ <--> │ Avatar │ <--> │ Avatar Pool │
└────────────┘ └──────────────┘ └──────────────┘
| | |
| Gravatar URL | |
| (md5 hash) | |
|----------------->| |
| | Loads images from |
| | local directory |
| |----------------------->|
| | |
| Returns avatar | |
|<-----------------| |
4: Installation
4.1: Prerequisites
- Go 1.18 or newer
- A directory of avatar images (PNG or JPEG)
4.2: Clone and Build
git clone https://github.com/andatoshiki/toshiki-avatar.git
cd toshiki-avatar
go mod tidy
go build -o toshiki-avatar main.go
5: Configuration
The server is configured via CLI flags:
| Flag | Description | Default |
|---|---|---|
-p | Port to listen on | 9090 |
-t | Output image type (png or jpg) | png |
-d | Directory containing avatar images | ./webp |
-h | Show help and usage |
Example:
./toshiki-avatar -p 8080 -t jpg -d ./avatars
6: Usage
6.1: Start the Server
./toshiki-avatar -p 9090 -t png -d ./webp
6.2: Example Avatar Pool
Place your images in the directory specified by -d. Supported formats: .png, .jpg, .jpeg, .webp (if enabled).
7: API Reference
7.1: Get Avatar Image
GET /avatar/<md5hash>?s=<size>
<md5hash>: MD5 hash of the user's email (lowercased, trimmed)s: Optional, image size in pixels (default: 128)
Example:
http://localhost:9090/avatar/7b7bc2512ee1fedcd76bdc68926d4f7b?s=256
7.2: Get Avatar Metadata (JSON)
GET /avatar/<md5hash>?format=json&s=<size>
Response:
{
"hash": "7b7bc2512ee1fedcd76bdc68926d4f7b",
"url": "http://localhost:9090/avatar/7b7bc2512ee1fedcd76bdc68926d4f7b?s=256",
"path": "./avatars/03.png",
"size": 256,
"type": "png"
}
7.3: Health Check
7.4: Get Random Avatar
GET /random?s=<size>
- Returns a random avatar from the pool.
s: Optional, image size in pixels (default: 128)
Example:
http://localhost:9090/random?s=128
GET /healthz
Returns 200 OK if the server is running.
8: Deployment
8.1: Systemd Service Example
Create a file /etc/systemd/system/toshiki-avatar.service:
[Unit]
Description=Toshiki Avatar Server
After=network.target
[Service]
ExecStart=/path/to/toshiki-avatar -p 9090 -t png -d /path/to/avatars
Restart=always
User=www-data
Group=www-data
WorkingDirectory=/path/to
[Install]
WantedBy=multi-user.target
8.2: Docker (Unofficial)
You can build a Docker image using the provided Dockerfile (if available) or create your own:
FROM golang:1.18-alpine AS build
WORKDIR /app
COPY . .
RUN go build -o toshiki-avatar main.go
FROM alpine:latest
WORKDIR /app
COPY --from=build /app/toshiki-avatar .
COPY ./webp ./webp
EXPOSE 9090
ENTRYPOINT ["./toshiki-avatar", "-p", "9090", "-t", "png", "-d", "./webp"]
9: Troubleshooting
- No avatars returned: Ensure the
-ddirectory exists and contains valid images. - Invalid image format: Only PNG and JPEG are supported by default. WebP support requires pure-Go library.
- Port already in use: Change the
-pflag to a free port. - Permission denied: Make sure the server has read access to the avatar directory.
- API returns 404: The hash may not map to any image if the pool is empty.
10: FAQ
Q: Can I use this as a Gravatar drop-in?
A: Yes! Just swap the Gravatar domain for your own server in any app that supports Gravatar URLs.
Q: How does the mapping work?
A: The server deterministically maps each email hash to an image in your pool, so the same email always gets the same avatar.
Q: Can I use animated images?
A: Not currently. Only static PNG/JPEG/WebP are supported.
Q: How do I add more avatars?
A: Just drop new images into the avatar directory and restart (or reload) the server.
Q: Is there a web UI?
A: Not in the backend. You can build a frontend using the API.
11: License
MIT. See LICENSE.