1
0
mirror of https://codeberg.org/crowci/crow.git synced 2025-04-18 04:44:01 +03:00

docs: add instructions for installing remote agents

This commit is contained in:
pat-s 2025-04-09 19:13:56 +01:00
parent 0aac3b94dc
commit 72a1461f58
No known key found for this signature in database
GPG Key ID: 3C6318841EF78925
3 changed files with 180 additions and 30 deletions

View File

@ -19,7 +19,7 @@ MD004:
# MD007/ul-indent - Unordered list indentation
MD007:
# Spaces for indent
indent: 4
indent: 2
# Whether to indent the first level of the list
start_indented: false

View File

@ -1,3 +1,7 @@
<!-- markdownlint-disable MD041 -->
# Installation
## General
Crow consists out of essential components (the "server" and the "agent") and an optional one (the "autoscaler").
@ -22,7 +26,7 @@ There are currently two official ways[^1] how to install Crow:
- Via [`docker-compose`](docker-compose.md) for single servers.
- Via [`helm`](helm.md) for Kubernetes.
## Crow agent secret
## Crow agent tokens
To allow secure communication between the _server_ and _agent_ via GRPC, a token is required.
@ -37,7 +41,7 @@ In the best case, no further configuration is required.
### System token
The system token is set via the env var `CROW_AGENT_SECRET` for both server and agent.
The system token is set via the env var `CROW_AGENT_SECRET` for both server and agent deployments.
**There can only ever be one system token at the same time, therefore.**
If a system token is set, the registration process is as follows:
@ -56,10 +60,12 @@ It is therefore recommended to persist `CROW_AGENT_CONFIG_FILE` to ensure idempo
### Agent token
Agent tokens are created in the UI of the server (`Settings -> Agents -> Add agent`).
This is an alternative way to tell the server about persistent agents and their possible connections.
Agent tokens come into play when one wants to provision multiple agents, which, optionally, have certain restrictions set with respect to which workflows they are processing.
Agent tokens can be handed over to individual agents via `CROW_AGENT_SECRET`, making it possible to register additional unique agents.
Such tokens can be created in the UI of the server (`Settings -> Agents -> Add agent`) or through the API.
The resulting tokens can be handed over to individual agents and referenced via `CROW_AGENT_SECRET`.
Once an agent connects to the server for the first time with a matching agent token, the server registers the agent and allows it to process workflows.
![Agent creation](img/new-agent-registration.png){ width="500" }
/// caption
@ -68,6 +74,75 @@ Registration of a new agent through UI
[^2]: This is primarily because Crow (still) stores pipeline logs in the DB. A refactoring to storing these outside the DB by default is planned but not yet implemented.
## Installing agents on separate machines
/// note
Ensure you register an agent in the Crow server first and then use the resulting agent token when connecting the remote agent.
///
The simplest and most straightforward setup is to deploy agents on the same machine where the Crow server is running.
In this case, agents can connect directly to the server's GRPC port (default `9000`) over a local connection.
Yet, there are several reasons to deploy agents on remote servers and have them process builds.
First and foremost, you might want to do this if the Crow server is deployed on a small machine (or with other low-resource deployments) but builds need to be run on more powerful hardware.
In such scenarios, the connectivity must happen between two different machines, which are possibly connected over the public internet.
In the following sections, we'll explore both scenarios: connecting an agent running on a separate machine over an internal network, and connecting via a public internet connection.
### Internal
In this case, the setup is not much different from the default scenario of running the agent alongside the server on the same machine.
The agent must be deployed with the following env vars:
```yaml
# address of the Crow server: private ip (e.g. 10.x.x.x) + port
CROW_SERVER: <private server ip>:8000
CROW_GRPC_ADDR: <private server ip>:9000
# agent token, previously created in Crow server
CROW_AGENT_SECRET: <token>
# (optional) agent labels to restrict workflows processing to matching labels
CROW_AGENT_LABELS: <labels>
# [...] additional agent settings
```
### Public
When the public route must be used (which is the case when adding an agent without controlling the Crow server instance), the process becomes a bit more complex.
This is because a secure SSL connection must be used for the GRPC connection between the server and agent, as otherwise the token exchanged between both could be intercepted.
When using an SSL-GRPC connection, you must have a TLS-ready ingress on the Crow server machine that can process incoming requests adequately.
This means, there must be
- a subdomain for the GRPC service of Crow server
- an SSL certificate for this subdomain
Once this exists, the agent configuration would look as follows:
```yaml
CROW_SERVER: crow.mydomain.com
CROW_GRPC_ADDR: grpc.crow.mydomain.com
CROW_GRPC_SECURE: 'true'
# agent token, previously created in Crow server
CROW_AGENT_SECRET: <token>
# (optional) agent labels to restrict workflows processing to matching labels
CROW_AGENT_LABELS: <labels>
# [...] additional agent settings
```
//// warning
Do not prepend "https" before the domain name for the `CROW_SERVER` var.
////
Some notes:
- `CROW_GRPC_SECURE` is important here as it tells the agent to use an SSL-backed connection when trying to establish the connection.
- If you struggle to configure a proxy server on port 443 taking the subdomain requests, you can also use something like `crow.mydomain.com:<port>`.
The important part is that the receiving proxy is able to handle the TLS termination and forward the request to the Crow server service.
/// tip
Examples of common GRPC-based ingress configurations are provided in the [Reverse proxy setup](./proxy.md) page.
///
## Image tags
/// info
@ -77,13 +152,13 @@ Alternatively, the `dev` tag can be used for rolling builds from the `main` bran
///
- `vX.Y.Z`: SemVer tags for specific releases, no entrypoint shell (scratch image)
- `vX.Y`
- `vX`
- `vX.Y`
- `vX`
- `vX.Y.Z-alpine`: SemVer tags for specific releases, rootless for Server and CLI
- `vX.Y-alpine`
- `vX-alpine`
- `vX.Y-alpine`
- `vX-alpine`
- `dev`: Built from the `main` branch
- `dev-<hash>`
- `dev-<hash>`
- `pull_<PR_ID>`: Images built from Pull Request branches.
## Image registries

