Roundcube Webmail on AWS User Guide
Overview
Roundcube is the widely used open source browser based IMAP mail client. It gives users folder management, threaded conversations, a rich text composer, a searchable address book and a responsive interface that works from desktop to phone. The cloudimg image installs Roundcube 1.7.2 from the official release, fronted by nginx with PHP 8.3 and backed by a local MariaDB for preferences and contacts, all from the Ubuntu 24.04 noble archive with no third party APT repositories.
Roundcube is a mail client, not a mail store, so a bare Roundcube install has nothing to sign in to. This image therefore also bundles a Dovecot IMAP server holding a real mailbox and a loopback only Postfix mail transfer agent, so you can sign in, read and compose the moment the instance boots. You can keep that bundled mailbox, or repoint Roundcube at your own corporate mail server or at Amazon SES by changing two settings. Both paths are covered below.
Read this before you plan on sending mail to the internet. This image is a complete webmail front end with a working local mailbox. It is not a ready to use public mail server, and no image can be. Amazon EC2 throttles outbound TCP port 25 until you request removal, and a new instance has no reverse DNS record and no sending reputation, so mail sent directly to the internet will not be delivered reliably. Step 9 covers configuring an authenticated relay, which is the supported way to send externally.
What is included:
- Roundcube Webmail 1.7.2 from the official release, SHA-256 verified at build time, served from
/var/www/roundcube - nginx with the Roundcube vhost at
/etc/nginx/sites-available/cloudimg-roundcube, docrootpublic_html - PHP 8.3 with the pdo_mysql, intl, mbstring, xml, gd, zip, curl, ldap, bcmath and opcache extensions
- MariaDB with the
roundcubedatabase androundcubeapp user, on the loopback only - Dovecot IMAP and LMTP with a virtual mailbox user, on the loopback only
- Postfix bound to
loopback-only, delivering into Dovecot over LMTP, never an open relay roundcube-firstboot.servicerotating the mailbox password, the database password, the database maintenance password and thedes_keyencryption key per instanceroundcube-cleandb.timerrunning Roundcube's own database housekeeping daily- Two dedicated EBS volumes: the MariaDB datadir at
/var/lib/mysqland the mail store at/var/vmail
Prerequisites
An AWS account, an EC2 key pair, and a VPC subnet with a route to the internet. m5.large (2 vCPU, 8 GB RAM) is the recommended instance type and suits a small team; move up for heavier mailbox usage. Open ports 80 and 443 in the security group, plus 22 for SSH from your management address. Do not open 25, 143, 993 or 3306. The mail and database services are deliberately bound to the loopback interface and will not answer on those ports anyway.
Step 1: Deploy and connect
Launch the image from AWS Marketplace, then connect over SSH. The login user depends on the AMI variant you launched:
| OS variant | SSH login user | Connect with |
|---|---|---|
| Ubuntu 24.04 | ubuntu |
ssh -i your-key.pem ubuntu@<public-ip> |
Step 2: Verify the services
Five services make up the appliance. All five should report active:
sudo systemctl is-active nginx php8.3-fpm mariadb dovecot postfix
php -r 'echo "php ".PHP_VERSION."\n";'
Expected output:
active
active
active
active
active
php 8.3.6
Confirm what is actually listening. Only SSH (22) and HTTP (80) are exposed; IMAP (143), SMTP (25) and MariaDB (3306) are all bound to 127.0.0.1:
sudo ss -tlnH | awk '{print $4}' | sort -u
0.0.0.0:22
0.0.0.0:80
127.0.0.1:143
127.0.0.1:25
127.0.0.1:3306
127.0.0.53%lo:53
127.0.0.54:53
[::]:22
[::]:80
Step 3: Read the first boot credentials
On the first boot of your instance, a one shot service generates a fresh mailbox password, a fresh database password, a fresh database maintenance password and a fresh des_key encryption key, all unique to that instance, and writes them to a root only file. No cloudimg image ships a shared or default password.
The credentials file holds real secrets, so read only the value you need rather than printing the whole file. These are the keys it contains:
sudo grep -oE '^[a-z.]+=' /root/roundcube-credentials.txt
roundcube.url=
roundcube.mail.user=
roundcube.mail.pass=
roundcube.mail.address=
roundcube.db.name=
roundcube.db.user=
roundcube.db.pass=
Read the mailbox username, and then the mailbox password, when you are ready to sign in:
sudo grep '^roundcube.mail.user=' /root/roundcube-credentials.txt | cut -d= -f2-
webmail
sudo grep '^roundcube.mail.pass=' /root/roundcube-credentials.txt | cut -d= -f2-
<ROUNDCUBE_MAIL_PASSWORD>
Step 4: Sign in to webmail
Browse to http://<public-ip>/ and sign in with the webmail user and the password from Step 3.

