Skip to main content

Command line · EU bare metal

Get your app online in three commands.

Install the CLI, log in, deploy. The same three lines work from your laptop and from a CI job — and every command on this page is one that runs as written.

terminal

curl -fsSL https://raw.githubusercontent.com/hostimdev/cli/main/install.sh | sh
hostim login
hostim deploy hello --docker-image nginx:alpine --plan sa-1-1 --port 80

A minute later that is a live HTTPS address on *.eu-center.hostim.dev, for €2.50 a month. Everything below is the same three steps with a different last line.

Once

Log in, and make a project.

A project is the namespace your apps, databases and volumes live in. You do this once — every later command acts on the selected project.

  1. Install the CLI

    Linux and macOS, amd64 and arm64. Windows binaries are attached to every release. PREFIX=$HOME/.local installs somewhere other than /usr/local/bin.

    install

    curl -fsSL https://raw.githubusercontent.com/hostimdev/cli/main/install.sh | sh
    
  2. Log in and select a project

    Create an API token in the console under Account Settings → API Tokens. It is validated against the API and saved to ~/.config/hostim/config.yml with mode 0600.

    login

    hostim login
    hostim projects create myproject --region eu-center
    hostim use myproject
    
  3. In CI, skip the login

    Two environment variables instead, and nothing is written to disk. Add -o json to any command to parse the result.

    ci

    export HOSTIM_TOKEN=…
    export HOSTIM_PROJECT=myproject
    hostim deploy app --git https://github.com/hostimdev/demo-express --branch main
    

A published image

Run an image from a registry.

Nothing is built. Give the image a plan, the port it listens on and — if it keeps data — a volume. These four are deployed exactly as written.

docker hub

# A static site or a proxy
hostim deploy site --docker-image nginx:alpine --plan sa-1-1 --port 80

# Uptime Kuma — monitoring and status pages, SQLite in the volume
hostim volumes create kuma-data --plan vol-0
hostim deploy kuma --docker-image louislam/uptime-kuma:2 --plan sa-1-1 --port 3001 --volume kuma-data:/app/data

# Memos — notes, a 20 MB image
hostim volumes create memos-data --plan vol-0
hostim deploy memos --docker-image neosmemo/memos:stable --plan sa-1-1 --port 5230 --volume memos-data:/var/opt/memos

# Vaultwarden — Bitwarden-compatible password manager
hostim volumes create vault-data --plan vol-0
hostim deploy vault --docker-image vaultwarden/server:latest --plan sa-1-1 --port 80 --volume vault-data:/data

The vol-0 volume plan is 1 GB and costs nothing, so each of these is €2.50/month in total. A private registry works the same with --registry, --docker-user and --docker-pass. Shipping a new build is the same command with a new tag — the app is updated, not recreated.

A Git repository

Build the Dockerfile in your repo.

The platform clones the repository, builds the Dockerfile and runs the image. The command waits for the build and exits non-zero if it fails, which is why the same line belongs in CI.

This is the Express example app — github.com/hostimdev/demo-express — with the PostgreSQL, Redis and volume it expects. No credential is typed anywhere: $(DB_POSTGRES_PASSWORD) and the rest are resolved by the platform when the container starts.

git

hostim db postgres create db --plan sp-0
hostim db redis create redis --plan sr-0
hostim volumes create avatar-uploads --plan vol-0

hostim deploy app --git https://github.com/hostimdev/demo-express --branch main \
  --plan sa-1-1 --port 3000 \
  --volume avatar-uploads:/app/public/uploads/avatars \
  --env 'DB_HOST=$(DB_POSTGRES_HOST)' \
  --env 'DB_USER=$(DB_POSTGRES_USER)' \
  --env 'DB_PASS=$(DB_POSTGRES_PASSWORD)' \
  --env 'DB_NAME=$(DB_POSTGRES_DATABASE)' \
  --env 'REDIS_HOST=$(REDIS_REDIS_HOST)' \
  --env 'REDIS_PORT=$(REDIS_REDIS_PORT)'

Point --git at your own repository and the command is unchanged. Private repositories take --git-token; a Dockerfile outside the root takes --dockerfile. Each example app below is the same shape, and its template creates the whole set in one command:

example app

hostim templates apply --id demo-expressjs --new-project express-demo --yes

Software you did not write

34 stacks, one command each.

A curated template creates the app, its database, its Redis and its volumes in order, with the environment variables already wired. Nothing to look up.

templates

hostim templates ls
hostim templates show linkding
hostim templates apply --id linkding --new-project bookmarks --yes

--new-project creates the project first, so those three lines are a whole deployment from an empty account. Without it the resources land in the project you selected. Drop --yes and the command prints what it will create and asks first.

Ghost

ghost-blog

listmonk

listmonk

Chatwoot

chatwoot

Mastodon

mastodon

Umami

umami

Linkding

linkding

Memos

memos

Trilium Notes

trilium

BookStack

bookstack

Docmost

docmost

FreshRSS

freshrss

