A lightweight HTTP proxy server written in Go that serves files from MinIO object storage. It acts as a simple nginx-like reverse proxy for MinIO, particularly optimized for HLS video streaming.
nginx-minio-proxy bridges HTTP clients and MinIO object storage, providing a simple REST API interface for accessing MinIO objects. It's designed for scenarios where you want to serve files from MinIO without exposing MinIO directly or requiring S3 API authentication from clients.
┌─────────────┐ ┌──────────────────────┐ ┌─────────────┐
│ Client │ │ nginx-minio-proxy │ │ MinIO │
│ (Browser/ │ │ (Go + Gin Web) │ │ Storage │
│ Player) │ │ │ │ │
└──────┬──────┘ └──────────┬───────────┘ └──────┬──────┘
│ │ │
│ GET /minio/video.m3u8 │ │
│──────────────────────────>│ │
│ │ │
│ │ GetObject(bucket, key) │
│ │───────────────────────────>│
│ │ │
│ │ <Stream Object Data> │
│ │<───────────────────────────│
│ │ │
│ <Stream HTTP Response> │ │
│<──────────────────────────│ │
│ Content-Type: application/ │
│ vnd.apple.mpegurl │ │
│ │ │
The proxy transforms HTTP paths into MinIO object keys:
HTTP Request Path: /minio/videos/stream1/playlist.m3u8
↓
Stripped Prefix: videos/stream1/playlist.m3u8
↓
Config Prefix (hls): hls/videos/stream1/playlist.m3u8
↓
MinIO Object Key: hls/videos/stream1/playlist.m3u8
Configuration Example:
- Proxy URL:
http://localhost:7050/minio/* - Config Prefix:
hls - MinIO Bucket:
videos - MinIO Host:
minio.example.com:9000
- Simple HTTP Proxy - Expose MinIO objects via clean HTTP URLs
- HLS Streaming Optimized - Automatic Content-Type detection for .m3u8 and .ts files
- Memory Efficient - Direct streaming without buffering entire files
- Flexible Path Mapping - Configurable object prefix support
- Secure Connections - Support for both HTTP and HTTPS MinIO backends
- Cross-Platform - Works on Linux, macOS, Windows (single static binary)
- Zero Dependencies - No external runtime dependencies required
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Video Player │─────>│ nginx-minio- │─────>│ MinIO │
│ (Web/App) │ HTTP │ proxy │ S3 │ (HLS Files) │
└──────────────┘ └──────────────┘ └──────────────┘
│
├─ /minio/stream1/index.m3u8
├─ /minio/stream1/segment-0.ts
└─ /minio/stream1/segment-1.ts
Benefits:
- No S3 authentication required from clients
- Standard HTTP URLs work with any video player
- Automatic MIME type handling for HLS files
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Website │─────>│ nginx-minio- │─────>│ MinIO │
│ (Static) │ │ proxy │ │ (Assets CDN) │
└──────────────┘ └──────────────┘ └──────────────┘
│ │
├─ /minio/images/logo.png
├─ /minio/css/style.css
└─ /minio/js/app.js
Benefits:
- Simple URL structure for static assets
- No need for S3 SDK in frontend code
- Easy integration with existing web applications
Download the latest release from the releases page and extract:
tar -xzvf nginx-minio-proxy-linux-amd64.tar.gz
cd nginx-minio-proxy-linux-amd64Requirements: Go 1.24.8 or higher
git clone https://github.com/shenhailuanma/nginx-minio-proxy.git
cd nginx-minio-proxy
go build -o nginx-minio-proxy main.goOr use the build script for cross-compilation:
# Build for Linux AMD64
bash base.sh linux amd64
# Build for Linux ARM64
bash base.sh linux arm64
# Build for macOS
bash base.sh darwin amd64
bash base.sh darwin arm64
# Build all targets
bash build-all.shCreate a JSON configuration file (e.g., nginx-minio-proxy.json):
{
"port": 7050,
"host": "minio.example.com:9000",
"bucket": "mybucket",
"prefix": "video/hls",
"ak": "your_access_key",
"sk": "your_secret_key",
"encrypt": false
}| Field | Type | Required | Description |
|---|---|---|---|
port |
int | No | HTTP server port (default: 7050) |
host |
string | Yes | MinIO server host and port |
bucket |
string | Yes | MinIO bucket name |
prefix |
string | No | Object prefix path (default: empty) |
ak |
string | Yes | MinIO access key |
sk |
string | Yes | MinIO secret key |
encrypt |
bool | No | Use HTTPS for MinIO connection (default: false) |
./nginx-minio-proxy -c /path/to/config.json -p 7050-c: Path to configuration file (default:/etc/nginx-minio-proxy.json)-p: Server port (default: 7050, overridden by config file if present)
Once the server is running, access your files via:
http://localhost:7050/minio/path/to/file.m3u8
http://localhost:7050/minio/video/segment001.ts
The /minio/ prefix is stripped and combined with the configured prefix to form the MinIO object key.
Example:
- Request:
http://localhost:7050/minio/stream/playlist.m3u8 - Config prefix:
video/hls - MinIO object key:
video/hls/stream/playlist.m3u8
Perfect for serving HLS video streams from MinIO:
# Configure with video prefix
{
"host": "minio.example.com:9000",
"bucket": "videos",
"prefix": "hls",
...
}
# Access HLS playlist
http://localhost:7050/minio/stream1/index.m3u8The proxy automatically sets correct Content-Types:
.m3u8files →application/vnd.apple.mpegurl.tsfiles →video/mp2t
Serve any static files from MinIO:
http://localhost:7050/minio/images/photo.jpg
http://localhost:7050/minio/documents/file.pdfThe project includes systemd service configuration for production deployment:
# Service management
sudo systemctl start nginx-minio-proxy
sudo systemctl stop nginx-minio-proxy
sudo systemctl restart nginx-minio-proxy
sudo systemctl status nginx-minio-proxy
# Enable auto-start on boot
sudo systemctl enable nginx-minio-proxy
# View logs
sudo tail -f /var/log/nginx-minio-proxy/nginx-minio-proxy.logManual installation files:
- Service file: nginx-minio-proxy.service
- Logrotate config: logrotate.conf
Build and run using Docker:
# Build Docker image
docker build -t nginx-minio-proxy:latest .
# Run container with config file mounted
docker run -d \
--name nginx-minio-proxy \
-p 7050:7050 \
-v /path/to/nginx-minio-proxy.json:/etc/nginx-minio-proxy.json:ro \
nginx-minio-proxy:latest
# View logs
docker logs -f nginx-minio-proxyOr using docker-compose:
version: '3.8'
services:
nginx-minio-proxy:
image: nginx-minio-proxy:latest
build: .
ports:
- "7050:7050"
volumes:
- ./nginx-minio-proxy.json:/etc/nginx-minio-proxy.json:ro
restart: unless-stopped
healthcheck:
test: ["CMD", "wget", "--spider", "-q", "http://localhost:7050/minio/health"]
interval: 30s
timeout: 3s
retries: 3- Framework: Gin web framework
- Storage Client: MinIO Go SDK v7
- Streaming: Direct streaming from MinIO to HTTP response (no memory buffering)
- Deployment: Single static binary with vendored dependencies
go run main.go -c nginx-minio-proxy.json -p 7050go get -u
go mod tidy
go mod vendorSee LICENSE file for details.
Contributions are welcome! Please feel free to submit a Pull Request.