# Securing Your AcelleMail Install: A Post-Install Checklist

> Your AcelleMail install works the moment the web installer turns green — but two things now live on your server that didn't before: your subscribers' personal data, and your domain's sending reputation. This checklist secures both, in priority order, without turning you into a sysadmin. Most of it is config you set once.

- Canonical URL: https://acellesend.com/kb/articles/post-install-hardening-checklist
- Author: Daniel Reyes, Technical Editor
- Category: Installation & Setup — Server requirements, deployment, Nginx/Apache, PHP config, SSL
- Content type: reference · Difficulty: intermediate
- Tags: Acellemail
- Published: 2026-07-04 · Last updated: 2026-08-15
- Reading time: 12 min
- Publisher: AcelleMail Knowledge Base, https://acellesend.com/kb

---

## What this is for

Your AcelleMail install is *working* the moment the [web installer](https://acellesend.com/kb/articles/install-acellemail-on-ubuntu-2404#step-10--run-the-web-installer) turns green. But "working" and "ready to put your subscribers on" are not the same thing. Two valuable things now live on your server that weren't there an hour ago:

1. **Your subscribers' personal data** — names, email addresses, sometimes phone numbers and custom fields. That's personal data, and you're now its custodian.
2. **Your domain's sending reputation** — every campaign signs with your domain. Get this wrong and your own legitimate mail lands in spam.

This checklist secures both, **in the order that matters**. It is not a generic Linux-hardening course — those exist, and we point to one at the end. It's the short list of things that, if you skip them, actually hurt *an email-marketing app specifically*.

Good news up front: self-hosting AcelleMail is genuinely manageable. Most of what follows is configuration you set once and never touch again. Budget about 30–40 minutes, do it in the first hour, and you're done.

> **How to read this:** each item says *why it matters for an email app* first, then *what to do*. If a "why" doesn't apply to you, skip that item consciously rather than blindly running commands.

## Priority 1 — Protect subscriber data

This is the one that turns a bad day into a reportable data breach. Lead here.

### 1.1 — Put the admin panel behind HTTPS, always

Every login, every subscriber export, every API token travels over this connection. On plain HTTP it's readable by anyone on the network path. Your install guide already set up a Let's Encrypt certificate — this step just makes sure AcelleMail *insists* on using it.

In your `.env`, confirm:

```
APP_URL=https://mail.example.com
FORCE_HTTPS=true
```

`FORCE_HTTPS=true` makes AcelleMail emit `https://` links even when it sits behind a proxy that terminates TLS (Cloudflare, an AWS load balancer). After editing `.env`, clear AcelleMail's config cache so the change takes effect (`php artisan config:clear` from the install directory, or your panel's "Clear cache" action).

> Don't have a certificate yet? That's a 5-minute fix — see the **TLS** step of your platform's install guide ([Ubuntu](https://acellesend.com/kb/articles/install-acellemail-on-ubuntu-2404#step-7--tls-with-certbot)).

### 1.2 — Don't run in debug mode

When `APP_DEBUG=true`, any uncaught error renders a full stack trace — which can include your database password and other `.env` values — straight into the browser. On a public site that's a credential leak waiting for the first error. It's the most common self-hosted misconfiguration, so check it explicitly — your `.env` must read:

```
APP_ENV=production
APP_DEBUG=false
```

Fix it if needed, then clear the config cache again.

### 1.3 — Keep the database off the public internet

Your subscriber data lives in MySQL/MariaDB. The AcelleMail installer creates a database user scoped to `localhost`, which is correct — but confirm the database server itself isn't listening to the whole world. On Ubuntu/Debian, `bind-address` in `/etc/mysql/mysql.conf.d/mysqld.cnf` should be `127.0.0.1`, never `0.0.0.0`. On a managed database (RDS, DigitalOcean Managed DB) this lives in the provider's security group instead — restrict it to your app server's IP.

You don't need to micromanage database grants for a single-app install; the installer's `localhost`-scoped user is already right. The thing that actually bites people is forgetting the firewall, which Priority 5 covers in one step.

### 1.4 — Set up automated backups *before* you import a single list

The cheapest backup you'll ever take is the first one, when the database is empty. Six months and 200 campaigns later, the temptation to "skip it just this once" is what kills people. A daily dump plus an off-site copy means a fat-fingered delete or a dead disk costs you a day, not your business.

