total 20
drwxr-xr-x  2 root root 4096 Sep 11 10:39 .
drwxr-xr-x 10 root root 4096 Sep 11 11:57 ..
-rw-r--r--  1 root root 1055 Sep 11 10:39 bulkmailer-api.service.example
-rw-r--r--  1 root root  719 Sep 11 10:39 bulkmailer-worker.service.example
-rw-r--r--  1 root root 2361 Sep 11 10:38 nginx.conf.example
---contents---
== bulkmailer-api.service.example ==
# Example systemd unit for running the API WITHOUT Docker (bare-metal / VM).
# Install to /etc/systemd/system/bulkmailer-api.service, then:
#   sudo systemctl daemon-reload
#   sudo systemctl enable --now bulkmailer-api
#
# Assumes:
#   - Code deployed to /opt/bulkmailer
#   - Python virtualenv at /opt/bulkmailer/venv (pip install -r requirements.txt)
#   - .env file present at /opt/bulkmailer/.env
#   - Postgres and Redis already running/reachable per DATABASE_URL/REDIS_URL

[Unit]
Description=Bulk Gmail Mailer API (gunicorn+uvicorn)
After=network.target postgresql.service redis.service

[Service]
Type=simple
User=bulkmailer
Group=bulkmailer
WorkingDirectory=/opt/bulkmailer
EnvironmentFile=/opt/bulkmailer/.env
ExecStart=/opt/bulkmailer/venv/bin/gunicorn app.main:app \
    -k uvicorn.workers.UvicornWorker \
    --bind 0.0.0.0:8000 \
    --workers 2 \
    --timeout 60 \
    --access-logfile - \
    --error-logfile -
Restart=on-failure
RestartSec=5

== bulkmailer-worker.service.example ==
# Example systemd unit for the Celery worker WITHOUT Docker (bare-metal / VM).
# Install to /etc/systemd/system/bulkmailer-worker.service, then:
#   sudo systemctl daemon-reload
#   sudo systemctl enable --now bulkmailer-worker

[Unit]
Description=Bulk Gmail Mailer Celery worker (real Gmail sending)
After=network.target postgresql.service redis.service

[Service]
Type=simple
User=bulkmailer
Group=bulkmailer
WorkingDirectory=/opt/bulkmailer
EnvironmentFile=/opt/bulkmailer/.env
ExecStart=/opt/bulkmailer/venv/bin/celery -A app.worker.celery_app worker \
    --loglevel=INFO -Q send,control
Restart=on-failure
RestartSec=5
NoNewPrivileges=true
ProtectSystem=full
PrivateTmp=true

[Install]
WantedBy=multi-user.target

== nginx.conf.example ==
# Example reverse-proxy config terminating HTTPS in front of the `api`
# container (docker-compose service on 127.0.0.1:8000).
#
# Install certbot (Let's Encrypt) or bring your own cert/key, then:
#   sudo cp nginx.conf.example /etc/nginx/sites-available/bulkmailer
#   sudo ln -s /etc/nginx/sites-available/bulkmailer /etc/nginx/sites-enabled/
#   sudo nginx -t && sudo systemctl reload nginx
#
# Replace `your-domain.example.com` and the cert paths below.

server {
    listen 80;
    server_name your-domain.example.com;
    # Redirect all HTTP to HTTPS
    location / {
        return 301 https://$host$request_uri;
    }
    # Let's Encrypt HTTP-01 challenge path (certbot webroot mode)
    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }
}

server {
    listen 443 ssl http2;
    server_name your-domain.example.com;

    ssl_certificate     /etc/letsencrypt/live/your-domain.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/your-domain.example.com/privkey.pem;
    ssl_protocols       TLSv1.2 TLSv1.3;

