Skip to content
Coolship

v0.3.0A project-local CLI for Coolify

Link once, then ship.

Link a repository to its Coolify application once, then deploy, tail logs, sync variables, and run locally from the terminal, without UUIDs.

Linux & macOSamd64 and arm64
curl -fsSL https://raw.githubusercontent.com/joaomnuno/coolship/main/scripts/install.sh | sh

View install scriptThen follow the quickstart

The whole loop, one binding

After link, no command needs a resource identifier. deploy submits one deployment and follows the UUID that submission returned, relaying the server's build log while it waits.

  • Interrupting stops local waiting only; the deployment continues and its UUID is reported.
  • Results go to stdout, progress and prompts to stderr, so piping stays useful.
  • This replay is a real session against the example application, typed back at typing speed.
my-app
$ coolship link --project coolship-example --environment production --application coolship-example
Linked project in /home/you/my-app/coolship.toml
Application: coolship-example (mm4c0zpbrzx8z96t0qiw3tff)
Environment: production
Project: coolship-example
Context: home

$ coolship deploy
→ coolship-example
→ production

✓ Deployed                      0:52
  ✓ build                       0:41
  ✓ rolling update              0:08
  ✓ container                   0:06
  ✓ cleanup                     0:00
Deployment: 03dusayin5rleswixblvdqba
Application: coolship-example (mm4c0zpbrzx8z96t0qiw3tff)
Status: finished
https://coolship.example.com

$ coolship logs --lines 5
2026-09-10T14:15:01.017517155Z 127.0.0.1 - - [10/Sep/2026:14:15:01 +0000] "GET / HTTP/1.1" 200 182 "-" "Wget" "-"
2026-09-10T14:15:11.049948936Z 127.0.0.1 - - [10/Sep/2026:14:15:11 +0000] "GET / HTTP/1.1" 200 182 "-" "Wget" "-"
2026-09-10T14:15:21.089560996Z 127.0.0.1 - - [10/Sep/2026:14:15:21 +0000] "GET / HTTP/1.1" 200 182 "-" "Wget" "-"
2026-09-10T14:15:31.130467890Z 127.0.0.1 - - [10/Sep/2026:14:15:31 +0000] "GET / HTTP/1.1" 200 182 "-" "Wget" "-"
2026-09-10T14:15:41.185711659Z 127.0.0.1 - - [10/Sep/2026:14:15:41 +0000] "GET / HTTP/1.1" 200 182 "-" "Wget" "-"

Showing the final output; animation is off because your system prefers reduced motion.

Four verbs, one project

Everything reads the binding that link wrote. Every command takes --format json.

A minute with Coolship

Five commands from a fresh terminal to a pull-request preview.

  1. Step 1: Log in once

    $ coolship login

    Coolship verifies the URL and token against the server, then stores them in the same file coolify-cli uses, so a login in either tool is a login in both.

    login reference
  2. Step 2: Link the repository

    $ coolship link

    It walks project, environment, and application, asking only when a choice is genuinely ambiguous, and writes coolship.toml. Every later command reads that binding.

    link reference
  3. Step 3: Deploy

    $ coolship deploy

    Deploy the source and branch already configured in Coolify, wait for exactly that deployment, and watch the build log stream while it runs.

    deploy reference
  4. Step 4: Pull the variables

    $ coolship env pull

    Write the application's variables into .env, keeping local-only keys and comments, and noting withheld values as comments rather than writing them empty.

    env reference
  5. Step 5: Preview a pull request

    $ coolship preview --pr 42

    Deploy the preview Coolify already holds for the pull request and observe it like deploy; in a GitHub Actions pull_request job the number comes from GITHUB_REF.

    preview reference

Complementary to coolify-cli, not a replacement

coolify-cli manages Coolify resources. Coolship manages the developer workflow around the project you are in. They share one login: both read the same credentials file.

Taskwith coolify-cliwith Coolship
Deploy
  • coolify deploy uuid <application-uuid>
  • $ coolship deploy

Waits for that exact deployment and streams its build log.

Logs
  • coolify app logs <uuid> --follow
  • $ coolship logs --follow

Polls snapshots and reports a gap instead of hiding it.

Variables
  • coolify app env list <app-uuid>
  • coolify app env sync <app-uuid>
  • $ coolship env pull
  • $ coolship env diff
  • $ coolship env push

One scope at a time; withheld values are never invented.

Status
  • coolify app get <uuid>
  • $ coolship status
Pull request preview
  • coolify deploy uuid <uuid> --pull-request-id 42
  • $ coolship preview --pr 42
Servers, keys, teams
  • coolify server …
  • coolify private-key …
  • coolify teams …

Out of scope on purpose. coolify-cli remains the right tool for administering the instance.

The parts around deploy

Real samples from the reference. Each one is a command you can run today.

Several applications, one file

A repository with several applications uses named targets instead of [project]. Commands pick the target whose root contains the current directory, or take its name.

Monorepos guide
coolship.toml
version = 1[apps.web]context = "home"project = "Personal"environment = "production"application = "frontend"root = "apps/web"[apps.api]context = "home"project = "Personal"environment = "production"application = "backend"root = "apps/api"
cd apps/api && coolship deploy   # the target whose root contains the directorycoolship deploy api              # or name it from anywherecoolship logs web --follow

Verified against Coolify 4.3.18. Every command was run end to end against a live instance; 4.3.19 changes none of the endpoints Coolship uses.

What was verified

Try it on the repository you have open right now

One line installs v0.3.0 into ~/.local/bin, checksum verified, never with sudo. Then coolship link.

Linux & macOSamd64 and arm64
curl -fsSL https://raw.githubusercontent.com/joaomnuno/coolship/main/scripts/install.sh | sh

View install scriptThen follow the quickstart