A local copy alone doesn't survive the server dying, so pair the daily dump with an off-site target (S3, Backblaze, or your provider's snapshots) and test a restore once. The full pattern — schedule, off-site copy, retention, restore drill — is its own guide. **Treat this as non-optional, not "nice to have."**

➡️ [Automated Database Backups](https://acellesend.com/kb/articles/automated-database-backups)

### 1.5 — Lock down the files that hold secrets

Your `.env` holds the database password, mail credentials, and the `APP_KEY` that encrypts session data. It should be readable by the web user and nobody else, and the rest of the install shouldn't be world-writable — only `storage/` and `bootstrap/cache/` need write access. If PHP is ever compromised, correct file permissions are what stop an attacker rewriting your app files. Your install guide sets these during setup; re-confirm them if you've been copying files around as root.

> **Want full encryption-at-rest** (encrypted volumes, encrypted backups) for regulated data? That's the next level up — see [Data Encryption for Self-Hosted Platforms](https://acellesend.com/kb/articles/data-encryption-for-self-hosted-platforms).

## Priority 2 — Protect your sending reputation

This is what's unique about an *email* app. A normal web app can be sloppy here and only its own uptime suffers. With AcelleMail, getting this wrong means mailbox providers start junking your campaigns — and reputation is slow to earn back.

### 2.1 — Get SPF, DKIM, and DMARC right (non-negotiable)

Gmail, Yahoo, and Microsoft now expect bulk senders to pass all three — and they must *align* to pass DMARC, not merely exist. In plain terms:

- **SPF** lists which servers may send for your domain.
- **DKIM** signs each message so receivers can prove it's really from you and untampered. Use a 2048-bit key.
- **DMARC** tells receivers what to do when a message fails the other two.

AcelleMail generates the DKIM key for you and shows the exact DNS records to publish. Don't hand-craft these — follow the in-app flow:

➡️ [How to Set Up SPF, DKIM, and DMARC Records](https://acellesend.com/kb/articles/how-to-set-up-spf-dkim-and-dmarc-records)

### 2.2 — Roll DMARC enforcement gradually

Don't publish `p=reject` on day one — if your SPF or DKIM alignment is even slightly off, you'll bounce *your own* legitimate mail. Start at `p=none` to collect reports and see exactly what's sending under your domain, then tighten to `p=quarantine`, then `p=reject` once the reports are clean. There's no flag-day deadline — the point is steady, verified progression.

➡️ [DMARC Enforcement Migration](https://acellesend.com/kb/articles/dmarc-enforcement-migration)

### 2.3 — Send at a sane rate, and don't IP-hop

Mailbox providers throttle suspicious patterns — sudden volume spikes or a brand-new IP blasting at full tilt — before they ever hard-block. Two habits keep you clear:

- **Pick a sending IP/domain and stick with it.** Constantly rotating IPs or sender names is a classic spammer signature. On a brand-new IP, warm it up gradually before full volume — see [Domain & IP Warmup](https://acellesend.com/kb/articles/domain-warmup).
- **Set rate limits in AcelleMail** to match what your sending server (your own SMTP, Amazon SES, SendGrid, Mailgun) actually allows. Configure these under **Sending servers** rather than letting one campaign fire 100k emails in a burst.

➡️ [Sending Throttling Strategies](https://acellesend.com/kb/articles/sending-throttling-strategies)

### 2.4 — Watch for reputation drops and blacklisting

Even a clean setup can get listed if a few hundred subscribers mark you as spam in a short window. The fix is mostly upstream — list hygiene and authentication — but you want to *know* when it happens, because throttling shows up before a hard block.

➡️ [Sender Reputation Monitoring](https://acellesend.com/kb/articles/sender-reputation-monitoring) · if you're already in trouble, the [Deliverability Incident Runbook](https://acellesend.com/kb/articles/deliverability-incident-runbook).

## Priority 3 — Lock down admin and API access

Your admin panel can export every subscriber and send on your behalf. The API can do the same programmatically. These are the two doors worth bolting.

### 3.1 — Strong admin password + two-factor

Multi-factor auth is the single highest-leverage control here — it stops credential-stuffing and brute-force outright, even if a password leaks. AcelleMail ships TOTP-based two-factor; turn it on for every admin account:

Go to **Admin → Account Settings → Two-Factor Authentication → enable**, scan the QR with any authenticator app (Google Authenticator, 1Password, Authy), and **save the recovery codes to your password manager immediately** — there's no override if you lose both the device and the codes.

### 3.2 — Restrict who can reach `/admin`

`/admin/login` is the highest-value brute-force target on the box. Beyond a strong password, two web-server layers help:

- **Rate-limit the login** so password sprayers get throttled — a few attempts per minute per IP is plenty.
- **If your team has fixed IPs, allowlist them.** Restricting `/admin` to known IP ranges makes stolen credentials nearly useless to an outside attacker. Skip this if your admins roam (cafés, mobile) — it'll lock *you* out.

These live in your web-server config (the nginx section of your install guide), not in AcelleMail's settings.

### 3.3 — Treat the API token like a password, and rotate it

Every AcelleMail account has an `api_token`. Anyone holding it can read your lists and send campaigns, so:

- **Store it in a secrets manager or `.env`, never in version control.**
- **Prefer the `Authorization: Bearer` header over the `?api_token=` query parameter** — query strings end up in server logs and browser history.
- **Rotate it** if it might have leaked (committed to a repo, shared in a ticket, an ex-employee had it). Rotating is just resetting the token in the account's API settings; the old one stops working immediately.

➡️ [REST API Authentication & Endpoints](https://acellesend.com/kb/articles/rest-api-authentication-and-endpoints)

## Priority 4 — Keep AcelleMail and PHP patched

A perfectly hardened box still gets owned by one unpatched known vulnerability. This is ongoing, not one-time.

- **AcelleMail updates** ship security fixes alongside features. Apply them when they land — don't sit three versions behind.
- **PHP** is the runtime everything sits on. Stay on a [supported PHP version](https://acellesend.com/kb/articles/install-acellemail-on-ubuntu-2404#step-2--php-83-the-engine) (8.3+ for current AcelleMail) and let your distro's unattended-upgrades apply security patches automatically.
- **Re-audit after any disclosed vulnerability** in PHP, nginx, MySQL/MariaDB, or AcelleMail — and on a quarterly cadence otherwise, the same rhythm you use to re-check your DNS records.

## Priority 5 — Server-OS basics (the short version)

These are general server-hardening steps — not AcelleMail-specific, so we won't reproduce a whole sysadmin course. Two matter most, done once:

**Firewall down to only what AcelleMail needs** — SSH, HTTP, and HTTPS inbound, nothing else. MySQL, Redis, and php-fpm should never be reachable from the internet. On Ubuntu that's a handful of `ufw allow` rules (OpenSSH + "Nginx Full"); on DigitalOcean or AWS, use the provider's Cloud Firewall / Security Group as the primary edge filter and treat the host firewall as defense in depth.

**SSH with keys, not passwords.** Copy your key first, confirm it works in a *second* terminal, then disable password login. Adding `fail2ban` to auto-ban repeat offenders is a nice extra.

That's the 80/20. The full Linux-hardening treatment (non-standard SSH port, disabling root login, kernel sysctl tuning) is a general OS topic — your platform's install guide covers the firewall and SSH basics in context:

➡️ [Install AcelleMail on Ubuntu 24.04](https://acellesend.com/kb/articles/install-acellemail-on-ubuntu-2404) (and the Debian / [Rocky](https://acellesend.com/kb/articles/install-acellemail-on-rocky-linux-9) / DigitalOcean / AWS variants)

## Quick verification

Two minutes to confirm the high-value items took:

- **In `.env`:** `APP_ENV=production`, `APP_DEBUG=false`, `FORCE_HTTPS=true`.
- **Database** is bound to `127.0.0.1` (or locked to your app IP in the provider security group).
- **Firewall** is up with only SSH / HTTP / HTTPS open.
- **A backup file actually exists** — and re-check tomorrow that the schedule fired.

Then, in the app: send a test campaign to a [mail-tester.com](https://www.mail-tester.com) address — it scores your SPF/DKIM/DMARC alignment in one click, the fastest way to confirm Priority 2 landed.

## Common issues

| What you see | Likely cause | Fix |
|---|---|---|
| Locked out of SSH after disabling passwords | Disabled password auth before the key worked | Use your provider's web console; re-enable password auth, copy the key, confirm, then disable again |
| Stack trace with `.env` values in the browser | `APP_DEBUG=true` still set | Set `APP_DEBUG=false`, clear the config cache |
| Your own campaigns land in spam | SPF/DKIM/DMARC not aligned, or `p=reject` set before alignment was clean | Run a [mail-tester](https://www.mail-tester.com); back DMARC down to `p=none`, fix alignment, re-tighten |
| Admin login locks out your whole office | Rate-limit or IP-allowlist too tight for a shared office IP | Raise the limit, or scope the allowlist to the office's real egress IP |
| Backups silently stopped, disk fills | The scheduled job didn't run | Confirm the backup schedule is active and its retention cleanup is firing |
| API token shows up in access logs | Using the `?api_token=` query parameter | Switch callers to the `Authorization: Bearer` header |

## What to do after

Once Priorities 1–3 are in place you can safely import your first list and publish the admin URL. Keep Priority 4 (patching) on a calendar reminder, and revisit this checklist whenever you add an admin user, change sending servers, or move the install to a new server.

## FAQ

**Do I need all of this before going live?** Priorities 1–3 yes, before you import real subscribers or publish the admin URL. Priority 4 is ongoing; Priority 5 is the OS floor — do the firewall + SSH-keys steps, defer the rest if you must.

**Is Cloudflare / a WAF a substitute for this?** No — it's an extra layer, not a replacement. Cloudflare in front gives you free DDoS protection and hides your origin IP, but it doesn't fix an exposed database, missing backups, or unaligned DMARC. Defense in depth means *both*.

**What about GDPR / CAN-SPAM?** Hardening protects the data; compliance is a separate set of content and process obligations on top. See the [GDPR Compliance Guide for Email Marketing](https://acellesend.com/kb/articles/gdpr-compliance-guide-for-email-marketing).

**Running AcelleMail in Docker?** Same priorities, applied at the container/host boundary — the [Docker Deployment Guide](https://acellesend.com/kb/articles/docker-deployment-guide-for-acellemail) covers the Docker-specific patterns.

## Related articles

- [Install AcelleMail on Ubuntu 24.04 LTS](https://acellesend.com/kb/articles/install-acellemail-on-ubuntu-2404) — the canonical install; run this checklist right after
- [Automated Database Backups](https://acellesend.com/kb/articles/automated-database-backups) — the full backup strategy behind Priority 1.4
- [How to Set Up SPF, DKIM, and DMARC Records](https://acellesend.com/kb/articles/how-to-set-up-spf-dkim-and-dmarc-records) — the heart of Priority 2
- [REST API Authentication & Endpoints](https://acellesend.com/kb/articles/rest-api-authentication-and-endpoints) — token handling for Priority 3.3
- [GDPR Compliance Guide for Email Marketing](https://acellesend.com/kb/articles/gdpr-compliance-guide-for-email-marketing) — for EU-resident sender programs

---

## Related articles

- [Install AcelleMail on AWS EC2](https://acellesend.com/kb/articles/install-acellemail-on-aws-ec2): This guide has moved. The install walkthrough for any server, an AWS EC2 instance included, is Install AcelleMail and Get Started.
- [Server Requirements and Hosting Options for AcelleMail](https://acellesend.com/kb/articles/server-requirements-and-hosting-options): The right server for AcelleMail is dictated by send volume, not subscriber count. A list of 5M subscribers mailed monthly needs less compute than a list of 100k mailed daily. This article gives concrete specs at four volume tiers, a current 2026 provider comparison, and the operational considerations that determine your real cost.
- [Docker Deployment Guide for AcelleMail](https://acellesend.com/kb/articles/docker-deployment-guide-for-acellemail): Containerised AcelleMail trades a small ergonomic cost (volumes, image rebuilds, patch flows) for dev/prod parity and clean image-tag rollback. This guide ships a production-ready Dockerfile (with all wizard-required PHP extensions baked in), a docker-compose.yml stack, and the operational recipes for patches, scaling, logs, and backups.
- [Install AcelleMail on Ubuntu 24.04 LTS](https://acellesend.com/kb/articles/install-acellemail-on-ubuntu-2404): This guide has moved. The install walkthrough for any server, an Ubuntu 24.04 server included, is Install AcelleMail and Get Started.
- [Installing AcelleMail on DigitalOcean](https://acellesend.com/kb/articles/installing-acellemail-on-digitalocean): This quickstart has moved. The install walkthrough for any server, a DigitalOcean droplet included, is Install AcelleMail and Get Started.
