th: the ThailandHosting CLI

Deploy Containers and static sites, copy files to Object Storage, connect to databases and caches, and send or receive queue messages from your terminal or CI.

What th is

th is the command line of ThailandHosting. It talks to the same API as the Console, acting as your account (after th auth login) or as an API key (in CI). Commands are grouped by service: th <group> <command> [arguments] [parameters].

Shell
th auth login
th container deploy api --source .
th static-site deploy docs ./dist
th object-storage cp -r ./backups th://my-bucket/backups
th database connect app-db
th queue tail jobs

th help lists every command. Add --help to any command (or run th help container deploy) to see its own parameters. Typing only a group, such as th container, lists the commands in it.

Parameters and arguments can come in any order: th container deploy api --port 3000 and th container deploy --port 3000 api do the same. A flag that is on by default is turned off with --no-, for example --no-ack.

Install

The install scripts download the latest release from GitHub and check it against the release’s SHA256SUMS before installing anything.

Shell
# Linux, macOS
curl -fsSL https://raw.githubusercontent.com/mrzack99s/thailandhosting-cli/main/install.sh | sh

# Windows (PowerShell)
irm https://raw.githubusercontent.com/mrzack99s/thailandhosting-cli/main/install.ps1 | iex
SystemWhere th goesOptions
Linux, macOS/usr/local/bin, or ~/.local/bin when that is not writableTH_VERSION=0.1.0 picks a version; TH_INSTALL_DIR picks the folder
Windows%LOCALAPPDATA%\Programs\th, added to your user PATH (open a new terminal afterwards)$env:TH_VERSION picks a version

You can also download an archive for your system from GitHub Releases, or build it with Go 1.23 or newer:

Shell
go install github.com/mrzack99s/thailandhosting-cli/cmd/th@latest

Check the installed version with th version.

Sign in

  1. Run th auth login. The CLI prints a link and a code, and opens the Console in your browser (with --no-browser it only prints the link, for a server without a desktop).
  2. In the Console, check that the code matches the one in your terminal, then click Approve.
  3. The terminal says who you are signed in as. If no Project is set yet, your first Project becomes the active one.

The sign-in lasts 90 days and is saved in the th config file (th/config.json in your user config folder, readable only by you). It is listed in the Console under Account → Sessions, where you can sign it out from anywhere.

Shell
th auth status        # who the CLI acts as (also: th whoami)
th auth logout        # sign this token out and remove it from the config file

In CI, don’t sign in: set an API key in TH_API_KEY instead (see Use in CI). When TH_API_KEY is set it takes precedence over a saved sign-in.

Choose a Project and region

Most commands work on one Project. New services also need a region. Set them once with th config, or per command:

Shell
th projects list
th config set project acme      # ID or slug
th regions list
th config set region bkk
th config list

Each setting is taken from the first place that has it:

  1. The parameter on the command line: --project, --region, --endpoint.
  2. The environment variable: TH_PROJECT, TH_REGION, TH_ENDPOINT.
  3. The config file, set with th config set.

With no region set, a command that creates a service uses the platform’s default region and says so. An API key belongs to one Project, so with TH_API_KEY the Project comes from the key.

Global parameters

Every command takes these parameters as well as its own.

