initial commit
This commit is contained in:
54
.env.sample
Normal file
54
.env.sample
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
# ==========================================
|
||||||
|
# Poste.io Mail Server Configuration
|
||||||
|
# ==========================================
|
||||||
|
|
||||||
|
# Your mail server's Fully Qualified Domain Name (FQDN)
|
||||||
|
MAIL_HOSTNAME=mail.amiirkhl.ir
|
||||||
|
|
||||||
|
# Server Timezone
|
||||||
|
TZ=Asia/Tehran
|
||||||
|
|
||||||
|
|
||||||
|
# ==========================================
|
||||||
|
# Performance & Feature Toggles
|
||||||
|
# ==========================================
|
||||||
|
|
||||||
|
# Disable ClamAV Antivirus to save RAM.
|
||||||
|
# TRUE saves ~$1 \text{ GB}$ of RAM. FALSE provides better security.
|
||||||
|
DISABLE_CLAMAV=TRUE
|
||||||
|
|
||||||
|
# Disable Rspamd (Anti-spam filter).
|
||||||
|
# Highly recommended to keep FALSE unless testing.
|
||||||
|
DISABLE_RSPAMD=FALSE
|
||||||
|
|
||||||
|
# Disable the built-in Roundcube Webmail interface.
|
||||||
|
# TRUE disables it, FALSE enables it.
|
||||||
|
DISABLE_ROUNDCUBE=FALSE
|
||||||
|
|
||||||
|
|
||||||
|
# ==========================================
|
||||||
|
# SSL / HTTPS Configuration
|
||||||
|
# ==========================================
|
||||||
|
|
||||||
|
# Controls Let's Encrypt and HTTP->HTTPS redirection.
|
||||||
|
# Since you are using custom SSL certificates manually, set this to OFF
|
||||||
|
# so Poste.io doesn't try to fetch its own certificates from Let's Encrypt.
|
||||||
|
HTTPS=OFF
|
||||||
|
|
||||||
|
# Absolute paths to your custom SSL certificates on the host machine
|
||||||
|
# Docker will mount these directly into the container.
|
||||||
|
SSL_CERT_PATH=/path/to/your/fullchain.pem
|
||||||
|
SSL_KEY_PATH=/path/to/your/privatekey.pem
|
||||||
|
|
||||||
|
# ==========================================
|
||||||
|
# Backup Configuration
|
||||||
|
# ==========================================
|
||||||
|
|
||||||
|
# Enable automated backups (TRUE/FALSE)
|
||||||
|
ENABLE_BACKUPS=TRUE
|
||||||
|
|
||||||
|
# Backup interval in cron format (e.g., "0 2 * * *" for daily at 2 AM)
|
||||||
|
BACKUP_CRON="0 2 * * *"
|
||||||
|
|
||||||
|
# Number of days to keep old backups
|
||||||
|
BACKUP_RETENTION_DAYS=7
|
||||||
13
.gitignore
vendored
Normal file
13
.gitignore
vendored
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
# Ignore the actual environment variables file
|
||||||
|
.env
|
||||||
|
|
||||||
|
# Ignore the data directory which will contain emails, databases, and private SSL keys
|
||||||
|
/data/
|
||||||
|
|
||||||
|
# OS generated files
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Backup files
|
||||||
|
/backups/
|
||||||
|
backup.log
|
||||||
95
README.md
Normal file
95
README.md
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
# Poste.io Dockerized Mail Server
|
||||||
|
|
||||||
|
Self-hosted, Git-managed mail server for your personal domain using [Poste.io](https://poste.io/).
|
||||||
|
|
||||||
|
*Last Updated: 1405/01/02 (2026/03/22)*
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
```text
|
||||||
|
poste-deployment
|
||||||
|
├── .env.sample
|
||||||
|
├── .gitignore
|
||||||
|
├── docker-compose.yml
|
||||||
|
└── README.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## Setup Instructions
|
||||||
|
|
||||||
|
### 1. Clone & Configure
|
||||||
|
Clone this repository to your server:
|
||||||
|
```bash
|
||||||
|
git clone https://git.amiirkhl.ir/interanet/poste-deployment.git /opt/mailserver
|
||||||
|
cd /opt/mailserver
|
||||||
|
```
|
||||||
|
|
||||||
|
Create your environment file from the sample:
|
||||||
|
```bash
|
||||||
|
cp .env.sample .env
|
||||||
|
```
|
||||||
|
Edit `.env` and ensure `MAIL_HOSTNAME` and `TZ` are correct.
|
||||||
|
|
||||||
|
### 2. Custom SSL Configuration
|
||||||
|
Since Let's Encrypt is disabled (`HTTPS=OFF`), you must provide your own SSL certificates. This project maps your existing certificates directly into the container.
|
||||||
|
|
||||||
|
1. Open your `.env` file.
|
||||||
|
2. Locate `SSL_CERT_PATH` and `SSL_KEY_PATH`.
|
||||||
|
3. Set their values to the **absolute paths** of your certificate files on the host server (e.g., `/etc/ssl/amiirkhl.ir/fullchain.pem`).
|
||||||
|
|
||||||
|
*⚠️ **CRITICAL DOCKER WARNING**: The files specified in `SSL_CERT_PATH` and `SSL_KEY_PATH` **must** exist on your server before you run `docker compose up`. If Docker cannot find the files, it will mistakenly create empty directories with those names, which will crash the mail server.*
|
||||||
|
|
||||||
|
### 3. Start the Server
|
||||||
|
Start the Docker container:
|
||||||
|
```bash
|
||||||
|
docker compose up -d
|
||||||
|
```
|
||||||
|
Once running, navigate to `https://mail.amiirkhl.ir` to access the Admin GUI and set your master admin password.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## DNS Configuration Guide
|
||||||
|
|
||||||
|
To ensure your emails do not go to the spam folder, configure the following records in your DNS management panel (Cloudflare, ArvanCloud, etc.).
|
||||||
|
|
||||||
|
*⚠️ **Important**: Ensure any Proxy/CDN settings (like Cloudflare's orange cloud) are turned **OFF** (DNS Only) for these records.*
|
||||||
|
|
||||||
|
| Type | Name / Host | Value / Target | Priority |
|
||||||
|
| :---: | :--- | :--- | :---: |
|
||||||
|
| **A** | `mail` | `<Your-Server-IP>` | - |
|
||||||
|
| **MX** | `@` | `mail.amiirkhl.ir` | $10$ |
|
||||||
|
| **TXT** | `@` | `v=spf1 mx a:mail.amiirkhl.ir ~all` | - |
|
||||||
|
| **TXT** | `_dmarc` | `v=DMARC1; p=quarantine; rua=mailto:admin@amiirkhl.ir` | - |
|
||||||
|
|
||||||
|
### DKIM Setup
|
||||||
|
DKIM adds a cryptographic signature to your emails.
|
||||||
|
1. Log into the Poste.io Admin Panel (`https://mail.amiirkhl.ir`).
|
||||||
|
2. Navigate to **Virtual domains** -> Click on `amiirkhl.ir`.
|
||||||
|
3. Locate the **DKIM key** section.
|
||||||
|
4. Click "Generate new key" (if not already generated).
|
||||||
|
5. Copy the provided TXT record and add it to your DNS panel. Usually, the Name is `s1._domainkey` and the Value is `v=DKIM1; k=rsa; p=...`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Data Persistence & Backups
|
||||||
|
All user data, emails, databases, and configuration overrides are stored inside the `./data` folder.
|
||||||
|
|
||||||
|
### Automated Backups
|
||||||
|
This project includes a script to automate backups of your `./data` directory based on your `.env` configuration.
|
||||||
|
|
||||||
|
1. Ensure the backup variables are set in your `.env` file:
|
||||||
|
- `ENABLE_BACKUPS=TRUE`
|
||||||
|
- `BACKUP_CRON="0 2 * * *"` (Sets the schedule, e.g., daily at $2$ AM)
|
||||||
|
- `BACKUP_RETENTION_DAYS=7` (Deletes backups older than $7$ days)
|
||||||
|
|
||||||
|
2. Make the setup script executable and run it:
|
||||||
|
```bash
|
||||||
|
chmod +x setup_backup.sh
|
||||||
|
./setup_backup.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
The script will automatically register a cron job on your host machine. Backups will be securely compressed as `.tar.gz` files and stored in the newly created `./backups` directory. Old backups are automatically pruned based on your retention settings.
|
||||||
|
|
||||||
|
### Manual Backup
|
||||||
|
If you prefer to trigger a backup manually at any time without using the script, simply run:
|
||||||
|
```bash
|
||||||
|
tar -czvf mail_backup_$(date +%F).tar.gz ./data/
|
||||||
|
```
|
||||||
31
docker-compose.yml
Normal file
31
docker-compose.yml
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
services:
|
||||||
|
mailserver:
|
||||||
|
image: analogic/poste.io:latest
|
||||||
|
hostname: ${MAIL_HOSTNAME}
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- "25:25"
|
||||||
|
- "80:80"
|
||||||
|
- "443:443"
|
||||||
|
- "110:110"
|
||||||
|
- "143:143"
|
||||||
|
- "465:465"
|
||||||
|
- "587:587"
|
||||||
|
- "993:993"
|
||||||
|
- "995:995"
|
||||||
|
environment:
|
||||||
|
- TZ=${TZ}
|
||||||
|
- DISABLE_CLAMAV=${DISABLE_CLAMAV}
|
||||||
|
- DISABLE_RSPAMD=${DISABLE_RSPAMD}
|
||||||
|
- DISABLE_ROUNDCUBE=${DISABLE_ROUNDCUBE}
|
||||||
|
- HTTPS=${HTTPS}
|
||||||
|
- ${SSL_CERT_PATH}:/data/ssl/server.crt:ro
|
||||||
|
- ${SSL_KEY_PATH}:/data/ssl/server.key:ro
|
||||||
|
volumes:
|
||||||
|
- ./data:/data
|
||||||
|
|
||||||
|
logging:
|
||||||
|
driver: "json-file"
|
||||||
|
options:
|
||||||
|
max-size: "10m"
|
||||||
|
max-file: "3"
|
||||||
49
setup_backup.sh
Normal file
49
setup_backup.sh
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Load environment variables
|
||||||
|
if [ -f .env ]; then
|
||||||
|
export $(grep -v '^#' .env | xargs)
|
||||||
|
else
|
||||||
|
echo "Error: .env file not found."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$ENABLE_BACKUPS" != "TRUE" ]; then
|
||||||
|
echo "Backups are disabled in .env. Exiting."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
PROJECT_DIR=$(pwd)
|
||||||
|
BACKUP_DIR="${PROJECT_DIR}/backups"
|
||||||
|
BACKUP_SCRIPT="${PROJECT_DIR}/run_backup.sh"
|
||||||
|
|
||||||
|
# Create backups directory
|
||||||
|
mkdir -p "$BACKUP_DIR"
|
||||||
|
|
||||||
|
# Create the actual backup script that cron will run
|
||||||
|
cat <<EOF > "$BACKUP_SCRIPT"
|
||||||
|
#!/bin/bash
|
||||||
|
# Auto-generated backup script
|
||||||
|
mkdir -p "$BACKUP_DIR"
|
||||||
|
cd "$PROJECT_DIR"
|
||||||
|
|
||||||
|
# Create new backup
|
||||||
|
FILENAME="mail_backup_\$(date +%F_%H-%M-%S).tar.gz"
|
||||||
|
tar -czvf "$BACKUP_DIR/\$FILENAME" ./data/ > /dev/null 2>&1
|
||||||
|
|
||||||
|
# Delete old backups based on retention days
|
||||||
|
find "$BACKUP_DIR" -type f -name "mail_backup_*.tar.gz" -mtime +$BACKUP_RETENTION_DAYS -exec rm {} \;
|
||||||
|
EOF
|
||||||
|
|
||||||
|
chmod +x "$BACKUP_SCRIPT"
|
||||||
|
|
||||||
|
# Remove existing cron job for this backup script to avoid duplicates
|
||||||
|
crontab -l | grep -v "$BACKUP_SCRIPT" | crontab -
|
||||||
|
|
||||||
|
# Add new cron job
|
||||||
|
(crontab -l 2>/dev/null; echo "$BACKUP_CRON $BACKUP_SCRIPT >> $PROJECT_DIR/backup.log 2>&1") | crontab -
|
||||||
|
|
||||||
|
echo "Backup automation configured successfully!"
|
||||||
|
echo "Schedule: $BACKUP_CRON"
|
||||||
|
echo "Retention: $BACKUP_RETENTION_DAYS days"
|
||||||
|
echo "Backups will be saved to: $BACKUP_DIR"
|
||||||
Reference in New Issue
Block a user