Appi.sh is zero-config hosting for your apps. Build your app once, ship it with a single command, and it goes live — no servers to configure, no infrastructure to manage.
We use Docker as the delivery format — the standard way to package
modern applications so they run the same way everywhere. When you're ready,
you run the docker push
command generated for you on the Dashboard. As soon as your app arrives,
we detect it, start hosting it, and give you a public URL at
https://<your-slot-id>.appi.sh.
Never touched Docker before? You don't need to be an expert. If you're coding with an AI assistant (Cursor, Claude Code, Copilot, ChatGPT, Aider, etc.), ask it two things — it will walk you through everything:
Dockerfile
for your app — just tell it what framework or language you're using.
That's it. After docker push finishes,
give it a few seconds — the Dashboard will flip from
Waiting for deploy to Active.
Active means "we've received your image and are working on it" —
not yet "your app is reachable". Next to the status you'll see a small
info icon — hover it to see the deployment sub-status. It walks through
Pushing → Deploying → Awaiting Health Check → Healthy.
Once it reads Healthy, your app is actually live at
https://<your-slot-id>.appi.sh.
Add a port_<number>
tag to your image. Examples:
Full example build command:
docker buildx build --platform linux/amd64 ^ -t push.to.appi.sh/<slot-id>/app:port_3000 ^ --push .
Add a tag in the format
env_<KEY>___<VALUE>
— one tag per variable.
Heads up on the separator:
between the key and the value there are three underscores
(___), not one.
This is because your key itself can contain single underscores
(e.g. DB_HOST),
so we need a distinct separator.
Allowed characters in both key and value follow Docker's tag rules:
letters a-z A-Z,
digits 0-9,
underscore _,
dot .,
and hyphen -.
Anything else — spaces, slashes, colons, @, !, etc. —
won't fit directly. For those, use
env64
(see below).
Examples:
Build command with multiple tags (one -t flag each):
docker buildx build --platform linux/amd64 ^ -t push.to.appi.sh/<slot-id>/app:port_3000 ^ -t push.to.appi.sh/<slot-id>/app:env_NODE_ENV___production ^ -t push.to.appi.sh/<slot-id>/app:env_LOG_LEVEL___debug ^ --push .
Values with special characters — use env64.
If your value contains anything Docker tags don't allow (spaces, ://,
@,
:,
?,
=, etc.),
use the env64_ prefix and
base64url-encode the value. We decode it before passing the variable to your app.
Format: env64_<KEY>___<BASE64URL_VALUE>
base64url is the URL-safe variant: same alphabet as base64 but
+ becomes
-,
/ becomes
_,
and the = padding is dropped.
Quick encode commands:
# Linux / macOS echo -n 'your value here' | base64 | tr '+/' '-_' | tr -d '=' # Python python -c "import base64,sys; print(base64.urlsafe_b64encode(sys.argv[1].encode()).rstrip(b'=').decode())" 'your value here'
Example — setting DATABASE_URL=postgres://user:pass@host:5432/db:
-t push.to.appi.sh/<slot-id>/app:env64_DATABASE_URL___cG9zdGdyZXM6Ly91c2VyOnBhc3NAaG9zdDo1NDMyL2Ri
Tip: the KEY stays plain — only the VALUE gets encoded. Docker tags cap at 128 characters total, so very long values may still need an external secrets approach.
Every account gets 1 free slot with a lifetime of up to 2 hours per deployment. When the slot expires, your containers are stopped automatically.
Pushing a new image renews the 2-hour clock — so as long as you keep iterating, the slot stays alive.
Paid slots extend the lifetime up to 1 month per deployment, and will soon allow multiple slots per account.
We do not read, inspect or retain the contents of your images beyond what's required to host them. Your image lives in a private registry scoped to your account.
Each running application is isolated in its own container with its own network namespace. Apps belonging to different users cannot see or reach each other.
We do store operational metadata — image digest, tags, timestamps, health-check results — to run the service itself. Nothing from inside your app.
Just run the same docker push
command again with your new build. The service detects the new image, replaces the running
container, and keeps the same public URL.
The previous deployment is marked as superseded automatically — no manual cleanup required.
Images must be built for linux/amd64.
Our generated build command includes --platform linux/amd64 —
keep that flag even if you're on Apple Silicon or ARM.
Any language / framework that produces a Docker image works: Node, Python, Go, Rust, Java, .NET, PHP, Ruby, static sites via nginx, etc.
When the expiration time hits, we stop your containers and mark the slot as Expired on the Dashboard. Your image itself remains in the registry — nothing is deleted.
To resume hosting, push a new image (or the same one again). A fresh 2-hour window starts.
Built-in databases — coming soon. We're working on the ability to spin up a database alongside your app as part of the deployment itself, so demo apps can run end-to-end out of the box with no external dependencies.
For now, use an external database (Supabase, Neon, PlanetScale,
Railway, your own server — anything that speaks the wire protocol) and pass the connection
string through an env64
variable (base64url-encoded, so
://,
@,
:,
? etc. all pass through):
-t push.to.appi.sh/<slot-id>/app:env64_DATABASE_URL___cG9zdGdyZXM6Ly91c2VyOnBhc3NAaG9zdDo1NDMyL2Ri
The example above decodes to
postgres://user:pass@host:5432/db.
See the "How do I pass environment variables?" section for the full
env64 format and encoding commands.
Yes — that's one of the things APPISH is built for. Push your image once,
paste https://<your-slot>.appi.sh
into your README under a "Try it live" heading, and visitors can poke at your
project without cloning anything.
Keeping the demo alive: a free slot stays up for
2 hours after each push, and every new push resets the clock. So before a release
announcement, a Show HN post, or a PR review you expect to get traffic on, just run
docker push
again to refresh the window. For demos that need to stay up indefinitely, a paid
slot extends the lifetime up to one month per deployment.
Join our Discord community to chat with the team, ask questions, and share what you're building: appi.sh/discord.
Prefer email? Drop us a line at [email protected] — any question, bug report or feature request is welcome.