# Email & webmail
URL: https://openship.io/docs/guides/email-webmail.md

Connect existing IMAP/SMTP mailboxes through webmail on Cloud, or run and manage your own mail server with Desktop and self-hosted Openship.

import { Step, Steps } from 'fumadocs-ui/components/steps';

Most people rent their email from someone else — Gmail, Outlook, and the like. Openship lets you run the
whole post office yourself: a real mail server on your own machine, with your own domain, that sends and
receives mail and even gives you a webmail inbox in the browser. Think of it as the difference between renting
a PO box and owning the building.

You're not limited to one, either. Each mail server runs on its own host (one mail setup per server), and
Openship keeps them all in a single **Mail servers** list — provision as many as you like and switch between
them from one place. A lone server opens straight into its admin panel; once you have more than one, you land
on the list first.

This is a big, hands-on feature, so this guide stays at the map level: what each screen does and the order you
go through them. The fiddly bits — the exact DNS records and the reverse-DNS setup — are called out where they
happen, because the wizard walks you through those live.

<Callout title="Cloud webmail and self-hosted mail servers">
**Emails** is available on Cloud, Desktop and self-hosted Openship. On Cloud, it connects your existing
IMAP/SMTP mailboxes through the webmail app. **Managed email is coming soon**: Cloud application plans
do not provision SMTP/IMAP servers or mailboxes. Mail-server setup and administration remain available
through Desktop and self-hosted Openship. See [Installation](/docs/getting-started/installation).
</Callout>

## Connect existing mailboxes on Cloud

Open **Emails → Connect existing mail server**. The standard webmail app installer asks for your
IMAP and SMTP hosts, the managed server that will run the client, and its public route. You can configure
ports in the backend's advanced fields; IMAP and SMTP connections require TLS. Confirming installation
deploys the webmail app through the normal application pipeline.

Sign in to the deployed webmail with your mailbox email address and password. Your existing provider
keeps the mailboxes and mail delivery; Openship hosts the browser client. Manage that client through
**Apps** or its project page, including domains, settings, logs and redeployment. This flow does not
install a new mail server, change MX records or create a mailbox at your provider.

The remaining steps in this guide apply to mail-server setup on Desktop and self-hosted instances.

<Callout title="What you need first">
- Openship running self-hosted, with at least one **connected server** (a clean Ubuntu or Debian machine is
  recommended). See [Connect your own server](/docs/guides/custom-servers) if you don't have one yet.
- A **domain name** you control, where you can edit DNS records.
- **Port 25 open** for outbound mail — some hosting providers block it by default, so check before you start.
- Access to your **VPS provider's panel** (for the reverse-DNS step near the end).
</Callout>

A few words you'll see a lot:

- **Mail server** — the software that actually sends and receives email. Openship installs a well-known stack
  (Postfix, Dovecot, and anti-spam tools) for you.
- **Mailbox** — one email account, like `you@yourdomain.com`, with its own password and inbox.
- **DNS records** — public settings for your domain that tell the rest of the internet where your mail lives.
- **Webmail** — an email app you open in a browser, so you don't need to configure a separate mail app.

## Step 1 — Provision a mail server

<Steps>

<Step>

### Open the Emails page

In the sidebar, click **Emails**. With no mail server set up yet, you land straight on the **Mail Server
Setup** form. If you already run **several** mail servers, you'll see a list of them first — click **Add mail
server** to start another. (With a single existing server, Openship opens it straight to its admin panel; use
the **Add mail server** button there to set up another.)

</Step>

<Step>

### Pick a server and a domain

Choose which of your connected servers the mail stack should run on. If you only have one, Openship picks it
for you.

Then fill in two things:

- **Domain** — your bare domain, like `example.com` (no `https://`, no path). Openship shows you that your
  mail server will live at `mail.example.com`.
- **Admin Password** — the password for the first mailbox, `postmaster@yourdomain`. You'll use it to log in
  after setup. Don't want to think one up? Click **Generate** for a strong random one, then copy it somewhere
  safe.

The right-hand panel lists exactly what gets installed — the mail stack, an automatic **Let's Encrypt** SSL
certificate, the DNS records you'll need, and the admin panel — plus the prerequisites (a domain with DNS
access, port 25 open, a clean server).

</Step>

<Step>

### Press Start Setup and watch it run

Click **Start Setup**. Openship connects to your server and works through the install one step at a time
(system update, mail stack, SSL, and so on), streaming the logs live — like watching the oven through the
glass door. You don't have to do anything while it runs.

Partway through, it pauses twice to wait for you. Those two pauses are the next two steps.

</Step>

<Step>

### Publish your DNS records

The install stops and shows a banner: **Publish DNS records before continuing**. Below it are cards — one per
record (things like MX, SPF, DKIM, and DMARC) — each with a **Copy value** button.

Go to wherever your domain's DNS is managed, add each record, and come back. Then click **I've set the records
- continue**.