View File

@ -1,4 +1,5 @@
<!-- markdownlint-disable MD041 -->
In the following, different reverse proxy setups are given (in alphabetical order) to make Crow work behind a reverse proxy:
## Apache
@ -19,35 +20,44 @@ ProxyPassReverse / http://127.0.0.1:8000/
## Caddy
```txt
# WebUI and API
### Server
```conf
crow.example.com {
reverse_proxy crow-server:8000
}
```
# expose gRPC
crow-agent.example.com {
### GRPC
/// note
This is only needed when agents on remote servers should be connected over the public internet.
///
```conf
grpc.crow.example.com {
reverse_proxy h2c://crow-server:9000
}
```
/// info
The above configuration shows how to create reverse-proxies for server and agent communication. If the agent is configured to use SSL, do not forget to enable `CROW_GRPC_SECURE`.
///
## Nginx
### Server
```conf
server {
listen 80;
listen 443 ssl;
server_name crow.example.com;
ssl_certificate path/to/cert;
ssl_certificate_key path/to/key;
location / {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_pass http://127.0.0.1:8000;
proxy_pass http://0.0.0.0:8000;
proxy_redirect off;
proxy_http_version 1.1;
proxy_buffering off;
@ -61,6 +71,26 @@ server {
This does not cover an SSL configuration with NGINX but only shows how to properly forward incoming requests through NGINX to Crow.
///
### GRPC
/// note
This is only needed when agents on remote servers should be connected over the public internet.
///
```conf
server {
listen 443 ssl;
server_name grpc.example.com;
ssl_certificate path/to/cert;
ssl_certificate_key path/to/key;
location / {
grpc_pass grpc://0.0.0.0:9000;
}
}
```
## Ngrok
Start `ngrok` using the designed Crow port, e.g. `ngrok http 8000`.
@ -83,22 +113,20 @@ Set `CROW_HOST` to the returned URL (e.g. exx.tunnelmole.net) and (re)start Crow
## Traefik
To install the crow server behind a Traefik load balancer, both the http and the gRPC ports must be exposed and configured.
This is a comprehensive example, which uses `traefik` running via docker compose and applies TLS termination and automatic redirection from http to https.
Here is a comprehensive example, which uses `traefik` running via docker compose and applies TLS termination and automatic redirection from http to https.
### Server
```yaml
services:
server:
image: ghcr.io/crowci/crow-server:latest
image: <image>
environment:
# Crow settings ...
# [..] Crow settings
networks:
- dmz # externally defined network, so that traefik can connect to the server
volumes:
- crow-server-data:/var/lib/crow/
deploy:
labels:
- traefik.enable=true
@ -119,18 +147,26 @@ services:
- traefik.http.middlewares.crow-redirect.redirectscheme.scheme=https
- traefik.http.middlewares.crow-redirect.redirectscheme.permanent=true
- traefik.http.routers.crow.middlewares=crow-redirect@docker
```
# gRPC service
### GRPC
/// note
This is only needed when agents on remote servers should be connected over the public internet.
///
```yaml
# [...] continued from previous block
- traefik.http.services.crow-grpc.loadbalancer.server.port=9000
- traefik.http.services.crow-grpc.loadbalancer.server.scheme=h2c
- traefik.http.routers.crow-grpc-secure.rule=Host(`crow-grpc.your-domain.com`)
- traefik.http.routers.crow-grpc-secure.rule=Host(`grpc.crow.example.com`)
- traefik.http.routers.crow-grpc-secure.tls=true
- traefik.http.routers.crow-grpc-secure.tls.certresolver=letsencrypt
- traefik.http.routers.crow-grpc-secure.entrypoints=web-secure
- traefik.http.routers.crow-grpc-secure.service=crow-grpc
- traefik.http.routers.crow-grpc.rule=Host(`crow-grpc.your-domain.com`)
- traefik.http.routers.crow-grpc.rule=Host(`grpc.crow.example.com`)
- traefik.http.routers.crow-grpc.entrypoints=web
- traefik.http.routers.crow-grpc.service=crow-grpc
@ -142,3 +178,42 @@ networks:
dmz:
external: true
```
## HAProxy
General frontend configuration:
```conf
frontend https_in
mode http
bind :::443 v4v6 ssl crt <cert>
acl is_ci_subdomain hdr(host) -i crow.example.com
acl is_grpc_ci_subdomain hdr(host) -i grpc.crow.example.com
use_backend crowci_backend if is_ci_subdomain
use_backend crowci_grpc_backend if is_grpc_ci_subdomain
```
### Server
```conf
backend crowci_backend
mode http
balance roundrobin
http-request del-header X-Forwarded-For
http-request del-header X-Real-IP
# add an X-Forwarded-For header to the request, containing the actual IP address of the client
option forwardfor
server crowci 0.0.0.0:8000 maxconn 100000 check
```
### GRPC
```conf
backend crowci_grpc_backend
mode http
server crowci_grpc 0.0.0.0:9000 maxconn 100000 no-check proto h2
```