A modern web-based admin tool for managing mail server data based on flurdy's "How to set up a mail server on a GNU / Linux system".
- v3: The current Rust based setup
- v1: The original Play Framework with Scala based setup, refer to the git tag v1
- Domain Management: Add, edit, and remove mail domains with quota and transport settings
- User Management: Manage mail users with password hashing and quota allocation
- Alias Management: Create and manage email aliases for forwarding
- Mailbox Management: Handle IMAP/POP3 mailboxes with individual settings
- Statistics Dashboard: View system-wide and per-domain statistics
- Modern UI: Built with Tailwind CSS for a clean, responsive interface
- Dark Mode Support: Toggle between light and dark themes with persistent preference
- HTMX Integration: Dynamic updates without full page reloads
- Secure Authentication: Password hashing and session management
- Backend: Rust with Axum web framework
- Database: MySQL with Diesel ORM
- Frontend: HTMX for dynamic interactions
- Styling: Tailwind CSS for modern UI
- Templates: Askama template engine
- Authentication: bcrypt password hashing
- Rust 1.70+ and Cargo
- MySQL 8.0+ or MariaDB 10.5+
- Diesel CLI
-
Install rustup
sudo dnf install rustup
or
brew install rustup
-
Initialise rustup
rustup-init
-
Install cargo binstall
cargo install cargo-binstall
-
install Diesel CLI binary
cargo binstall diesel-cli
Or MySQL only
cargo install diesel_cli --no-default-features --features mysql
For detailed step-by-step installation instructions, see ONBOARDING.md.
The easiest way to run Sorting Office is using Docker Compose:
-
Clone the repository:
git clone <repository-url> cd sortingoffice
-
Build and start services:
# Make the Docker script executable chmod +x docker.sh # Build and start all services ./docker.sh build ./docker.sh up
-
Access the application:
- Sorting Office: http://localhost:3000
- phpMyAdmin: http://localhost:8080
- Default login: admin/admin
Docker Management Commands:
./docker.sh help # Show all available commands
./docker.sh status # Check service status
./docker.sh logs # View logs
./docker.sh down # Stop services
./docker.sh restart # Restart services
./docker.sh clean # Remove all containers and volumes
-
Prerequisites:
- Rust 1.70+ and Cargo
- MySQL 8.0+ or MariaDB 10.5+
- Diesel CLI
-
Set up the database:
# Create MySQL database mysql -u root -p CREATE DATABASE sortingoffice CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE USER 'sortingoffice'@'localhost' IDENTIFIED BY 'your_password'; GRANT ALL PRIVILEGES ON sortingoffice.* TO 'sortingoffice'@'localhost'; FLUSH PRIVILEGES; EXIT;
-
Configure environment:
cp env.example .env # Edit .env with your database credentials
-
Run database migrations:
# For detailed database setup instructions, see DATABASE_MANAGEMENT.md # Quick setup with seed data: make prod-db-setup # Or manual setup: diesel setup diesel migration run make seed
-
Build and run:
cargo build --release cargo run
The application will be available at http://localhost:3000
.
Sorting Office implements a secure, role-based authentication system with support for multiple admin users and different permission levels.
- Username:
admin
- Password:
admin123
Important: Change these credentials in production!
- Multiple Admin Support: Configure multiple admin users with different roles
- Role-Based Access Control: Read-Only and Edit permission levels
- Secure Password Storage: bcrypt hashing for all passwords
- Session Management: HTTP-only cookies with expiration
For detailed authentication documentation, see AUTHENTICATION.md.
The application uses the following tables based on flurdy's mail server schema:
id
: Primary keydomain
: Domain name (unique)description
: Optional descriptionaliases
: Maximum number of aliasesmailboxes
: Maximum number of mailboxesmaxquota
: Maximum quota in bytesquota
: Current quota in bytestransport
: Mail transport methodbackupmx
: Backup MX flagactive
: Active statuscreated
/modified
: Timestamps
id
: Primary keyusername
: Username (unique)password
: bcrypt hashed passwordname
: Display namemaildir
: Mail directory pathquota
: User quota in bytesdomain
: Associated domainactive
: Active statuscreated
/modified
: Timestamps
id
: Primary keyaddress
: Email address (unique)goto
: Forwarding addressdomain
: Associated domainactive
: Active statuscreated
/modified
: Timestamps
id
: Primary keyusername
: Username (unique)password
: bcrypt hashed passwordname
: Display namemaildir
: Mail directory pathquota
: Mailbox quota in bytesdomain
: Associated domainactive
: Active statuscreated
/modified
: Timestamps
The main dashboard shows:
- System statistics (total domains, users, aliases, mailboxes)
- Quick action buttons for common tasks
- Overview of mail server health
- View all domains in a table format
- Add new domains with quota and transport settings
- Edit existing domain configurations
- Enable/disable domains
- Set backup MX status
- Create new mail users
- Set individual quotas
- Manage user passwords securely
- Enable/disable users
- View user details and statistics
- Create email forwarding aliases
- Point aliases to multiple destinations
- Manage alias domains
- Enable/disable aliases
- Create IMAP/POP3 mailboxes
- Set mailbox-specific quotas
- Manage mailbox passwords
- Configure mail directories
The application supports both light and dark themes:
- Toggle Button: Click the sun/moon icon in the top navigation bar
- Persistent Preference: Your theme choice is saved in localStorage
- Automatic Detection: The theme preference is restored on page reload
- Server Integration: Theme changes are also sent to the server for potential future server-side persistence
The theme toggle works across all pages including:
- Dashboard
- Domain management
- User management
- Alias management
- Mailbox management
- Statistics
- Login page
The Docker setup includes:
- Application: Rust application with optimized multi-stage build
- Database: MySQL 8.0 with persistent storage
- phpMyAdmin: Web-based database management interface
- Networking: Isolated network for secure communication
- Health Checks: Automatic health monitoring for all services
For development with live code reloading:
# Start development environment
./docker.sh dev
# Stop development environment
./docker.sh dev-down
The development environment includes:
- Volume mounts for live code changes
- Debug logging enabled
- Exposed database ports for direct access
- Development-specific Dockerfile
docker-compose.yml
: Production configurationdocker-compose.dev.yml
: Development overridesDockerfile
: Production-optimized multi-stage buildDockerfile.dev
: Development environment with tools
Docker environment variables are configured in docker-compose.yml
:
environment:
DATABASE_URL: mysql://sortingoffice:sortingoffice@db:3306/sortingoffice
RUST_LOG: info
HOST: 0.0.0.0
PORT: 3000
mysql_data
: Persistent MySQL data storage./templates
: Template files (read-only)./migrations
: Database migration files
3000
: Sorting Office web application3306
: MySQL database (exposed for development)8080
: phpMyAdmin interface
src/
├── main.rs # Application entry point
├── models.rs # Database models
├── schema.rs # Diesel schema
├── db.rs # Database operations
├── handlers/ # HTTP request handlers
│ ├── mod.rs
│ ├── dashboard.rs
│ ├── auth.rs
│ ├── domains.rs
│ ├── users.rs
│ ├── aliases.rs
│ ├── mailboxes.rs
│ └── stats.rs
└── templates/ # Askama template definitions
├── mod.rs
├── base.rs
├── dashboard.rs
├── auth.rs
├── domains.rs
├── users.rs
├── aliases.rs
├── mailboxes.rs
└── stats.rs
templates/ # HTML templates
├── layout.html
├── login.html
├── dashboard.html
├── domains/
├── users/
├── aliases/
├── mailboxes/
└── stats.html
migrations/ # Database migrations
└── *.sql
- Database Changes: Create new migration files
- Models: Add new models in
src/models.rs
- Database Operations: Add functions in
src/db.rs
- Handlers: Create new handlers in
src/handlers/
- Templates: Add template definitions and HTML files
- Routes: Update routes in
src/main.rs
# Run all tests (automatically sets up test database)
make test
# Run only unit tests
make test-unit
# Run only UI tests
make test-ui
# Run smoke tests (end-to-end validation)
make test-smoke
# Run with specific log level
RUST_LOG=debug cargo run
Test Database Setup: The project uses Testcontainers to provide isolated MySQL instances for each test. For detailed information about the test database setup, see TEST_DATABASE_SETUP.md.
Test Types:
- Unit Tests: Isolated database operations using testcontainers
- Integration Tests: End-to-end workflows
- UI Tests: Selenium-based browser automation
- Smoke Tests: Complete end-to-end user workflows with testcontainers support
Smoke Tests: The application includes comprehensive smoke tests that validate complete user workflows from authentication through resource creation and cleanup. These tests are integrated into CI/CD and can be run both locally and in automated environments. For detailed information, see UI_TESTS.md.
For comprehensive database management, see DATABASE_MANAGEMENT.md.
Quick Commands:
# Show all database commands
make db-help
# Setup development database with seed data
make prod-db-setup
# Setup test database
make test-db-setup
# Run seed data
make seed
# Reset databases (WARNING: destructive)
make prod-db-reset # Development database
make test-db-reset # Test database
For quick health checks, use the simple curl scripts:
# Basic health check (detailed)
./scripts/health-check.sh
# Health check with verbose output
./scripts/health-check.sh -v
# Health check remote host
./scripts/health-check.sh -h 192.168.1.100:3000
# Health check with custom timeout
./scripts/health-check.sh -t 5
# Super simple one-liner health check
./scripts/health-check-simple.sh
# Simple health check for remote host
./scripts/health-check-simple.sh 192.168.1.100:3000
Environment Management:
# Set up different environments
source scripts/set-env.sh dev # Development
source scripts/set-env.sh test # Testing
source scripts/set-env.sh docker # Docker
- Role-Based Authentication: Secure, role-based access control with multiple admin support
- Password Security: All passwords are hashed using bcrypt with configurable cost
- Session Management: HTTP-only cookies with automatic expiration and CSRF protection
- SQL Injection Protection: All database operations use Diesel ORM with parameterized queries
- Input Validation: Comprehensive validation and sanitization of all user inputs
- Security Headers: Comprehensive security headers including X-Content-Type-Options, X-Frame-Options, X-XSS-Protection, Referrer-Policy, Content Security Policy, and Strict-Transport-Security
- HTTPS Ready: Designed for HTTPS deployment with secure cookie attributes
For detailed security information, see AUTHENTICATION.md.
- Environment: Set production environment variables
- Database: Use production MySQL/MariaDB instance
- Reverse Proxy: Configure nginx/Apache as reverse proxy
- SSL/TLS: Enable HTTPS with proper certificates
- Authentication: Configure role-based authentication with multiple admin users (see AUTHENTICATION.md)
- Backup: Set up regular database backups (see DATABASE_BACKUP.md)
- Monitoring: Configure logging and monitoring
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
For detailed contribution guidelines and contact information, see CONTRIBUTING.md and docs/CONTACT.md.
This project is licensed under the MIT License - see the LICENSE file for details.
- Based on flurdy's Postfix mail server guide
- Built with modern Rust web development tools
- UI inspired by modern admin dashboard designs
Sorting Office allows you to configure which email aliases are considered "required" for each domain. This is used in the reports to identify missing required aliases.
-
Environment Variable: Set the
REQUIRED_ALIASES
environment variable with a comma-separated list:export REQUIRED_ALIASES="postmaster,abuse,webmaster,admin,support,info,noreply,no-reply"
-
Configuration File: Create a
config/required_aliases.toml
file:# Required Aliases Configuration required_aliases = [ "postmaster", "abuse", "webmaster", "admin", "support", "info", "noreply", "no-reply", "hostmaster", "security", "help", "contact", "sales", "marketing", "hr", "finance", "legal", "privacy", "dmca", "spam" ]
-
Web Interface: Access the configuration page at
/config
to view current configuration and domain-specific overrides (read-only).
If no configuration is provided, the following aliases are considered required by default:
postmaster
abuse
webmaster
admin
support
info
noreply
no-reply
The required aliases configuration is used in the catch-all reports (/reports/catch-all
) to:
- Show which required aliases are missing for domains without catch-all aliases
- List all required aliases for domains with catch-all aliases
- Help ensure compliance with email standards and organizational requirements