Guides

Custom domains, DNS & SSL

Put your app on your own address like app.example.com, with automatic HTTPS — add the domain, point your DNS, verify, done.

When you first deploy, Openship gives your app a working web address for free. This guide is about the next step: putting it on a name you own, like app.example.com, with the little padlock (HTTPS) turned on automatically.

Here's the idea in plain terms. A domain is the name people type to reach your app. DNS is the internet's phone book — it's how a name like app.example.com gets connected to the actual computer running your app. SSL (that padlock) is what makes the address start with https:// and keeps traffic private. Openship handles the padlock for you; your only real job is adding a couple of entries to your domain's phone book. This guide walks you through all of it.

What you need first

  • A project already deployed in Openship (see Your first deployment).
  • A domain you own, bought from a registrar (Namecheap, Cloudflare, GoDaddy, Google Domains, etc.).
  • Access to that registrar's DNS settings — the page where you add records. That's where you'll paste the two lines Openship gives you.

The click-by-click way

Open your project's Domains tab

Go to your project and open the Domains tab. This is home base for everything about addresses and HTTPS.

Screenshot

Project page, the Domains tab selected, showing the current access URL and an Add domain button. (screenshot pending)

Add your domain

Press Add domain. In the form that opens, choose Custom domain, then type the full address you want, like app.example.com.

If your project runs a server, you'll also see a Maps to port field — this is which internal port the domain sends traffic to. Openship pre-fills it with your app's port, so you can usually leave it.

There are two optional toggles:

  • Include www — also set up records for the www. version of your domain.
  • External ingress & TLS — turn this on only if your own edge (like a Cloudflare Tunnel or a load balancer) already handles HTTPS. Most people leave it off. See DNS setup, three ways below.

