Nexent Cloud documentation
Nexent Cloud runs your applications for you. You bring code, a container image, or pick an app from the marketplace; the platform builds it, rolls it out, routes traffic to it, issues certificates and keeps its data on persistent volumes. There are no servers to set up and no configuration files to learn.
How it fits together
Everything lives in a workspace - the unit of billing, membership and networking. A workspace holds apps (your services, marketplace apps and databases are all apps), services (SMS sender names with credits and API keys), integrations (GitHub, GitLab, container registries) and a wallet. Apps in one workspace can talk to each other privately; apps in different workspaces cannot.
Each app is a set of containers in its own isolated environment, an address on nexentcloud.com when it serves HTTP, and whatever volumes its template or settings declare. A deployment is one attempt to build (if needed) and roll out a version; the console shows every deployment with its steps and logs.
Getting started
1. Account and workspace
Create an account at console.cloud.nexent.dev/register and verify your email. On first sign-in you either create a workspace or land in one you were invited to. A workspace has a name, a currency (USD or TZS - fixed at creation, every quote and invoice uses it) and an owner.
2. Fund it
Resources are charged monthly against the workspace wallet. Top it up under Workspace › Billing by mobile money or card (ClickPesa); the amount is credited when the payment provider confirms it, usually within a minute. Nothing is charged until you deploy something.
3. First deploy
Marketplace app Apps -> Marketplace -> pick one -> Deploy -> name it -> Deploy
Your own code Apps -> New app -> Source: GitHub -> connect -> pick repo + branch -> Deploy
Either way you get:
- a URL: https://<app-name>.nexentcloud.com (TLS included)
- logs, a terminal, metrics and an audit trail on the app page
- a persistent volume where the template or your settings ask for oneThe console
The sidebar is organised by what you own; the app bar shows where you are and lets you switch workspace.
| Area | What lives there |
|---|---|
| Apps | Every app in the workspace as a table or cards, with status, usage, and quick actions (open, restart, stop). Create ▾ starts a new app from a source or a template. |
| Marketplace | One-click templates with their default resources and prices. |
| Services | SMS sender names: approval state, balance, monthly limit, API keys, delivery log. |
| Workspace › Profile | Name, currency, owner. |
| Workspace › Billing / Invoices | Wallet balance, top-ups, monthly invoices. |
| Workspace › Members | Invite people, set roles, grant integration management. |
| Workspace › Integrations | GitHub / GitLab accounts, linked repositories, container registries, per-repo access. |
| Workspace › Trash | Deleted apps whose data is still retained; restore or purge. |
Inside an app
| Tab | Purpose |
|---|---|
| App Details | Running instances and their state, address, network toggles, resource plan, linked database. |
| Usage & Analytics | CPU, memory, network and request history; what right-sizing observed. |
| Logs | Live stream from every container of the app; previous container on a crash. |
| Settings | Source, build settings, environment, resources, domains, volumes, security (allowlist, public access), notifications, danger zone. |
| Files | Browse, read, edit, upload and download files inside the running container. |
| Database | Database apps only: tables, rows, structure, read-only SQL, CSV export. |
| Audit trail | Who did what to this app and when. |
| Deployments | Every deployment with steps, logs, cancel, rebuild, redeploy, pull-latest. |
| Terminal | A shell in the running container. |
One-click apps
A marketplace template is a compose-style description of one or more containers plus what the platform must provide around them: environment inputs shown as a form, volumes that become persistent storage, a backup schedule for databases, and whether the app serves HTTP. See the catalogue.
Installing
- Choose the template and click Deploy. Sign in if you aren't.
- Name the app. Fill the inputs - a version, an admin username, a password (leave generate on to get a strong one you can read later under Settings › Environment).
- Review resources. The template's minimums are pre-filled; raise CPU, memory or storage if you know you'll need more. The monthly price updates as you change them.
- Deploy. The stack is rendered, volumes are created, containers start, and the app gets its address.
Apps that need a database
Some templates (Odoo, Survey Solutions, Metabase, …) declare that they need PostgreSQL. At install time you choose: create a new database app alongside (the default), use a database app already in the workspace, or point at an external server. For workspace databases the platform creates a dedicated login and database on that server for the app and writes the connection details into the app's environment - you never handle the password.
Changing an installed app
- Inputs live in Settings › Environment. Saving re-renders the stack and rolls it out; data on volumes is untouched.
- Version is usually an input (e.g.
POSTGRES_VERSION). Major database upgrades need a dump and restore - the data directory format changes. - Resources - Settings › Resources; a rolling update follows.
- Redeploy on the Deployments tab re-runs the template deployment as-is.
Deployment sources
An app has exactly one source. There are two families: sources we build from code, and images we pull as they are.
| Source | How it works | Redeploys when |
|---|---|---|
| GitHub | Install the Nexent GitHub App on an account or organisation and connect it to the workspace (Workspace › Integrations). Pick a repository and branch from the ones the App can see. | A push lands on the deploy branch (GitHub webhook). |
| GitLab | Connect a gitlab.com account by OAuth. Pick a project and branch. A push webhook is created on the project through the API - nothing to paste. | A push lands on the deploy branch. |
| Git repository | Any host by HTTPS URL - Bitbucket, Gitea, a self-hosted server. Optional username/token for private repos. | The branch head moves; checked every 5 minutes. |
| Upload ZIP | A ZIP of the source with a Dockerfile, uploaded at creation. Good for one-off deploys. | Only when you upload again. |
| Docker image | Any public image reference, e.g. nginx:1.27 or ghcr.io/org/app:v3. | Pull Latest & Deploy, or a redeploy. |
| GitHub / GitLab / Docker Hub registry | A private image from a registry connected to the workspace. Tags are listed for you. | Pull Latest & Deploy, or a redeploy. |
Connecting GitHub
- Workspace › Integrations › Connect account › GitHub. GitHub asks which account or organisation and which repositories the App may see - all, or a selection.
- Back in the console the installation is connected to the workspace. Every member can now deploy from those repositories; Link repositories lets you pre-link several at once.
- Repositories an app deploys from are shown as in use and can't be unlinked until the app moves.
To add repositories later, open the installation on GitHub (Repository not listed? in the picker takes you there) and extend its access; the list refreshes.
Connecting GitLab
Workspace › Integrations › Connect account › GitLab opens GitLab's OAuth consent. The connection is stored per workspace; the token is refreshed automatically and used both to clone at build time and to create the push webhook when a project is linked.
Changing the source
Settings › Deployment source shows the connected source. Change source lets you pick another; linking it replaces the current one and starts a deployment. The previous link is removed - the app's data and settings stay.
Builds & Dockerfiles
Code sources are built on the platform from the Dockerfile in your repository - there is no buildpack magic and no platform config file. The image is pushed to the workspace's registry and rolled out.
Build settings
| Setting | Meaning |
|---|---|
| Dockerfile path | Relative to the repository root, default Dockerfile. The picker lists Dockerfiles it finds on the chosen branch; you can type a path that doesn’t exist yet. |
| Build arguments | Key/value pairs passed as --build-arg. Use these for build-time configuration (a public API URL for a frontend build); use environment variables for runtime. |
| Shared builds | On by default. If two apps in the workspace build the same commit of the same repository with the same settings, the second reuses the first’s image instead of building again. Turn it off if the Dockerfile depends on something outside the repo. |
| Follow another app | Under Deployment source: run whatever another app in the workspace builds, with this app’s own environment and resources - for a worker or a second region of the same code. |
A Dockerfile that behaves well here
FROM node:22-alpine AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
FROM node:22-alpine
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
ENV NODE_ENV=production PORT=3000
EXPOSE 3000
USER node
CMD ["node", "server.js"]- Listen on the port you set in Settings. The readiness check and the Service target that port; a mismatch is the most common cause of a 502.
- Bind to 0.0.0.0, not localhost.
- Don't bake secrets into the image. Read them from environment variables at runtime.
- Multi-stage builds keep the runtime image small and the rollout quick.
- Write only to a mounted volume if you need files to survive a redeploy; the container filesystem is replaced on every rollout.
Runtime settings
Environment variables
Settings › Environment. Saving rolls the app out with the new values. Values are also written to /nexent-runtime-config/env.json inside the container at start, so a static frontend can read its current configuration at request time from a tiny server-side route instead of being rebuilt.
Port and health check
Settings › Networking. Container port is where your process listens; traffic and the readiness probe go there. Optionally set a health check path (e.g. /healthz) - it must answer 2xx/3xx quickly; otherwise a TCP check on the port is used. The probe runs every 10 s with a 5 s timeout and needs 3 failures to mark the app not ready.
Process type
An app can be a web service (gets an address, is probed) or a worker (no address, no probe - a queue consumer, a scheduler). Workers are billed the same way and get the same logs, terminal and volumes.
Resources
Settings › Resources sets the plan: CPU cores, memory, storage and bandwidth per month, and for stateless apps the number of replicas. Limits are what you set; the memory request (what the scheduler reserves) is right-sized nightly from observed use so you aren't reserving for peaks that never come. Databases and other stateful templates are pinned to one replica.
Restart, stop, start
The app bar has Restart (rolling restart, same image and settings), Stop (scale to zero; storage and address are kept, compute stops being charged) and Start.
Deployments & rollouts
Every deployment runs the same steps and records each one with its log:
checkout -> fetch the commit (or the ZIP / template)
build -> build the image from the Dockerfile (code sources only)
push -> push the image to the workspace registry
database -> create the app's login/database (templates that need one, first time)
deploy -> apply the containers, volumes, service and routes
verify -> wait for the new instance to become ready; fail fast on a crash loopZero-downtime
A rollout starts the new instance and only retires the old one after the new one passes its readiness check, so a single-instance web app keeps answering during an update. If the new version crashes or never becomes ready, the deployment fails and the old version keeps serving.
Actions on the Deployments tab
| Action | What it does |
|---|---|
| Cancel | Stops a queued or running deployment. A build in progress is killed; nothing is rolled out. |
| Rebuild | Runs the same commit again from scratch (ignores shared-build cache). |
| Redeploy | Repeats the most recent deployment exactly: same commit, image or template. Use it after changing build settings. |
| Pull Latest & Deploy | Deploys the newest commit on the branch (git sources) or re-pulls the tag (image sources). For template apps it re-runs the template. |
Automatic deployments
Deploy on push is per app. GitHub and GitLab notify us by webhook; plain git URLs are polled every five minutes and deployed when the branch head changes (the first look only records the current head - it never deploys what was already there).
Logs, files, terminal
Logs
The Logs tab streams stdout/stderr from every container of the app, live, with the last few hundred lines of history. After a crash the previous container's log is available so you can see why. Multi-container templates show each container separately.
Files
Browse the running container's filesystem, read and edit text files, tail a log file, upload and download, create folders, delete. Edits are written into the container - on a volume they persist; elsewhere they last until the next rollout. Useful for a quick config fix; keep the real change in your repository.
Terminal
A shell in the app's container, in the browser. It has whatever the image has (sh at least on Alpine images). Handy for running a migration, inspecting a volume or checking connectivity to a database (nc -zv storefront-db 5432).
Metrics
Usage & Analytics shows CPU, memory, network and request rates over time per app, and the workspace summary shows totals against the plan. The nightly right-sizing pass uses the same data.
Audit trail
Every change to an app - deploys, setting edits, restarts, domain changes, permission grants - is recorded with who and when, per app and for the whole workspace.
Databases
PostgreSQL (14–18), MySQL and MariaDB are marketplace templates. A database app is a single server on a dedicated persistent volume (10 GB by default) inside your workspace, private unless you say otherwise, with a strong generated password, TLS with a self-signed certificate made on first start, and a nightly backup job.
Connecting from your apps
The App Details page of the database shows its private host, port, database, user and password, and copy-ready connection strings. The private host is the database app's name, reachable only from apps in the same workspace:
DATABASE_URL=postgresql://postgres:<password>@storefront-db:5432/postgres
# MySQL / MariaDB
DATABASE_URL=mysql://root:<password>@storefront-mysql:3306/appMarketplace apps that declare a database dependency get a dedicated database and login created on the server automatically, and the variables written into their environment.
Sizing
Start with the template default (1 core, 1 GB, 10 GB) and watch Usage & Analytics. Raise memory before CPU for most workloads; raise storage before the volume reaches ~80% - growing a volume is online, shrinking is not supported.
Database browser
Database apps have a Database tab in the console that talks to the server over the private network - no client needed.
- Databases - pick any database on the server, with its size.
- Tables - filter by name; see row estimates and size.
- Browse - rows with paging and page size, click a row for a detail panel, find-in-table, sort; wide tables scroll inside the card with a sticky first column.
- Structure - columns, types, nullability, defaults, indexes.
- Query - run a single read-only
SELECT; results are shown with timing, and a query history is kept in the browser. - Export - the current result set as CSV.
- Connect - connection strings for psql, DBeaver, Prisma, Django, and the public endpoint if enabled.
psql is in the image) or your own client over public access for writes.Backups & restore
Database templates declare a backup schedule and a retention. A scheduled job next to the database runs pg_dump (or mysqldump) on that schedule, uploads the dump to the workspace's object storage, and removes dumps older than the retention (7 days for the PostgreSQL template).
Console
- Settings › Backups lists every dump with size and time.
- Back up now runs the job immediately - do this before a risky migration.
- Download a dump to keep it elsewhere.
- Restore loads a dump into the server with
pg_restore --clean: objects are dropped and recreated from the dump. The app is unavailable during the restore.
Volumes & storage
There are two kinds of persistent storage, and it matters which one you have.
| Kind | Where it comes from | Behaviour |
|---|---|---|
| Persistent volume | Declared by a marketplace template (databases, Nextcloud, Gitea …). | A real block volume attached to the app. Survives restarts, redeploys and resource changes. Kept in the Trash after deletion until retention expires. Sized in GB; billed as storage. |
| Synced volume | Settings › Volumes on your own apps: a container path mapped to a folder in the app’s object storage. | The path is a local directory kept in sync with object storage every 30 s and on shutdown. Simple and privilege-free; a crash between syncs can lose the last few seconds of writes. Good for uploads and generated files; not for databases. |
Files that aren't on a volume
The container filesystem is replaced on every rollout. Anything written there - logs, caches, uploads - is gone after the next deploy. Put it on a volume or in object storage.
Object storage
Every app has its own S3-compatible bucket, used for synced volumes and backups. Its usage is shown on App Details and billed as storage.
Trash & retention
Deleting an app stops its containers, removes its address and stops its charges - but its persistent volumes are kept for 30 days in Workspace › Trash. Restoring re-creates the app with the same volumes attached. After 30 days the volumes are purged for good. Deleting a database app offers to also drop the logins and databases it created for other apps; that part is immediate and explicit.
Deleting a workspace
Only the owner can, and only when it has no apps. Delete or move the apps first.
Domains & TLS
Every web app is reachable at https://<app>.nexentcloud.com from the moment it's ready, with a certificate issued for it. Your own domains are added per app.
Adding a domain
- Settings › Domains › Add domain. Enter
app.example.comor the apexexample.com. - Create the DNS record the console shows: a CNAME from your hostname to
<app>.nexentcloud.com, or for an apex an A record to the platform address. - Click Verify (or wait - it's checked automatically). Once DNS resolves to us, a Let's Encrypt certificate is requested over HTTP-01 and installed; renewals are automatic.
- Set one domain as main if you want the others to redirect to it.
Force HTTPS
On by default: HTTP requests are redirected to HTTPS - but only once the domain's certificate is ready, because redirecting earlier would break the HTTP-01 challenge that issues it.
Hosting DNS with Nexent
Workspace › DNS lets you host a zone here and manage its records (A, AAAA, CNAME, TXT, MX). Point your registrar's nameservers at the ones shown for the zone.
Public database access
Databases are private by default. To reach one from your laptop, a CI job or a BI tool outside the platform, turn on Public access in the database app's Settings › Security.
| Engine | Public address | Port |
|---|---|---|
| PostgreSQL | <random-slug>.db.nexentcloud.com | 5432 |
| MySQL / MariaDB | <random-slug>.db.nexentcloud.com | 3306 |
The hostname is assigned once and kept. Connections must use TLS (sslmode=require for Postgres) - the platform routes by the TLS server name, so plain-text connections are refused.
psql "postgresql://postgres:<password>@nova-delta-f7d4.db.nexentcloud.com:5432/postgres?sslmode=require"IP allowlist
Settings › Security › IP allowlist. Add the addresses or CIDR ranges that may connect and turn enforcement on. With enforcement off the list is kept but everything is allowed. Public access without an allowlist is an open door with only the password in the way.
0.0.0.0/0 is a standing target for automated wipers. Allow only what needs it, and rotate the password if it was ever shared in a chat or a repo.Private networking
- Each app runs in its own isolated environment that accepts traffic from apps in the same workspace and from the platform's edge, and nothing else.
- Apps reach each other by name:
http://<app-name>:<port>. Multi-container templates also expose each internal service by its compose name. - Outbound internet access is open (package registries, third-party APIs, webhooks).
- Only HTTP(S) is exposed publicly through the ingress, plus database ports via public access. Other TCP ports (mail, game servers) are not reachable from outside yet.
SMS sender names
A service is a sender name - the text recipients see as the sender - with its own prepaid credits, monthly limit, API keys and delivery log. Sender names are issued by the carrier gateway and must be approved, so there is a short workflow.
Requesting one
- Services › New service. Enter the sender name (3–11 characters, letters and digits, no spaces - a carrier rule) and a short note on how it will be used.
- The request is reviewed by Nexent (pending), then forwarded to the gateway (submitted), then approved or rejected with a reason. Approval usually takes one to three business days.
- Once approved the service can send. Everything else - keys, credits, limits - can be set up while you wait.
Credits and limits
Messages are prepaid at a flat rate per SMS shown on the service page. Buy credits from the wallet or pay directly (mobile money / card); direct payments are credited when confirmed. A monthly limit caps how many messages the service may send in a calendar month regardless of balance - a safety net against a runaway loop. Failed sends are not charged.
API keys
Each service has an API key and a secret. The secret is shown once, at creation or rotation; rotate it from the service page if it leaks. Keys are per service, so a compromised key can only spend that service's credits.
Linking apps
Optionally link the apps that use the service. Sends can then be attributed to an app in the log, and the app page shows its messaging usage.
Send API
One endpoint, authenticated with the service's key and secret in headers.
POST https://api.cloud.nexent.dev/v1/notifications/send/
X-API-Key: <service api key>
X-API-Secret: <service api secret>
Content-Type: application/json| Field | Type | Notes |
|---|---|---|
| channel | string | "sms" today. "email" will use the same endpoint when it ships. |
| to | string | string[] | One number or a list, international format without "+", e.g. 255712345678. Duplicates are sent once. |
| message | string | The text. Longer than 160 GSM characters is sent as concatenated parts and charged per part. |
| app | string (optional) | The uid of an app linked to the service, to attribute the send in the log. |
curl -X POST https://api.cloud.nexent.dev/v1/notifications/send/ \
-H "X-API-Key: $NEXENT_SMS_KEY" \
-H "X-API-Secret: $NEXENT_SMS_SECRET" \
-H "Content-Type: application/json" \
-d '{"channel":"sms","to":"255712345678","message":"Your order #1042 has shipped."}'import os, requests
resp = requests.post(
"https://api.cloud.nexent.dev/v1/notifications/send/",
headers={"X-API-Key": os.environ["NEXENT_SMS_KEY"], "X-API-Secret": os.environ["NEXENT_SMS_SECRET"]},
json={"channel": "sms", "to": ["255712345678", "255754000000"], "message": "Hello from Nexent"},
timeout=15,
)
print(resp.status_code, resp.json())const resp = await fetch("https://api.cloud.nexent.dev/v1/notifications/send/", {
method: "POST",
headers: {
"X-API-Key": process.env.NEXENT_SMS_KEY,
"X-API-Secret": process.env.NEXENT_SMS_SECRET,
"Content-Type": "application/json",
},
body: JSON.stringify({ channel: "sms", to: "255712345678", message: "Your code is 482913" }),
});
const body = await resp.json();Responses
200 {"success": true, "data": {"sent": 1, "failed": 0, ...}, "message": "Sent"}| Status | Meaning |
|---|---|
| 200 | Every recipient accepted by the gateway (or at least one, with "Partly sent"). |
| 400 | Bad request - missing field, invalid number, empty message. |
| 401 | Key or secret wrong, or the secret was rotated. |
| 402 | Not enough credits. Nothing was sent. |
| 403 | The service isn’t approved yet, is over its monthly limit, or "app" isn’t linked to it. |
| 502 | The gateway rejected every recipient. Nothing was charged. |
Every attempt appears in the service's delivery log with recipient, status, cost and the gateway's reference, and can be filtered by app, status and recipient.
Alerts & notifications
The platform tells you when something needs attention; you choose what and where, per member.
- Events: deployment succeeded / failed, app crash-looping, app unhealthy, restarted by the platform, volume nearly full, wallet low, invoice issued, SMS credits low.
- Channels: in-console notifications (the bell), email, and - for members with a phone number - SMS.
- Preferences are per member under Workspace › Members; owners and admins can set them for others. Send test confirms a channel works.
- Webhooks per app under Settings › Notifications post the same events as JSON to your URL (Slack, PagerDuty, your own service).
Members & roles
| Role | Can |
|---|---|
| Owner | Everything, including billing, member roles, integrations and deleting the workspace. One per workspace; transferable. |
| Admin | Manage apps, members (below owner), integrations and alerts. Cannot change billing or delete the workspace. |
| Member | Create and operate apps, deploy, view logs and metrics, use connected integrations. |
| Consultant | Like a member, but time-boxed - access ends on the date set at invitation. |
| Guest | Read-only: see apps, logs and metrics; cannot deploy or change settings. |
Invitations
Workspace › Members › Invite sends an email with a link; the invitee signs up or in and lands in the workspace with the role you chose. Pending invitations can be revoked.
Fine-grained permissions
- Can manage integrations - a per-member switch (Members › edit) that lets someone who isn't an admin connect accounts, link repositories and add registries.
- Restricted repositories - a linked repository can be limited to named members; others don't see it in the source picker.
- Collections group apps and can carry their own team, so a client's apps are visible to that client's people only.
Integrations
Workspace › Integrations holds everything the workspace connects to. Connections are shared: connected once, usable by every member (subject to the permissions above).
Accounts
GitHub installations and GitLab accounts. Disconnecting is refused while an app still deploys from one of its repositories or pulls from its registry - move the app first.
Repositories
The repositories linked to the workspace, with the apps using each one. Link several at once; unlink when nothing uses them; restrict access per repository.
Registries
| Kind | Credentials | Notes |
|---|---|---|
| GitHub Container Registry | Managed - taken from the connected GitHub installation and refreshed automatically. | Needs the "Packages: read" permission on the GitHub App. Created for you when a GitHub account is connected. |
| GitLab registry | A deploy token or personal access token with read_registry. | registry.gitlab.com by default; self-managed hosts supported. |
| Docker Hub | Username + access token. | For private repositories; public images need no registry. |
| Other | Host + username + password/token. | Any Docker Registry v2 API (Harbor, ACR, ECR with a token, …). |
Credentials are verified against the registry before they are saved, synced as pull secrets into every app that needs them, and re-verified when rotated. A registry in use by an app can't be removed.
Billing & pricing
Pricing is per resource, per month, in the workspace's currency. Current rates are on the pricing page and in the console when you size an app. An app's price is the sum of its plan - cores × rate + memory × rate + storage × rate + bandwidth × rate - charged to the wallet monthly on the app's billing date, counted from the day it was created.
Locked pricing
When you create an app, the rates in force are recorded on its resource agreement. Later rate changes apply to new apps; existing apps keep their locked rates until you change their plan.
Wallet and payments
- Top up with mobile money or card. Each app's monthly amount is taken from the balance when due; a low-balance alert fires before it runs out.
- If a charge fails it is retried daily for three days with notifications; after that the app is paused (scaled to zero, data and address kept) and resumes on its own once the wallet is topped up.
- SMS credits can be bought from the wallet or paid for directly.
- Invoices are issued monthly and listed under Workspace › Invoices as PDF.
What isn't charged
The nexentcloud.com address, TLS certificates for it and your domains, private networking, logs, metrics, the terminal, backups within retention, and Trash retention.
Security
- Isolation: every app runs in its own sandboxed environment with a default-deny network policy that admits only same-workspace apps and the platform's edge. Containers run unprivileged; templates that need extra capabilities declare them.
- Secrets: registry credentials, database passwords and service secrets are stored encrypted and delivered to containers as secrets, never written into images; API secrets are shown once and stored hashed.
- Transport: TLS on every public address, on custom domains, and on public database endpoints; the console and API are HTTPS only.
- Access: roles and per-resource permissions as above; every change is in the audit trail with actor and time.
- Data: persistent volumes on replicated block storage; database backups in object storage within the same region.
- Reporting: security@nexent.dev. Please give us a reasonable time to fix before disclosure.
FAQ
My build fails
Open the deployment and read the build step. Usual causes: the Dockerfile path is wrong, a dependency needs a build argument, a base image doesn't exist for linux/amd64, or the repository the App can see doesn't include the one you picked. Fix and push, or Rebuild.
The app is running but returns 502
The container isn't listening on the port in Settings › Networking, is bound to localhost, or the health check path errors. Check Logs; the failed verify step names the port it waited on.
The deployment succeeded but I see the old version
Browser or CDN cache. Hard-refresh; if you front the app with Cloudflare, purge. The Deployments tab shows which image is running.
Files I uploaded disappeared after a deploy
They were on the container filesystem. Put the upload directory on a volume (Settings › Volumes) or in object storage.
Can two apps share a database?
Yes. Point the second app at the same database app; each gets its own login and database on the server, or use one database explicitly by setting the connection string yourself.
How do I move an app to another workspace?
Not yet as a single action. Deploy it in the new workspace from the same source, restore a database backup, then delete the old one.
I deleted an app by mistake
Workspace › Trash lists deleted apps for 30 days; Restore brings it back with its volumes.
Where is the platform hosted?
In one region, on infrastructure operated by Nexent. If you need to run the platform on your own servers, see Nexent Enterprise on the roadmap.
Support
Email support@nexent.dev with the workspace and app name, or use the contact page.