๐Ÿš€ AIC-Web Deploy Guide

Follow these rules and your app will deploy successfully. AI agents: read this page before deploying.

The 4 Golden Rules

1. Use process.env.PORT โ€” never hardcode a port.
The platform assigns a unique port to each app and injects it as process.env.PORT. Your app must read it. Do NOT use 3000, 8080, or any fixed number.
2. Have a package.json with a start script.
The platform runs npm start to launch your app. Make sure "scripts": {"start": "node index.js"} exists.
3. Bind to the host the platform gives you.
Your app must listen on process.env.HOST (always 127.0.0.1). Caddy handles public HTTPS.
4. Store user uploads in process.env.STORAGE_PATH โ€” never in the code directory.
Every deploy WIPES the code directory and replaces it. STORAGE_PATH is a per-app persistent directory that survives all redeploys (removed only when the app is deleted).

Correct code (Express example)

const express = require('express');
const app = express();
app.get('/', (req, res) => res.send('Hello!'));
app.listen(process.env.PORT, process.env.HOST);

Wrong code (won't deploy)

app.listen(3000); // โŒ hardcoded port โ€” will crash

How to Deploy

Option A: Ask your AI agent

Deploy my app to AIC-Web. The app name is "myportfolio".

The agent zips your code, uploads it, and returns your live URL.

Option B: Upload via the portal

  1. Zip your app folder (must have package.json at the root)
  2. Log in to https://aicc-web.com/portal
  3. Go to Apps โ†’ Deploy app
  4. Upload the zip, enter a name, click Deploy

Option C: Deploy from a Git repo

Choose the ๐Ÿ”— Git URL tab (or tell your agent the repo URL). The server clones the repo โ€” no upload needed.

FieldMeaning
git_urlThe repo to clone (HTTPS or SSH)
git_branchOptional: which branch to deploy. Leave empty for the repo's default branch
git_keyLegacy: SSH private key for private SSH repos. Stored encrypted โ€” later redeploys reuse it. Prefer the deploy-key flow below (no secret sharing)

Private repos โ€” the no-secrets way (deploy keys)

Nobody should ever paste an SSH private key or a PAT into a chat. The platform generates the keypair instead:

  1. Your agent calls create_deploy_key (MCP) or POST /api/me/deploy-keys with the repo URL
  2. The agent shows you the public key (not a secret โ€” safe to display anywhere)
  3. On GitHub: repo โ†’ Settings โ†’ Deploy keys โ†’ Add deploy key โ†’ paste it, leave Allow write access unchecked (read-only is enough)
  4. Tell the agent "done" โ€” it deploys. The private half lives encrypted on the platform and is reused for every redeploy and webhook of that repo, forever

One key covers all your apps and sites from the same repo. If a deploy hits a private repo before the key is added, the error message already contains the public key and these steps โ€” follow it and retry.

For private HTTPS repos you can alternatively embed a token in the URL (https://<token>@github.com/user/repo.git) โ€” the platform extracts it, stores it encrypted, and never shows it again.

Redeploying is one click. After the first git deploy, push new code to your repo and hit Redeploy in the portal (or your agent calls redeploy_app / POST /api/me/apps/:name/redeploy). The stored URL, branch, build/start commands, env secrets, and database are all reused.

GitHub Auto-Deploy (push-to-deploy)

Connect a repo once โ€” then every git push to the tracked branch redeploys your app automatically.

  1. Open your app in the portal โ†’ GitHub auto-deploy section
  2. Toggle Enabled, optionally set the tracked branch
  3. Click Generate secret and copy the webhook URL + secret shown
  4. In GitHub: repo โ†’ Settings โ†’ Webhooks โ†’ Add webhook:

Every webhook is signature-verified (HMAC-SHA256) โ€” pushes with an invalid signature are rejected with 401. Pushes to other branches do nothing. Pushes that arrive while a deploy is running are queued and collapsed into a single redeploy. Static sites support auto-deploy too (via the API).

Environment Variables (.env)

Each app has a .env editor (portal app page, or the .env button on the Apps list). Add secrets once as KEY=value lines โ€” they are stored encrypted at rest, survive redeploys (merged by default), and are re-applied to the running process on save. Agents can use update_app_env (MCP) or PATCH /api/me/apps/:name/env (REST).

Webhook-style apps (e.g. Telegram bots) should read APP_BASE_URL from env โ€” the platform injects the app's own public HTTPS URL automatically. No manual configuration needed.

Uploads & Persistent Files (images, PDFsโ€ฆ)

Every deploy replaces your app's code directory. Files written inside it at runtime โ€” uploads included โ€” are deleted on redeploy.

The platform gives every app a persistent storage directory that no deploy ever touches, exposed as process.env.STORAGE_PATH. Write uploads there and they survive every redeploy (the directory is removed only when the app is deleted):

// Express + multer example
const STORAGE = process.env.STORAGE_PATH;
const upload = multer({ dest: STORAGE });          // uploads land in storage
app.post('/api/upload', upload.single('file'), (req, res) => {
  db.save({ path: req.file.filename });            // keep names in your DB
  res.json({ ok: true });
});
app.use('/uploads', express.static(STORAGE));      // serve them back
// โ†’ https://your-app-url/uploads/<filename>

Students can browse and manage stored files in the portal: app page โ†’ Files โ†’ Storage tab. One-off commands (run_app_command) also see STORAGE_PATH.

Frameworks

Frameworkstart_commandbuild_commandNotes
Express / plain Nodenode index.js(none)Simplest โ€” works out of the box
Next.jsnext startnpm run buildMust set build_command or it won't compile
Nuxtnuxt startnpm run buildSame as Next.js โ€” needs build step
Static HTML/CSS/JS(none)(none)Deploy as a static site instead โ€” no server needed

Auto-Injected Environment Variables

The platform sets these automatically. Do NOT set them yourself:

VariableValue
PORTUnique port assigned to your app
HOST127.0.0.1
NODE_ENVproduction
DATABASE_URLPostgres connection string (if a DB is attached)
APP_BASE_URLYour app's public HTTPS URL
STORAGE_PATHPer-app persistent directory โ€” survives redeploys. Write uploads here (see below)

Package Managers

npm, pnpm, and yarn are all installed. The platform detects your lockfile (package-lock.json, pnpm-lock.yaml, or yarn.lock) and uses the right one automatically.

Common Mistakes

ProblemCauseFix
App crashes on deployHardcoded portUse process.env.PORT
"package.json not found"Wrong zip structureZip the contents, not a wrapper folder
502 Bad GatewayApp didn't bind its port in 30sTest npm start locally first
Next.js failsMissing build stepSet build_command: npm run build
Uploaded files vanish after redeployFiles written into the code dir (wiped every deploy)Write to process.env.STORAGE_PATH

Your App URL

After deploying, your app is live at:

https://<app-name>-<your-username>.s1.aicc-web.com

Example Prompts for AI Agents

Build a Node.js app using Express that shows a personal portfolio with my name, a bio, and 3 project cards. Use process.env.PORT. Create a package.json with a start script. Then deploy it to AIC-Web as "myportfolio".

Build a simple blog using Next.js with App Router. Include a home page with a list of posts and individual post pages. Set the build command to "npm run build". Deploy it to AIC-Web as "myblog".

Build a Node.js product-catalog app with Express where I can add products with a photo. Store product info in the database and save the uploaded photos to process.env.STORAGE_PATH (never in the code folder โ€” redeploys wipe it). Serve photos at /uploads with express.static. Deploy it to AIC-Web as "myshop".

AIC-Web Student Hosting Platform ยท Student Portal ยท MCP Auth Spec