Repository navigation
Expand file tree
/
Copy pathcompose.yaml
More file actions
148 lines (141 loc) · 6.47 KB
/
Copy pathcompose.yaml
File metadata and controls
148 lines (141 loc) · 6.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
name: sensorbox
services:
# On-demand custom ImageBuilder builder. Always running, exposes an
# API at /builder/ (proxied through the selector nginx). Triggered
# by the firmware-selector when a recipe references a custom_branch.
# Only builds when the fork has new commits vs the existing container.
openwrt-builder:
build:
context: ./openwrt-builder
dockerfile: Dockerfile
restart: unless-stopped
environment:
BRANCHES_FILE: /app/branches.yaml
CONTAINER_SOCKET_PATH: ${CONTAINER_SOCKET_PATH}
BASE_CONTAINER: "ghcr.io/openwrt/imagebuilder"
CACHE_DIR: /cache
volumes:
- ${CONTAINER_SOCKET_PATH}:${CONTAINER_SOCKET_PATH}:rw
- ./branches.yaml:/app/branches.yaml:ro
- ./openwrt-builder/configs:/builder-configs:ro
- openwrt-build-cache:/cache:rw
security_opt:
- label=disable
redis:
image: docker.io/redis/redis-stack-server
restart: unless-stopped
volumes:
- ./redis-data:/data:rw
# Both ASU services run upstream's published image. sensorbox used to build
# from a vendored fork to get custom apk feeds in "append" mode; that support
# is upstream now, so the fork and its submodule are gone.
#
# Pinned by digest, not :latest -- upstream publishes only a floating tag,
# and this stack bakes credentials into firmware, so the build inputs should
# not change underneath a rebuild without a commit saying so. To update:
# podman pull docker.io/openwrt/asu:latest
# podman image inspect docker.io/openwrt/asu:latest --format '{{.Digest}}'
asu-server:
image: docker.io/openwrt/asu@sha256:1359bbc4fd3e244c0c5e6f1a5f8b16fb18ca355a2b4017b09ca8467afc05e2a1
restart: unless-stopped
command: uv run uvicorn --host 0.0.0.0 asu.main:app
env_file: .env
environment:
REDIS_URL: redis://redis:6379/0
# ASU's default cap on the `defaults` field is 20480 chars. Our
# rendered first-boot script (common + recipe + extras) is
# already ~22 KB once Tailscale + the orb-capture web UI are
# included. Bump generously so we have room for follow-on
# features without re-tripping this validation.
MAX_DEFAULTS_LENGTH: "65536"
# Ceiling for a build request's rootfs_size_mb. ASU's default is 1024,
# below the 2048 MiB our SD/eMMC recipes ask for (recipes/README.md,
# `rootfs_size_mb`). Validation happens here in the server AND again in
# the worker's Settings, so both services carry the same value.
MAX_CUSTOM_ROOTFS_SIZE_MB: "4096"
# Loads branches.yaml into ASU at interpreter start; see
# asu-shim/sitecustomize.py for what it patches and why.
PYTHONPATH: /opt/asu-shim
volumes:
- ${PUBLIC_PATH}/store:${PUBLIC_PATH}/store:ro
- ${PUBLIC_PATH}/logs:${PUBLIC_PATH}/logs:ro
- ./branches.yaml:/app/branches.yaml:ro
- ./asu-shim:/opt/asu-shim:ro
ports:
# Host-side port only; the container always listens on 8000, which is
# what selector/nginx.conf.template proxies to internally.
- "127.0.0.1:${ASU_PORT:-8000}:8000"
depends_on:
- redis
asu-worker:
image: docker.io/openwrt/asu@sha256:1359bbc4fd3e244c0c5e6f1a5f8b16fb18ca355a2b4017b09ca8467afc05e2a1
restart: unless-stopped
command: uv run rqworker --logging_level INFO
env_file: .env
environment:
REDIS_URL: redis://redis:6379/0
MAX_DEFAULTS_LENGTH: "65536"
MAX_CUSTOM_ROOTFS_SIZE_MB: "4096"
# Loads branches.yaml into ASU at interpreter start; see
# asu-shim/sitecustomize.py for what it patches and why.
PYTHONPATH: /opt/asu-shim
volumes:
- ${PUBLIC_PATH}:${PUBLIC_PATH}:rw
# Upstream ASU no longer reads CONTAINER_SOCKET_PATH; its worker probes
# only ./podman.sock and /var/podman.sock inside the container
# (asu/util.py _find_podman_socket). So the host socket has to land at
# exactly this destination or every build fails with
# "Unable to make connection to UDS '/var/podman.sock'".
- ${CONTAINER_SOCKET_PATH}:/var/podman.sock:rw
- ./branches.yaml:/app/branches.yaml:ro
- ./asu-shim:/opt/asu-shim:ro
# The Podman machine VM runs Fedora CoreOS with SELinux enforcing.
# Without this, the worker can't open the bind-mounted Podman socket
# even though Unix perms would allow it (EACCES on stat).
security_opt:
- label=disable
# Upstream ASU attaches every per-build container to a Podman network
# literally named "asu-build" (asu/build.py). Upstream's own compose marks
# it external and expects a manual `podman network create`; listing the
# worker on it here makes compose create it instead, so `up` stays the
# only step. `default` keeps the worker's route to redis.
networks:
- default
- asu-build
depends_on:
- redis
selector:
image: docker.io/nginx:alpine
restart: unless-stopped
volumes:
- ./firmware-selector/www:/usr/share/nginx/html:ro
# nginx config is a TEMPLATE rendered at container start by
# 10-resolver.sh below — it substitutes RESOLVER_PLACEHOLDER with
# the actual /etc/resolv.conf nameserver IP. Hardcoding fails
# whenever Podman gives the compose network a new gateway IP.
- ./selector/nginx.conf.template:/etc/nginx/sensorbox-template.conf:ro
- ./selector/resolver-entrypoint.sh:/docker-entrypoint.d/10-resolver.sh:ro
# Recipes mounted read-only; the entrypoint hook below copies them
# into a writable container-layer path and generates an index.json
# so the browser can enumerate devices without a directory listing.
- ./recipes:/orb-recipes-src:ro
- ./selector/generate-recipes-index.sh:/docker-entrypoint.d/40-generate-recipes-index.sh:ro
ports:
# Host-side port only; nginx inside the container always listens on 80.
# Defaults keep the stack working for an .env predating these vars.
- "127.0.0.1:${SELECTOR_PORT:-8080}:80"
depends_on:
- asu-server
volumes:
# Persistent cache for the OpenWrt buildroot source tree and build
# artifacts. Survives container recreation so incremental builds
# only recompile what changed. ~5 GB when populated.
openwrt-build-cache:
networks:
# Declared explicitly because asu-worker names its networks; a service that
# lists networks must list every one it joins, including the implicit one.
default: {}
# Build containers live here, isolated from redis and the selector. The
# name must be exactly asu-build because ASU asks for it by that string.
asu-build:
name: asu-build