2026.06 / field guide
My AI App Factory: Hetzner, Hermes, Coolify, GitHub, Cloudflare, and Telegram
I wanted a setup where I could message an AI agent from my phone, ask it to build an app, have it create a private GitHub repo, deploy through Coolify, put it behind Cloudflare, and then verify that the live URL actually works.
This post documents the stack I am using right now. It is intentionally practical: one VPS, open-source/self-hosted infrastructure where possible, GitHub as the source of truth, Coolify as the deployment layer, Cloudflare for DNS/proxying, and Telegram as the control surface.
No private keys, API tokens, or provider secrets are shown here. Treat the commands as a blueprint and keep your own credentials in environment files or secret stores.
The current stack
This site is running on a Hetzner VPS with Ubuntu and Docker. On the box I currently have:
- Server: Hetzner Ubuntu 26.04 LTS VPS, 8 GB class, Falkenstein-style hostname.
- Docker: Docker 29.x with Docker Compose v5.x.
- Hermes Agent: multiple profiles running as long-lived agents, including a Telegram-connected profile.
- Coolify: Coolify 4.1.x running in Docker with Traefik as the public reverse proxy.
- GitHub: private repositories by default, deploy keys for Coolify access.
- Cloudflare: DNS, proxying, SSL mode, and final public edge routing.
- Telegram: the chat interface I use to direct the AI agents from anywhere.
The live pattern looks like this:
Telegram DM
↓
Hermes Agent running on the VPS
↓
Local tools: shell, files, git, browser checks, Coolify API
↓
GitHub private repo
↓
Coolify build + deploy
↓
Traefik reverse proxy + Let's Encrypt origin cert
↓
Cloudflare DNS/proxy
↓
Live app on a real domain
Why this setup works so well
The magic is not any single tool. It is the loop:
- I describe what I want in Telegram.
- Hermes edits files, runs commands, creates repos, and checks logs.
- GitHub stores the code and history.
- Coolify builds and deploys the app from GitHub.
- Cloudflare points the real domain at the VPS.
- Hermes verifies the live website and reports back in the same Telegram chat.
That means I do not just get a code snippet. I get a working artifact: a repository, a deployment, and a public URL that has been checked.
Step 1 — Start with a clean VPS
Provision a VPS from Hetzner Cloud. I use Ubuntu because almost every tool supports it cleanly and the package ecosystem is predictable.
After first login, do the boring but important setup:
sudo apt update
sudo apt upgrade -y
sudo adduser deployer
sudo usermod -aG sudo deployer
Then add your SSH key, disable password login if appropriate, and configure a firewall. A simple baseline is:
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
If you plan to run mail or other services, open only the specific ports you need. Do not expose databases directly unless you have a very good reason.
Step 2 — Install Docker
Coolify and most small apps are easiest when Docker is the deployment substrate. Use Docker's official install docs for your exact distribution: Install Docker Engine on Ubuntu.
The end state you want is:
docker --version
docker compose version
On my server, Docker and Compose are available system-wide, which lets Coolify build and run apps without special handling.
Step 3 — Install Coolify
Coolify is the self-hosted deployment platform in this setup. It gives you a UI and API for projects, apps, databases, environment variables, deployments, logs, domains, and SSL.
Install Coolify using the official docs: Coolify installation guide.
On this VPS, Coolify runs as Docker containers, including:
coolify # the app/API
coolify-proxy # Traefik reverse proxy
coolify-db # Coolify's Postgres
coolify-redis # queue/cache
coolify-realtime # realtime service
coolify-sentinel # monitoring/helper service
A quick health check looks like:
curl http://127.0.0.1:8000/api/health
curl http://127.0.0.1:8000/api/v1/health
Both should return OK.
Step 4 — Give Coolify API access
Hermes can drive Coolify through the REST API. In the Coolify dashboard, enable API access and create a token with read, write, and deploy permissions.
Store the token somewhere the agent can read, but never commit it to GitHub:
COOLIFY_URL=http://127.0.0.1:8000
COOLIFY_TOKEN=your_token_here
Then verify it without printing the token:
curl "$COOLIFY_URL/api/v1/version" \
-H "Authorization: Bearer TOKEN_PLACEHOLDER" \
-H "Accept: application/json"
One useful gotcha: if Coolify has an API IP allowlist, requests from the same physical VPS may appear to come from Docker bridge IPs rather than 127.0.0.1. If you get a 403 from a valid token, check the allowlist before regenerating credentials.
Step 5 — Install Hermes Agent
Hermes Agent is the AI agent layer. It can use tools to edit files, run terminal commands, search sessions, manage skills, call APIs, spawn subagents, and talk through messaging platforms.
Install Hermes from the official docs or installer:
curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash
hermes setup
hermes status
Hermes supports multiple model providers, persistent memory, skills, scheduled jobs, browser automation, file tools, terminal tools, and platform gateways. In this setup I use it as the operator sitting on the VPS.
Step 6 — Use multiple Hermes profiles
Profiles let you run separate Hermes instances with isolated config, memory, tools, sessions, and credentials. That is useful when you want one general agent and another agent dedicated to background jobs or a specific Telegram workflow.
hermes profile list
hermes profile create jobs
hermes --profile jobs setup
On this VPS I have multiple profiles, including a default profile and a jobs profile. They can run independently, which makes the system feel less like one chatbot and more like a small AI operations team.
Step 7 — Connect Telegram
Telegram is the interface I use most. I can send a normal message from my phone like “build a blog site and deploy it,” and Hermes can work through the actual server steps.
Create a bot with BotFather, then configure the Hermes gateway:
hermes gateway setup
hermes gateway run
For a long-running server, install or run the gateway as a background service according to the Hermes messaging docs.
The goal is simple: Telegram becomes your command center, while the agent stays close to the files, Docker daemon, Git repo, and Coolify API on the VPS.
Step 8 — Wire GitHub as the source of truth
Every app should live in GitHub. I prefer private repositories by default. The agent can create repos, commit changes, push, and then hand Coolify a deploy key or GitHub App connection.
The basic shape is:
mkdir my-new-app
cd my-new-app
git init -b main
# create files, Dockerfile, README, etc.
git add .
git commit -m "Initial app"
git remote add origin [email protected]:YOUR_USER/my-new-app.git
git push -u origin main
For Coolify, either:
- Use a public repo for the simplest setup.
- Use a private repo with a read-only deploy key.
- Use a GitHub App integration if you want smoother long-term repo management.
I like deploy keys for small private projects because they are narrow: one key, one repo, read-only.
Step 9 — Make apps deployable with a Dockerfile
The agent should produce apps that Coolify can deploy predictably. A simple static site can be as small as:
FROM nginx:1.27-alpine
COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY . /usr/share/nginx/html
EXPOSE 80
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
CMD wget -qO- http://127.0.0.1/ >/dev/null || exit 1
For a Node, Python, or Go app, the same idea applies: expose one internal port, include a healthcheck, keep secrets in environment variables, and make the image build from a clean checkout.
Step 10 — Create the app in Coolify
Once GitHub has the repo, create a Coolify project, environment, and application. You can do this in the UI, or the agent can call the API.
The important settings are:
- Project: one logical group per product or experiment.
- Environment: usually
productionfor small apps. - Server: the local Coolify host.
- Repository: GitHub URL and branch, usually
main. - Build pack: Dockerfile for predictable builds.
- Domain: the final domain or subdomain.
- Environment variables: app secrets and config, never committed.
Then deploy and watch logs. The agent should not stop at “I pushed code.” It should verify that Coolify built the image, started the container, passed the healthcheck, and served the app.
Step 11 — Put Cloudflare in front
Cloudflare handles DNS and optional proxying. The usual flow is:
- Add an A record for your domain or subdomain pointing to the VPS IP.
- Let Coolify/Traefik issue a Let's Encrypt origin certificate.
- Verify direct origin HTTPS works.
- Turn Cloudflare proxy on if you want edge protection and caching.
- Use Full (strict) once the origin certificate is valid.
Useful verification commands:
# Public DNS should point where you expect
getent ahostsv4 example.com
# Verify the origin cert directly from the VPS
echo | openssl s_client -connect 127.0.0.1:443 -servername example.com 2>/dev/null \
| openssl x509 -noout -subject -issuer -dates -ext subjectAltName
# Verify the live site
curl -I https://example.com/
If Cloudflare returns 526, it usually means Cloudflare cannot validate the origin certificate. Temporarily set the DNS record to DNS-only, let Traefik issue the certificate, verify the origin cert, then switch back to proxy and Full (strict).
Step 12 — Let Hermes do the boring verification
The biggest advantage of this setup is not generation. It is verification. A good agent loop should run checks like:
docker ps
curl -I https://your-domain.com/
curl https://your-domain.com/ | grep "expected text"
git status --short
git log -1 --oneline
For a real app, the checklist might also include database migrations, SMTP checks, queue workers, logs, health endpoints, and a browser screenshot.
A complete app-building prompt
Here is the kind of prompt I can send from Telegram:
Create a private GitHub repo for a small FastAPI lead-capture app.
Build it with a Dockerfile, SQLite or Postgres depending on what fits,
add a clean landing page, deploy it with Coolify to leads.example.com,
configure env vars through Coolify, then verify the live HTTPS URL.
Do not expose secrets. Commit everything and report the repo and URL.
The agent can then break the work into actual steps: create files, build locally, create a repo, push, create the Coolify app, add env vars, deploy, inspect logs, and curl the live domain.
My safety rules
- Private repos by default. Make things public later, deliberately.
- No secrets in Git. Use Coolify environment variables and local env files.
- Read-only deploy keys where possible. Keep access narrow.
- Verify with real commands. No pretending a deployment worked.
- Use healthchecks. A running container is not always a working app.
- Keep DNS boring. Cert problems are usually DNS/proxy problems.
- Let agents inspect, but not leak. Logs are useful; tokens do not belong in blog posts, commits, or screenshots.
What this unlocks
This setup turns app creation into a tight feedback loop. I can go from idea to live URL without manually babysitting every file, commit, container, DNS check, and deployment log.
It is still real infrastructure. The agent is not magic. But when the VPS, Hermes, GitHub, Coolify, Cloudflare, and Telegram are wired together properly, the agent has the context and tools to do the tedious parts quickly — and, importantly, to prove that the result is live.
That is the difference between “AI wrote some code” and “AI helped ship an app.”