A NameOcean App Server is a Linux server with your project in a git repository. You push, it runs. This guide takes a Flask app from the first push to its own domain with HTTPS; Django, Node.js and Next.js differ in one line.
visitor ──HTTPS:443──▶ NameOcean load balancer ──HTTP:80──▶ nginx ──▶ your app on 127.0.0.1:8000
The load balancer holds the certificates, so the server only serves port 80. Your app listens on 127.0.0.1:8000 under supervisor, and nginx passes requests to it.
$ nameocean servers plans $ nameocean servers create --plan starter --yes $ nameocean servers ls ID NAME STATUS PLAN DEFAULT DOMAIN DOMAINS 812 3f9a1c2e running starter 3f9a1c2e.nameocean.org - $ nameocean servers ssh-keys add 3f9a1c2e
A server is billed monthly; servers create without --yes only shows the price. You can also create it under Dashboard → Hosting. ssh-keys add installs ~/.ssh/id_ed25519.pub, which git uses to push.
import os
from flask import Flask
app = Flask(__name__)
@app.get("/")
def home():
return f"Hello from {os.environ.get('SITE_NAME', 'NameOcean')}"
flask gunicorn
#!/bin/bash # runs on the server after every push, in /root/app, with your env variables set -e pip install -r requirements.txt
deploy.sh is where build steps go: installing packages, migrations, npm run build. Its output shows up in your terminal when you push.
$ git add . && git commit -m "First deploy" $ nameocean deploy 3f9a1c2e
nameocean deploy adds a git remote named nameocean, pushes the current branch into /root/app on the server (the server deploys that branch from then on), pushes it to your own origin too, and restarts the apps.
Tell supervisor how to start the app and nginx to pass requests to it. Both files are on the server with examples for each stack; you only uncomment.
$ nameocean servers info 3f9a1c2e # the ssh line $ ssh -p 2152 root@3f9a1c2e.nameocean.org # vi /root/conf/supervisor.conf # uncomment the Flask [program:app] and the shared settings # supervisorctl reread && supervisorctl update # vi /root/conf/nginx.conf # remove the static "location /", uncomment the proxy one # nginx -t && systemctl reload nginx # curl -s http://127.0.0.1/ Hello from NameOcean
The [program:app] for Flask:
[program:app] command=/root/.pyenv/versions/app/bin/gunicorn app:app --workers 2 --bind 127.0.0.1:8000 directory=/root/app environment=PATH="/root/.pyenv/versions/app/bin:/usr/local/bin:/usr/bin:/bin" autostart=true autorestart=true redirect_stderr=true stdout_logfile=/var/log/supervisor/app.log
For other stacks only command changes (the file has these examples too):
| Django | /root/.pyenv/versions/app/bin/gunicorn myproject.wsgi:application --workers 2 --bind 127.0.0.1:8000 |
| FastAPI | /root/.pyenv/versions/app/bin/uvicorn main:app --host 127.0.0.1 --port 8000 --workers 2 |
| Node.js | /usr/bin/node server.js with environment=NODE_ENV="production",PORT="8000",HOST="127.0.0.1" |
| Next.js | /usr/bin/npx next start -H 127.0.0.1 -p 8000 and npm ci && npm run build in deploy.sh |
| Go | /root/app/server and go build -o server . in deploy.sh |
Your app is now live at https://3f9a1c2e.nameocean.org.
$ nameocean servers env set 3f9a1c2e SITE_NAME=Kahvebot SECRET_KEY=…
Every app, deploy.sh and SSH session gets them, and the apps restart to read them. They are kept on the server only, never in the repository or in NameOcean's database.
$ nameocean bind kahvebot.com 3f9a1c2e
The domain's DNS must be on NameOcean. NameOcean adds the DNS records, issues the certificate and sets up the load balancer (HTTP to HTTPS, and the bare domain to www); it usually takes a few minutes. Nothing changes on the server.
$ git commit -am "New page" $ nameocean deploy $ nameocean servers logs 3f9a1c2e --app app -f # if it does not come up
Each deploy sends a server.deployed webhook event with the commit and whether the apps came up. Backups, restarts and the rest of the API: App Server API. The server has a guide for AI agents in /root/AGENTS.md.