After signing in you land in the inbox. The folder list (Inbox, Drafts, Sent, Junk, Trash, Archive) is created automatically, and a getting started message from cloudimg is waiting for you.

Open the message to read it in the reading pane. It summarises what is running on the instance, the outbound mail position, and how to repoint Roundcube at your own mail server.

Step 5: Compose a message
Click Compose to open the composer. The From identity is already set to the bundled mailbox, and attachments up to 64 MB are allowed.

Because the bundled Postfix is loopback only and has no relay configured, mail addressed to the local mailbox is delivered straight back into Dovecot, which is a quick way to verify the stack end to end. Mail addressed to an external recipient will not be delivered until you configure a relay, which is Step 9.
Set your display name and signature under Settings then Identities:

Step 6: Confirm the security posture
The image ships no known credential and exposes no mail service to the network. You can verify each property yourself.
The MTA accepts connections only from the instance itself, trusts only the loopback network, and terminates its relay rules with reject_unauth_destination:
sudo postconf -h inet_interfaces
sudo postconf -h mynetworks
sudo postconf -h smtpd_relay_restrictions
loopback-only
127.0.0.0/8
permit_mynetworks, reject_unauth_destination
That is what makes it impossible for this instance to be used as an open relay: an open relay is an MTA that accepts mail from arbitrary remote clients, and nothing remote can reach this one. Prove it by trying to open the SMTP port on the instance's own private address, which is refused, while the loopback answers:
PRIV=$(hostname -I | awk '{print $1}')
timeout 5 bash -c "exec 3<>/dev/tcp/${PRIV}/25" && echo "REACHABLE - unexpected" || echo "refused on ${PRIV}:25 as expected"
timeout 5 bash -c 'exec 3<>/dev/tcp/127.0.0.1/25; head -1 <&3'
refused on 172.31.83.124:25 as expected
220 localhost.localdomain ESMTP
IMAP authentication is restricted to the virtual mailbox user. Dovecot's system and PAM authentication is disabled, so operating system accounts cannot sign in to webmail:
sudo doveconf -n | grep -E 'driver =' | sed 's/^ *//'
driver = passwd-file
driver = static
And the per instance mailbox credential genuinely authenticates end to end, through the real Roundcube login form into Dovecot IMAP, while blank and weak guesses are rejected:
sudo bash /usr/local/sbin/roundcube-cred-roundtrip.sh
OK per-instance mailbox credential authenticates end-to-end via the Roundcube web login form (-> Dovecot IMAP); blank + weak guesses rejected
Step 7: Verify the data volumes
The MariaDB datadir and the Dovecot mail store are on separate EBS volumes, both mounted by filesystem UUID, so your mail and your preferences are kept off the operating system disk and can be snapshotted and resized independently. Mail grows without bound, which is why it gets its own volume.
findmnt -no SOURCE,TARGET,FSTYPE,SIZE /var/lib/mysql
findmnt -no SOURCE,TARGET,FSTYPE,SIZE /var/vmail
sudo doveadm mailbox status -u webmail messages INBOX
Expected output:
/dev/nvme1n1 /var/lib/mysql ext4 19.5G
/dev/nvme2n1 /var/vmail ext4 29.4G
INBOX messages=1
To grow either tier, modify the EBS volume in the AWS console and then extend the filesystem in place with sudo resize2fs <device>. Neither operation needs downtime.
Step 8: The health endpoint
nginx serves an unauthenticated static health endpoint suitable for an Application Load Balancer or Network Load Balancer target group health check:
curl -sI http://127.0.0.1/healthz | head -1
HTTP/1.1 200 OK
Step 9: Sending mail to the internet
This is the step most deployments need, so read it carefully.
Why the default does not send externally. Three separate things stand in the way, and none of them is something an AMI can fix for you:
- Port 25 is throttled. AWS rate limits outbound TCP port 25 from EC2 by default. You remove that limit by submitting the Request to remove email sending limitations form from the AWS Support Center, which also lets you associate a reverse DNS record with the instance's Elastic IP.
- No reverse DNS and no reputation. A brand new EC2 address has no PTR record and no sending history. Most large receivers reject or junk mail from such addresses regardless of port 25 access.
- No SPF or DKIM. Without published SPF and DKIM records that authorise your sender, receivers cannot verify the mail is really from your domain.
The supported approach is an authenticated relay. Amazon SES is the usual choice on AWS: it handles reputation, DKIM signing and deliverability reporting, and it accepts submissions on port 587, which is not throttled. Create SES SMTP credentials in the SES console, verify your sending domain, and publish the SPF and DKIM records SES gives you. Then point Postfix at SES as a smarthost, using your SES SMTP credentials and the SES endpoint for your region. cloudimg support will walk you through the Postfix relayhost and SASL configuration for your account and region.
Alternatively, do not send from this instance at all. If your users already have mailboxes on a corporate mail server, Step 10 repoints Roundcube at it and outbound mail leaves through that server instead. For many deployments that is the simplest answer.
Step 10: Point Roundcube at your own mail server
Roundcube speaks standard IMAP and SMTP, so it can front any compliant mail server. Edit two settings in the Roundcube configuration:
| What to change | File | Setting |
|---|---|---|
| IMAP server | /var/www/roundcube/config/config.inc.php |
$config['imap_host'] |
| SMTP server | /var/www/roundcube/config/config.inc.php |
$config['smtp_host'] |
Open the file with your editor of choice and set them to your own servers, for example:
$config['imap_host'] = 'ssl://imap.example.com:993';
$config['smtp_host'] = 'tls://smtp.example.com:587';
Roundcube signs users in against that server with the credentials they type, so also set the SMTP overrides so it authenticates as the signed in user rather than as the loopback:
$config['smtp_user'] = '%u';
$config['smtp_pass'] = '%p';
Then reload PHP:
sudo systemctl reload php8.3-fpm
Your users now sign in with their corporate mailbox credentials. The bundled Dovecot and Postfix can be left running, since they are loopback only and harmless. If you would rather turn them off once you no longer need the bundled mailbox, run sudo systemctl disable --now dovecot postfix. Note that this stops local delivery, so the bundled webmail mailbox and the credential round trip check in Step 6 will no longer work after it.
Step 11: Enable HTTPS
The image serves HTTP on port 80 so it works immediately on a bare IP. For production, point a DNS record at the instance and issue a certificate:
sudo apt-get update && sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d mail.your-domain.com
Certbot rewrites the nginx vhost and installs a renewal timer. After enabling HTTPS, tell Roundcube to issue secure cookies by adding this to /var/www/roundcube/config/config.inc.php:
$config['use_https'] = true;
Maintenance
Roundcube's own database housekeeping runs daily via a systemd timer:
systemctl is-active roundcube-cleandb.timer
active
Add another mailbox to the bundled Dovecot server by appending a user to the passwd file and creating its maildir. doveadm pw prompts interactively for the new password and stores only its SHA512-CRYPT hash, so no password is ever typed on the command line. Run these three in an interactive shell:
sudo sh -c 'printf "%s:%s\n" alice "$(doveadm pw -s SHA512-CRYPT)" >> /etc/dovecot/cloudimg-users'
sudo install -d -o vmail -g vmail -m 0700 /var/vmail/alice
sudo systemctl reload dovecot
On box database maintenance runs as the MariaDB root user over the unix socket, with no password:
sudo mariadb -e 'SELECT COUNT(*) AS roundcube_tables FROM information_schema.tables WHERE table_schema="roundcube";'
roundcube_tables
18
Troubleshooting
The sign in page returns a database error. The first boot service rotates the database password and the Roundcube configuration together. Check that it completed:
systemctl is-active roundcube-firstboot.service
active
sudo tail -20 /var/log/roundcube-firstboot.log
Sign in is rejected. Confirm the password you are using matches the current mailbox credential, and that Dovecot agrees:
sudo bash /usr/local/sbin/roundcube-cred-roundtrip.sh
Roundcube reports an IMAP connection error. Check Dovecot is running:
systemctl is-active dovecot
active
A composed message never arrives at an external address. That is expected until you complete Step 9. Inspect the mail queue to confirm what happened:
sudo postqueue -p
Application errors. Roundcube logs to its own tree, which nginx never serves:
sudo tail -30 /var/www/roundcube/logs/errors.log
Security notes
- No shared or default password ships in the image. The mailbox password, the Roundcube database password, the MariaDB maintenance password in
/etc/mysql/debian.cnfand thedes_keyused to encrypt stored IMAP session passwords are all generated uniquely on each instance's first boot. The mailbox and database values are written to/root/roundcube-credentials.txtwith mode0600. - Dovecot's system and PAM authentication is disabled, so only the virtual mailbox user can sign in. Operating system accounts cannot access webmail.
- Postfix is bound to
loopback-onlywithmynetworksrestricted to127.0.0.0/8, so it can never act as an open relay. - MariaDB, Dovecot IMAP and Postfix all listen on
127.0.0.1only. Never open 25, 143, 993 or 3306 in the security group. - Roundcube's web installer is removed from the image and
enable_installerisfalse. - The web root is the
public_htmldirectory, so the configuration file holding the database password anddes_keysits outside the docroot entirely and is additionally denied by nginx. - Keep the instance patched with
sudo apt-get update && sudo apt-get upgrade. Unattended security upgrades are enabled by default.
Support
cloudimg provides 24/7 technical support for this Roundcube image, including deployment guidance, connecting to external IMAP and SMTP servers, authenticated relay and Amazon SES setup, SPF and DKIM and deliverability troubleshooting, TLS certificate installation, plugin and skin configuration, address book and LDAP integration, upgrades and MariaDB administration.
Email support@cloudimg.co.uk.