← Back to atech/postal

How to Deploy & Use atech/postal

Postal: Open Source Mail Delivery Platform

Postal is a complete and fully-featured mail server for incoming and outgoing e-mail, designed to be an open-source alternative to services like Sendgrid or Mailgun.

Prerequisites

Before deploying Postal, ensure you have the following installed and configured:

  • Operating System: Ubuntu 20.04 LTS or newer (recommended).
  • Ruby: Postal is built with Ruby. A compatible version will be installed during the setup process.
  • MySQL/MariaDB: A database server for storing Postal's data.
  • RabbitMQ: A message broker for handling background jobs.
  • Redis: An in-memory data store, used for caching and session management.
  • NGINX: A web server to proxy requests to Postal's web interface.
  • DNS Configuration:
    • A record for your Postal web interface (e.g., postal.example.com).
    • A record for your SMTP hostname (e.g., smtp.example.com).
    • MX records pointing to your SMTP hostname.
    • SPF and DKIM records for email authentication.
  • Server Resources: Minimum 2 CPU cores, 4GB RAM, and 40GB storage.

Installation

The recommended installation method for Postal is using the provided curl script, which automates most of the setup.

  1. Log in as root:

    sudo -i
    
  2. Download and run the installation script:

    curl https://install.postal.dev/install | sh
    

    This script will:

    • Install necessary dependencies (Ruby, MySQL, RabbitMQ, Redis, NGINX).
    • Set up Postal's database.
    • Configure system services.
    • Prompt you for configuration details during the process.
  3. Follow the on-screen prompts: The installer will ask for information such as:

    • The hostname for your Postal web interface (e.g., postal.example.com).
    • The hostname for your SMTP server (e.g., smtp.example.com).
    • Database credentials.

Configuration

Postal's configuration is managed through a postal.yml file, typically located at /opt/postal/config/postal.yml. The installer will generate a basic configuration, but you can customize it further.

The ConfigSchema in lib/postal/config_schema.rb defines available configuration options. Key configuration groups include:

  • postal:
    • web_hostname: The hostname for the Postal web interface (default: postal.example.com).
    • web_protocol: The HTTP protocol for the web interface (default: https).
    • smtp_hostname: The hostname for the Postal SMTP server (default: postal.example.com).
    • use_ip_pools: Enable or disable IP pools (default: false).
    • default_maximum_delivery_attempts: Max delivery attempts for messages (default: 18).
    • default_spam_threshold: Score at which a message is considered spam (default: 5).

Example postal.yml snippet (for illustration, actual file generated by installer):

# /opt/postal/config/postal.yml
postal:
  web_hostname: your.postal.domain.com
  web_protocol: https
  smtp_hostname: smtp.your.postal.domain.com
  use_ip_pools: false
  default_maximum_delivery_attempts: 18
  default_maximum_hold_expiry_days: 7
  default_spam_threshold: 5

database:
  host: 127.0.0.1
  port: 3306
  database: postal
  username: postal
  password: your_database_password

# ... other configurations for rabbitmq, redis, etc.

After modifying postal.yml: You may need to restart Postal services for changes to take effect.

Build & Run

Postal is designed to run as a set of services. There isn't a typical "build" step in the development sense for deployment, as the installation script handles setting up the application.

Running Locally (Development)

For local development, you would typically clone the repository and set up the environment manually. This is generally not recommended for production.

  1. Clone the repository:

    git clone https://github.com/postalserver/postal.git
    cd postal
    
  2. Install Ruby dependencies:

    bundle install
    
  3. Database setup:

    • Configure your config/database.yml for development.
    • Create and migrate the database:
      bin/rails db:create
      bin/rails db:migrate
      
    • The db/schema.rb file defines the current database schema.
  4. Start services: You would typically need to run the web server, SMTP server, and worker processes.

    • Web server: bin/rails server
    • SMTP server: bin/rails postal:smtp_server:run (or similar, check Rake tasks)
    • Workers: bundle exec rake postal:worker:run

