Skip to content

Deployment Overview of Mastodon on Server

Prerequisites and Basic Requirements

The deployment of Mastodon requires the following environment specifications and privileges:

  • Operating System: Ubuntu (as indicated by the task configuration)

  • Privileges: Root access or sudo privileges to install Docker, manage services, and configure the firewall

  • Docker Engine: Must be installed and running

  • Docker Compose: The docker-compose command and docker-compose-plugin are required

  • Domain: A valid domain or subdomain on the hostkey.in zone is required for the FQDN

  • Ports: Ports 3000 (web), 4000 (streaming), 80 (HTTP redirect), and 443 (HTTPS) must be available

  • User: The service runs under a dedicated user named mastodon with a home directory at /opt/mastodon

FQDN of the Final Panel

The application is accessible via the following Fully Qualified Domain Name (FQDN) format:

  • Format: <prefix><Server ID>.hostkey.in:<port>

  • Primary Domain: mastodon<Server ID>.hostkey.in

  • Web Interface: Port 443 (HTTPS)

  • Streaming API: Port 443 (HTTPS, proxied to internal port 4000)

Note: The specific <Server ID> is determined by the server configuration variables and is appended directly to the prefix mastodon in the domain name.

File and Directory Structure

The application files, configuration, and data are organized within the following directory hierarchy under /opt/mastodon:

  • /opt/mastodon/ (Main application directory)

  • /opt/mastodon/.env.production (Production environment configuration)

  • /opt/mastodon/.env.db (Database environment configuration)

  • /opt/mastodon/docker-compose.yml (Docker Compose orchestration file)

  • /opt/mastodon/data/postgres (PostgreSQL data storage)

  • /opt/mastodon/data/redis (Redis data storage)

  • /opt/mastodon/data/public/system (Public media file storage)

  • /data/nginx/user_conf.d/mastodon<Server ID>.hostkey.in.conf (Nginx proxy configuration)

  • /data/nginx/nginx-certbot.env (SSL certificate configuration for Let's Encrypt)

Application Installation Process

The installation process involves deploying Mastodon version v4.3.1 using Docker containers. The system performs the following steps to prepare and launch the application:

  1. Docker Setup: Ensures Docker and Docker Compose are installed.

  2. User Creation: Creates a system user mastodon with a home directory at /opt/mastodon.

  3. Directory Initialization: Creates necessary directories for PostgreSQL, Redis, and public files, setting ownership to the mastodon user.

  4. Environment Configuration:

    • Generates .env.db with PostgreSQL credentials.

    • Generates .env.production with application secrets.

    • Dynamically generates cryptographic secrets (SECRET_KEY_BASE, OTP_SECRET, VAPID keys, and Active Record encryption keys) using rails commands and injects them into the .env.production file.

  5. Service Launch: Starts the Docker containers defined in docker-compose.yml.

  6. Database Migration: Executes database migrations (rails db:migrate) to initialize the schema.

  7. Seed Data: Runs rails db:seed to create the initial admin user and default data.

  8. Final Restart: Restarts the services to ensure all configurations are applied.

Docker Containers and Their Deployment

The deployment utilizes Docker Compose to orchestrate the following services. All services are configured with restart: always or restart: unless-stopped.

Service Container Image Description
nginx jonasal/nginx-certbot:latest Handles SSL termination, Let's Encrypt certificate management, and reverse proxying. Uses host network mode.
db postgres:14-alpine PostgreSQL 14 database service.
redis redis:7-alpine Redis 7 caching and queue service.
web ghcr.io/mastodon/mastodon:v4.3.1 The main Mastodon web application (Puma server). Exposes port 3000.
streaming ghcr.io/mastodon/mastodon-streaming:v4.3.1 WebSocket streaming server. Exposes port 4000.
sidekiq ghcr.io/mastodon/mastodon:v4.3.1 Background job processor (Sidekiq).

The nginx container mounts /etc/letsencrypt for certificates and /data/nginx/user_conf.d for custom server configurations. The web and sidekiq containers mount the local public/system directory to /mastodon/public/system for media storage.

Proxy Servers

Nginx acts as the reverse proxy and SSL termination point for the Mastodon instance.

  • Configuration Location: /data/nginx/user_conf.d/mastodon<Server ID>.hostkey.in.conf

  • SSL/TLS: Handled by Let's Encrypt (certbot) via the jonasal/nginx-certbot container.

  • Domains: The proxy listens for the domain mastodon<Server ID>.hostkey.in.

  • Routing:

    • All standard requests (/) are proxied to the web container at mastodon<Server ID>.hostkey.in:3000.

    • Streaming requests (/api/v1/streaming) are proxied to the streaming container at mastodon<Server ID>.hostkey.in:4000.

  • Headers: The proxy configuration sets standard headers including X-Forwarded-Proto, X-Forwarded-Ssl, Host, X-Real-IP, and X-Forwarded-For to ensure the application correctly identifies client connections.

  • Redirects: HTTP traffic on port 80 is automatically redirected to HTTPS on port 443.

Databases

The application relies on external services for data storage and caching, configured as follows:

  • PostgreSQL:

    • Service: db (PostgreSQL 14 Alpine)

    • Host: db (internal Docker network)

    • Port: 5432

    • User: postgres

    • Database Name: postgres

    • Password: Set via the ansible_ssh_pass variable in .env.db

    • Data Storage: Persisted in /opt/mastodon/postgres14 (mapped from ./postgres14 in compose.yml)

    • Authentication Method: Trust (within the Docker network)

  • Redis:

    • Service: redis (Redis 7 Alpine)

    • Host: redis (internal Docker network)

    • Port: 6379

    • Data Storage: Persisted in /opt/mastodon/redis (mapped from ./redis in compose.yml)

  • Elasticsearch:

    • The configuration includes commented-out blocks for Elasticsearch, indicating it is not actively deployed in this setup.

Access Rights and Security

Security is enforced through user separation, file permissions, and network isolation:

  • System User: The mastodon user owns the application directory and data files.

  • File Permissions:

    • Configuration files (.env.production, .env.db) are set to mode 0600 (read/write for owner only).

    • Application directories are set to mode 0755.

    • The docker-compose.yml file is readable by the owner and group (0644).

  • Network Isolation:

    • An internal_network is used for communication between db, redis, web, streaming, and sidekiq, preventing external direct access to these services.

    • The nginx container uses network_mode: host to bind directly to the server's network interfaces for public access.

  • Secrets: Sensitive keys (SECRET_KEY_BASE, OTP_SECRET, encryption keys, VAPID keys) are generated dynamically and stored in .env.production with restricted permissions.

Permission Settings

The file and directory permissions are established during the deployment process:

  • Owner: All files and directories under /opt/mastodon are owned by the mastodon user and group.

  • Root-Owned Configs: Nginx configuration files located in /data/nginx/user_conf.d/ are owned by root:root.

  • Executable Permissions: No specific executable bits are set on scripts in the context of the final state; services are managed via Docker Compose.

  • Data Directories:

    • /opt/mastodon/data/postgres: 755

    • /opt/mastodon/data/redis: 755

    • /opt/mastodon/data/public/system: 755

Location of Configuration Files and Data

  • Application Root: /opt/mastodon

  • Production Environment: /opt/mastodon/.env.production

  • Database Environment: /opt/mastodon/.env.db

  • Docker Orchestration: /opt/mastodon/docker-compose.yml

  • Nginx Proxy Config: /data/nginx/user_conf.d/mastodon<Server ID>.hostkey.in.conf

  • PostgreSQL Data: /opt/mastodon/postgres14 (Docker volume)

  • Redis Data: /opt/mastodon/redis (Docker volume)

  • Public Media Files: /opt/mastodon/data/public/system

Available Ports for Connection

The following ports are exposed and utilized by the deployment:

Port Protocol Service Description
80 TCP Nginx HTTP traffic (redirects to HTTPS)
443 TCP Nginx HTTPS traffic (Main web and streaming API)
3000 TCP Mastodon Web Internal port for the web application (proxied by Nginx)
4000 TCP Mastodon Streaming Internal port for WebSocket streaming (proxied by Nginx)

Direct access to ports 3000 and 4000 is restricted to the internal Docker network; external users must access the application via Nginx on port 443.

Starting, Stopping, and Updating

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

  • Start Services:

    cd /opt/mastodon
    docker-compose -f docker-compose.yml up -d
    

  • Stop Services:

    cd /opt/mastodon
    docker-compose -f docker-compose.yml down
    

  • Restart Services:

    cd /opt/mastodon
    docker-compose -f docker-compose.yml restart
    

  • Update Database Migrations:

    cd /opt/mastodon
    docker-compose run --rm web bundle exec rails db:migrate
    

  • Check Database Status:

    cd /opt/mastodon
    docker-compose -f docker-compose.yml exec -T db pg_isready -U postgres
    

question_mark
Is there anything I can help you with?
question_mark
AI Assistant ×