Domains
Every workspace can expose services to the internet with HTTPS. You have several options depending on your needs.
Domain options at a glance
| Option | Example | SSL | Setup | Plan |
|---|---|---|---|---|
| Preview URL | a1b2c3.preview.oblien.com | Automatic | Expose a port | All |
| App subdomain | a1b2c3.oblien.app | Automatic | Expose a port | All |
| Custom domain | app.example.com | Auto (ACME) | DNS records required | All |
| Custom prefix | *.dev.yourcompany.com | Auto (ACME) | Wildcard DNS + setup | Enterprise |
Free preview URLs
When you expose a port, you get instant HTTPS URLs under two domains:
https://a1b2c3.preview.oblien.com → workspace:3000
https://a1b2c3.oblien.app → workspace:3000Both work identically — the hash is unique per workspace + port. Preview URLs are instant, public, and ephemeral (removed when the port is revoked or workspace stops). See Public Access for the full API.
Custom domains
Connect your own domain to a workspace for a production-ready URL.
How it works
- Your domain CNAMEs to
edge.oblien.com - Oblien edge terminates SSL using an auto-provisioned certificate
- Traffic is routed to your workspace's internal IP and port
- Your app serves plain HTTP — HTTPS is handled for you
Step 1: Add DNS records
At your DNS provider, add two records:
| Type | Name | Value |
|---|---|---|
CNAME | app | edge.oblien.com |
TXT | _oblien.app.example.com | verify=ws_a1b2c3d4 |
| Type | Name | Value |
|---|---|---|
A | @ | 65.109.38.240 |
TXT | _oblien.example.com | verify=ws_a1b2c3d4 |
Root domains can't use CNAME. Use the A record pointing to the Oblien edge IP instead.
Cloudflare users: If you have proxy enabled (orange cloud), Cloudflare hides the CNAME. Use an A record pointing to 65.109.38.240 instead. The TXT ownership record is still required.
Enterprise custom-domain grants can connect with approved edge DNS only, and may use a branded TXT prefix such as _opsh instead of _oblien.
The TXT record proves you own the domain. Replace ws_a1b2c3d4 with your actual workspace ID.
Step 2: Verify DNS
Check that DNS is configured before connecting:
const check = await ws.domains.checkDNS({ domain: 'app.example.com' });
if (check.verified) {
console.log('Ready to connect');
} else {
console.log('Fix these:', check.errors);
// e.g. ["No CNAME to edge.oblien.com found", "Missing TXT ownership record"]
}DNS propagation can take a few minutes. The check uses Google DNS-over-HTTPS for fast, reliable resolution.
Step 3: Connect
const result = await ws.domains.connect({
domain: 'app.example.com',
port: 3000,
include_www: true,
});
console.log(result.url);
// "https://app.example.com"
console.log(result.ssl);
// { status: "active", expiresAt: "2026-06-10" }This will:
- Re-verify DNS records
- Register the routing rule in etcd immediately
- Request or reuse an SSL certificate if the domain is already pointed at the edge
- Save the domain config on the workspace
If ownership is valid but the domain is not yet pointed at the edge, the route still connects and result.ssl.status stays pending until DNS is fixed and you run renewSSL().
Managing the domain
// Get current domain config
const domain = await ws.domains.get();
// {
// customDomain: "app.example.com",
// port: 3000,
// sslStatus: "pending",
// sslExpiry: null,
// sslError: "DNS is not pointed to edge yet",
// includeWww: true
// }
// Renew SSL (auto-renews, but you can trigger manually)
await ws.domains.renewSSL();
// Disconnect
await ws.domains.disconnect();One domain per workspace
Each workspace supports one custom domain. Connecting a new domain replaces the previous one. To serve multiple domains, use separate workspaces.
SSL certificates
- Requested automatically via ACME (Let's Encrypt) when edge DNS is ready
- 90-day validity, auto-renewed when < 14 days remain
- Stored securely and pushed to the edge via etcd
- Domains can remain
pendinguntil edge DNS is correct; force renewal anytime withrenewSSL()
Domain survives restarts
When a workspace restarts and gets a new internal IP, the domain route is automatically re-synced. The routing config lives in etcd (edge layer) and the workspace record (database), so it persists across restarts.
Enterprise: custom prefix
Available on Enterprise plans. Contact sales for setup.
Enterprise customers can configure a branded wildcard domain prefix, giving each workspace an automatic subdomain under your own domain:
workspace-1.dev.yourcompany.com → workspace-1 port 3000
workspace-2.dev.yourcompany.com → workspace-2 port 8080
staging.dev.yourcompany.com → staging workspace port 443Setup
- Add a wildcard DNS record:
*.dev.yourcompany.com → CNAME edge.oblien.com - Oblien configures the prefix in your namespace settings
- Each workspace automatically gets a subdomain based on its name or slug
Benefits
- White-label — your developers see your domain, not Oblien
- Automatic — no manual DNS per workspace
- Wildcard SSL — one certificate covers all subdomains
- Custom TXT prefix — ownership verification uses your configured prefix instead of
_oblien
Comparison
| Feature | Preview URL | Custom domain | Custom prefix |
|---|---|---|---|
| Domain | *.preview.oblien.com / *.oblien.app | Your domain | *.yourdomain.com |
| SSL | Auto | ACME (90-day) | Wildcard |
| DNS setup | None | CNAME + TXT | Wildcard CNAME |
| Per-workspace config | No | Yes | Automatic |
| Production use | Dev/preview | Yes | Yes |
| Plan | All | All | Enterprise |
Error reference
| Error | Meaning | Fix |
|---|---|---|
invalid_domain | Domain format is invalid | Check format (e.g. example.com, no protocol) |
invalid_port | Port out of 1–65535 range | Use a valid port number |
domain_in_use | Another workspace uses this domain | Disconnect it from the other workspace first |
dns_not_configured | Standard plans: TXT ownership missing or wrong. Enterprise: no valid edge DNS signal yet | Add the required DNS records and wait for propagation |
ssl_failed | ACME couldn't issue a certificate | Ensure DNS is correct and domain is publicly resolvable |
vm_not_running | Workspace isn't running | Start the workspace first |
no_domain | No domain connected (for renewSSL) | Connect a domain first |
For the full endpoint reference, see the Domains API.