Add headless Angor services and shared-index install guard
Demo images / Build & push demo images (push) Failing after 43s
Demo images / Build & push demo images (push) Failing after 43s
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
# Angor Indexer
|
||||
|
||||
Headless mainnet API endpoint for Angor. The service reuses this node's Mempool
|
||||
backend and Electrum index instead of creating a second blockchain database.
|
||||
An unpruned, fully synced Bitcoin node is required. Installing against a pruned
|
||||
node must show the existing archival-node requirement; it must never silently
|
||||
unprune or replace its Bitcoin data.
|
||||
|
||||
## Connect Angor
|
||||
|
||||
Install **Angor Indexer** in the store. Its API appears under **Services**.
|
||||
In Angor settings, use `http://<node-address>:8998/` as the custom indexer origin.
|
||||
The `/health` endpoint reports readiness against Mempool's indexed block height;
|
||||
it returns 503 while that backend is unavailable. Index building may take time.
|
||||
|
||||
Browser clients require a reachable HTTPS origin with a trusted certificate.
|
||||
Configure your HTTPS reverse proxy to forward to port 8998, then use that HTTPS
|
||||
origin in Angor. Do not disable browser TLS checks. The API supports both
|
||||
`/api/v1/` and `/api/` paths, transaction broadcast, and CORS without cookies.
|
||||
|
||||
This endpoint intentionally exposes public blockchain queries and transaction
|
||||
broadcast through the app gate without dashboard-cookie login. It has no Bitcoin
|
||||
RPC password, wallet keys, or persistent wallet data. The backend stays on the
|
||||
managed container network; its private port does not become publicly exposed.
|
||||
You can change network access using the node's normal access controls.
|
||||
|
||||
## Relay
|
||||
|
||||
A relay is optional. Angor can continue using its configured external relays.
|
||||
Install **Angor Relay** separately to host project metadata locally, then add
|
||||
`ws://<node-address>:8091/` in Angor, or a trusted `wss://` proxy origin for browser
|
||||
clients. Its storage and configuration are separate from the node's internal
|
||||
relay; installing or uninstalling it does not change the internal relay.
|
||||
|
||||
## Packaging
|
||||
|
||||
Build the pinned image with:
|
||||
|
||||
```
|
||||
podman build -t source.archipelago-foundation.org/chaum/angor-indexer:1.0.1 apps/angor-indexer/container
|
||||
```
|
||||
|
||||
The image runs as UID 101 with a read-only root filesystem and no capabilities.
|
||||
Only temporary nginx state is writable. Runtime DNS is read from resolv.conf so
|
||||
Mempool recreation does not require editing IP addresses or restarting this app.
|
||||
No app-specific Rust installer is required.
|
||||
|
||||
Source documentation: [Angor's official deployment guide](https://github.com/block-core/angor/blob/869dd43cf38332dd7128a284a6bf4c1cac44c1a7/docker/DEPLOY-INDEXER-AND-RELAY.md).
|
||||
The unmodified icon comes from [angor.io/images/logo-text.svg](https://angor.io/images/logo-text.svg), retrieved 2026-09-30.
|
||||
|
||||
Tests and release acceptance are recorded in the next-release checklist. The
|
||||
health probe establishes backend availability, not a guarantee that every
|
||||
address query is indexed at the latest Bitcoin tip.
|
||||
|
||||
Install Mempool Explorer first. The declarative `install_prerequisites` check
|
||||
refuses a new adapter installation if its Mempool API component is absent, before
|
||||
creating an installed-app record. It does not install or resync Bitcoin for you.
|
||||
@@ -0,0 +1,6 @@
|
||||
FROM docker.io/library/nginx:1.31.3-alpine@sha256:1d40e3eb3bf4f138de1d67193f2aa5309fcaf343eb5ffadbf5e9439de1eb1ebb
|
||||
COPY nginx.conf /etc/angor-nginx.conf.template
|
||||
COPY entrypoint.sh /usr/local/bin/angor-indexer
|
||||
USER 101:101
|
||||
EXPOSE 8080
|
||||
ENTRYPOINT ["/usr/local/bin/angor-indexer"]
|
||||
Executable
+12
@@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
# Resolve through the container runtime's DNS, including after dependency
|
||||
# recreation. Never bake a container IP into the indexer endpoint.
|
||||
DNS_RESOLVER=$(awk '/^nameserver[[:space:]]/ {print $2; exit}' /etc/resolv.conf)
|
||||
case "$DNS_RESOLVER" in
|
||||
''|*[!0-9a-fA-F.:]*) echo 'Container DNS resolver is unavailable' >&2; exit 1 ;;
|
||||
esac
|
||||
case "$DNS_RESOLVER" in *:*) DNS_RESOLVER="[$DNS_RESOLVER]" ;; esac
|
||||
export DNS_RESOLVER
|
||||
envsubst '${DNS_RESOLVER}' < /etc/angor-nginx.conf.template > /tmp/nginx.conf
|
||||
exec nginx -c /tmp/nginx.conf -g 'daemon off;'
|
||||
@@ -0,0 +1,63 @@
|
||||
worker_processes 1;
|
||||
pid /tmp/nginx.pid;
|
||||
error_log /dev/stderr warn;
|
||||
events { worker_connections 512; }
|
||||
http {
|
||||
access_log off;
|
||||
server_tokens off;
|
||||
client_body_temp_path /tmp/client_temp;
|
||||
proxy_temp_path /tmp/proxy_temp;
|
||||
fastcgi_temp_path /tmp/fastcgi_temp;
|
||||
uwsgi_temp_path /tmp/uwsgi_temp;
|
||||
scgi_temp_path /tmp/scgi_temp;
|
||||
resolver ${DNS_RESOLVER} valid=10s ipv6=off;
|
||||
upstream mempool_backend {
|
||||
zone mempool_backend 64k;
|
||||
server mempool-api:8999 resolve;
|
||||
}
|
||||
server {
|
||||
listen 8080;
|
||||
client_max_body_size 4m;
|
||||
proxy_connect_timeout 5s;
|
||||
proxy_read_timeout 60s;
|
||||
proxy_send_timeout 30s;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header Connection "";
|
||||
proxy_set_header Authorization "";
|
||||
proxy_set_header Cookie "";
|
||||
proxy_hide_header Access-Control-Allow-Origin;
|
||||
add_header Access-Control-Allow-Origin '*' always;
|
||||
add_header Access-Control-Allow-Methods 'GET, HEAD, POST, OPTIONS' always;
|
||||
add_header Access-Control-Allow-Headers 'Content-Type' always;
|
||||
add_header Cache-Control 'no-store' always;
|
||||
if ($request_method = OPTIONS) { return 204; }
|
||||
# Mempool's backend uses /api/v1. Match its frontend's shorter /api
|
||||
# surface too, without doubling already-versioned Angor URLs.
|
||||
rewrite ^/api/(?!v1/)(.*)$ /api/v1/$1 last;
|
||||
location = / {
|
||||
default_type application/json;
|
||||
return 200 '{"service":"Angor Indexer","network":"mainnet","api":"/api/v1","health":"/health"}\n';
|
||||
}
|
||||
# Readiness checks the indexing backend, not this gateway's process.
|
||||
location = /health {
|
||||
limit_except GET { deny all; }
|
||||
proxy_pass http://mempool_backend/api/v1/blocks/tip/height;
|
||||
proxy_intercept_errors on;
|
||||
error_page 500 502 503 504 =503 @waiting;
|
||||
}
|
||||
location @waiting {
|
||||
default_type application/json;
|
||||
return 503 '{"status":"waiting","message":"Waiting for Bitcoin and Mempool indexing"}\n';
|
||||
}
|
||||
location ~ ^/api/(v1/)?tx$ {
|
||||
limit_except GET POST { deny all; }
|
||||
proxy_pass http://mempool_backend;
|
||||
}
|
||||
location /api/ {
|
||||
limit_except GET { deny all; }
|
||||
proxy_pass http://mempool_backend;
|
||||
}
|
||||
location / { return 404; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
app:
|
||||
id: angor-indexer
|
||||
name: Angor Indexer
|
||||
version: 1.0.1
|
||||
description: Headless Bitcoin indexer endpoint for Angor. Reuses this node’s Mempool
|
||||
and Electrum index; requires a synced, unpruned Bitcoin node. Add this service’s
|
||||
address as the custom indexer in Angor settings. A relay is optional and installed
|
||||
separately.
|
||||
category: money
|
||||
install_prerequisites:
|
||||
- mempool-api
|
||||
upstream:
|
||||
kind: github
|
||||
repo: block-core/angor
|
||||
container:
|
||||
image: source.archipelago-foundation.org/chaum/angor-indexer:1.0.1
|
||||
pull_policy: if-not-present
|
||||
network: archy-net
|
||||
dependencies:
|
||||
- app_id: mempool-api
|
||||
version: '>=3.0.0'
|
||||
- bitcoin:archival
|
||||
resources:
|
||||
cpu_limit: 1
|
||||
memory_limit: 128Mi
|
||||
disk_limit: 128Mi
|
||||
security:
|
||||
capabilities: []
|
||||
readonly_root: true
|
||||
no_new_privileges: true
|
||||
user: 101
|
||||
network_policy: isolated
|
||||
ports:
|
||||
- host: 8998
|
||||
container: 8080
|
||||
protocol: tcp
|
||||
bind: 127.0.0.1
|
||||
auth: open
|
||||
auth_rationale: Public Bitcoin chain-data API and validated transaction broadcast for Angor clients; no wallet keys or node RPC credentials are exposed. Browser cookie login would break machine clients.
|
||||
interfaces:
|
||||
main:
|
||||
name: Angor Indexer API
|
||||
description: Use this origin as Angor’s custom mainnet indexer URL. HTTPS is
|
||||
required for browser clients.
|
||||
type: api
|
||||
port: 8998
|
||||
protocol: http
|
||||
path: /
|
||||
health_check:
|
||||
type: http
|
||||
endpoint: http://localhost:8080
|
||||
path: /health
|
||||
interval: 30s
|
||||
timeout: 8s
|
||||
retries: 3
|
||||
bitcoin_integration:
|
||||
rpc_access: none
|
||||
sync_required: true
|
||||
pruning_support: false
|
||||
metadata:
|
||||
icon: /assets/img/app-icons/angor.svg
|
||||
tier: optional
|
||||
repo: https://github.com/block-core/angor
|
||||
features:
|
||||
- Angor mainnet API
|
||||
- Reuses existing Mempool indexing
|
||||
- No separate blockchain database
|
||||
- Optional independent relay
|
||||
Reference in New Issue
Block a user