#!/bin/bash set -euo pipefail # ============================================================================= # RustFS S3-Compatible Storage - Startup Script # ============================================================================= : "${DATA_DIR:=/data}" : "${S3_PORT:=9000}" : "${CONSOLE_PORT:=9001}" : "${APP_PORT:=7860}" : "${RUSTFS_ACCESS_KEY:=admin}" : "${RUSTFS_SECRET_KEY:=verysecret}" : "${DEFAULT_BUCKET:=storage}" : "${CLIENT_MAX_BODY_SIZE:=0}" : "${WORKER_CONNECTIONS:=1024}" : "${NGINX_LOG_LEVEL:=error}" : "${ALLOWED_ORIGINS:=*}" echo "===== RustFS Startup =====" echo "Version: $(rustfs --version | head -n1)" mkdir -p "${DATA_DIR}" /etc/rustfs /var/log/rustfs # Configure CORS for nginx if [ "${ALLOWED_ORIGINS}" = "*" ]; then CORS_ORIGIN_VALUE='$http_origin' echo "CORS: Allowing all origins (wildcard)" elif [ -z "${ALLOWED_ORIGINS}" ]; then CORS_ORIGIN_VALUE='' echo "CORS: Disabled" else CORS_ORIGIN_VALUE="${ALLOWED_ORIGINS}" echo "CORS: Allowing specific origins: ${ALLOWED_ORIGINS}" fi # Generate nginx config with environment variables echo "Configuring nginx..." sed -e "s|\${S3_PORT}|${S3_PORT}|g" \ -e "s|\${CONSOLE_PORT}|${CONSOLE_PORT}|g" \ -e "s|\${APP_PORT}|${APP_PORT}|g" \ -e "s|\${CLIENT_MAX_BODY_SIZE}|${CLIENT_MAX_BODY_SIZE}|g" \ -e "s|\${WORKER_CONNECTIONS}|${WORKER_CONNECTIONS}|g" \ -e "s|\${NGINX_LOG_LEVEL}|${NGINX_LOG_LEVEL}|g" \ -e "s|\${CORS_ORIGIN_VALUE}|${CORS_ORIGIN_VALUE}|g" \ /etc/nginx/nginx.conf > /tmp/nginx.conf && mv /tmp/nginx.conf /etc/nginx/nginx.conf echo "S3 credentials configured:" echo " Access Key: ${RUSTFS_ACCESS_KEY}" echo " Secret Key: [HIDDEN]" # Start RustFS server echo "Starting RustFS server..." rustfs \ --address ":${S3_PORT}" \ --console-enable \ --console-address ":${CONSOLE_PORT}" \ --access-key "${RUSTFS_ACCESS_KEY}" \ --secret-key "${RUSTFS_SECRET_KEY}" \ "${DATA_DIR}" \ > /var/log/rustfs/rustfs.log 2>&1 & RUSTFS_PID=$! echo "RustFS started with PID: ${RUSTFS_PID}" # Wait for RustFS to be ready echo "Waiting for RustFS to start..." for i in {1..30}; do # Check if process is still running if ! kill -0 $RUSTFS_PID 2>/dev/null; then echo "ERROR: RustFS process died!" echo "===== RustFS Logs =====" cat /var/log/rustfs/rustfs.log exit 1 fi # Check if RustFS is responding (any HTTP response is good, even errors) if curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:${S3_PORT}/ 2>/dev/null | grep -q .; then echo "✓ RustFS S3 API is ready" break fi if [ $i -eq 30 ]; then echo "ERROR: RustFS failed to start in 30 seconds" echo "===== RustFS Logs =====" cat /var/log/rustfs/rustfs.log exit 1 fi echo " Attempt $i/30..." sleep 1 done # Wait for Console to be ready for i in {1..10}; do if curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:${CONSOLE_PORT}/ 2>/dev/null | grep -q .; then echo "✓ RustFS Console is ready" break fi sleep 1 done echo "===== RustFS Services Ready =====" echo "Access URLs:" echo " - S3 API: http://localhost:${APP_PORT}/" echo " - Console: http://localhost:${APP_PORT}/console/" echo " - Health: http://localhost:${APP_PORT}/health" echo "=============================" # Test nginx configuration echo "Testing nginx configuration..." if ! nginx -t; then echo "ERROR: Nginx configuration test failed!" nginx -t 2>&1 exit 1 fi echo "✓ Nginx configuration is valid" # Start nginx echo "Starting nginx..." nginx echo "✓ Nginx started" # Wait for nginx to be ready echo "Waiting for nginx to be ready..." for i in {1..20}; do if ! pgrep nginx >/dev/null; then echo "ERROR: Nginx is not running!" tail -50 /var/log/nginx/error.log 2>/dev/null || echo "No error log found" exit 1 fi if curl -sf http://127.0.0.1:${APP_PORT}/health >/dev/null 2>&1; then echo "✓ Nginx is ready and responding" break fi if [ $i -eq 20 ]; then echo "ERROR: Nginx not responding after 20 seconds" ps aux | grep nginx exit 1 fi sleep 1 done # Create default bucket (after nginx is running) echo "Creating default bucket: ${DEFAULT_BUCKET}..." sleep 2 # Use mc (MinIO Client) to create bucket with read-only policy # First, install mc if needed if ! command -v mc &> /dev/null; then echo "Installing MinIO Client (mc)..." wget -qO /usr/local/bin/mc https://dl.min.io/client/mc/release/linux-amd64/mc chmod +x /usr/local/bin/mc fi # Configure mc to use RustFS mc alias set rustfs http://localhost:${S3_PORT} ${RUSTFS_ACCESS_KEY} ${RUSTFS_SECRET_KEY} || true # Create bucket mc mb rustfs/${DEFAULT_BUCKET} 2>/dev/null || echo "Bucket may already exist" # Set bucket to public read-only (anonymous users can only read/download) # This policy allows: GetObject, ListBucket for anonymous users # But requires authentication for PutObject, DeleteObject cat > /tmp/public-read-policy.json << EOF { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": {"AWS": ["*"]}, "Action": ["s3:GetObject"], "Resource": ["arn:aws:s3:::${DEFAULT_BUCKET}/*"] }, { "Effect": "Allow", "Principal": {"AWS": ["*"]}, "Action": ["s3:ListBucket"], "Resource": ["arn:aws:s3:::${DEFAULT_BUCKET}"] } ] } EOF # Apply bucket policy mc anonymous set-json /tmp/public-read-policy.json rustfs/${DEFAULT_BUCKET} 2>/dev/null || echo "Policy may already be set" # Upload a test file echo 'Welcome to RustFS Storage! This bucket is read-only for public access.' > /tmp/test.txt mc cp /tmp/test.txt rustfs/${DEFAULT_BUCKET}/test.txt 2>/dev/null || echo "Test file already exists" echo "" echo "✓ Bucket initialization complete!" echo " - Bucket: ${DEFAULT_BUCKET}" echo " - Policy: Public Read-Only" echo " - Test file: test.txt uploaded" echo " - Status: Ready for operations" echo "===== Setup complete, monitoring services =====" # Keep container running - monitor RustFS and nginx while true; do if ! kill -0 $RUSTFS_PID 2>/dev/null; then echo "ERROR: RustFS died!" exit 1 fi if ! pgrep nginx >/dev/null; then echo "ERROR: Nginx died!" exit 1 fi sleep 30 done