DEV Community

I Made Ocy Darma Putra
I Made Ocy Darma Putra

Posted on

Self-Hosted Docker Registry on Your Own SFTP: Introducing Refity

refity

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 push and docker 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 pull commands.
  • 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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

2. Run with Docker Compose

docker-compose up -d
Enter fullscreen mode Exit fullscreen mode

3. Use it

Push an image:

docker tag nginx localhost:5000/mygroup/nginx:latest
docker push localhost:5000/mygroup/nginx:latest
Enter fullscreen mode Exit fullscreen mode

Pull:

docker pull localhost:5000/mygroup/nginx:latest
Enter fullscreen mode Exit fullscreen mode

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-backend and troke12/refity-frontend on 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

If you try it and have feedback or ideas, open an issue or discussion on GitHub.

Top comments (0)