Initial AnonAddy Cloudron package

This commit is contained in:
Your Name
2025-10-22 08:24:36 -06:00
commit da0f53a470
8 changed files with 838 additions and 0 deletions

28
CloudronManifest.json Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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