Node-RED

node-red

ActivePieces

activepieces

OpenWebUI

openwebui

Stirling PDF

stirling-pdf

PhotoPrism

photoprism

Navidrome

navidrome

Komga

komga

NodeBB

nodebb

Remark42

remark42

Actual Budget

actual

Bytebase

bytebase

Penpot

penpot

Dolibarr

dolibarr

That is a selection; hostim templates ls prints the rest. Any template can be written out with --save stack.yml, edited — a bigger plan, a different image tag, an extra variable — and deployed with hostim templates apply -f stack.yml.

A docker-compose.yml

Bring the file you already have.

The Compose file is converted into a stack: each service becomes its own app on its own plan, named volumes become volumes, and postgres, mysql or redis services become managed instances instead of containers you have to maintain.

compose

hostim templates apply --compose docker-compose.yml --save stack.yml
hostim templates validate -f stack.yml
hostim templates apply -f stack.yml

Saving first is worth the extra line. The converted file is plain YAML, and it is where you set plans, fix a port, or add the Git URL for a service that was build: . locally. validate checks it offline, without creating anything.

After it is up

Everything else is one line.

Logs, variables, domains, a shell in the container, and what it all costs.

day two

hostim status                              # build and runtime state of every app
hostim logs web --follow                   # stream logs
hostim env set -a web KEY=value            # set a variable, restarts the app
hostim env pull -a web                     # write them to a local .env
hostim domain add app.example.com -a web   # prints the DNS record to create
hostim exec web -- sh                      # a shell inside the container
hostim overview                            # every resource and its monthly cost

It scripts

Every command takes -o json, and every write prints a single result object — hostim status -o json | jq is the whole integration story. Failures print JSON on stderr and exit non-zero.

The complete manual

hostim agent prints every command, flag, JSON field and exit code to stdout, for the version you have installed. Pipe it into a coding assistant and it stops guessing flags. Same text as cli-manual.md and the README, which is MIT-licensed.

Questions

Before you start.

How do I deploy my app from the command line?

Install the CLI with: curl -fsSL https://raw.githubusercontent.com/hostimdev/cli/main/install.sh | sh. Run hostim login with an API token from the console, then deploy — hostim deploy web --docker-image nginx:alpine --plan sa-1-1 --port 80 for an image, or hostim deploy web --git <repository> --branch main --plan sa-1-1 --port 3000 for a repository that contains a Dockerfile. The command creates the app the first time and rebuilds it every time after, waits for the build, and exits non-zero if it fails, so the same line works in a CI job.

Can I deploy an app that has no Dockerfile?

Only if you already have an image. Deploying from Git builds the Dockerfile in your repository, so the repository needs one — there is no buildpack that guesses your stack. Deploying a published image needs no Dockerfile at all: hostim deploy kuma --docker-image louislam/uptime-kuma:2 --plan sa-1-1 --port 3001 runs any public image as it is.

How do I connect my app to a database?

Create one with hostim db postgres create db --plan sp-0 (256 MB, free), then point the app at it with a service reference instead of a password: hostim env set -a web 'DATABASE_URL=postgres://$(DB_POSTGRES_USER):$(DB_POSTGRES_PASSWORD)@$(DB_POSTGRES_HOST):$(DB_POSTGRES_PORT)/$(DB_POSTGRES_DATABASE)'. Each $(NAME_KEY) is resolved by the platform when the container starts, so no credential is typed into a command, stored in CI or committed to a repository. MySQL and Redis work the same way, for example $(REDIS_REDIS_HOST).

How do I deploy a docker-compose.yml?

Run hostim templates apply --compose docker-compose.yml. Each service becomes its own app on its own plan, and services whose image is postgres, mysql or redis are created as managed instances instead of containers you maintain. Add --save stack.yml to write the converted file out first, edit it, then deploy it with hostim templates apply -f stack.yml.

What does it cost to host a small app?

One app on the smallest shared plan is €2.50/month for 1 vCPU and 1 GB of RAM. Managed services have a permanently free tier — PostgreSQL 256 MB (sp-0), MySQL 256 MB (sm-0), Redis 128 MB (sr-0) and a 1 GB volume (vol-0) — so a small app with a database and persistent storage is €2.50/month in total. CPU, memory, egress and build minutes are not metered, so the bill does not move with traffic.

Where does the app run, and does it sleep?

On EU bare metal in Falkenstein, Germany, currently the only region. Containers are long-lived: they never sleep and never scale to zero, on every plan including the cheapest. Websockets, in-memory caches, background intervals and loaded model weights survive between requests, and nothing cold-starts.

How do I get a domain and HTTPS?

Every app gets an HTTPS address on *.eu-center.hostim.dev as soon as it is created. For your own domain run hostim domain add app.example.com -a web; the command prints the DNS record to create at your provider. Once the record resolves, the certificate is issued and renewed automatically.

Start now

Put something live today.

The 5-day trial project needs no card. Install the CLI and deploy into it, or click through the console — the same resources either way.