| 1 | # Deploying |
| 2 | |
| 3 | Deploying is getting a build off your machine and onto the URL people |
| 4 | use, and then knowing — not hoping — that the URL is serving it. One |
| 5 | command covers all of that. |
| 6 | |
| 7 | ```sh |
| 8 | carlos deploy -app hello ./hello |
| 9 | ``` |
| 10 | |
| 11 | It prints where it is deploying to, then `shipped`, then `promoted`, and |
| 12 | finally `live` against each hostname. That last line is the one that |
| 13 | matters. The others say a write succeeded; only `live` says a visitor |
| 14 | would get the new build. |
| 15 | |
| 16 | ## What the one command is doing |
| 17 | |
| 18 | Three steps, and you can run them separately when you want the gap |
| 19 | between them. |
| 20 | |
| 21 | Shipping hashes your artifact, stores it under its content address, and |
| 22 | records a manifest that never changes afterwards. Nothing you serve |
| 23 | changes yet. Promoting points a channel at that version — see |
| 24 | [Channels](/docs/channels/) for what a channel is and when you would have |
| 25 | more than one. Then the command watches: it polls the live hostname for |
| 26 | the `X-Carlos-Version` header until that header names the version you |
| 27 | shipped, over a 2xx. It gives up after two minutes by default, and |
| 28 | `-timeout` moves that. |
| 29 | |
| 30 | The header is also how you check by hand later, and it is worth |
| 31 | preferring over anything else you might reach for. A page that looks |
| 32 | right can be a cached copy of the old build: |
| 33 | |
| 34 | ```sh |
| 35 | curl -sI https://hello.bdf.oncarlos.com | grep -i x-carlos-version |
| 36 | ``` |
| 37 | |
| 38 | ## What you ship |
| 39 | |
| 40 | The version defaults to `git rev-parse --short HEAD`, so a deploy from a |
| 41 | clean checkout is already labelled with the commit it came from. |
| 42 | `-version` overrides it. |
| 43 | |
| 44 | Binaries are the common case, and `-target` says what you built for. It |
| 45 | defaults to `linux-arm64`, which is what Carloku runs, so a Go build for |
| 46 | this platform is: |
| 47 | |
| 48 | ```sh |
| 49 | GOOS=linux GOARCH=arm64 go build -o hello . |
| 50 | ``` |
| 51 | |
| 52 | A directory of files ships as a site, with `-kind static`: |
| 53 | |
| 54 | ```sh |
| 55 | carlos deploy -app hello-site -kind static ./public |
| 56 | ``` |
| 57 | |
| 58 | Run any of these once from your project and the CLI offers to remember |
| 59 | the app and the artifact in `.carlos/config`. Say yes and the whole |
| 60 | release becomes `carlos deploy` with no arguments, which is the form to |
| 61 | put in a Makefile or a git hook. |
| 62 | |
| 63 | ## When it doesn't go live |
| 64 | |
| 65 | A deploy that stops short usually stops for a reason it will tell you. |
| 66 | |
| 67 | If the channel you are promoting into needs approvals, the ship still |
| 68 | lands and the promote becomes a proposal: the CLI says how many |
| 69 | confirmations it needs and where to confirm them. If the channel has a |
| 70 | bake window, the promote lands and the fleet adopts when the window |
| 71 | expires — the command exits successfully, because the hold is policy |
| 72 | rather than a failure. And if no instance follows the channel yet, it |
| 73 | says so instead of watching a URL that nobody serves, and names |
| 74 | `carlos instances create` as the step that gives the version somewhere to |
| 75 | run. |
| 76 | |
| 77 | A watch that times out is a different situation. The version is published |
| 78 | and the pointer has moved, so your app is either failing to start or |
| 79 | failing its first request. Go to the logs: |
| 80 | |
| 81 | ```sh |
| 82 | carlos logs -app hello -since 10m |
| 83 | ``` |
| 84 | |
| 85 | Full flag lists for |
| 86 | [deploy](https://carlosframework.com/docs/cli/#carlos-deploy), |
| 87 | [ship](https://carlosframework.com/docs/cli/#carlos-ship) and |
| 88 | [promote](https://carlosframework.com/docs/cli/#carlos-promote) are in |
| 89 | the CLI reference, and `carlos deploy -h` prints them at your terminal. |
| 90 | |