|
| 1 | +# Extension: ccache-remote |
| 2 | + |
| 3 | +[ccache](https://ccache.dev/) significantly speeds up repeated kernel and |
| 4 | +U-Boot builds by caching compiled objects. By default, each build host has |
| 5 | +its own local cache. This extension adds a **shared remote cache** so that |
| 6 | +multiple build machines (or a CI server and a developer workstation) can all |
| 7 | +benefit from objects already compiled by someone else. |
| 8 | + |
| 9 | +Typical scenarios: |
| 10 | + |
| 11 | +- A home lab with several SBCs used as build hosts — first build populates |
| 12 | + the cache, subsequent builds on other machines hit it. |
| 13 | +- A CI server and developer laptops sharing one cache server so that a |
| 14 | + developer rarely needs to compile from scratch after CI has run. |
| 15 | +- A single machine where the local cache was lost (disk wiped) but the |
| 16 | + remote cache is still warm. |
| 17 | + |
| 18 | +The extension supports two backends: |
| 19 | + |
| 20 | +- **Redis** — lower latency, recommended for fast local networks. Cache lives |
| 21 | + entirely in RAM on the server, so capacity is limited by available memory. |
| 22 | +- **HTTP/WebDAV** (nginx) — somewhat slower, but stores cache on disk. Can |
| 23 | + be orders of magnitude larger than a RAM-backed Redis instance, making it |
| 24 | + a better choice when cache size matters more than speed. |
| 25 | + |
| 26 | +### Auto-discovery vs. explicit configuration |
| 27 | + |
| 28 | +The simplest deployment uses **Avahi (DNS-SD)**. Once the cache server is |
| 29 | +set up and publishing its service, and Avahi is installed on all build hosts, |
| 30 | +enabling the extension is all that is needed — no URL configuration required. |
| 31 | + |
| 32 | +If Avahi is not available or not desirable, the server URL must be provided |
| 33 | +explicitly via `CCACHE_REMOTE_STORAGE`, or for remote servers via |
| 34 | +`CCACHE_REMOTE_DOMAIN` (DNS SRV). See [Parameters](#parameters) below. |
| 35 | + |
| 36 | +The extension automatically enables `USE_CCACHE=yes` and handles all ccache |
| 37 | +configuration including Docker pass-through. |
| 38 | + |
| 39 | +## Quick start |
| 40 | + |
| 41 | +If a cache server is already running on the local network and advertising |
| 42 | +itself via DNS-SD (Avahi), no configuration is needed: |
| 43 | + |
| 44 | +```bash |
| 45 | +./compile.sh BOARD=<board> BRANCH=<branch> ENABLE_EXTENSIONS="ccache-remote" |
| 46 | +``` |
| 47 | + |
| 48 | +With an explicit Redis server: |
| 49 | + |
| 50 | +```bash |
| 51 | +./compile.sh BOARD=<board> BRANCH=<branch> \ |
| 52 | + ENABLE_EXTENSIONS="ccache-remote" \ |
| 53 | + CCACHE_REMOTE_STORAGE="redis://192.168.1.65:6379" |
| 54 | +``` |
| 55 | + |
| 56 | +With an explicit HTTP/WebDAV server: |
| 57 | + |
| 58 | +```bash |
| 59 | +./compile.sh BOARD=<board> BRANCH=<branch> \ |
| 60 | + ENABLE_EXTENSIONS="ccache-remote" \ |
| 61 | + CCACHE_REMOTE_STORAGE="http://192.168.1.65:8088/ccache/" |
| 62 | +``` |
| 63 | + |
| 64 | +To enable permanently from a userconfig file: |
| 65 | + |
| 66 | +```bash |
| 67 | +enable_extension "ccache-remote" |
| 68 | +# optionally: |
| 69 | +# CCACHE_REMOTE_STORAGE="redis://192.168.1.65:6379" |
| 70 | +``` |
| 71 | + |
| 72 | +## Requirements |
| 73 | + |
| 74 | +- **ccache**: version 4.4 or newer (for remote storage support). |
| 75 | +- **Redis backend**: Redis server accessible from the build host. |
| 76 | +- **HTTP backend**: nginx with WebDAV module (`nginx-extras`). |
| 77 | +- **Auto-discovery**: `avahi-browse` (package `avahi-utils`) on the build host. |
| 78 | + |
| 79 | +## Parameters |
| 80 | + |
| 81 | +| Variable | Default | Description | |
| 82 | +|---|---|---| |
| 83 | +| **`CCACHE_REMOTE_STORAGE`** | _(empty)_ | Remote storage URL. If not set, auto-discovery is attempted. | |
| 84 | +| **`CCACHE_REMOTE_DOMAIN`** | _(empty)_ | Domain for DNS SRV discovery (e.g. `example.com`). | |
| 85 | +| **`CCACHE_REMOTE_ONLY`** | `no` | Set to `yes` to disable local cache and use only remote storage (saves local disk space). | |
| 86 | +| **`CCACHE_REDIS_CONNECT_TIMEOUT`** | `500` | Redis connection timeout in milliseconds. | |
| 87 | +| **`CCACHE_READONLY`** | _(empty)_ | Set to any value to use cache read-only (don't write new entries). | |
| 88 | +| **`CCACHE_RECACHE`** | _(empty)_ | Recompile everything and update cache (bypass existing entries). | |
| 89 | +| **`CCACHE_RESHARE`** | _(empty)_ | Push existing local cache entries to remote storage. | |
| 90 | +| **`CCACHE_MAXSIZE`** | _(empty)_ | Maximum local cache size (e.g. `10G`). | |
| 91 | +| **`CCACHE_NAMESPACE`** | _(empty)_ | Namespace for cache isolation between projects or branches. | |
| 92 | +| **`CCACHE_DISABLE`** | _(empty)_ | Set to any value to disable ccache completely. | |
| 93 | + |
| 94 | +For the full list of supported variables see the `CCACHE_PASSTHROUGH_VARS` |
| 95 | +array in the extension source or the |
| 96 | +[ccache configuration reference](https://ccache.dev/manual/latest.html#config_remote_storage). |
| 97 | + |
| 98 | +### CCACHE_REMOTE_STORAGE URL format |
| 99 | + |
| 100 | +``` |
| 101 | +Redis: redis://[[USER:]PASSWORD@]HOST[:PORT][|attribute=value...] |
| 102 | +HTTP: http://HOST[:PORT]/PATH/[|attribute=value...] |
| 103 | +``` |
| 104 | + |
| 105 | +Common attributes: |
| 106 | + |
| 107 | +| Attribute | Default | Description | |
| 108 | +|---|---|---| |
| 109 | +| `connect-timeout` | `100` ms | Connection timeout. Increase on slow networks. | |
| 110 | +| `operation-timeout` | `10000` ms | Per-operation timeout. | |
| 111 | + |
| 112 | +Examples: |
| 113 | + |
| 114 | +``` |
| 115 | +redis://192.168.1.65:6379|connect-timeout=500 |
| 116 | +redis://default:secretpass@192.168.1.65:6379|connect-timeout=500 |
| 117 | +http://192.168.1.65:8088/ccache/ |
| 118 | +``` |
| 119 | + |
| 120 | +!!! warning |
| 121 | + Redis passwords must not contain `/`, `+`, `=`, or spaces — these break |
| 122 | + URL parsing. Generate a safe password with: |
| 123 | + ```bash |
| 124 | + openssl rand -hex 24 |
| 125 | + ``` |
| 126 | + |
| 127 | +## Server discovery |
| 128 | + |
| 129 | +When `CCACHE_REMOTE_STORAGE` is not set, the extension tries to discover a |
| 130 | +cache server automatically in this order: |
| 131 | + |
| 132 | +1. **DNS-SD** (mDNS / Avahi): browse for `_ccache._tcp` on the local network. |
| 133 | + Requires `avahi-browse` on the build host and the cache server publishing |
| 134 | + a DNS-SD service. Redis is preferred over HTTP when both are found. |
| 135 | + |
| 136 | +2. **DNS SRV**: query `_ccache._tcp.DOMAIN` when `CCACHE_REMOTE_DOMAIN` is |
| 137 | + set. Useful for remote or cloud-hosted build servers. |
| 138 | + |
| 139 | +3. **Legacy mDNS**: resolve the hostname `ccache.local` (falls back to Redis |
| 140 | + on port 6379). Kept for backward compatibility. |
| 141 | + |
| 142 | +If none of these succeeds, the extension silently falls back to local cache only. |
| 143 | + |
| 144 | +## Cache sharing requirements |
| 145 | + |
| 146 | +For the cache to be shared across multiple build hosts, **the Armbian source |
| 147 | +tree must be at the same path on all machines** (e.g. `/home/build/armbian`). |
| 148 | +ccache includes the working directory in the cache key, so different paths |
| 149 | +produce different keys and the cache will not be shared. |
| 150 | + |
| 151 | +Docker builds are not affected — they always use a consistent internal path. |
| 152 | + |
| 153 | +## Server setup |
| 154 | + |
| 155 | +### Redis (recommended) |
| 156 | + |
| 157 | +1. Install: |
| 158 | + |
| 159 | + ```bash |
| 160 | + apt install redis-server avahi-daemon avahi-utils |
| 161 | + ``` |
| 162 | + |
| 163 | +2. Configure Redis — copy `misc/redis/redis-ccache.conf` from the extension |
| 164 | + directory and include it in `/etc/redis/redis.conf`: |
| 165 | + |
| 166 | + ```bash |
| 167 | + echo "include /etc/redis/redis-ccache.conf" >> /etc/redis/redis.conf |
| 168 | + systemctl restart redis-server |
| 169 | + ``` |
| 170 | + |
| 171 | +3. Set a password (recommended for any non-isolated network): |
| 172 | + |
| 173 | + ```bash |
| 174 | + openssl rand -hex 24 # use output as password |
| 175 | + # set requirepass <password> in redis-ccache.conf |
| 176 | + ``` |
| 177 | + |
| 178 | +4. Publish the DNS-SD service so clients discover it automatically: |
| 179 | + |
| 180 | + ```bash |
| 181 | + # Static (always advertise): |
| 182 | + cp misc/avahi/ccache-redis.service /etc/avahi/services/ |
| 183 | +
|
| 184 | + # Or tied to redis-server lifecycle: |
| 185 | + cp misc/systemd/ccache-avahi-redis.service /etc/systemd/system/ |
| 186 | + systemctl enable --now ccache-avahi-redis |
| 187 | + ``` |
| 188 | + |
| 189 | +### HTTP/WebDAV (nginx) |
| 190 | + |
| 191 | +1. Install: |
| 192 | + |
| 193 | + ```bash |
| 194 | + apt install nginx-extras avahi-daemon avahi-utils |
| 195 | + ``` |
| 196 | + |
| 197 | +2. Enable the WebDAV site: |
| 198 | + |
| 199 | + ```bash |
| 200 | + cp misc/nginx/ccache-webdav.conf /etc/nginx/sites-available/ccache-webdav |
| 201 | + ln -s /etc/nginx/sites-available/ccache-webdav /etc/nginx/sites-enabled/ |
| 202 | + mkdir -p /var/cache/ccache-webdav/ccache |
| 203 | + chown -R www-data:www-data /var/cache/ccache-webdav |
| 204 | + systemctl reload nginx |
| 205 | + ``` |
| 206 | + |
| 207 | +3. Verify: |
| 208 | + |
| 209 | + ```bash |
| 210 | + curl -X PUT -d "test" http://localhost:8088/ccache/test.txt |
| 211 | + curl http://localhost:8088/ccache/test.txt |
| 212 | + ``` |
| 213 | + |
| 214 | + !!! warning |
| 215 | + The provided nginx configuration has no authentication. Use only on a |
| 216 | + trusted private network. |
| 217 | + |
| 218 | +4. Publish the DNS-SD service: |
| 219 | + |
| 220 | + ```bash |
| 221 | + cp misc/avahi/ccache-webdav.service /etc/avahi/services/ |
| 222 | + ``` |
| 223 | + |
| 224 | +### DNS SRV records (remote servers) |
| 225 | + |
| 226 | +For build hosts that cannot reach the cache server via mDNS, set |
| 227 | +`CCACHE_REMOTE_DOMAIN` and create DNS records: |
| 228 | + |
| 229 | +Redis backend: |
| 230 | +```text |
| 231 | +_ccache._tcp.example.com. SRV 0 0 6379 ccache.example.com. |
| 232 | +_ccache._tcp.example.com. TXT "type=redis" |
| 233 | +``` |
| 234 | + |
| 235 | +HTTP/WebDAV backend: |
| 236 | +```text |
| 237 | +_ccache._tcp.example.com. SRV 0 0 8088 ccache.example.com. |
| 238 | +_ccache._tcp.example.com. TXT "type=http" "path=/ccache/" |
| 239 | +``` |
| 240 | + |
| 241 | +### mDNS client requirements |
| 242 | + |
| 243 | +For `.local` hostname resolution to work on the build host: |
| 244 | + |
| 245 | +```bash |
| 246 | +# Option A: systemd-resolved |
| 247 | +apt install libnss-resolve |
| 248 | +
|
| 249 | +# Option B: standalone |
| 250 | +apt install libnss-mdns |
| 251 | +``` |
| 252 | + |
| 253 | +## References |
| 254 | + |
| 255 | +- [ccache remote storage documentation](https://ccache.dev/manual/latest.html#config_remote_storage) |
| 256 | +- [ccache Redis how-to](https://ccache.dev/howto/redis-storage.html) |
| 257 | +- [ccache HTTP how-to](https://ccache.dev/howto/http-storage.html) |
0 commit comments