<Callout title="Why this matters" type="info">
Email delivery breaks without these records — they're how Gmail and Outlook decide your mail is real and not
spam. If you host DNS at a supported provider, the banner also offers **Auto-configure DNS**, which pushes the
records for you. Otherwise, copy them in by hand. For a gentler intro to DNS, see [Custom domains](/docs/guides/custom-domains).
</Callout>

</Step>

<Step>

### Set reverse DNS (PTR)

Next comes a second banner: **Set reverse DNS (PTR) before continuing**. This one is different — you set it at
your **VPS provider's panel** (Hostinger, DigitalOcean, AWS, and so on), **not** at your DNS provider.

The banner shows your server's IP address and the value to point it at (`mail.yourdomain`). Set it there, wait
a few minutes for it to take effect, then click **I've set the PTRs - continue**.

<Callout title="Reverse DNS in one line" type="info">
Normal DNS turns a name into an IP address; reverse DNS (a **PTR** record) turns the IP back into a name. Big
mail providers reject mail from servers whose reverse DNS doesn't match — so this step is not optional.
</Callout>

</Step>

<Step>

### Done

Openship finishes the SSL step and the page flips to the **admin panel**. Your mail server is live. It also
offers to send a quick welcome test email so you can confirm mail is flowing.

</Step>

</Steps>

<Callout title="Already have a mail server from Openship?" type="info">
If you set one up before and Openship lost track of it (for example, you moved to a new computer), you don't
have to reinstall. On the setup form, click **Already have a mail server? Adopt it**, pick the server, and
click **Scan server**. If a mail stack is found, click **Adopt** — it's brought back into the dashboard with
your mailboxes and data left untouched.
</Callout>

## Step 2 — Manage domains and mailboxes

Once a server is provisioned, the **Emails** page becomes its admin panel — your home base for running the mail
server. It's organized into tabs:

- **Overview** — the hostname, the webmail button, mail stats (domains, mailboxes, storage), and quick links.
- **Domains** — add extra domains you want to receive mail for. A new domain accepts mail once its MX record
  points at this server.
- **Mailboxes** — create email accounts under a domain. Each one is a login (`name@domain`) with its own
  password and quota. This is also where you change the `postmaster` password later.
- **Aliases** — forwarding addresses, and a catch-all for everything else at a domain.
- **Notifications** — get told in a notification channel (Slack, Telegram, Discord, a webhook) when mail
  arrives at one of these addresses.
- **Sending** — how outbound mail leaves: direct, or relayed through a provider. **Send test email** lives
  here too.
- **DNS** — a reference copy of every record each domain needs, with a **Verify** button that checks whether
  they're actually published.
- **Health** — live status of each mail process, refreshed automatically.
- **Backup** — snapshot the mail server (accounts, messages, keys) to one of your backup destinations.
- **Advanced** — the IMAP/SMTP connection settings for wiring up a mail app by hand, plus power-user actions
  like restarting the stack or re-running the wizard.

<Callout title="Adding a second domain" type="info">
When you add a domain under the **Domains** tab, Openship generates its DNS records (including a fresh DKIM
key). Publish those at your DNS provider — the **DNS** tab shows them and can verify them — before you rely on
that domain for mail.
</Callout>

## Step 3 — Deploy the webmail app

A mail server on its own has no web page — you'd point a mail app at it. Openship can also deploy **Zero**, a
webmail app, so you (and your users) get an inbox in the browser instead.

<Steps>

<Step>

### Start from the Overview tab

On the admin panel's **Overview** tab, find the mail server card and click **Deploy webmail**. This opens the
**Deploy webmail** screen.

</Step>

<Step>

### Choose where it runs and at which address

Two choices:

- **Deploy to** — where the webmail app should run. You can put it on **this mail server**, on **another one of
  your servers**, or on one of your managed **Openship Cloud servers**. The shared server picker connects a
  selected Cloud server when needed. Redeploying an existing webmail starts with its saved destination.
- **Domain** — the web address people will open to reach the inbox. It defaults to `mail.yourdomain`. Whatever
  you pick, its DNS must point at the deploy target — the on-screen hint tells you what's expected for the
  option you chose.

The summary panel on the right shows the webmail address and the mail server it connects to.

</Step>

<Step>

### Press Deploy webmail

Click **Deploy webmail**. Openship creates a project and a deployment for you and drops you on the standard
**build screen**, which streams the logs live — the same screen you'd see [deploying any app](/docs/guides/deploy-from-github).
When it's done, the Overview card's button changes to **Open webmail**, which opens your inbox in a new tab.

</Step>

</Steps>

<Callout title="Upgrading a webmail from Openship 0.6.1 or earlier" type="warn">
Webmail used to ship as a prebuilt bundle instead of an app, and those older installs can't be redeployed —
they're replaced. The Overview card shows a **Replace webmail** link, and the deploy screen explains what goes
before the button does anything: the old webmail's project, container and sign-in sessions. Your mailboxes,
domains and every message stay on the mail server, untouched — everyone just signs in to the new inbox again.
</Callout>

## CLI

