Finished BUD 1
This commit is contained in:
233
config/deploy.sh
Executable file
233
config/deploy.sh
Executable file
@@ -0,0 +1,233 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
# Ginxsom Deployment Script
|
||||
# This script sets up the ginxsom blossom server configuration
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
log_info() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
log_warn() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
check_root() {
|
||||
if [[ $EUID -eq 0 ]]; then
|
||||
log_error "This script should not be run as root. Please run as a regular user with sudo access."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
check_dependencies() {
|
||||
log_info "Checking dependencies..."
|
||||
|
||||
if ! command -v nginx &> /dev/null; then
|
||||
log_error "nginx is not installed. Please install nginx first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v systemctl &> /dev/null; then
|
||||
log_error "systemctl is not available. This script requires systemd."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "Dependencies check passed."
|
||||
}
|
||||
|
||||
create_directories() {
|
||||
log_info "Creating required directories..."
|
||||
|
||||
# Create data directories
|
||||
sudo mkdir -p /var/lib/ginxsom/files
|
||||
sudo mkdir -p /var/lib/ginxsom/db
|
||||
sudo mkdir -p /run/ginxsom
|
||||
sudo mkdir -p /var/log/ginxsom
|
||||
sudo mkdir -p /etc/ginxsom
|
||||
|
||||
log_info "Directories created."
|
||||
}
|
||||
|
||||
create_user() {
|
||||
log_info "Creating ginxsom user..."
|
||||
|
||||
if ! id "ginxsom" &>/dev/null; then
|
||||
sudo useradd --system --no-create-home --shell /bin/false ginxsom
|
||||
log_info "User 'ginxsom' created."
|
||||
else
|
||||
log_info "User 'ginxsom' already exists."
|
||||
fi
|
||||
}
|
||||
|
||||
set_permissions() {
|
||||
log_info "Setting file permissions..."
|
||||
|
||||
# Set ownership of data directories
|
||||
sudo chown -R ginxsom:ginxsom /var/lib/ginxsom
|
||||
sudo chown -R ginxsom:ginxsom /run/ginxsom
|
||||
sudo chown -R ginxsom:ginxsom /var/log/ginxsom
|
||||
sudo chown -R ginxsom:ginxsom /etc/ginxsom
|
||||
|
||||
# Set proper permissions
|
||||
sudo chmod 755 /var/lib/ginxsom
|
||||
sudo chmod 755 /var/lib/ginxsom/files
|
||||
sudo chmod 755 /var/lib/ginxsom/db
|
||||
sudo chmod 755 /run/ginxsom
|
||||
sudo chmod 755 /var/log/ginxsom
|
||||
sudo chmod 755 /etc/ginxsom
|
||||
|
||||
log_info "Permissions set."
|
||||
}
|
||||
|
||||
deploy_nginx_config() {
|
||||
log_info "Deploying nginx configuration..."
|
||||
|
||||
# Copy nginx configuration
|
||||
sudo cp "$SCRIPT_DIR/nginx/ginxsom.conf" /etc/nginx/sites-available/ginxsom
|
||||
|
||||
# Enable the site
|
||||
if [[ ! -L /etc/nginx/sites-enabled/ginxsom ]]; then
|
||||
sudo ln -sf /etc/nginx/sites-available/ginxsom /etc/nginx/sites-enabled/ginxsom
|
||||
log_info "Nginx site enabled."
|
||||
else
|
||||
log_info "Nginx site already enabled."
|
||||
fi
|
||||
|
||||
# Test nginx configuration
|
||||
if sudo nginx -t; then
|
||||
log_info "Nginx configuration test passed."
|
||||
else
|
||||
log_error "Nginx configuration test failed. Please check the configuration."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
deploy_systemd_service() {
|
||||
log_info "Deploying systemd service..."
|
||||
|
||||
# Copy systemd service file
|
||||
sudo cp "$SCRIPT_DIR/systemd/ginxsom.service" /etc/systemd/system/ginxsom.service
|
||||
|
||||
# Reload systemd
|
||||
sudo systemctl daemon-reload
|
||||
|
||||
log_info "Systemd service installed."
|
||||
}
|
||||
|
||||
create_sample_config() {
|
||||
log_info "Creating sample configuration..."
|
||||
|
||||
if [[ ! -f /etc/ginxsom/config.toml ]]; then
|
||||
sudo tee /etc/ginxsom/config.toml > /dev/null << 'EOF'
|
||||
# Ginxsom Blossom Server Configuration
|
||||
|
||||
[server]
|
||||
# FastCGI socket path
|
||||
socket = "/run/ginxsom/ginxsom.sock"
|
||||
|
||||
# Data directory for files
|
||||
data_dir = "/var/lib/ginxsom"
|
||||
|
||||
# Maximum file size in bytes (100MB)
|
||||
max_file_size = 104857600
|
||||
|
||||
[logging]
|
||||
level = "info"
|
||||
file = "/var/log/ginxsom/ginxsom.log"
|
||||
|
||||
[storage]
|
||||
# File storage directory
|
||||
files_dir = "/var/lib/ginxsom/files"
|
||||
|
||||
# Database file for metadata
|
||||
database = "/var/lib/ginxsom/db/ginxsom.db"
|
||||
|
||||
[auth]
|
||||
# Enable authentication for uploads
|
||||
require_auth = true
|
||||
|
||||
# Enable list endpoint
|
||||
enable_list = false
|
||||
|
||||
# Enable mirror endpoint
|
||||
enable_mirror = false
|
||||
EOF
|
||||
sudo chown ginxsom:ginxsom /etc/ginxsom/config.toml
|
||||
sudo chmod 640 /etc/ginxsom/config.toml
|
||||
log_info "Sample configuration created at /etc/ginxsom/config.toml"
|
||||
else
|
||||
log_info "Configuration file already exists at /etc/ginxsom/config.toml"
|
||||
fi
|
||||
}
|
||||
|
||||
show_status() {
|
||||
log_info "Deployment complete! Next steps:"
|
||||
echo ""
|
||||
echo "1. Build and install the ginxsom binary:"
|
||||
echo " cd $PROJECT_ROOT"
|
||||
echo " make build"
|
||||
echo " sudo make install"
|
||||
echo ""
|
||||
echo "2. Start the services:"
|
||||
echo " sudo systemctl enable ginxsom"
|
||||
echo " sudo systemctl start ginxsom"
|
||||
echo " sudo systemctl reload nginx"
|
||||
echo ""
|
||||
echo "3. Check status:"
|
||||
echo " sudo systemctl status ginxsom"
|
||||
echo " sudo systemctl status nginx"
|
||||
echo ""
|
||||
echo "4. Test the server:"
|
||||
echo " curl http://localhost/health"
|
||||
echo ""
|
||||
echo "Configuration files:"
|
||||
echo " - Nginx: /etc/nginx/sites-available/ginxsom"
|
||||
echo " - SystemD: /etc/systemd/system/ginxsom.service"
|
||||
echo " - Config: /etc/ginxsom/config.toml"
|
||||
echo ""
|
||||
}
|
||||
|
||||
main() {
|
||||
log_info "Starting ginxsom deployment..."
|
||||
|
||||
check_root
|
||||
check_dependencies
|
||||
create_user
|
||||
create_directories
|
||||
set_permissions
|
||||
deploy_nginx_config
|
||||
deploy_systemd_service
|
||||
create_sample_config
|
||||
show_status
|
||||
|
||||
log_info "Deployment script completed successfully!"
|
||||
}
|
||||
|
||||
# Parse command line arguments
|
||||
case "${1:-}" in
|
||||
--help|-h)
|
||||
echo "Usage: $0 [options]"
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " --help, -h Show this help message"
|
||||
echo ""
|
||||
echo "This script deploys the ginxsom blossom server configuration."
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
main "$@"
|
||||
;;
|
||||
esac
|
||||
109
config/local-nginx.conf
Normal file
109
config/local-nginx.conf
Normal file
@@ -0,0 +1,109 @@
|
||||
# Local Ginxsom Development Server Configuration
|
||||
# This configuration serves files directly from the local repo directory
|
||||
|
||||
# Main context - specify error log here to override system default
|
||||
error_log logs/error.log;
|
||||
pid logs/nginx.pid;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
# HTTP context
|
||||
http {
|
||||
# Basic settings
|
||||
sendfile on;
|
||||
tcp_nopush on;
|
||||
tcp_nodelay on;
|
||||
keepalive_timeout 65;
|
||||
types_hash_max_size 2048;
|
||||
|
||||
# MIME types
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
# Logging (relative to prefix directory)
|
||||
access_log logs/access.log;
|
||||
|
||||
# FastCGI upstream configuration
|
||||
upstream fastcgi_backend {
|
||||
server unix:/tmp/ginxsom-fcgi.sock;
|
||||
}
|
||||
|
||||
# Local development server
|
||||
server {
|
||||
listen 9001;
|
||||
server_name localhost;
|
||||
|
||||
# Root directory for blossom files (local blobs directory)
|
||||
root blobs;
|
||||
|
||||
# Maximum upload size (adjust as needed)
|
||||
client_max_body_size 100M;
|
||||
|
||||
# Security headers
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header X-Frame-Options DENY;
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
|
||||
# Handle GET and HEAD requests for blob files - Blossom compliant
|
||||
location ~ "^/([a-f0-9]{64}).*$" {
|
||||
limit_except HEAD GET {
|
||||
deny all;
|
||||
}
|
||||
|
||||
# Route HEAD requests to FastCGI via rewrite
|
||||
if ($request_method = HEAD) {
|
||||
rewrite ^/(.*)$ /fcgi-head/$1 last;
|
||||
}
|
||||
|
||||
# GET requests served directly with hash-only lookup
|
||||
try_files /$1* =404;
|
||||
|
||||
# Set appropriate headers for blobs
|
||||
add_header Cache-Control "public, max-age=31536000, immutable";
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header X-Frame-Options DENY;
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
}
|
||||
|
||||
# FastCGI handler for HEAD requests
|
||||
location ~ "^/fcgi-head/([a-f0-9]{64}).*$" {
|
||||
internal;
|
||||
fastcgi_pass fastcgi_backend;
|
||||
fastcgi_param REQUEST_METHOD HEAD;
|
||||
fastcgi_param REQUEST_URI /$1;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
fastcgi_param QUERY_STRING $query_string;
|
||||
fastcgi_param CONTENT_TYPE $content_type;
|
||||
fastcgi_param CONTENT_LENGTH $content_length;
|
||||
fastcgi_param SERVER_PROTOCOL $server_protocol;
|
||||
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
|
||||
fastcgi_param REMOTE_ADDR $remote_addr;
|
||||
fastcgi_param REMOTE_PORT $remote_port;
|
||||
fastcgi_param SERVER_ADDR $server_addr;
|
||||
fastcgi_param SERVER_PORT $server_port;
|
||||
fastcgi_param SERVER_NAME $server_name;
|
||||
}
|
||||
|
||||
|
||||
# Health check endpoint
|
||||
location /health {
|
||||
access_log off;
|
||||
return 200 "OK\n";
|
||||
add_header Content-Type text/plain;
|
||||
}
|
||||
|
||||
# List files endpoint for debugging
|
||||
location /debug/list {
|
||||
autoindex on;
|
||||
autoindex_format json;
|
||||
}
|
||||
|
||||
# Root redirect
|
||||
location = / {
|
||||
return 200 "Ginxsom Local Development Server\nTry: GET /<sha256>\nHealth: GET /health\n";
|
||||
add_header Content-Type text/plain;
|
||||
}
|
||||
}
|
||||
}
|
||||
131
config/nginx/ginxsom.conf
Normal file
131
config/nginx/ginxsom.conf
Normal file
@@ -0,0 +1,131 @@
|
||||
# Ginxsom Blossom Server Configuration
|
||||
# This configuration serves files directly via nginx for maximum performance
|
||||
# while handling authenticated operations through FastCGI
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name localhost; # Change this to your domain
|
||||
|
||||
# Root directory for blossom files (organized by SHA-256 hash)
|
||||
root /var/lib/ginxsom/files;
|
||||
|
||||
# Maximum upload size (adjust as needed)
|
||||
client_max_body_size 100M;
|
||||
|
||||
# Security headers
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header X-Frame-Options DENY;
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
|
||||
# Logging
|
||||
access_log /var/log/nginx/ginxsom_access.log;
|
||||
error_log /var/log/nginx/ginxsom_error.log;
|
||||
|
||||
# Static file serving - nginx handles this directly for maximum performance
|
||||
# Files are stored as: /var/lib/ginxsom/files/{first2chars}/{remaining_hash}
|
||||
location ~ ^/([a-f0-9]{64})$ {
|
||||
set $hash $1;
|
||||
set $prefix $1; # First 2 characters
|
||||
set $suffix $1; # Remaining characters
|
||||
|
||||
# Extract first 2 chars and remaining
|
||||
if ($hash ~ ^([a-f0-9]{2})([a-f0-9]{62})$) {
|
||||
set $prefix $1;
|
||||
set $suffix $2;
|
||||
}
|
||||
|
||||
try_files /$prefix/$suffix =404;
|
||||
|
||||
# Set proper content type based on file extension in metadata
|
||||
# This will be enhanced when we add metadata lookup
|
||||
add_header Content-Type application/octet-stream;
|
||||
add_header Cache-Control "public, max-age=31536000, immutable";
|
||||
}
|
||||
|
||||
# HEAD requests for file existence checking
|
||||
# This endpoint checks if a file exists and returns metadata
|
||||
location ~ ^/head/([a-f0-9]{64})$ {
|
||||
# Pass to FastCGI application for metadata lookup
|
||||
include fastcgi_params;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root/ginxsom.fcgi;
|
||||
fastcgi_param REQUEST_METHOD HEAD;
|
||||
fastcgi_param BLOSSOM_HASH $1;
|
||||
fastcgi_pass unix:/run/ginxsom/ginxsom.sock;
|
||||
}
|
||||
|
||||
# Upload endpoint - requires authentication
|
||||
location /upload {
|
||||
# Pass to FastCGI application for processing
|
||||
include fastcgi_params;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root/ginxsom.fcgi;
|
||||
fastcgi_pass unix:/run/ginxsom/ginxsom.sock;
|
||||
|
||||
# Only allow PUT method for uploads
|
||||
if ($request_method !~ ^(PUT)$ ) {
|
||||
return 405;
|
||||
}
|
||||
}
|
||||
|
||||
# List endpoint - returns list of files (if enabled)
|
||||
location /list {
|
||||
# Pass to FastCGI application
|
||||
include fastcgi_params;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root/ginxsom.fcgi;
|
||||
fastcgi_pass unix:/run/ginxsom/ginxsom.sock;
|
||||
|
||||
# Only allow GET method
|
||||
if ($request_method !~ ^(GET)$ ) {
|
||||
return 405;
|
||||
}
|
||||
}
|
||||
|
||||
# Mirror endpoint - for mirroring files from other servers
|
||||
location /mirror {
|
||||
# Pass to FastCGI application
|
||||
include fastcgi_params;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root/ginxsom.fcgi;
|
||||
fastcgi_pass unix:/run/ginxsom/ginxsom.sock;
|
||||
|
||||
# Only allow PUT method
|
||||
if ($request_method !~ ^(PUT)$ ) {
|
||||
return 405;
|
||||
}
|
||||
}
|
||||
|
||||
# Delete endpoint - requires authentication
|
||||
location ~ ^/([a-f0-9]{64})$ {
|
||||
# Handle DELETE requests through FastCGI
|
||||
if ($request_method = DELETE) {
|
||||
include fastcgi_params;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root/ginxsom.fcgi;
|
||||
fastcgi_param BLOSSOM_HASH $1;
|
||||
fastcgi_pass unix:/run/ginxsom/ginxsom.sock;
|
||||
}
|
||||
|
||||
# For GET/HEAD, fall through to static file serving above
|
||||
}
|
||||
|
||||
# Health check endpoint
|
||||
location /health {
|
||||
# Pass to FastCGI application
|
||||
include fastcgi_params;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root/ginxsom.fcgi;
|
||||
fastcgi_pass unix:/run/ginxsom/ginxsom.sock;
|
||||
|
||||
access_log off;
|
||||
}
|
||||
|
||||
# Deny access to hidden files and directories
|
||||
location ~ /\. {
|
||||
deny all;
|
||||
access_log off;
|
||||
log_not_found off;
|
||||
}
|
||||
|
||||
# Deny access to backup and temporary files
|
||||
location ~ ~$ {
|
||||
deny all;
|
||||
access_log off;
|
||||
log_not_found off;
|
||||
}
|
||||
}
|
||||
47
config/systemd/ginxsom.service
Normal file
47
config/systemd/ginxsom.service
Normal file
@@ -0,0 +1,47 @@
|
||||
[Unit]
|
||||
Description=Ginxsom Blossom Server FastCGI Application
|
||||
After=network.target
|
||||
Wants=network-online.target
|
||||
After=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=notify
|
||||
User=ginxsom
|
||||
Group=ginxsom
|
||||
WorkingDirectory=/var/lib/ginxsom
|
||||
ExecStart=/usr/local/bin/ginxsom --fastcgi --socket /run/ginxsom/ginxsom.sock
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
KillMode=process
|
||||
Restart=on-failure
|
||||
RestartSec=5s
|
||||
|
||||
# Security settings
|
||||
NoNewPrivileges=true
|
||||
ProtectSystem=strict
|
||||
ProtectHome=true
|
||||
ReadWritePaths=/var/lib/ginxsom /run/ginxsom /var/log/ginxsom
|
||||
PrivateTmp=true
|
||||
PrivateDevices=true
|
||||
ProtectHostname=true
|
||||
ProtectClock=true
|
||||
ProtectKernelTunables=true
|
||||
ProtectKernelModules=true
|
||||
ProtectKernelLogs=true
|
||||
ProtectControlGroups=true
|
||||
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
|
||||
RestrictRealtime=true
|
||||
RestrictSUIDSGID=true
|
||||
LockPersonality=true
|
||||
MemoryDenyWriteExecute=true
|
||||
|
||||
# Resource limits
|
||||
LimitNOFILE=65536
|
||||
LimitNPROC=4096
|
||||
|
||||
# Environment
|
||||
Environment=GINXSOM_CONFIG=/etc/ginxsom/config.toml
|
||||
Environment=GINXSOM_DATA_DIR=/var/lib/ginxsom
|
||||
Environment=GINXSOM_LOG_LEVEL=info
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Reference in New Issue
Block a user