When the form is filled in, press the Add domain button at the bottom of the form to save it. (Yes, it's the same label as the button you just clicked — the first one opens the form, this one saves it.)

Adding a domain doesn't put it live yet

Saving the domain just registers your intent. It stays Pending until you add the DNS records and verify — that's the next two steps.

Screenshot

The Add domain form: Custom domain selected, the domain-name field filled in, the "Maps to port" field, and the Include-www / External-ingress toggles. (screenshot pending)

Copy the DNS records Openship shows you

Right after you add the domain, a DNS Records panel appears with the exact entries to create at your registrar. Each row has a Type, a Host, and a Value, and a Copy button next to it.

There are usually two records:

  • A routing record (an A or CNAME — Openship picks the right one for you, see below) that points the name at your app.
  • A TXT record with host _openship-challenge. This is a secret code that proves you own the domain. Nobody else can add it, so it's how Openship knows the domain is really yours.

Copy each value exactly as shown — don't retype it, use the Copy button.

Screenshot

The DNS Records panel with the routing record and the _openship-challenge TXT record, each with a Copy button. (screenshot pending)

Paste them into your registrar

Open your domain registrar in another tab and find its DNS or DNS records page. Add each record from Openship — matching the Type, Host, and Value. Save.

What does “Host” mean at my registrar?

Registrars phrase it differently — you might see "Host", "Name", or "@". Paste the host exactly as Openship shows it. If your registrar rejects @, it usually means "the root of the domain"; and a host like _openship-challenge is added as a subdomain entry. When in doubt, copy Openship's value verbatim.

Verify

Back in Openship, click Verify next to the domain (it reads Verify app.example.com). Openship looks up your DNS and checks two things: the routing record points the right way, and the _openship-challenge TXT matches its secret code.

If both check out, the domain flips to Verified and Openship starts setting up HTTPS in the background — you don't do anything for that part.

DNS is not instant

After you save records at your registrar, they can take a few minutes — occasionally up to 48 hours — to spread across the internet. If Verify doesn't work on the first try, wait a bit and click it again. Openship also re-checks pending domains on its own in the background.

Watch HTTPS turn on

Once verified, the SSL status shows Provisioning while Openship requests a free certificate from Let's Encrypt (a trusted certificate authority). When it lands, the status becomes Active and your app is reachable at https://app.example.com with the padlock. Certificates also renew automatically before they expire, so this is a one-time setup.

Screenshot

A verified custom domain row showing Verified status and SSL: Active, with a Visit action. (screenshot pending)

DNS setup, three ways

Openship figures out which records you need based on where your project runs. You don't choose the first two — they're picked for you. The records panel tells you which one applies.

Your project runs on your own server, so the domain points straight at that machine's public IP address.

TypeHostValue
A@your server's public IP
TXT_openship-challengea long verification string

Openship checks that the A record resolves to your server and that the TXT matches, then issues the HTTPS certificate for you.

Your project runs on Openship Cloud, so the domain points at a Cloud address using a CNAME (a "this name is an alias for that name" record).

TypeHostValue
CNAME@an Openship Cloud target
TXT_openship-challengea long verification string

Openship confirms the CNAME and the TXT, then handles HTTPS for you.

For advanced setups where your own edge already terminates HTTPS — a Cloudflare Tunnel, a load balancer, or another reverse proxy in front of Openship. Turn on External ingress & TLS when adding the domain.

TypeHostValue
TXT_openship-challengea long verification string

Here Openship only checks the TXT record to confirm you own the name. It does not require the domain to point at it and does not issue a certificate — your edge is doing that job. The SSL status will read External TLS.

Bring your own certificate

For setups where your upstream needs the origin to present a real certificate too — most commonly Cloudflare Full (strict) — upload your own instead of using Let's Encrypt.

  1. On a verified domain, open its menu and choose Upload certificate.
  2. Paste the certificate (full chain, PEM) and the matching private key (PEM). A free Cloudflare Origin CA certificate (15-year) is a great fit here.
  3. Openship serves HTTPS from that certificate and stops running Let's Encrypt for this domain.

Uploaded certificates don't auto-renew

There's nothing for Openship to renew, so it watches the expiry and reminds you — upload a fresh certificate before it lapses.

Prefer the terminal?

Every step above has a CLI equivalent. The add command prints the DNS records and the domain's ID; use that ID to verify.

# See exactly which records a domain will need (nothing is saved)
openship domain preview app.example.com

# Add the domain to a project (prints the records + the domain ID)
openship domain add app.example.com --project <projectId>

# Once your DNS is in place, verify it
openship domain verify <domainId>

# List a project's domains and their status
openship domain list --project <projectId>

Other domain commands

openship domain records <domainId> reprints the records for an existing domain, openship domain primary <domainId> makes a domain the project's main address, and openship domain renew <domainId> / openship domain verify-ssl <domainId> manage the certificate. Full details are in the Domains API reference.

If something goes wrong

Verify keeps failing

Openship tells you which of the two checks is still missing. If the routing record (A/CNAME) is the problem, it hasn't resolved to your app yet. If the TXT is the problem, the _openship-challenge record is missing or its value doesn't match. Open the DNS Records panel again, compare each record against your registrar character-for-character (copy/paste, don't retype), fix any mismatch, then click Verify again.

DNS is not propagating

This is the most common hold-up and it's usually just time. DNS changes can take minutes, and occasionally up to 48 hours, to spread worldwide. Save the records, then wait and retry Verify — Openship also re-checks pending domains automatically in the background. A frequent cause of "never propagates": a typo in the host, or leaving an old conflicting record in place. Delete any stale record for the same name before adding the new one.

Verified, but SSL is stuck on “Provisioning”

The certificate is still being issued, or a request to Let's Encrypt hasn't completed. Give it a minute, then open the domain's menu and click Recheck SSL — a quick, no-cost check that flips the status to Active once the certificate is actually in place. If it never provisions, use Renew SSL to try again; the error message will name the real reason.

What next?

On this page