mirror of
https://github.com/aaif-goose/goose.git
synced 2026-07-03 14:10:03 +02:00
docs: add guide for connecting goose Desktop to a remote goosed server (#9275)
Signed-off-by: James Crosswell <james.crosswell@gmail.com> Signed-off-by: Douwe Osinga <douwe@squareup.com> Co-authored-by: Douwe Osinga <douwe@squareup.com>
This commit is contained in:
@@ -559,6 +559,30 @@ These variables configure the [Langfuse integration for observability](/docs/tut
|
||||
| `LANGFUSE_INIT_PROJECT_PUBLIC_KEY` | Alternative public key for Langfuse | String | None |
|
||||
| `LANGFUSE_INIT_PROJECT_SECRET_KEY` | Alternative secret key for Langfuse | String | None |
|
||||
|
||||
## goose Server
|
||||
|
||||
These variables configure the `goosed` server process. They are most often used when [running `goosed` on a remote machine](/docs/guides/remote-goose-server) and connecting goose Desktop to it, but they apply to any `goosed` invocation.
|
||||
|
||||
| Variable | Purpose | Values | Default |
|
||||
|----------|---------|---------|---------|
|
||||
| `GOOSE_HOST` | Interface the server binds to. Use `0.0.0.0` to accept connections from other machines; `localhost` or `127.0.0.1` restricts to the local machine. | Hostname or IP | `127.0.0.1` |
|
||||
| `GOOSE_PORT` | TCP port the server listens on | Port number | `3000` |
|
||||
| `GOOSE_TLS` | Enable TLS with a self-signed certificate. Required when connecting goose Desktop to a remote `goosed`. | `true`, `false` | `true` |
|
||||
| `GOOSE_SERVER__SECRET_KEY` | Shared secret required in the `X-Secret-Key` header on all client requests | Secret string | Random (auto-generated) |
|
||||
|
||||
**Examples**
|
||||
|
||||
```bash
|
||||
# Start a goosed server reachable on the local network over TLS
|
||||
export GOOSE_HOST=0.0.0.0
|
||||
export GOOSE_PORT=3000
|
||||
export GOOSE_TLS=true
|
||||
export GOOSE_SERVER__SECRET_KEY='a-long-random-secret'
|
||||
goosed agent
|
||||
```
|
||||
|
||||
When TLS is enabled, `goosed` prints a `GOOSED_CERT_FINGERPRINT=...` line on startup. Clients (such as goose Desktop) need this fingerprint to verify the self-signed certificate. See [Running a Remote goose Server](/docs/guides/remote-goose-server) for the full setup.
|
||||
|
||||
## Recipe Configuration
|
||||
|
||||
These variables control recipe discovery and management.
|
||||
|
||||
@@ -0,0 +1,219 @@
|
||||
---
|
||||
sidebar_position: 90
|
||||
title: Running a Remote goose Server
|
||||
sidebar_label: Remote Server
|
||||
---
|
||||
|
||||
# Running a Remote goose Server
|
||||
|
||||
goose Desktop normally runs its own `goosed` server process in the background on the same machine. You can also run `goosed` separately — for example, on a remote VM or a different machine on your network — and point goose Desktop at it.
|
||||
|
||||
This is useful when you want goose to run somewhere with more compute, a stable IP, or shared access, while still driving it from a local Desktop UI.
|
||||
|
||||
This guide covers:
|
||||
|
||||
1. [Starting a `goosed` server on a remote machine](#1-start-the-goosed-server)
|
||||
2. [Verifying it is reachable](#2-verify-the-server-is-up)
|
||||
3. [Locating the certificate fingerprint](#3-find-the-certificate-fingerprint)
|
||||
4. [Configuring goose Desktop to connect to it](#4-configure-goose-desktop)
|
||||
5. [Running `goosed` as a background service on macOS](#running-goosed-as-a-background-service-macos)
|
||||
6. [Troubleshooting](#troubleshooting)
|
||||
|
||||
:::warning TLS is required
|
||||
goose Desktop will refuse to connect to a remote `goosed` server over plain HTTP. TLS is enabled by default (`GOOSE_TLS=true`), so make sure you have not disabled it.
|
||||
:::
|
||||
|
||||
## Initial Setup
|
||||
|
||||
### 1. Start the `goosed` server
|
||||
|
||||
On the remote machine, launch `goosed` with the host, port, TLS, and a shared secret key:
|
||||
|
||||
```bash
|
||||
GOOSE_HOST=0.0.0.0 \
|
||||
GOOSE_PORT=3000 \
|
||||
GOOSE_TLS=true \
|
||||
GOOSE_SERVER__SECRET_KEY='YOUR_SECRET' \
|
||||
/Applications/Goose.app/Contents/Resources/bin/goosed agent
|
||||
```
|
||||
|
||||
On Linux or Windows the path to the `goosed` binary will differ — use the one bundled with your goose installation, or a standalone `goosed` build.
|
||||
|
||||
| Variable | Purpose |
|
||||
|----------|---------|
|
||||
| `GOOSE_HOST` | Interface to bind to. Use `0.0.0.0` to accept connections from other machines. Binding to `localhost` or `127.0.0.1` will only accept local connections. |
|
||||
| `GOOSE_PORT` | TCP port to listen on. |
|
||||
| `GOOSE_TLS` | Must be `true`. goose Desktop will not connect to a plain HTTP server. |
|
||||
| `GOOSE_SERVER__SECRET_KEY` | Shared secret. The client must send this in the `X-Secret-Key` header. Treat it like a password. |
|
||||
|
||||
:::tip
|
||||
Pick a long, random value for `GOOSE_SERVER__SECRET_KEY` and store it in a password manager — the same value goes into goose Desktop later.
|
||||
:::
|
||||
|
||||
### 2. Verify the server is up
|
||||
|
||||
First, confirm `goosed` is actually listening on the port you expect:
|
||||
|
||||
```bash
|
||||
lsof -nP -iTCP:3000 -sTCP:LISTEN
|
||||
```
|
||||
|
||||
Then test the endpoints from the server itself. The `-k` flag tells `curl` to accept the self-signed TLS certificate that `goosed` generates:
|
||||
|
||||
```bash
|
||||
# Connectivity only
|
||||
curl -i https://127.0.0.1:3000/status -k
|
||||
|
||||
# Authenticated endpoint (real test)
|
||||
curl -i https://127.0.0.1:3000/config/read -k \
|
||||
-H 'Content-Type: application/json' \
|
||||
-H 'X-Secret-Key: YOUR_SECRET' \
|
||||
--data '{"key":"GOOSE_PROVIDER","is_secret":false}'
|
||||
```
|
||||
|
||||
A `200` response from the second call confirms that TLS is up, the secret key is being accepted, and the server is ready to receive client requests.
|
||||
|
||||
If you intend to reach the server from another machine, also test from there using the server's hostname or VPN address — not `127.0.0.1`.
|
||||
|
||||
### 3. Find the certificate fingerprint
|
||||
|
||||
Because `goosed` generates a self-signed TLS certificate, goose Desktop pins it by SHA-256 fingerprint rather than relying on a public certificate authority.
|
||||
|
||||
When TLS is enabled, `goosed` logs the fingerprint on startup. It looks like:
|
||||
|
||||
```text
|
||||
GOOSED_CERT_FINGERPRINT=AA:BB:CC:DD:EE:FF:...
|
||||
```
|
||||
|
||||
To capture it, either:
|
||||
|
||||
- Run `goosed` interactively and read it from the terminal output, or
|
||||
- Tail the log file you redirect to when running as a service (see [Running `goosed` as a background service](#running-goosed-as-a-background-service-macos)):
|
||||
|
||||
```bash
|
||||
grep GOOSED_CERT_FINGERPRINT ~/Library/Logs/GooseExternal/goosed.out.log
|
||||
```
|
||||
|
||||
Make a note of the fingerprint — you will paste it into goose Desktop in the next step.
|
||||
|
||||
:::note
|
||||
The fingerprint changes whenever `goosed` regenerates its certificate (for example, if you delete the cert file). If goose Desktop suddenly refuses to connect after a server restart, re-check the fingerprint.
|
||||
:::
|
||||
|
||||
### 4. Configure goose Desktop
|
||||
|
||||
On the client machine, open goose Desktop and navigate to **Settings → goose Server**:
|
||||
|
||||
| Setting | Value |
|
||||
|---------|-------|
|
||||
| **Use external server** | Enabled |
|
||||
| **URL** | `https://your-server-host:3000` (use the hostname or IP that the client can reach — for example a VPN/tailnet address) |
|
||||
| **Secret Key** | The same value you used for `GOOSE_SERVER__SECRET_KEY` |
|
||||
| **Certificate Fingerprint** | The `GOOSED_CERT_FINGERPRINT` value from the server logs |
|
||||
|
||||
After saving, goose Desktop will route all backend requests to the remote `goosed`. If the connection fails, see [Troubleshooting](#troubleshooting).
|
||||
|
||||
## Running `goosed` as a Background Service (macOS)
|
||||
|
||||
Running `goosed` in a terminal session is fine for testing, but for everyday use you probably want it managed as a background service so it starts at login and restarts on failure. On macOS, this is done with `launchd`.
|
||||
|
||||
Create a LaunchAgent plist at `~/Library/LaunchAgents/com.goose.goosed.external.plist`:
|
||||
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key>
|
||||
<string>com.goose.goosed.external</string>
|
||||
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>/Applications/Goose.app/Contents/Resources/bin/goosed</string>
|
||||
<string>agent</string>
|
||||
</array>
|
||||
|
||||
<key>EnvironmentVariables</key>
|
||||
<dict>
|
||||
<key>GOOSE_HOST</key><string>0.0.0.0</string>
|
||||
<key>GOOSE_PORT</key><string>3000</string>
|
||||
<key>GOOSE_TLS</key><string>true</string>
|
||||
<key>GOOSE_SERVER__SECRET_KEY</key><string>YOUR_SECRET</string>
|
||||
</dict>
|
||||
|
||||
<key>RunAtLoad</key><true/>
|
||||
<key>KeepAlive</key><true/>
|
||||
|
||||
<key>StandardOutPath</key>
|
||||
<string>/Users/YOUR_USERNAME/Library/Logs/GooseExternal/goosed.out.log</string>
|
||||
<key>StandardErrorPath</key>
|
||||
<string>/Users/YOUR_USERNAME/Library/Logs/GooseExternal/goosed.err.log</string>
|
||||
</dict>
|
||||
</plist>
|
||||
```
|
||||
|
||||
Replace `YOUR_SECRET` and `YOUR_USERNAME` with appropriate values, and make sure the log directory exists:
|
||||
|
||||
```bash
|
||||
mkdir -p ~/Library/Logs/GooseExternal
|
||||
```
|
||||
|
||||
Then load and start the service:
|
||||
|
||||
```bash
|
||||
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.goose.goosed.external.plist
|
||||
launchctl kickstart -k gui/$(id -u)/com.goose.goosed.external
|
||||
```
|
||||
|
||||
To stop or remove it later:
|
||||
|
||||
```bash
|
||||
launchctl bootout gui/$(id -u)/com.goose.goosed.external
|
||||
```
|
||||
|
||||
:::tip
|
||||
Because the secret key is stored in plain text in the plist, the file should be readable only by your user. macOS LaunchAgents under `~/Library/LaunchAgents/` are already user-scoped, but you can tighten further with `chmod 600 ~/Library/LaunchAgents/com.goose.goosed.external.plist`.
|
||||
:::
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Server only accepts local connections
|
||||
|
||||
If `curl` works from the server but the client machine times out or gets "connection refused", check what interface `goosed` is bound to. If `GOOSE_HOST` is `localhost` or `127.0.0.1`, only loopback connections are accepted.
|
||||
|
||||
Set `GOOSE_HOST=0.0.0.0` to accept connections on all interfaces, then restart `goosed`. You can verify with:
|
||||
|
||||
```bash
|
||||
lsof -nP -iTCP:3000 -sTCP:LISTEN
|
||||
```
|
||||
|
||||
The output should show the address as `*:3000` or the specific external IP, not `127.0.0.1:3000`.
|
||||
|
||||
### TLS is not enabled
|
||||
|
||||
In the server's startup logs:
|
||||
|
||||
- If you see `listening on http://...`, TLS is **not** enabled. goose Desktop will not connect. Set `GOOSE_TLS=true` and restart `goosed`.
|
||||
- If you see `listening on https://...`, TLS is enabled and you are good to go.
|
||||
|
||||
The startup logs also contain the `GOOSED_CERT_FINGERPRINT=...` line you need for the goose Desktop configuration. Search the server's stdout (or log file, if running under `launchd`) for `GOOSED_CERT_FINGERPRINT` to find it.
|
||||
|
||||
### Client cannot authenticate (401 / Unauthorized)
|
||||
|
||||
A `401` from the server, or a goose Desktop error indicating that the secret was rejected, almost always means that `GOOSE_SERVER__SECRET_KEY` on the server does not match the **Secret Key** in goose Desktop's settings.
|
||||
|
||||
To check the secret end-to-end without involving goose Desktop, run the authenticated `curl` from [step 2](#2-verify-the-server-is-up) using exactly the value you have configured on the client. If that returns `200`, the secret is correct and the problem is in the client configuration; if it returns `401`, the secret on the server is different from what you are sending.
|
||||
|
||||
If you rotate the secret on the server, you must also update it in goose Desktop's settings — they are not synchronized automatically.
|
||||
|
||||
### Certificate fingerprint mismatch
|
||||
|
||||
If goose Desktop refuses to connect with a certificate or fingerprint error, the most common causes are:
|
||||
|
||||
- The server regenerated its certificate (for example, after deleting the cert file). Look at the latest startup logs for the current `GOOSED_CERT_FINGERPRINT` and update goose Desktop.
|
||||
- You copied the fingerprint with extra whitespace or pasted the wrong value.
|
||||
|
||||
## Related
|
||||
|
||||
- [Environment Variables](/docs/guides/environment-variables) — full reference for all `GOOSE_*` variables
|
||||
- [Configuration Files](/docs/guides/config-files) — persistent client-side configuration
|
||||
Reference in New Issue
Block a user