NameTypeDescription
--projectstringProject ID or slug (default: config / TH_PROJECT)
--regionstringRegion ID (default: config / TH_REGION)
--endpointstringAPI endpoint (default: config / TH_ENDPOINT, else https://cloud.thailandhosting.com)
--formatstringOutput format: text or json
--quietflagDo not prompt; assume yes

--help (or -h) prints a command’s usage and parameters instead of running it.

Output formats

By default commands print text for people: tables with a header row, or a short sentence saying what was done. With --format json they print the API’s JSON instead, for scripts and tools such as jq.

Shell
th container services list
th container services list --format json | jq -r '.[].name'
  • Standard output carries only the result: the table, the JSON, the file you asked for (th object-storage cat), or the message (th queue receive).
  • Standard error carries progress and hints: “Packing sources…”, build logs, upload progress, prompts and errors. Redirecting standard output to a file therefore gives you clean data.
  • Errors look like ERROR: (th.container.deploy) …, naming the command that failed.

Commands that delete or replace something ask Do you want to continue (Y/n)? first. --quiet answers yes for you; without it, a command that cannot ask (no terminal on standard input) stops with an error instead of guessing.

Environment variables

VariableWhat it does
TH_API_KEYAn API key from the Console (Integrations → API keys). Used instead of the saved sign-in; the key’s scopes decide what th may do.
TH_TOKENA token to send instead of the saved sign-in (a value starting with thk_ is treated as an API key). th auth print-access-token shows the token in use.
TH_ENDPOINTThe API address the CLI calls. Default: https://cloud.thailandhosting.com.
TH_PROJECTThe Project, by ID or slug.
TH_REGIONThe region for new services.
TH_OBJECT_STORAGE_KEY_ID, TH_OBJECT_STORAGE_SECRETAn Object Storage access key for the th object-storage file commands. Set both or neither.
TH_QUEUE_KEY_ID, TH_QUEUE_SECRETA Queue Service access key for sending, receiving and the other message commands. Set both or neither.

Object Storage and the Queue Service take their own access keys, not the CLI sign-in. Signed in on your own computer you don’t need to create one: th asks the Console for a short-lived key of the Project (valid 12 hours, with what your role allows) and keeps it next to the config file until shortly before it expires. With TH_API_KEY, or to use a specific key, set the variables above.

Use in CI

Create a key in the Console, store it as a secret in your CI, and pass it in an environment variable. Use --quiet so nothing waits for an answer.

ToKeyVariables
Deploy ContainersAPI key with Containers: deploy (run:write)TH_API_KEY
Deploy Static WebAPI key with Static Web: deploy (static:write)TH_API_KEY
Only read Containers or Static WebAPI key with run:read or static:readTH_API_KEY
Object StorageAn Object Storage access keyTH_OBJECT_STORAGE_KEY_ID, TH_OBJECT_STORAGE_SECRET
Queue ServiceA Queue Service access keyTH_QUEUE_KEY_ID, TH_QUEUE_SECRET

An API key works only on its own Project. GitHub Actions:

Shell
# .github/workflows/deploy.yml
on:
  push:
    branches: [main]
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: |
          curl -fsSL https://raw.githubusercontent.com/mrzack99s/thailandhosting-cli/main/install.sh | TH_INSTALL_DIR="$HOME/.local/bin" sh
          echo "$HOME/.local/bin" >> "$GITHUB_PATH"
      - run: th container deploy api --source . --quiet
        env:
          TH_API_KEY: ${{ secrets.TH_API_KEY }}

Give each pipeline its own key with only the scopes it needs. If one leaks, revoke just that key.

Exit codes

CodeMeaning
0The command succeeded (also for --help, and for th queue tail stopped with Ctrl+C).
1An error, or you answered no to a confirmation (“Aborted.”). The reason is on standard error.
130You pressed Ctrl+C while th was following a build log (th container deploy --source, th builds log --follow, th static-site builds log --follow). The build keeps going on the server; follow it again with the command th prints.
Otherth database connect and th cache connect end with the exit code of the client they started (psql, mysql, redis-cli and so on).

Command groups

CommandDescription
th authSign the CLI in and out, see who it acts as, and log Docker in to your Project’s container registry. (5)
th configSet the Project, region and Console endpoint the CLI uses, list your Projects and regions, and print the CLI version. (7)
th containerDeploy Containers from a folder or an image, roll back to earlier revisions, read logs, and keep your Project’s registry tidy. (13)
th registryCreate registries, tag, copy and delete images, sign docker and CI in with access tokens, and keep storage down with cleanup policies. (13)
th functionsDeploy Python, Node.js (TypeScript) and Go functions from a folder, pull the code you edited in the Console, and call them. (10)
th triggersCall a Container or function on a cron schedule or for every message of a queue. (7)
th static-siteDeploy a built folder as a Static Web site, roll back to an earlier release, connect your own domain and follow Git builds. (13)
th object-storageCreate buckets, copy and sync files with th:// paths, make folders public, and share single files with links that expire. (12)
th databaseCreate PostgreSQL, MySQL and MariaDB databases, connect from your computer with one command, back up and restore, and add read replicas. (20)
th cacheCreate ThailandHosting Cache (works with Redis clients) and Valkey caches, connect with redis-cli or valkey-cli, resize them and manage backups. (17)
th queueCreate queues, send messages, receive and acknowledge them, and tail a queue as a simple consumer. (11)