Skip to content

Deployment Overview of Mastodon on Server

Prerequisites and Basic Requirements

The deployment requires a Linux server running Ubuntu with root privileges. The following components must be present on the system:

  • Docker Engine installed and running.
  • Docker Compose and the Docker Compose plugin installed.
  • A dedicated system user named mastodon created for service management.
  • A valid domain name configured for the server, following the pattern {prefix}{server_id}.{zone}.
  • Network access to ports 80 and 443 for HTTP and HTTPS traffic.
  • Network access to internal ports 3000 (Web), 4000 (Streaming), 5432 (PostgreSQL), and 6379 (Redis) within the Docker network.

File and Directory Structure

The application files, configuration, and data are organized in the following locations:

  • Base Directory: /opt/mastodon
  • Contains the main application files and Docker Compose configuration.
  • Environment Files:
  • /opt/mastodon/.env.db: Contains PostgreSQL credentials.
  • /opt/mastodon/.env.production: Contains application secrets, domain settings, and service configurations.
  • Docker Compose File: /opt/mastodon/docker-compose.yml
  • Data Volumes:
  • /opt/mastodon/postgres14: Stores PostgreSQL database data.
  • /opt/mastodon/redis: Stores Redis cache data.
  • /opt/mastodon/public/system: Stores uploaded media and public assets.
  • Nginx Configuration:
  • /data/nginx/user_conf.d/{prefix}{server_id}.{zone}.conf: Custom server block configuration.
  • /etc/letsencrypt/live/{prefix}{server_id}.{zone}/: SSL certificate files.

Application Installation Process

The Mastodon application is deployed using Docker containers. The installation process involves the following steps:

  1. User and Directory Setup: A system user mastodon is created with a home directory at /opt/mastodon. Required subdirectories for data storage are created and assigned to this user.
  2. Configuration Generation:
    • The .env.db file is generated with PostgreSQL credentials.
    • The .env.production file is generated with the local domain and service settings.
    • The docker-compose.yml file is deployed to the base directory.
  3. Secret Generation:
    • SECRET_KEY_BASE and OTP_SECRET are generated using the Rails secret generator.
    • VAPID_PRIVATE_KEY and VAPID_PUBLIC_KEY are generated for web push notifications.
    • Active Record Encryption keys (ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY, ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT, ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY) are generated.
    • These secrets are injected into the .env.production file.
  4. Service Initialization:
    • Docker Compose services are started.
    • The system waits for the PostgreSQL database to be ready.
    • Pre-deployment database migrations are executed.
    • Services are restarted to apply changes.
    • Post-deployment database migrations are executed.
    • The initial admin user and seed data are created via the db:seed task.
    • Services are restarted to finalize the deployment.

Access Rights and Security

Security is enforced through user isolation, network segmentation, and firewall rules managed by the proxy:

  • User Isolation: The mastodon user owns the application directory and configuration files. Sensitive files like .env.production and .env.db are set to mode 0600, readable only by the owner.
  • Network Segmentation:
  • An internal_network is used for communication between the database, Redis, and application containers.
  • An external_network is used for the web and streaming services to communicate with the proxy.
  • Firewall and Proxy:
  • Nginx handles SSL termination and forwards traffic to the internal containers.
  • HTTP traffic on port 80 is redirected to HTTPS on port 443.
  • The Nginx configuration restricts access to specific server names and validates SSL certificates.

Databases

The application utilizes two primary data stores:

  • PostgreSQL:
  • Image: postgres:14-alpine
  • Host: db (internal Docker network)
  • Port: 5432
  • User: postgres
  • Database Name: postgres
  • Storage: Data is persisted in the volume mapped to /opt/mastodon/postgres14.
  • Authentication: Configured to trust local connections within the Docker network.
  • Redis:
  • Image: redis:7-alpine
  • Host: redis (internal Docker network)
  • Port: 6379
  • Storage: Data is persisted in the volume mapped to /opt/mastodon/redis.

Docker Containers and Their Deployment

The deployment consists of the following Docker containers defined in docker-compose.yml:

  • nginx:
  • Image: jonasal/nginx-certbot:latest
  • Function: Handles SSL termination and reverse proxying.
  • Network Mode: Host.
  • Volumes: Mounts Let's Encrypt secrets and custom Nginx configurations.
  • db:
  • Image: postgres:14-alpine
  • Function: Primary database storage.
  • Health Check: Uses pg_isready to verify status.
  • redis:
  • Image: redis:7-alpine
  • Function: Caching and session storage.
  • Health Check: Uses redis-cli ping to verify status.
  • web:
  • Image: ghcr.io/mastodon/mastodon:{version}
  • Function: Main application interface (Puma server).
  • Port: Exposes port 3000 internally.
  • Health Check: Verifies the /health endpoint.
  • streaming:
  • Image: ghcr.io/mastodon/mastodon-streaming:{version}
  • Function: Handles real-time streaming API.
  • Port: Exposes port 4000 internally.
  • Health Check: Verifies the /api/v1/streaming/health endpoint.
  • sidekiq:
  • Image: ghcr.io/mastodon/mastodon:{version}
  • Function: Background job processing.
  • Health Check: Verifies the presence of the Sidekiq process.

Proxy Servers

Nginx is configured as the reverse proxy and SSL terminator for the Mastodon instance:

  • Configuration Location: /data/nginx/user_conf.d/{prefix}{server_id}.{zone}.conf
  • SSL Certificates: Managed by Certbot, stored in /etc/letsencrypt/live/{prefix}{server_id}.{zone}/.
  • Routing:
  • All traffic to the root path / is proxied to the web container on port 3000.
  • Traffic to /api/v1/streaming is proxied to the streaming container on port 4000.
  • Headers: The proxy sets X-Forwarded-Proto, X-Forwarded-Ssl, Host, X-Real-IP, and X-Forwarded-For headers to ensure the application correctly identifies the client and protocol.
  • WebSockets: The configuration enables HTTP/1.1 and disables proxy buffering to support WebSocket connections for the streaming API.

Permission Settings

File and directory permissions are set to ensure security and proper operation:

  • Base Directory: /opt/mastodon is owned by mastodon:mastodon with mode 0755.
  • Data Directories:
  • /opt/mastodon/postgres14
  • /opt/mastodon/redis
  • /opt/mastodon/public/system
  • All are owned by mastodon:mastodon with mode 0755.
  • Configuration Files:
  • .env.db and .env.production are owned by mastodon:mastodon with mode 0600 (read/write for owner only).
  • docker-compose.yml is owned by mastodon:mastodon with mode 0644.
  • Nginx Configuration: The custom server block is owned by root:root with mode 0644.

Starting, Stopping, and Updating

Service management is performed using Docker Compose commands executed from the /opt/mastodon directory:

  • Start Services:
    docker-compose -f /opt/mastodon/docker-compose.yml up -d
    
  • Restart Services:
    docker-compose -f /opt/mastodon/docker-compose.yml restart
    
  • Run Migrations:
    docker-compose run --rm web bundle exec rails db:migrate
    
  • Create Admin User:
    docker-compose -f /opt/mastodon/docker-compose.yml exec -T web bin/rails db:seed
    
  • Check Database Status:
    docker-compose -f /opt/mastodon/docker-compose.yml exec -T db pg_isready -U postgres
    
question_mark
Is there anything I can help you with?
question_mark
AI Assistant ×