If you want a private Docker registry but don't want to depend on a cloud registry or object storage, Refity might be what you need. It's a small, self-hosted registry that uses SFTP as the only backend for your images. Everything—blobs, manifests, metadata—lives on your SFTP server. No S3, no GCS, no vendor lock-in.
I built Refity for myself that already have SFTP (rent from Hetzner Storage Box) and want to reuse it for container images without adding another storage system.
Why SFTP?
- You already have SFTP (e.g. Hetzner Storage Box, shared hosting, or your own server).
- You want to avoid cloud object storage and its pricing/complexity.
- You need something that works in locked-down or legacy environments where only SSH/SFTP is allowed.
- You prefer one place for backups and access control (your existing SFTP).
Refity doesn't replace your SFTP; it uses it as the only storage backend.
What Refity Does
-
Docker Registry API v2 — Standard
docker pushanddocker pull; works with existing tools and CI. - SFTP-only storage — All layers and manifests are stored on your SFTP server; the app only coordinates and serves them.
-
Web UI — A React app to browse groups, repositories, and tags, create/delete repos, and copy
docker pullcommands. - Auth — JWT-based login; you can put the backend behind your own proxy/VPN for extra security.
- One-command deploy — Backend + frontend with Docker Compose; optional env vars for production (JWT secret, CORS, SSH host verification).
So: a classic "registry in front of your own storage" with a simple UI and no new storage stack.
Quick Start
1. Clone and configure
git clone https://github.com/troke12/refity.git
cd refity
cp .env.example .env
Edit .env with your SFTP details and (for production) a JWT_SECRET:
FTP_HOST=your-sftp.example.com
FTP_PORT=22
FTP_USERNAME=sftpuser
FTP_PASSWORD=sftppass
JWT_SECRET=your-long-random-secret # required in production
2. Run with Docker Compose
docker-compose up -d
3. Use it
-
Web UI: http://localhost:8080 (default login:
admin/admin— change it right away). - Registry: http://localhost:5000
Push an image:
docker tag nginx localhost:5000/mygroup/nginx:latest
docker push localhost:5000/mygroup/nginx:latest
Pull:
docker pull localhost:5000/mygroup/nginx:latest
Groups and repositories are created from the UI (or you can align with how you organize folders on SFTP). No auto-creation of top-level paths; you keep control over structure and access.
Tech Stack
- Backend: Go — Registry v2 + REST API, SQLite for metadata, JWT auth.
- Frontend: React + Vite, served by nginx in Docker.
-
Images:
troke12/refity-backendandtroke12/refity-frontendon Docker Hub (tags:latest,v1.0.0).
Who It's For
- Small teams or solo devs who want a private registry without cloud dependencies.
- Environments where SFTP is the only or preferred storage (e.g. existing storage boxes or restricted networks).
- Anyone who likes to self-host and keep image storage under their control.
Links
- GitHub: github.com/troke12/refity
- Docker Hub: refity-backend · refity-frontend
If you try it and have feedback or ideas, open an issue or discussion on GitHub.

Top comments (0)