The provisioning flow works from the CLI too. `openship mail webmail` exposes the same deployment workflow;
see the [mail command reference](/docs/cli/reference/mail#openship-mail-webmail) for its options. Every `mail`
command addresses a self-hosted Openship instance, which can deploy the webmail app to a connected Cloud server.

```bash
# Start the install on a server for your domain (streams live)
openship mail setup <serverId> --domain example.com

# When it pauses for DNS: publish the records, then acknowledge and resume
openship mail dns-ack <serverId>
openship mail setup <serverId> --domain example.com --start-step <n>

# When it pauses for reverse DNS: set the PTR, then acknowledge and resume
openship mail ptr-ack <serverId>
openship mail setup <serverId> --domain example.com --start-step <n>

# Check where things stand at any time
openship mail status <serverId>

# Re-adopt an existing install (after losing the dashboard's record of it)
openship mail scan <serverId>
openship mail adopt <serverId>
```

<Callout title="Tip" type="info">
When the install pauses, the CLI prints the exact `--start-step` number to resume from. Copy it into the next
`mail setup` command and it picks up right where it left off.
</Callout>

## Troubleshooting

<Callout title="Webmail opens, but sign-in cannot reach the mail server" type="warn">
Webmail connects to IMAP from the server running the webmail app. A mailbox working in Gmail or another
client does not prove that this server can reach it. For an Openship-managed mail server, the app settings
should use `mail.<install-domain>` on IMAP port **993** and SMTP port **465**, even for mailboxes on additional
domains or when outgoing mail uses a relay. The webmail address may be different from this backend hostname.

When webmail runs on the mail server itself, Openship maps this backend hostname to Docker's
`host-gateway` in the service configuration. This avoids a host DNS resolver returning a loopback
address inside the container while preserving the hostname used to verify the mail certificate.
The mapping is saved for redeploy and rollback. Cloud and other-server webmail use the mail server's
ordinary DNS address; external-backend settings are left as supplied.
Both IMAP and SMTP honor the container's hostname mappings; SMTP still requires verified TLS before
sending credentials. Existing installs need the updated control plane and webmail image, then
**Mail → Deploy webmail** once to save the mapping. Later project redeploys reuse it.

Connection failures and invalid or expired certificates show a mail-server connection error. “Invalid email
or password” is reserved for a credential rejection from IMAP. Check the webmail host's DNS and network path,
the mail server's client ports, and its certificate; keep TLS verification enabled. After changing a mailbox
password or backend setting, sign in again to refresh the saved session credentials.
Sign-in has a 40-second browser deadline covering verification and session confirmation. If the
connection stalls, the form shows “Sign in timed out” and allows another attempt.
</Callout>

<Callout title="I don't see an “Emails” item in the sidebar" type="warn">
Email is self-hosted only. It appears when Openship is running on your own infrastructure. On a managed/cloud
plan it's hidden on purpose.
</Callout>

<Callout title="The “Check Port 25” step warns that port 25 is blocked" type="warn">
This step is a check, not a wall — the install keeps going even when it warns. Direct-to-MX sending needs
outbound port 25. Many hosting providers block it by default, including AWS. You can
finish setup and route sending through an SMTP provider from the **Sending** tab (Amazon SES, and similar),
then use **Sending → Send test email** to confirm mail flows.
</Callout>

<Callout title="“Verify Public Mail Ports” warns about TCP 25 but 465/587/993 are open" type="warn">
On a single-server install the probe runs from the same machine it is testing. An outbound port-25 restriction
can make `mail.example.com:25` time out even when the daemon listens on a non-loopback interface. If all three
client ports complete a TCP handshake and only TCP 25 times out, setup continues with a warning. Connection
refusals, routing errors, missing or loopback-only listeners, and client-port failures still stop setup.

Health keeps inbound SMTP **unverified**. Check TCP 25 from an independent host or send a test message from
another mail provider: open client ports do not prove that other mail servers can reach your inbound SMTP.
If receiving fails, check inbound TCP 25 in the host and provider firewalls. A relay configured in **Sending**
handles outgoing mail only.
</Callout>

<Callout title="Mail sends but lands in spam" type="warn">
This is normal for a brand-new domain — providers are cautious for the first day or two. Make sure your DNS
records (SPF, DKIM, DMARC) and your reverse DNS (PTR) are all published and verified: use the **DNS** tab's
**Verify** button and the **Health** tab. Marking early test messages as "not spam" speeds things up.
</Callout>

<Callout title="A record won't verify" type="error">
DNS changes can take a few minutes (sometimes longer) to spread. Give it time, then re-check on the **DNS**
tab. Double-check you pasted the value exactly and added it to the right domain.
</Callout>

## Related guides

<Cards>
  <Card title="Custom domains" href="/docs/guides/custom-domains" description="How DNS and automatic HTTPS work for your apps — useful background for the mail DNS steps." />
  <Card title="Deploy from GitHub" href="/docs/guides/deploy-from-github" description="Understand the build screen you land on when deploying webmail." />
  <Card title="Connect your own server" href="/docs/guides/custom-servers" description="Add the machine your mail stack runs on, over SSH." />
</Cards>
