Naijacloud
Docs

Deploy from your machine

Two commands cover going from an empty account to something running. naijacloud deploy ships the directory you are in, and naijacloud launch walks you through creating a project, an environment and a service in one pass.

6 min read

Deploy a static site

Terminal
bash
naijacloud deploy

That is the whole command. The first time in a directory it asks a few questions, deploys, and writes the answers to naijacloud.json. Every run after that takes no arguments.

first deploy
output
No naijacloud.json here — a few questions, then this is the last time. Site name [acme-marketing]: Build command (from package.json; 'none' to skip) [npm run build]: Output directory (detected) [dist]: Single-page app? (detected: React Router) [Y/n]: Running `npm run build` Packaged 18 files, 2.1 MB → 640 KB compressed Uploading 640 KB Created site acme-marketing QUEUED BUILDING RUNNING https://acme-marketing.naijacloud.app Wrote naijacloud.json

The defaults are detected locally. The output directory comes from the conventional build folders, the build command from package.json, and the SPA setting from the framework in your dependencies. Nothing is guessed over the network.

One question does read from the API: where the site should live. Services belong to an environment, so a static site is offered the same choice. Take the default and Naijacloud places it for you, or pick a project / environment to put it in the tree.

The pipeline is: run the build, archive the output, request an upload slot, PUT the bytes to storage, then release. The first deploy creates a site. Every later one replaces it in place, atomically, on the same URL, with the previous version still serving if the new build fails.

naijacloud.json

naijacloud.json
json
{ "$schema": "https://raw.githubusercontent.com/naijacloud/nc-cli/v1.5.0/schema/naijacloud.schema.json", "version": 1, "name": "acme-marketing", "serviceId": "svc_01HX…", "environmentId": "env_01HX…", "build": "npm run build", "output": "dist", "spa": true, "ignore": ["**/*.map"] }
FieldPurpose
nameSite name, used for the subdomain. First deploy only
serviceIdWritten by the first successful deploy. Its presence is what makes the next deploy a redeploy
environmentIdThe environment the site was created in. Absent when Naijacloud placed the site itself
buildRun locally before archiving. A non-zero exit aborts before anything uploads
outputDirectory to deploy, relative to the manifest. May be a single .html file
spaServe the entry file for unmatched paths, so client-side routes survive a refresh
indexEntry file, when it is not index.html
ignorePatterns excluded from the archive, in .gitignore syntax. ! re-includes

Commit the file. The serviceId is not a secret and is only actionable with credentials for the owning team. Committing it is what lets CI deploy from a clean checkout with no linking step.

.git, node_modules, .naijacloud, every .env file and credential files are excluded from the archive whatever ignore says. A static bundle is world readable by definition, so there is no case for uploading one.

Credential files are package-registry and login files (.npmrc, .yarnrc.yml, .pypirc, .netrc, .git-credentials, .pgpass, .my.cnf, .htpasswd), Cloudflare's .dev.vars, private keys and keystores (id_rsa*, id_ed25519*, *.pem, *.key, *.p12, *.pfx, *.jks), credentials.json, service-account*.json, Terraform state, and the .ssh/, .aws/, .docker/, .gnupg/ and .kube/ directories. The deploy lists each one it left out. Any other dotfile it is about to publish, outside .well-known/, is named in a warning, so check that list.

To leave out more, add a .naijacloudignore in .gitignore syntax, in the deployed directory or beside naijacloud.json:

.naijacloudignore
bash
*.map drafts/ !drafts/published.html

A ! pattern brings back something an earlier pattern left out, but never a credential file.

Options

FlagEffect
--prebuiltSkip the build command. The output is already built
--newCreate a new site, ignoring the manifest's serviceId
--env <project/environment>Create the site in a specific environment
--yesAccept detected defaults instead of prompting. Required for a first deploy in CI
--no-waitReturn as soon as the build is queued
--jsonMachine readable result on stdout
--name --output --index --spaOne-off overrides of the manifest fields

A positional path deploys that directory directly, already built:

Terminal
bash
naijacloud deploy ./dist

Write the manifest without deploying

Terminal
bash
naijacloud init # same questions, same file, no deploy naijacloud init --yes # accept every detected default naijacloud init --force # rewrite an existing manifest

Useful when configuring the repo and shipping the site are separate acts, such as setting up CI before the first build exists.

Start from nothing

The platform models everything as team, then project, then environment, then service. All four have to exist before anything runs. naijacloud launch creates each level that is missing, in one pass.

Terminal
bash
naijacloud launch

It walks you through picking or creating the project and environment, connecting a repo or choosing a static directory, and handing over your .env so the first build already has its configuration.

The same steps with flags, which is what launch calls underneath:

Terminal
bash
naijacloud projects create storefront --team acme naijacloud environments create prod --project storefront naijacloud services create api \ --env storefront/prod \ --repo acme/storefront --branch main \ --build "npm run build" --start "npm start" --port 3000 \ --dotenv .env

Instead of --repo, services create takes --git <https url> for any public repository without the GitHub App, or --image <reference> for a prebuilt Docker image. It also takes --type cron --schedule "0 3 * * *" --command <cmd>, --root-dir for a monorepo, --runtime-version, --health-check, --region, --tier and --no-wait.

--tier free|starter|pro|pro-max sets the size of a web service or cron job, and defaults to Free. Each account gets one free app; a free web service sleeps after 15 minutes without visitors and wakes on the next visit, while paid sizes never sleep. Once the free app is in use, launch asks which paid size to use and shows its monthly price, and services create stops without creating anything and lists the paid sizes with their prices. Neither picks a paid size for you.

A web service comes from a repository.

Naijacloud builds a web service from a repository (through the GitHub App, or any public git URL) or runs a prebuilt image. There is no upload-and-build path for one. The only thing that accepts bytes from your machine is a static site.

If the team has no GitHub App installation yet, launch prints the install URL rather than failing.

Deploy from CI

.github/workflows/deploy.yml
yaml
- run: npm ci && npm run build - run: npx @naijacloud/cli deploy --prebuilt --yes --json env: HOSTING_API_TOKEN: ${{ secrets.NAIJACLOUD_API_KEY }}

NAIJACLOUD_API_KEY is a workspace API key from Settings → API keys in the dashboard, saved as a secret in your CI. A static site needs the key's Platform API scope.

--prebuilt skips the manifest's build command, since CI has already run it. --yes is required for a first deploy, where there is no manifest to read defaults from. deploy waits for the build and exits non-zero if it fails, so it gates the job on its own.

Next steps