Production Environment

In a production environment, Postal runs as system services managed by systemd. The installation script configures these automatically.

  • Web interface: Handled by NGINX proxying to the Postal Rails application.
  • SMTP server: Runs as a dedicated service, handling incoming mail (app/lib/smtp_server/client.rb).
  • Message processing: Background workers process messages, handle deliveries, etc. (lib/postal/message_db/message.rb).

Deployment

The primary deployment method is the automated installation script described in the "Installation" section. This script is designed for a single-server deployment.

Key components deployed:

  • Postal Application: Ruby on Rails application.
  • MySQL/MariaDB: Database for all Postal data (e.g., credentials, messages, servers as seen in db/initial_schema.rb and db/schema.rb).
  • RabbitMQ: Message queue for internal communication and job processing.
  • Redis: Caching and session management.
  • NGINX: Reverse proxy and SSL termination for the web interface.
  • Postal SMTP Server: A custom SMTP server written in Ruby, handling incoming mail.

Post-Installation Steps:

  1. Access the Web Interface: Navigate to the web_hostname you configured (e.g., https://postal.example.com).
  2. Create Admin Account: The first time you access the web interface, you'll be prompted to create an administrator account.
  3. Configure DNS: Ensure your DNS records (A, MX, SPF, DKIM) are correctly pointing to your Postal server.
  4. Add Servers and Domains: In the Postal web interface, add your mail servers and domains.
  5. Generate API Keys/Credentials: Create credentials for sending mail through Postal. The credentials table in the database stores these.

Troubleshooting

Here are some common issues and their solutions:

  • 550 5.1.1 Recipient address rejected: User unknown:

    • Cause: The recipient domain or address is not configured in Postal, or the server for the domain is not enabled.
    • Solution: Ensure the domain is added to a server in Postal and that the server is active. Check your routes and aliases.
  • Emails are not being sent/received:

    • Check Postal logs: The main Postal logs are usually found in /opt/postal/log/postal.log. Look for errors related to SMTP connections, delivery attempts, or worker failures.
    • Check system services: Ensure all Postal services are running:
      sudo systemctl status postal
      sudo systemctl status postal-web
      sudo systemctl status postal-smtp
      sudo systemctl status postal-worker
      sudo systemctl status mysql # or mariadb
      sudo systemctl status rabbitmq-server
      sudo systemctl status redis-server
      sudo systemctl status nginx
      
    • Firewall: Verify that ports 25 (SMTP), 587 (SMTP Submission), 465 (SMTPS), and 80/443 (HTTP/HTTPS) are open on your server's firewall.
    • DNS Issues: Double-check your MX, SPF, and DKIM records using a DNS lookup tool. Incorrect DNS can lead to emails being rejected or marked as spam.
  • Web interface not loading:

    • NGINX configuration: Check /etc/nginx/sites-enabled/postal.conf for correct proxy settings.
    • Postal web service: Ensure postal-web service is running.
    • Firewall: Make sure ports 80 and 443 are open.
  • Database connection errors:

    • Check MySQL/MariaDB service: Ensure the database server is running.
    • Credentials: Verify database credentials in /opt/postal/config/postal.yml match those configured in your database.
    • Disk space: Ensure your database server has sufficient disk space.
  • Slow performance:

    • Server resources: Check CPU, RAM, and disk I/O usage. Upgrade resources if necessary.
    • Database optimization: Ensure your database is properly indexed and maintained.
    • RabbitMQ: Check RabbitMQ queue lengths. If queues are backing up, it might indicate worker issues.
  • Updating Postal:

    • Refer to the official documentation for upgrade instructions. Typically, this involves pulling the latest code and running database migrations.
    • bundle exec rake postal:generate_config_docs is mentioned in lib/postal/config_schema.rb for regenerating config documentation after schema changes, which might be relevant during upgrades.