Skip to content

TheAlexRamirez/openinary-railway-template

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

13 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Openinary β€” Self-hosted Cloudinary Alternative

The open-source, self-hosted alternative to Cloudinary

On-the-fly image & video transformations Β· S3-compatible storage Β· Admin dashboard

Deploy on Railway

πŸ“¦ Last version tested: v0.1.8 (April 12, 2026)

Build Status Docker Pulls License: AGPL-3.0 Documentation


✨ What is Openinary?

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.

Features

  • πŸ–ΌοΈ 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

πŸš€ One-Click Deploy

Click the button below to deploy Openinary to Railway in under 2 minutes:

Deploy on Railway

After deploying, visit https://your-app.up.railway.app/setup to create your admin account.


βš™οΈ Post-Deploy Setup (3 steps)

  1. Open your app URL β€” Railway provides it automatically after deploy
  2. Visit /setup β€” create your admin account (only available once, on first run)
  3. Generate an API key β€” go to your profile β†’ API Keys β†’ Create Key

That's it. Your Openinary instance is ready to process media! πŸŽ‰


πŸ“Έ URL Transformation Examples

Openinary uses a URL-based API. Just prepend /t/<params>/ to your media path.

Images

# 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

Videos

# 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.mp4

☁️ S3 Storage Compatibility

Openinary works with any S3-compatible storage provider. Configure these environment variables in your Railway project:

Cloudflare R2

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.com

Wasabi

STORAGE_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-name

AWS S3

STORAGE_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.com

MinIO / DigitalOcean Spaces / Other

STORAGE_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

πŸ”§ Environment Variables

πŸ–₯️ Server

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.

πŸ” Authentication

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.

πŸͺ£ Storage (S3-compatible)

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 ⚠️ Non-AWS S3-compatible endpoint (required for R2, Wasabi, MinIO, etc.)
STORAGE_PUBLIC_URL βœ… Yes Public URL to serve stored files (CDN or bucket URL)

🎬 Video Processing

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)

🐳 Docker Resources

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)

πŸ—οΈ Architecture

This template uses the official openinary/openinary Docker image β€” a single container running:

  • Nginx β€” reverse proxy, routes /api and / 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.


πŸ’Ύ Persistent Volume (Required)

⚠️ 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:

  1. Go to your service β†’ Volumes tab
  2. Click Add Volume
  3. Set the Mount Path to /app/data
  4. Save and redeploy

πŸ“š Resources

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

🏷️ Supported Docker Version

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 update ARG IMAGE_TAG in Dockerfile.


πŸ“„ License

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

About

πŸš€ One-click Railway template for Openinary β€” self-hosted, open-source alternative to Cloudinary. On-the-fly image & video transformations with S3-compatible storage.

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors