Skip to content
HostStack Docs

Deploying Your First App

Pick your runtime and configure your build. HostStack handles the rest.

Supported Runtimes

Select your runtime when creating a service. HostStack auto-detects build tools where possible. You can also bring your own Dockerfile for any language.

Node.js
Bun
Python
Go
Rust
Ruby
Elixir
.NET
PHP
Java
Node.jsJavaScript/TypeScript with npm, pnpm, or yarn
BunFast JavaScript runtime and toolkit
PythonPython 3.12+
GoGo compiled binaries
RustRust compiled binaries via Cargo
RubyRuby with Bundler
ElixirElixir with Mix and releases
.NET.NET SDK 8.0
PHPPHP 8.3 with Composer
JavaJava with Maven or Gradle

Build & Start Commands

Configure your install, build, and start commands in service settings. Here are common examples:

Node.js / Bun
Build Command:  npm run build
Start Command:  npm start
Python
Build Command:  pip install -r requirements.txt
Start Command:  gunicorn app:app --bind 0.0.0.0:$PORT
Go
Build Command:  go build -o server .
Start Command:  ./server
Ruby
Build Command:  bundle install
Start Command:  bundle exec rails server -p $PORT
Elixir
Build Command:  mix deps.get && mix release
Start Command:  _build/prod/rel/my_app/bin/my_app start
.NET
Build Command:  dotnet publish -c Release -o out
Start Command:  dotnet out/MyApp.dll
PHP
Build Command:  composer install --no-dev
Start Command:  php -S 0.0.0.0:$PORT -t public
Java
Build Command:  ./mvnw -q -DskipTests package
Start Command:  java -jar target/my-app.jar --server.port=$PORT

Docker Deploys

If your language isn't natively supported or you need custom system dependencies, add a Dockerfile to your repo and select the Docker runtime. HostStack will build your image and deploy the resulting container.

Example Dockerfile
FROM node:20-slim
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY . .
EXPOSE $PORT
CMD ["node", "server.js"]

Zero-Downtime Deploys

HostStack uses zero-downtime rolling deploys. When you deploy, a new container starts alongside the current one. Once the new container passes health checks, traffic switches over. The old container is gracefully stopped. Your users never see downtime.

Environment Variables

Set environment variables in the Settings tab. They're encrypted at rest and available during build and runtime. See the Environment Variables guide for details.

Health Checks

HostStack checks your service is healthy before routing traffic. Set a health check path (e.g., /health) in your service settings. The endpoint should return HTTP 200 when your app is ready.

yaml
healthcheck:
  path: /health
  interval: 10s
  timeout: 5s
  retries: 3

If no health check path is set, HostStack will check that your container starts and listens on the configured port.

Build Cache

HostStack caches your build dependencies between deploys. For Node.js, this means node_modules is cached. For Python, pip packages are cached. This significantly speeds up subsequent builds. Cache is cleared when your lock file changes.

Database Migrations

Run your migrations as part of the service start command (e.g., npm run migrate && node server.js). They execute inside the new container before traffic switches, so a broken migration fails the deploy and the previous version keeps serving.

Each successful application emits a migration.applied activity-log event (visible in the dashboard activity feed and via the MCP list_activity_log tool), so you can tell a "no-op redeploy" apart from a "ran a fresh migration" without grepping deploy logs.

Seed migrations bypass app-layer caches

When a migration writes data directly to Postgres (seed rows, content backfills, lookup-table updates), it doesn't go through your application code, so any Redis / in-memory cache that fronts those rows will keep serving stale data until it expires or is explicitly flushed. If your app caches the affected reads, flush the relevant prefix at the end of the migration script:

ts
// At the end of your data-seed migration:
import { redis } from './redis';
await redis.del(...(await redis.keys('seo:*')));

Troubleshooting

Build fails with "command not found"

Ensure your build command matches your runtime. For Node.js, check that your package.json has a build script defined.

App crashes on startup with "EADDRINUSE"

Your app must listen on the port specified by the PORT environment variable. Don't hardcode a port number.

Container killed: out of memory (OOM)

Your service is exceeding its size's memory limit. Resize to a larger instance size, reduce memory usage, or check for memory leaks in your application.

Build is slow (>5 minutes)

Check if your .gitignore excludes large files. Make sure you're using a lock file (package-lock.json, yarn.lock, etc.) for consistent, cached installs.

Essential cookies only — for login sessions. No tracking. Details