Initial AnonAddy Cloudron package
This commit is contained in:
28
CloudronManifest.json
Normal file
28
CloudronManifest.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"id": "org.anonaddy.cloudron",
|
||||
"title": "AnonAddy",
|
||||
"author": "AnonAddy Team",
|
||||
"description": "Anonymous email forwarding service that lets you create unlimited email aliases to protect your real email address from spam and tracking.",
|
||||
"tagline": "Anonymous email forwarding",
|
||||
"version": "1.3.5",
|
||||
"healthCheckPath": "/",
|
||||
"httpPort": 8000,
|
||||
"addons": {
|
||||
"localstorage": {},
|
||||
"mysql": {},
|
||||
"redis": {},
|
||||
"sendmail": {}
|
||||
},
|
||||
"manifestVersion": 2,
|
||||
"website": "https://anonaddy.com",
|
||||
"contactEmail": "support@anonaddy.com",
|
||||
"minBoxVersion": "7.0.0",
|
||||
"maxBoxVersion": "8.0.0",
|
||||
"mediaLinks": [
|
||||
"https://anonaddy.com/assets/img/logo.svg"
|
||||
],
|
||||
"postInstallMessage": "AnonAddy is now installed!\n\nIMPORTANT SETUP STEPS:\n\n1. Login with the default admin credentials:\n Email: admin@example.com\n Password: password\n\n2. IMMEDIATELY change the admin password in Settings\n\n3. Configure your domain in Settings -> Domains\n\n4. Set up DNS records:\n - MX record pointing to your Cloudron server\n - SPF record for email authentication\n - DKIM keys (generated in Settings)\n\n5. Configure SMTP settings to receive emails\n\nFor more information, visit: https://anonaddy.com/help",
|
||||
"icon": "file://logo.png",
|
||||
"memoryLimit": 512000000,
|
||||
"optionalSso": true
|
||||
}
|
||||
96
Dockerfile
Normal file
96
Dockerfile
Normal file
@@ -0,0 +1,96 @@
|
||||
FROM cloudron/base:5.0.0
|
||||
|
||||
# Install dependencies
|
||||
RUN apt-get update && \
|
||||
apt-get install -y \
|
||||
php8.3 \
|
||||
php8.3-cli \
|
||||
php8.3-fpm \
|
||||
php8.3-mysql \
|
||||
php8.3-redis \
|
||||
php8.3-curl \
|
||||
php8.3-gd \
|
||||
php8.3-mbstring \
|
||||
php8.3-xml \
|
||||
php8.3-zip \
|
||||
php8.3-bcmath \
|
||||
php8.3-intl \
|
||||
php8.3-gnupg \
|
||||
php8.3-gmp \
|
||||
php8.3-imagick \
|
||||
php8.3-mailparse \
|
||||
composer \
|
||||
nginx \
|
||||
supervisor \
|
||||
postfix \
|
||||
rspamd \
|
||||
redis-tools \
|
||||
mysql-client \
|
||||
gnupg \
|
||||
git \
|
||||
curl \
|
||||
nodejs \
|
||||
npm && \
|
||||
apt-get clean && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /app/code
|
||||
|
||||
# Clone AnonAddy repository
|
||||
RUN git clone --branch v1.3.5 https://github.com/anonaddy/anonaddy.git /app/code && \
|
||||
chown -R cloudron:cloudron /app/code
|
||||
|
||||
# Install PHP dependencies
|
||||
RUN cd /app/code && \
|
||||
composer install --no-dev --optimize-autoloader --no-interaction && \
|
||||
chown -R cloudron:cloudron /app/code/vendor
|
||||
|
||||
# Install Node dependencies and build assets
|
||||
RUN cd /app/code && \
|
||||
npm install && \
|
||||
npm run prod && \
|
||||
rm -rf node_modules && \
|
||||
chown -R cloudron:cloudron /app/code/public
|
||||
|
||||
# Copy configuration files
|
||||
COPY nginx.conf /etc/nginx/sites-available/default
|
||||
COPY supervisor.conf /etc/supervisor/conf.d/anonaddy.conf
|
||||
COPY start.sh /app/code/start.sh
|
||||
COPY postfix-main.cf /tmp/postfix-main.cf
|
||||
COPY postfix-master.cf /tmp/postfix-master.cf
|
||||
|
||||
# Initialize data directory structure
|
||||
RUN mkdir -p /tmp/data && \
|
||||
mkdir -p /tmp/data/storage && \
|
||||
mkdir -p /tmp/data/storage/logs && \
|
||||
mkdir -p /tmp/data/storage/framework && \
|
||||
mkdir -p /tmp/data/storage/framework/cache && \
|
||||
mkdir -p /tmp/data/storage/framework/sessions && \
|
||||
mkdir -p /tmp/data/storage/framework/views && \
|
||||
mkdir -p /tmp/data/storage/app && \
|
||||
mkdir -p /tmp/data/storage/app/public && \
|
||||
mkdir -p /tmp/data/dkim && \
|
||||
mkdir -p /tmp/data/postfix && \
|
||||
mkdir -p /tmp/data/rspamd && \
|
||||
chown -R cloudron:cloudron /tmp/data
|
||||
|
||||
# Set permissions
|
||||
RUN chmod +x /app/code/start.sh && \
|
||||
chown -R cloudron:cloudron /app/code && \
|
||||
chmod -R 755 /app/code/storage && \
|
||||
chmod -R 755 /app/code/bootstrap/cache
|
||||
|
||||
# Configure PHP-FPM to run as cloudron user
|
||||
RUN sed -i 's/user = www-data/user = cloudron/g' /etc/php/8.3/fpm/pool.d/www.conf && \
|
||||
sed -i 's/group = www-data/group = cloudron/g' /etc/php/8.3/fpm/pool.d/www.conf && \
|
||||
sed -i 's/listen.owner = www-data/listen.owner = cloudron/g' /etc/php/8.3/fpm/pool.d/www.conf && \
|
||||
sed -i 's/listen.group = www-data/listen.group = cloudron/g' /etc/php/8.3/fpm/pool.d/www.conf
|
||||
|
||||
# Configure PHP to log to stderr
|
||||
RUN sed -i 's/;catch_workers_output = yes/catch_workers_output = yes/g' /etc/php/8.3/fpm/pool.d/www.conf && \
|
||||
sed -i 's/;php_admin_flag[log_errors] = on/php_admin_flag[log_errors] = on/g' /etc/php/8.3/fpm/pool.d/www.conf
|
||||
|
||||
EXPOSE 8000 25
|
||||
|
||||
CMD ["/app/code/start.sh"]
|
||||
297
README.md
Normal file
297
README.md
Normal file
@@ -0,0 +1,297 @@
|
||||
# AnonAddy Cloudron Package
|
||||
|
||||
This is a complete Cloudron package for [AnonAddy](https://anonaddy.com), an open-source anonymous email forwarding service.
|
||||
|
||||
## Features
|
||||
|
||||
- Anonymous email forwarding with unlimited aliases
|
||||
- Custom domain support
|
||||
- GPG/OpenPGP email encryption
|
||||
- Reply anonymously without revealing your real email
|
||||
- MySQL database for data storage
|
||||
- Redis for caching and queues
|
||||
- Postfix for SMTP email handling
|
||||
- Rspamd for spam filtering
|
||||
- Laravel queue worker for background jobs
|
||||
- Automatic database migrations
|
||||
|
||||
## Package Contents
|
||||
|
||||
- `CloudronManifest.json` - Cloudron package manifest
|
||||
- `Dockerfile` - Container image definition
|
||||
- `start.sh` - Initialization and startup script
|
||||
- `nginx.conf` - NGINX web server configuration
|
||||
- `supervisor.conf` - Process supervisor configuration
|
||||
- `postfix-main.cf` - Postfix main configuration
|
||||
- `postfix-master.cf` - Postfix master process configuration
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. Cloudron CLI installed and configured
|
||||
2. Docker access (handled by Cloudron build service)
|
||||
3. Cloudron instance running version 7.0.0 or higher
|
||||
4. Domain with proper DNS configuration
|
||||
|
||||
## Building the Package
|
||||
|
||||
Build the package using the Cloudron build service:
|
||||
|
||||
```bash
|
||||
cloudron build \
|
||||
--set-build-service builder.docker.due.ren \
|
||||
--build-service-token e3265de06b1d0e7bb38400539012a8433a74c2c96a17955e \
|
||||
--set-repository andreasdueren/anonaddy-cloudron \
|
||||
--tag 0.1.0
|
||||
```
|
||||
|
||||
The build process will:
|
||||
1. Create a Docker image based on cloudron/base:5.0.0
|
||||
2. Install PHP 8.3, NGINX, Postfix, Rspamd, and other dependencies
|
||||
3. Clone AnonAddy v1.3.5 from GitHub
|
||||
4. Install Composer dependencies
|
||||
5. Build frontend assets
|
||||
6. Configure all services
|
||||
|
||||
## Installation
|
||||
|
||||
Install the package on your Cloudron instance:
|
||||
|
||||
```bash
|
||||
cloudron install \
|
||||
--location anonaddy.yourdomain.com \
|
||||
--image andreasdueren/anonaddy-cloudron:0.1.0
|
||||
```
|
||||
|
||||
Replace `anonaddy.yourdomain.com` with your desired subdomain.
|
||||
|
||||
## Post-Installation Setup
|
||||
|
||||
### 1. Initial Login
|
||||
|
||||
After installation, you'll see a post-install message with default credentials:
|
||||
|
||||
- Email: `admin@example.com`
|
||||
- Password: `password`
|
||||
|
||||
**IMPORTANT:** Change this password immediately after first login!
|
||||
|
||||
### 2. DNS Configuration
|
||||
|
||||
Configure the following DNS records for your domain:
|
||||
|
||||
#### MX Record
|
||||
```
|
||||
@ IN MX 10 anonaddy.yourdomain.com.
|
||||
```
|
||||
|
||||
#### SPF Record
|
||||
```
|
||||
@ IN TXT "v=spf1 mx ~all"
|
||||
```
|
||||
|
||||
#### DKIM Keys
|
||||
1. Login to AnonAddy
|
||||
2. Navigate to Settings → DKIM
|
||||
3. Generate DKIM keys
|
||||
4. Add the provided DNS TXT record
|
||||
|
||||
Example:
|
||||
```
|
||||
default._domainkey IN TXT "v=DKIM1; k=rsa; p=YOUR_PUBLIC_KEY_HERE"
|
||||
```
|
||||
|
||||
#### DMARC Record (Optional but recommended)
|
||||
```
|
||||
_dmarc IN TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc@yourdomain.com"
|
||||
```
|
||||
|
||||
### 3. Configure Domain Settings
|
||||
|
||||
1. Login to AnonAddy
|
||||
2. Go to Settings → Domains
|
||||
3. Add your custom domain(s)
|
||||
4. Verify domain ownership
|
||||
|
||||
### 4. Configure Email Recipients
|
||||
|
||||
1. Add recipient email addresses (your real email addresses)
|
||||
2. Verify recipient addresses via email confirmation
|
||||
3. Set default recipient for new aliases
|
||||
|
||||
## Usage
|
||||
|
||||
### Creating Aliases
|
||||
|
||||
AnonAddy supports multiple alias formats:
|
||||
|
||||
1. **Standard Aliases:** `anything@yourdomain.com`
|
||||
2. **UUID Aliases:** `94960540-f914-42e0-9c50-6fecbe7f5061@yourdomain.com`
|
||||
3. **Custom Aliases:** `newsletter@yourdomain.com`
|
||||
|
||||
### Replying Anonymously
|
||||
|
||||
Reply to forwarded emails directly. AnonAddy will send the reply through the alias, maintaining your anonymity.
|
||||
|
||||
### Encryption
|
||||
|
||||
Enable GPG encryption in Settings to encrypt all incoming emails with your public key.
|
||||
|
||||
## Architecture
|
||||
|
||||
### Services
|
||||
|
||||
The package runs multiple services via supervisor:
|
||||
|
||||
- **NGINX** - Web server (port 8000)
|
||||
- **PHP-FPM** - PHP processor
|
||||
- **Laravel Queue Worker** - Background job processing
|
||||
- **Laravel Scheduler** - Cron job handler
|
||||
- **Postfix** - SMTP server (port 25)
|
||||
- **Rspamd** - Spam filtering (port 11334)
|
||||
|
||||
### Data Persistence
|
||||
|
||||
All persistent data is stored in `/app/data`:
|
||||
|
||||
- `/app/data/storage` - Laravel storage (logs, cache, sessions)
|
||||
- `/app/data/dkim` - DKIM keys
|
||||
- `/app/data/postfix` - Postfix spool
|
||||
- `/app/data/rspamd` - Rspamd data
|
||||
- `/app/data/app_key` - Laravel application key
|
||||
- `/app/data/anonaddy_secret` - AnonAddy secret for anonymous replies
|
||||
|
||||
### Database
|
||||
|
||||
The package uses:
|
||||
- **MySQL** - Main database (via Cloudron addon)
|
||||
- **Redis** - Cache and queue backend (via Cloudron addon)
|
||||
|
||||
### Email Integration
|
||||
|
||||
- **Inbound:** Postfix receives emails on port 25
|
||||
- **Outbound:** Cloudron SMTP addon for sending emails
|
||||
- **Spam Filtering:** Rspamd filters incoming emails
|
||||
- **Virtual Aliases:** Postfix queries Rspamd for alias lookups
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### View Logs
|
||||
|
||||
```bash
|
||||
cloudron logs --app anonaddy.yourdomain.com -f
|
||||
```
|
||||
|
||||
### Shell Access
|
||||
|
||||
```bash
|
||||
cloudron exec --app anonaddy.yourdomain.com
|
||||
```
|
||||
|
||||
### Common Issues
|
||||
|
||||
#### Emails Not Receiving
|
||||
|
||||
1. Check MX records: `dig MX yourdomain.com`
|
||||
2. Verify port 25 is open on your Cloudron server
|
||||
3. Check Postfix logs: `cloudron logs --app anonaddy.yourdomain.com | grep postfix`
|
||||
4. Test SMTP: `telnet anonaddy.yourdomain.com 25`
|
||||
|
||||
#### Emails Marked as Spam
|
||||
|
||||
1. Ensure SPF record is configured
|
||||
2. Add DKIM keys in Settings
|
||||
3. Configure DMARC record
|
||||
4. Check your server's IP reputation
|
||||
|
||||
#### Queue Not Processing
|
||||
|
||||
1. Check Laravel queue worker: `cloudron logs --app anonaddy.yourdomain.com | grep queue`
|
||||
2. Verify Redis connection
|
||||
3. Restart the app: `cloudron restart --app anonaddy.yourdomain.com`
|
||||
|
||||
#### Application Errors
|
||||
|
||||
1. Check storage permissions in `/app/data/storage`
|
||||
2. Clear cache: `cloudron exec --app anonaddy.yourdomain.com 'php artisan cache:clear'`
|
||||
3. Run migrations: `cloudron exec --app anonaddy.yourdomain.com 'php artisan migrate'`
|
||||
|
||||
### Database Migrations
|
||||
|
||||
Migrations run automatically on startup. To manually run migrations:
|
||||
|
||||
```bash
|
||||
cloudron exec --app anonaddy.yourdomain.com
|
||||
cd /app/code
|
||||
php artisan migrate
|
||||
```
|
||||
|
||||
### Clear Cache
|
||||
|
||||
```bash
|
||||
cloudron exec --app anonaddy.yourdomain.com
|
||||
cd /app/code
|
||||
php artisan cache:clear
|
||||
php artisan config:clear
|
||||
php artisan view:clear
|
||||
```
|
||||
|
||||
## Updating
|
||||
|
||||
To update to a new version:
|
||||
|
||||
1. Build the new version with updated tag
|
||||
2. Uninstall the old version: `cloudron uninstall --app anonaddy.yourdomain.com`
|
||||
3. Install the new version: `cloudron install --location anonaddy.yourdomain.com --image andreasdueren/anonaddy-cloudron:NEW_VERSION`
|
||||
|
||||
**Note:** Always backup your data before updating!
|
||||
|
||||
## Development
|
||||
|
||||
### Local Testing
|
||||
|
||||
1. Clone the repository
|
||||
2. Make changes to configuration files
|
||||
3. Build locally: `cloudron build --tag test`
|
||||
4. Install for testing: `cloudron install --location test.anonaddy.local --image andreasdueren/anonaddy-cloudron:test`
|
||||
|
||||
### File Locations
|
||||
|
||||
- Application code: `/app/code`
|
||||
- Persistent data: `/app/data`
|
||||
- NGINX config: `/etc/nginx/sites-available/default`
|
||||
- PHP-FPM config: `/etc/php/8.3/fpm/pool.d/www.conf`
|
||||
- Postfix config: `/etc/postfix/main.cf`
|
||||
- Supervisor config: `/etc/supervisor/conf.d/anonaddy.conf`
|
||||
|
||||
## Security Considerations
|
||||
|
||||
1. **Change Default Password:** Immediately after installation
|
||||
2. **HTTPS Only:** Cloudron automatically provides SSL/TLS
|
||||
3. **SPF/DKIM/DMARC:** Configure all email authentication records
|
||||
4. **Firewall:** Ensure only necessary ports (80, 443, 25) are open
|
||||
5. **Updates:** Keep AnonAddy updated to latest version
|
||||
6. **Backups:** Regular backups via Cloudron
|
||||
|
||||
## Resources
|
||||
|
||||
- [AnonAddy Website](https://anonaddy.com)
|
||||
- [AnonAddy GitHub](https://github.com/anonaddy/anonaddy)
|
||||
- [AnonAddy Documentation](https://anonaddy.com/help)
|
||||
- [Cloudron Documentation](https://docs.cloudron.io)
|
||||
- [Cloudron Packaging Guide](https://docs.cloudron.io/packaging/)
|
||||
|
||||
## License
|
||||
|
||||
AnonAddy is open-source software licensed under the MIT license.
|
||||
|
||||
## Support
|
||||
|
||||
For issues with:
|
||||
- **AnonAddy application:** https://github.com/anonaddy/anonaddy/issues
|
||||
- **Cloudron package:** https://git.due.ren/andreas/anonaddy.git
|
||||
- **Cloudron platform:** https://forum.cloudron.io
|
||||
|
||||
## Credits
|
||||
|
||||
- AnonAddy by [Will Browning](https://github.com/willbrowningme)
|
||||
- Cloudron package by Andreas Dueren
|
||||
85
nginx.conf
Normal file
85
nginx.conf
Normal file
@@ -0,0 +1,85 @@
|
||||
server {
|
||||
listen 8000 default_server;
|
||||
listen [::]:8000 default_server;
|
||||
|
||||
server_name _;
|
||||
|
||||
root /app/code/public;
|
||||
index index.php index.html;
|
||||
|
||||
# Logging to stdout/stderr
|
||||
access_log /dev/stdout;
|
||||
error_log /dev/stderr;
|
||||
|
||||
# Security headers
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-XSS-Protection "1; mode=block" always;
|
||||
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||
|
||||
# Client body size
|
||||
client_max_body_size 25M;
|
||||
|
||||
# Gzip compression
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_proxied any;
|
||||
gzip_comp_level 6;
|
||||
gzip_types text/plain text/css text/xml text/javascript application/json application/javascript application/xml+rss application/rss+xml font/truetype font/opentype application/vnd.ms-fontobject image/svg+xml;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.php?$query_string;
|
||||
}
|
||||
|
||||
location = /favicon.ico {
|
||||
access_log off;
|
||||
log_not_found off;
|
||||
}
|
||||
|
||||
location = /robots.txt {
|
||||
access_log off;
|
||||
log_not_found off;
|
||||
}
|
||||
|
||||
# Deny access to hidden files
|
||||
location ~ /\. {
|
||||
deny all;
|
||||
access_log off;
|
||||
log_not_found off;
|
||||
}
|
||||
|
||||
# PHP-FPM configuration
|
||||
location ~ \.php$ {
|
||||
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
|
||||
fastcgi_index index.php;
|
||||
include fastcgi_params;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
fastcgi_param PATH_INFO $fastcgi_path_info;
|
||||
fastcgi_param HTTP_PROXY "";
|
||||
|
||||
# Proxy headers for Cloudron
|
||||
fastcgi_param HTTP_X_FORWARDED_FOR $proxy_add_x_forwarded_for;
|
||||
fastcgi_param HTTP_X_FORWARDED_PROTO $scheme;
|
||||
fastcgi_param HTTP_HOST $host;
|
||||
|
||||
fastcgi_intercept_errors off;
|
||||
fastcgi_buffer_size 16k;
|
||||
fastcgi_buffers 4 16k;
|
||||
fastcgi_connect_timeout 300;
|
||||
fastcgi_send_timeout 300;
|
||||
fastcgi_read_timeout 300;
|
||||
}
|
||||
|
||||
# Static files caching
|
||||
location ~* \.(jpg|jpeg|gif|png|css|js|ico|xml|svg|woff|woff2|ttf|eot)$ {
|
||||
expires 30d;
|
||||
access_log off;
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
|
||||
# Deny access to sensitive files
|
||||
location ~ /\.(?!well-known).* {
|
||||
deny all;
|
||||
}
|
||||
}
|
||||
67
postfix-main.cf
Normal file
67
postfix-main.cf
Normal file
@@ -0,0 +1,67 @@
|
||||
# Basic configuration
|
||||
compatibility_level = 2
|
||||
smtpd_banner = $myhostname ESMTP
|
||||
biff = no
|
||||
append_dot_mydomain = no
|
||||
readme_directory = no
|
||||
|
||||
# TLS parameters
|
||||
smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
|
||||
smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
|
||||
smtpd_use_tls=yes
|
||||
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
|
||||
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
|
||||
smtpd_tls_security_level = may
|
||||
smtp_tls_security_level = may
|
||||
smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
|
||||
smtp_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
|
||||
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
|
||||
smtp_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
|
||||
|
||||
# Network and domain settings
|
||||
myhostname = CLOUDRON_APP_DOMAIN
|
||||
myorigin = CLOUDRON_MAIL_DOMAIN
|
||||
mydestination = CLOUDRON_APP_DOMAIN, localhost
|
||||
relayhost =
|
||||
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
|
||||
mailbox_size_limit = 0
|
||||
recipient_delimiter = +
|
||||
inet_interfaces = all
|
||||
inet_protocols = all
|
||||
|
||||
# Virtual alias domains
|
||||
virtual_alias_domains = CLOUDRON_APP_DOMAIN
|
||||
virtual_alias_maps = tcp:127.0.0.1:11334
|
||||
|
||||
# Queue and message settings
|
||||
message_size_limit = 26214400
|
||||
mailbox_size_limit = 0
|
||||
maximal_queue_lifetime = 1d
|
||||
bounce_queue_lifetime = 1d
|
||||
|
||||
# Milter configuration for Rspamd
|
||||
smtpd_milters = inet:127.0.0.1:11332
|
||||
non_smtpd_milters = inet:127.0.0.1:11332
|
||||
milter_protocol = 6
|
||||
milter_mail_macros = i {mail_addr} {client_addr} {client_name} {auth_authen}
|
||||
milter_default_action = accept
|
||||
|
||||
# SMTP restrictions
|
||||
smtpd_recipient_restrictions =
|
||||
permit_mynetworks,
|
||||
reject_unauth_destination,
|
||||
reject_non_fqdn_recipient,
|
||||
reject_unknown_recipient_domain
|
||||
|
||||
smtpd_helo_restrictions =
|
||||
permit_mynetworks,
|
||||
reject_invalid_helo_hostname,
|
||||
reject_non_fqdn_helo_hostname
|
||||
|
||||
smtpd_sender_restrictions =
|
||||
permit_mynetworks,
|
||||
reject_non_fqdn_sender,
|
||||
reject_unknown_sender_domain
|
||||
|
||||
# Logging
|
||||
maillog_file = /dev/stdout
|
||||
41
postfix-master.cf
Normal file
41
postfix-master.cf
Normal file
@@ -0,0 +1,41 @@
|
||||
# ==========================================================================
|
||||
# service type private unpriv chroot wakeup maxproc command + args
|
||||
# (yes) (yes) (no) (never) (100)
|
||||
# ==========================================================================
|
||||
smtp inet n - n - - smtpd
|
||||
pickup unix n - n 60 1 pickup
|
||||
cleanup unix n - n - 0 cleanup
|
||||
qmgr unix n - n 300 1 qmgr
|
||||
tlsmgr unix - - n 1000? 1 tlsmgr
|
||||
rewrite unix - - n - - trivial-rewrite
|
||||
bounce unix - - n - 0 bounce
|
||||
defer unix - - n - 0 bounce
|
||||
trace unix - - n - 0 bounce
|
||||
verify unix - - n - 1 verify
|
||||
flush unix n - n 1000? 0 flush
|
||||
proxymap unix - - n - - proxymap
|
||||
proxywrite unix - - n - 1 proxymap
|
||||
smtp unix - - n - - smtp
|
||||
relay unix - - n - - smtp
|
||||
showq unix n - n - - showq
|
||||
error unix - - n - - error
|
||||
retry unix - - n - - error
|
||||
discard unix - - n - - discard
|
||||
local unix - n n - - local
|
||||
virtual unix - n n - - virtual
|
||||
lmtp unix - - n - - lmtp
|
||||
anvil unix - - n - 1 anvil
|
||||
scache unix - - n - 1 scache
|
||||
maildrop unix - n n - - pipe
|
||||
flags=DRhu user=vmail argv=/usr/bin/maildrop -d ${recipient}
|
||||
uucp unix - n n - - pipe
|
||||
flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient)
|
||||
ifmail unix - n n - - pipe
|
||||
flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient)
|
||||
bsmtp unix - n n - - pipe
|
||||
flags=Fq. user=bsmtp argv=/usr/lib/bsmtp/bsmtp -t$nexthop -f$sender $recipient
|
||||
scalemail-backend unix - n n - 2 pipe
|
||||
flags=R user=scalemail argv=/usr/lib/scalemail/bin/scalemail-store ${nexthop} ${user} ${extension}
|
||||
mailman unix - n n - - pipe
|
||||
flags=FR user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py
|
||||
${nexthop} ${user}
|
||||
150
start.sh
Normal file
150
start.sh
Normal file
@@ -0,0 +1,150 @@
|
||||
#!/bin/bash
|
||||
set -eu
|
||||
|
||||
echo "==> Starting AnonAddy initialization"
|
||||
|
||||
# Initialize /app/data if empty
|
||||
if [ ! -d "/app/data/storage" ]; then
|
||||
echo "==> Initializing /app/data from /tmp/data"
|
||||
cp -r /tmp/data/* /app/data/
|
||||
chown -R cloudron:cloudron /app/data
|
||||
fi
|
||||
|
||||
# Ensure proper permissions
|
||||
chown -R cloudron:cloudron /app/data
|
||||
chmod -R 755 /app/data/storage
|
||||
|
||||
# Link storage directory to Laravel storage
|
||||
rm -rf /app/code/storage
|
||||
ln -sf /app/data/storage /app/code/storage
|
||||
|
||||
# Create .env file
|
||||
echo "==> Configuring application environment"
|
||||
cat > /app/code/.env <<EOF
|
||||
APP_NAME="AnonAddy"
|
||||
APP_ENV=production
|
||||
APP_DEBUG=false
|
||||
APP_URL=${CLOUDRON_APP_ORIGIN}
|
||||
|
||||
# Database Configuration
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=${CLOUDRON_MYSQL_HOST}
|
||||
DB_PORT=${CLOUDRON_MYSQL_PORT}
|
||||
DB_DATABASE=${CLOUDRON_MYSQL_DATABASE}
|
||||
DB_USERNAME=${CLOUDRON_MYSQL_USERNAME}
|
||||
DB_PASSWORD=${CLOUDRON_MYSQL_PASSWORD}
|
||||
|
||||
# Redis Configuration
|
||||
REDIS_HOST=${CLOUDRON_REDIS_HOST}
|
||||
REDIS_PASSWORD=${CLOUDRON_REDIS_PASSWORD}
|
||||
REDIS_PORT=${CLOUDRON_REDIS_PORT}
|
||||
|
||||
# Mail Configuration
|
||||
MAIL_MAILER=smtp
|
||||
MAIL_HOST=${CLOUDRON_MAIL_SMTP_SERVER}
|
||||
MAIL_PORT=${CLOUDRON_MAIL_SMTP_PORT}
|
||||
MAIL_USERNAME=${CLOUDRON_MAIL_SMTP_USERNAME}
|
||||
MAIL_PASSWORD=${CLOUDRON_MAIL_SMTP_PASSWORD}
|
||||
MAIL_ENCRYPTION=tls
|
||||
MAIL_FROM_ADDRESS=noreply@${CLOUDRON_APP_DOMAIN}
|
||||
MAIL_FROM_NAME="AnonAddy"
|
||||
|
||||
# AnonAddy Configuration
|
||||
ANONADDY_DOMAIN=${CLOUDRON_APP_DOMAIN}
|
||||
ANONADDY_HOSTNAME=${CLOUDRON_APP_DOMAIN}
|
||||
ANONADDY_SIGNING_KEY_FINGERPRINT=""
|
||||
|
||||
# Queue Configuration
|
||||
QUEUE_CONNECTION=redis
|
||||
QUEUE_DRIVER=redis
|
||||
|
||||
# Session Configuration
|
||||
SESSION_DRIVER=redis
|
||||
SESSION_LIFETIME=120
|
||||
|
||||
# Cache Configuration
|
||||
CACHE_DRIVER=redis
|
||||
|
||||
# Log Configuration
|
||||
LOG_CHANNEL=stderr
|
||||
LOG_LEVEL=info
|
||||
|
||||
# Security
|
||||
BCRYPT_ROUNDS=12
|
||||
EOF
|
||||
|
||||
# Generate APP_KEY if it doesn't exist
|
||||
if [ ! -f "/app/data/app_key" ]; then
|
||||
echo "==> Generating application key"
|
||||
cd /app/code
|
||||
sudo -u cloudron php artisan key:generate --force
|
||||
# Save the key to persistent storage
|
||||
grep "APP_KEY=" /app/code/.env | cut -d= -f2 > /app/data/app_key
|
||||
else
|
||||
echo "==> Using existing application key"
|
||||
APP_KEY=$(cat /app/data/app_key)
|
||||
sed -i "s|APP_KEY=.*|APP_KEY=${APP_KEY}|g" /app/code/.env
|
||||
fi
|
||||
|
||||
# Generate ANONADDY_SECRET if it doesn't exist
|
||||
if [ ! -f "/app/data/anonaddy_secret" ]; then
|
||||
echo "==> Generating AnonAddy secret"
|
||||
ANONADDY_SECRET=$(openssl rand -hex 32)
|
||||
echo "$ANONADDY_SECRET" > /app/data/anonaddy_secret
|
||||
echo "ANONADDY_SECRET=${ANONADDY_SECRET}" >> /app/code/.env
|
||||
else
|
||||
echo "==> Using existing AnonAddy secret"
|
||||
ANONADDY_SECRET=$(cat /app/data/anonaddy_secret)
|
||||
echo "ANONADDY_SECRET=${ANONADDY_SECRET}" >> /app/code/.env
|
||||
fi
|
||||
|
||||
# Set proper ownership
|
||||
chown cloudron:cloudron /app/code/.env
|
||||
chmod 640 /app/code/.env
|
||||
|
||||
# Run database migrations
|
||||
echo "==> Running database migrations"
|
||||
cd /app/code
|
||||
sudo -u cloudron php artisan migrate --force
|
||||
|
||||
# Clear and cache configuration
|
||||
echo "==> Optimizing application"
|
||||
sudo -u cloudron php artisan config:clear
|
||||
sudo -u cloudron php artisan cache:clear
|
||||
sudo -u cloudron php artisan view:clear
|
||||
sudo -u cloudron php artisan config:cache
|
||||
sudo -u cloudron php artisan route:cache
|
||||
|
||||
# Create default admin user if database is empty
|
||||
USER_COUNT=$(sudo -u cloudron php artisan tinker --execute="echo \App\Models\User::count();")
|
||||
if [ "$USER_COUNT" -eq "0" ]; then
|
||||
echo "==> Creating default admin user"
|
||||
sudo -u cloudron php artisan tinker <<TINKER
|
||||
\$user = new \App\Models\User();
|
||||
\$user->username = 'admin';
|
||||
\$user->email = 'admin@example.com';
|
||||
\$user->password = bcrypt('password');
|
||||
\$user->save();
|
||||
echo "Default admin user created: admin@example.com / password";
|
||||
TINKER
|
||||
echo "==> IMPORTANT: Change the default password after first login!"
|
||||
fi
|
||||
|
||||
# Configure Postfix
|
||||
echo "==> Configuring Postfix"
|
||||
cp /tmp/postfix-main.cf /etc/postfix/main.cf
|
||||
cp /tmp/postfix-master.cf /etc/postfix/master.cf
|
||||
|
||||
# Update Postfix configuration with domain
|
||||
sed -i "s|CLOUDRON_APP_DOMAIN|${CLOUDRON_APP_DOMAIN}|g" /etc/postfix/main.cf
|
||||
sed -i "s|CLOUDRON_MAIL_DOMAIN|${CLOUDRON_MAIL_DOMAIN}|g" /etc/postfix/main.cf
|
||||
|
||||
# Create Postfix directories
|
||||
mkdir -p /app/data/postfix/spool
|
||||
mkdir -p /var/spool/postfix
|
||||
chown -R postfix:postfix /var/spool/postfix
|
||||
chown -R cloudron:cloudron /app/data/postfix
|
||||
|
||||
# Start services via supervisor
|
||||
echo "==> Starting services"
|
||||
exec /usr/bin/supervisord -c /etc/supervisor/supervisord.conf
|
||||
74
supervisor.conf
Normal file
74
supervisor.conf
Normal file
@@ -0,0 +1,74 @@
|
||||
[supervisord]
|
||||
nodaemon=true
|
||||
user=root
|
||||
logfile=/dev/null
|
||||
logfile_maxbytes=0
|
||||
pidfile=/run/supervisord.pid
|
||||
|
||||
[program:nginx]
|
||||
command=/usr/sbin/nginx -g "daemon off;"
|
||||
autostart=true
|
||||
autorestart=true
|
||||
priority=10
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
||||
|
||||
[program:php-fpm]
|
||||
command=/usr/sbin/php-fpm8.3 -F
|
||||
autostart=true
|
||||
autorestart=true
|
||||
priority=10
|
||||
user=cloudron
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
||||
|
||||
[program:laravel-queue]
|
||||
command=/usr/bin/php /app/code/artisan queue:work redis --sleep=3 --tries=3 --timeout=90
|
||||
directory=/app/code
|
||||
autostart=true
|
||||
autorestart=true
|
||||
priority=20
|
||||
user=cloudron
|
||||
numprocs=1
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
||||
stopwaitsecs=3600
|
||||
|
||||
[program:laravel-scheduler]
|
||||
command=/bin/bash -c "while true; do /usr/bin/php /app/code/artisan schedule:run --verbose --no-interaction; sleep 60; done"
|
||||
directory=/app/code
|
||||
autostart=true
|
||||
autorestart=true
|
||||
priority=20
|
||||
user=cloudron
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
||||
|
||||
[program:postfix]
|
||||
command=/usr/sbin/postfix start-fg
|
||||
autostart=true
|
||||
autorestart=true
|
||||
priority=15
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
||||
|
||||
[program:rspamd]
|
||||
command=/usr/bin/rspamd -f -u cloudron -g cloudron
|
||||
autostart=true
|
||||
autorestart=true
|
||||
priority=15
|
||||
user=cloudron
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
||||
Reference in New Issue
Block a user