On-the-fly image & video transformations Β· S3-compatible storage Β· Admin dashboard
π¦ Last version tested: v0.1.8 (April 12, 2026)
Openinary is a self-hosted media processing platform β a powerful open-source alternative to Cloudinary. It lets you deliver perfectly optimized images and videos through simple URL-based transformations, without paying per-transformation fees.
Deploy it once on Railway, point it at your S3-compatible bucket, and start transforming media instantly.
- πΌοΈ Image transformations β resize, crop, convert, optimize (WebP, AVIF, JPEG, PNG)
- π¬ Video processing β resize, compress, clip, thumbnail extraction, format conversion
- βοΈ S3-compatible storage β works with AWS S3, Cloudflare R2, Wasabi, MinIO, DigitalOcean Spaces
- β‘ Smart caching β processed media is cached and served at edge speed
- π Authentication β built-in admin dashboard with API key management
- π³ Docker-native β one image, zero dependencies
- π URL-based API β no SDK required, works from any language or framework
Click the button below to deploy Openinary to Railway in under 2 minutes:
After deploying, visit
https://your-app.up.railway.app/setupto create your admin account.
- Open your app URL β Railway provides it automatically after deploy
- Visit
/setupβ create your admin account (only available once, on first run) - Generate an API key β go to your profile β API Keys β Create Key
That's it. Your Openinary instance is ready to process media! π
Openinary uses a URL-based API. Just prepend /t/<params>/ to your media path.
# Resize to 800Γ600 and convert to WebP
GET /t/w_800,h_600,f_webp,q_80/photo.jpg
# Smart crop with face detection
GET /t/w_400,h_400,c_fill,g_face/portrait.jpg
# Convert to AVIF with quality optimization
GET /t/w_1200,h_800,f_avif,q_80/banner.jpg
# Aspect ratio with auto-detection
GET /t/ar_16:9,g_auto,w_1920,h_1080/hero.jpg
# Thumbnail (small, WebP, fast)
GET /t/w_400,f_webp/path/to/image.png# Resize + web-optimized compression
GET /t/w_1280,h_720,q_75/video.mp4
# Full HD with format conversion
GET /t/w_1920,h_1080,f_mp4/video.mov
# Extract a clip (10s to 30s)
GET /t/so_10,eo_30/interview.mp4
# Thumbnail frame at 5 seconds as AVIF
GET /t/w_800,h_450,so_5,f_avif/video.mp4
# Lightweight preview (low quality, small file)
GET /t/w_480,h_270,q_50/demo.mp4Openinary works with any S3-compatible storage provider. Configure these environment variables in your Railway project:
STORAGE_REGION=auto
STORAGE_ACCESS_KEY_ID=your_r2_access_key
STORAGE_SECRET_ACCESS_KEY=your_r2_secret_key
STORAGE_BUCKET_NAME=your-bucket-name
STORAGE_ENDPOINT=https://YOUR_ACCOUNT_ID.r2.cloudflarestorage.com
STORAGE_PUBLIC_URL=https://your-custom-domain.comSTORAGE_REGION=us-east-1
STORAGE_ACCESS_KEY_ID=your_wasabi_access_key
STORAGE_SECRET_ACCESS_KEY=your_wasabi_secret_key
STORAGE_BUCKET_NAME=your-bucket-name
STORAGE_ENDPOINT=https://s3.wasabisys.com
STORAGE_PUBLIC_URL=https://s3.wasabisys.com/your-bucket-nameSTORAGE_REGION=us-east-1
STORAGE_ACCESS_KEY_ID=your_aws_access_key
STORAGE_SECRET_ACCESS_KEY=your_aws_secret_key
STORAGE_BUCKET_NAME=your-bucket-name
STORAGE_PUBLIC_URL=https://your-bucket-name.s3.us-east-1.amazonaws.comSTORAGE_REGION=us-east-1
STORAGE_ACCESS_KEY_ID=your_access_key
STORAGE_SECRET_ACCESS_KEY=your_secret_key
STORAGE_BUCKET_NAME=your-bucket-name
STORAGE_ENDPOINT=https://your-s3-compatible-endpoint.com
STORAGE_PUBLIC_URL=https://your-cdn-or-bucket-url.com| Variable | Default | Description |
|---|---|---|
NODE_ENV |
production |
Node.js runtime mode. Keep as production. |
IMAGE_TAG |
v0.1.8 |
Openinary Docker image version. Update in Dockerfile ARG IMAGE_TAG. |
| Variable | Required | Description |
|---|---|---|
BETTER_AUTH_SECRET |
β‘ Auto | π Secret for auth tokens. Auto-generated if empty. Manual: openssl rand -base64 32 |
BETTER_AUTH_URL |
β‘ Auto | π Your public URL. Auto-configured from Railway's domain if empty. |
| Variable | Required | Description |
|---|---|---|
STORAGE_REGION |
β Yes | S3 region (us-east-1, auto for R2) |
STORAGE_ACCESS_KEY_ID |
β Yes | S3 access key from your provider |
STORAGE_SECRET_ACCESS_KEY |
β Yes | S3 secret key from your provider |
STORAGE_BUCKET_NAME |
β Yes | Name of your S3 bucket |
STORAGE_ENDPOINT |
S3-compatible endpoint (required for R2, Wasabi, MinIO, etc.) | |
STORAGE_PUBLIC_URL |
β Yes | Public URL to serve stored files (CDN or bucket URL) |
| Variable | Default | Description |
|---|---|---|
VIDEO_MAX_CONCURRENT |
auto | Concurrent video jobs (auto: 1 per 2GB RAM) |
VIDEO_JOB_RETRY_MAX |
3 |
Max retries for failed video jobs |
VIDEO_JOB_CLEANUP_HOURS |
24 |
Hours before completed jobs are removed |
VIDEO_WORKER_POLL_INTERVAL_MS |
1000 |
Worker queue polling interval (ms) |
| Variable | Default | Description |
|---|---|---|
DOCKER_CPU_LIMIT |
2.0 |
Max CPU cores for the container |
DOCKER_MEMORY_LIMIT |
4G |
Max memory (e.g. 2048m, 4G, 12G) |
This template uses the official openinary/openinary Docker image β a single container running:
- Nginx β reverse proxy, routes
/apiand/traffic - Openinary API β media transformation engine (Node.js + FFmpeg)
- Openinary Web β admin dashboard (Next.js)
- SQLite β local database for auth (persisted via Railway volume)
For production workloads, Railway's persistent volumes keep your data safe across deploys.
β οΈ This volume is required. Without it, your admin account, API keys and all metadata are wiped on every redeploy.
| Mount Path | Purpose |
|---|---|
/app/data |
SQLite database β admin accounts, API keys, metadata |
The railway.toml in this repo configures the volume automatically:
[[volumes]]
name = "openinary-db"
mountPath = "/app/data"If you're deploying manually via the Railway dashboard:
- Go to your service β Volumes tab
- Click Add Volume
- Set the Mount Path to
/app/data - Save and redeploy
| Link | Description |
|---|---|
| π Documentation | Full Openinary docs |
| π GitHub Repository | Source code & issues |
| π³ Docker Hub | Official Docker image |
| π Railway Docs | Railway platform docs |
| π¦ Twitter / X | Updates from the creator |
This template is tested and verified with openinary/openinary:v0.1.8 (April 12, 2026).
π¦ Release Notes Β· All Releases
β οΈ To update to a newer version: check the releases page and updateARG IMAGE_TAGinDockerfile.
This Railway template is licensed under the MIT License.
Openinary itself is licensed under AGPL-3.0.
Made with β€οΈ for the self-hosted community Β Β·Β Deploy on Railway