Skip to content

Commit 7c2505b

Browse files
committed
Update install.sh
1 parent 8275dfe commit 7c2505b

File tree

1 file changed

+158
-25
lines changed

1 file changed

+158
-25
lines changed

install.sh

Lines changed: 158 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,13 @@ ENV_FILE="${FULA_CONFIG}/.env"
2626
NGINX_CONF="/etc/nginx/sites-available/fula-gateway"
2727
NGINX_ENABLED="/etc/nginx/sites-enabled/fula-gateway"
2828

29-
# Default values
30-
DEFAULT_GATEWAY_PORT="8080"
29+
# Default values (must match Dockerfile defaults)
30+
DEFAULT_GATEWAY_PORT="9000"
3131
DEFAULT_IPFS_PORT="5001"
3232
DEFAULT_IPFS_GATEWAY_PORT="8081"
33+
DEFAULT_MAX_BODY_SIZE="5368709120" # 5GB
34+
DEFAULT_RATE_LIMIT_RPS="100"
35+
DEFAULT_REQUEST_TIMEOUT="3600" # 1 hour for large uploads
3336

3437
# Logging
3538
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
@@ -244,6 +247,13 @@ collect_configuration() {
244247
# Gateway port
245248
prompt_env "GATEWAY_PORT" "Gateway internal port" "${GATEWAY_PORT:-$DEFAULT_GATEWAY_PORT}"
246249

250+
# Performance settings
251+
echo ""
252+
log_info "Performance Settings"
253+
prompt_env "MAX_BODY_SIZE" "Max upload size in bytes (default 5GB)" "${MAX_BODY_SIZE:-$DEFAULT_MAX_BODY_SIZE}"
254+
prompt_env "RATE_LIMIT_RPS" "Rate limit requests per second" "${RATE_LIMIT_RPS:-$DEFAULT_RATE_LIMIT_RPS}"
255+
prompt_env "REQUEST_TIMEOUT" "Request timeout in seconds" "${REQUEST_TIMEOUT:-$DEFAULT_REQUEST_TIMEOUT}"
256+
247257
# Confirm
248258
echo ""
249259
echo "==========================================="
@@ -286,14 +296,20 @@ OAUTH_AUDIENCE=${OAUTH_AUDIENCE:-}
286296
CORS_ENABLED=true
287297
CORS_ORIGINS=${CORS_ORIGINS}
288298
289-
# Gateway Settings
290-
GATEWAY_PORT=${GATEWAY_PORT}
291-
RUST_LOG=info,fula_cli=debug
299+
# Gateway Settings (FULA_PORT must match Dockerfile)
300+
FULA_HOST=0.0.0.0
301+
FULA_PORT=${GATEWAY_PORT}
302+
RUST_LOG=info,fula_cli=debug,fula_core=debug
303+
304+
# Performance Settings
305+
MAX_BODY_SIZE=${MAX_BODY_SIZE}
306+
RATE_LIMIT_RPS=${RATE_LIMIT_RPS}
307+
REQUEST_TIMEOUT=${REQUEST_TIMEOUT}
292308
293309
# IPFS Configuration
294310
IPFS_URL=http://localhost:5001
295311
296-
# Pinning Service (optional)
312+
# Pinning Service (optional - gateway-level pinning for all uploads)
297313
PINNING_SERVICE_ENDPOINT=${PINNING_SERVICE_ENDPOINT:-}
298314
PINNING_SERVICE_TOKEN=${PINNING_SERVICE_TOKEN:-}
299315
EOF
@@ -312,24 +328,47 @@ create_docker_compose() {
312328
if [[ -n "${IPFS_DOMAIN}" ]] && [[ "${IPFS_RUNNING}" != "true" ]]; then
313329
IPFS_SERVICE="
314330
ipfs:
315-
image: ipfs/kubo:latest
331+
image: ipfs/kubo:v0.32.1
316332
container_name: fula-ipfs
317333
restart: unless-stopped
318334
volumes:
319335
- ${FULA_HOME}/ipfs:/data/ipfs
320336
ports:
321337
- '127.0.0.1:5001:5001'
322338
- '127.0.0.1:8081:8080'
339+
- '4001:4001' # Swarm TCP
340+
- '4001:4001/udp' # Swarm QUIC
323341
environment:
324342
- IPFS_PROFILE=server
343+
command: ['daemon', '--migrate=true', '--enable-gc']
344+
deploy:
345+
resources:
346+
limits:
347+
memory: 4G
348+
reservations:
349+
memory: 1G
325350
healthcheck:
326351
test: ['CMD-SHELL', 'ipfs id || exit 1']
327352
interval: 30s
328353
timeout: 10s
329354
retries: 3
355+
logging:
356+
driver: json-file
357+
options:
358+
max-size: '100m'
359+
max-file: '3'
330360
"
331361
fi
332362

363+
# Determine depends_on based on IPFS configuration
364+
local DEPENDS_ON=""
365+
if [[ -n "${IPFS_DOMAIN}" ]] && [[ "${IPFS_RUNNING}" != "true" ]]; then
366+
DEPENDS_ON="
367+
depends_on:
368+
ipfs:
369+
condition: service_healthy"
370+
fi
371+
333372
cat > "${FULA_CONFIG}/docker-compose.yml" << EOF
334373
version: '3.8'
335374
@@ -340,18 +379,33 @@ services:
340379
restart: unless-stopped
341380
env_file:
342381
- ${ENV_FILE}
382+
environment:
383+
# Override IPFS URL to use Docker network
384+
- IPFS_API_URL=http://ipfs:5001
343385
volumes:
344386
- ${FULA_HOME}/data:/var/lib/fula/data
345387
ports:
346388
- '127.0.0.1:${GATEWAY_PORT}:${GATEWAY_PORT}'
347-
depends_on:
348-
${IPFS_DOMAIN:+ipfs:}
349-
${IPFS_DOMAIN:+ condition: service_healthy}
389+
deploy:
390+
resources:
391+
limits:
392+
memory: 2G
393+
reservations:
394+
memory: 512M
350395
healthcheck:
351-
test: ['CMD', 'curl', '-f', 'http://localhost:${GATEWAY_PORT}/']
396+
# Use HEAD request to health check endpoint (more efficient)
397+
test: ['CMD', 'curl', '-f', '-X', 'HEAD', 'http://localhost:${GATEWAY_PORT}/']
352398
interval: 30s
353399
timeout: 10s
354400
retries: 3
401+
start_period: 30s
402+
logging:
403+
driver: json-file
404+
options:
405+
max-size: '100m'
406+
max-file: '5'
407+
# Graceful shutdown - allow time for in-flight requests
408+
stop_grace_period: 30s${DEPENDS_ON}
355409
${IPFS_SERVICE}
356410
networks:
357411
default:
@@ -370,9 +424,15 @@ configure_nginx() {
370424
# Gateway nginx config
371425
cat > "${NGINX_CONF}" << EOF
372426
# Fula Gateway - Rate Limiting
373-
limit_req_zone \$binary_remote_addr zone=fula_limit:10m rate=100r/s;
427+
limit_req_zone \$binary_remote_addr zone=fula_limit:10m rate=${RATE_LIMIT_RPS}r/s;
374428
limit_conn_zone \$binary_remote_addr zone=fula_conn:10m;
375429
430+
# Upstream with keepalive connections
431+
upstream fula_gateway {
432+
server 127.0.0.1:${GATEWAY_PORT};
433+
keepalive 32;
434+
}
435+
376436
# Gateway Server
377437
server {
378438
listen 80;
@@ -384,35 +444,48 @@ server {
384444
add_header X-Content-Type-Options "nosniff" always;
385445
add_header X-XSS-Protection "1; mode=block" always;
386446
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
447+
add_header Content-Security-Policy "default-src 'self'" always;
387448
388449
# Rate limiting
389450
limit_req zone=fula_limit burst=50 nodelay;
390451
limit_conn fula_conn 20;
391452
392-
# Request size limit (for large uploads, adjust as needed)
453+
# Request size limit (for large uploads)
393454
client_max_body_size 5G;
394-
client_body_timeout 3600s;
395-
proxy_read_timeout 3600s;
396-
proxy_send_timeout 3600s;
455+
client_body_timeout ${REQUEST_TIMEOUT}s;
456+
proxy_read_timeout ${REQUEST_TIMEOUT}s;
457+
proxy_send_timeout ${REQUEST_TIMEOUT}s;
458+
send_timeout ${REQUEST_TIMEOUT}s;
459+
460+
# Increase buffer sizes for S3 clients that send many headers
461+
proxy_buffer_size 16k;
462+
proxy_buffers 4 32k;
463+
proxy_busy_buffers_size 64k;
464+
large_client_header_buffers 4 32k;
397465
398466
location / {
399-
proxy_pass http://127.0.0.1:${GATEWAY_PORT};
467+
proxy_pass http://fula_gateway;
400468
proxy_http_version 1.1;
401469
proxy_set_header Host \$host;
402470
proxy_set_header X-Real-IP \$remote_addr;
403471
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
404472
proxy_set_header X-Forwarded-Proto \$scheme;
405473
proxy_set_header Connection "";
406474
407-
# Buffering settings for large files
475+
# Disable buffering for streaming uploads/downloads
408476
proxy_buffering off;
409477
proxy_request_buffering off;
478+
479+
# Pass through all S3 headers
480+
proxy_pass_request_headers on;
410481
}
411482
412-
# Health check endpoint (no rate limit)
413-
location = /health {
483+
# Health check endpoint (no rate limit, efficient HEAD request)
484+
location = /_health {
414485
limit_req off;
415-
proxy_pass http://127.0.0.1:${GATEWAY_PORT}/;
486+
limit_conn off;
487+
proxy_pass http://fula_gateway/;
488+
proxy_method HEAD;
416489
}
417490
}
418491
EOF
@@ -502,7 +575,8 @@ configure_firewall() {
502575

503576
# Allow IPFS swarm if running local IPFS
504577
if [[ -n "${IPFS_DOMAIN}" ]] && [[ "${IPFS_RUNNING}" != "true" ]]; then
505-
ufw allow 4001/tcp # IPFS swarm
578+
ufw allow 4001/tcp # IPFS swarm TCP
579+
ufw allow 4001/udp # IPFS swarm QUIC
506580
fi
507581

508582
ufw --force enable
@@ -569,6 +643,40 @@ EOF
569643
log_success "Systemd service created"
570644
}
571645

646+
# Configure IPFS settings for optimal performance
647+
configure_ipfs_settings() {
648+
if [[ -z "${IPFS_DOMAIN}" ]] && [[ "${IPFS_RUNNING}" != "true" ]]; then
649+
return 0
650+
fi
651+
652+
log_info "Configuring IPFS settings..."
653+
654+
# Wait for IPFS to be ready
655+
local retries=30
656+
while ! curl -s http://localhost:5001/api/v0/id > /dev/null 2>&1; do
657+
retries=$((retries - 1))
658+
if [[ $retries -eq 0 ]]; then
659+
log_warn "IPFS not responding, skipping configuration"
660+
return 0
661+
fi
662+
sleep 2
663+
done
664+
665+
# Configure IPFS for production
666+
# Increase connection limits
667+
curl -s -X POST "http://localhost:5001/api/v0/config?arg=Swarm.ConnMgr.LowWater&arg=100&json=true" > /dev/null
668+
curl -s -X POST "http://localhost:5001/api/v0/config?arg=Swarm.ConnMgr.HighWater&arg=400&json=true" > /dev/null
669+
curl -s -X POST "http://localhost:5001/api/v0/config?arg=Swarm.ConnMgr.GracePeriod&arg=60s&json=true" > /dev/null
670+
671+
# Enable QUIC transport
672+
curl -s -X POST "http://localhost:5001/api/v0/config?arg=Swarm.Transports.Network.QUIC&arg=true&json=true" > /dev/null
673+
674+
# Increase API timeout for large operations
675+
curl -s -X POST "http://localhost:5001/api/v0/config?arg=API.HTTPHeaders.Access-Control-Allow-Origin&arg=[\"*\"]&json=true" > /dev/null
676+
677+
log_success "IPFS configured for production"
678+
}
679+
572680
# Start services
573681
start_services() {
574682
log_info "Starting services..."
@@ -579,6 +687,9 @@ start_services() {
579687
# Wait for services to start
580688
sleep 5
581689

690+
# Configure IPFS if running
691+
configure_ipfs_settings
692+
582693
log_success "Services started"
583694
}
584695

@@ -603,12 +714,22 @@ verify_installation() {
603714
log_warn "Gateway container not yet running (may be pulling image)"
604715
fi
605716

606-
# Check gateway health (via localhost)
717+
# Check gateway health (via localhost) using HEAD request
607718
sleep 10
608-
if curl -s http://localhost:${GATEWAY_PORT}/ > /dev/null 2>&1; then
719+
if curl -s -X HEAD -o /dev/null -w "%{http_code}" http://localhost:${GATEWAY_PORT}/ | grep -q "200"; then
609720
log_success "Gateway responding on localhost:${GATEWAY_PORT}"
610721
else
611722
log_warn "Gateway not responding yet (may still be starting)"
723+
log_info "Check logs: docker compose -f ${FULA_CONFIG}/docker-compose.yml logs gateway"
724+
fi
725+
726+
# Check IPFS if configured
727+
if [[ -n "${IPFS_DOMAIN}" ]] || [[ "${IPFS_RUNNING}" == "true" ]]; then
728+
if curl -s http://localhost:5001/api/v0/id > /dev/null 2>&1; then
729+
log_success "IPFS daemon responding on localhost:5001"
730+
else
731+
log_warn "IPFS daemon not responding"
732+
fi
612733
fi
613734

614735
# Check SSL
@@ -637,7 +758,12 @@ verify_installation() {
637758
echo " Stop: systemctl stop fula-gateway"
638759
echo " Restart: systemctl restart fula-gateway"
639760
echo " Status: systemctl status fula-gateway"
640-
echo " Logs: journalctl -u fula-gateway -f"
761+
echo " Logs: docker compose -f ${FULA_CONFIG}/docker-compose.yml logs -f"
762+
echo ""
763+
echo "Configuration files:"
764+
echo " Environment: ${ENV_FILE}"
765+
echo " Docker: ${FULA_CONFIG}/docker-compose.yml"
766+
echo " Nginx: ${NGINX_CONF}"
641767
echo ""
642768

643769
if [[ ! "${IPFS_RUNNING}" == "true" ]] && [[ -z "${IPFS_DOMAIN}" ]]; then
@@ -648,6 +774,13 @@ verify_installation() {
648774
log_warn " 2. Re-run this script with an IPFS domain"
649775
fi
650776

777+
echo ""
778+
echo "Troubleshooting:"
779+
echo " View gateway logs: docker compose -f ${FULA_CONFIG}/docker-compose.yml logs gateway"
780+
echo " View IPFS logs: docker compose -f ${FULA_CONFIG}/docker-compose.yml logs ipfs"
781+
echo " Test health: curl -I https://${FULA_DOMAIN}/"
782+
echo " Rebuild image: cd /path/to/fula-api && docker build -t ghcr.io/functionland/fula-gateway:latest ."
783+
echo ""
651784
echo "==========================================="
652785

653786
if [[ $errors -gt 0 ]]; then

0 commit comments

Comments
 (0)