-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDockerfile.node
More file actions
72 lines (69 loc) · 4.18 KB
/
Copy pathDockerfile.node
File metadata and controls
72 lines (69 loc) · 4.18 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
# A weed node with its local control UI: host/discover/download from a
# browser instead of memorizing weed.py's CLI flags (see web_ui.py's own
# docstring). This bundles node.py's real protocol logic plus the static
# web/ frontend — same code the CLI and shell.py call, no separate
# reimplementation.
#
# Separate from the repo's other Dockerfiles on purpose: Dockerfile is
# poc_network_challenge.py's holder/relay/verifier demo, and
# Dockerfile.discovery-relay / Dockerfile.tunnel-relay are the two dumb
# store-and-forward relays. This one is the actual node a person runs.
FROM python:3.13-slim
WORKDIR /app
# ffmpeg: only for /api/orbit-mux, the Orbit picture+audio as one live
# Matroska stream (stream copy, no transcoding) for Kodi and friends;
# everything else is stdlib. Drop this line and that one endpoint 503s.
RUN apt-get update && apt-get install -y --no-install-recommends ffmpeg && rm -rf /var/lib/apt/lists/*
# weed.py/shell.py/discovery_relay.py/lightning_settle.py/dht.py weren't
# here before -- the image only ever ran web_ui.py, so there was no way
# to get an interactive shell or bare CLI *inside this exact container*
# to compare against. That mattered for real: a "why does this fail in
# Docker but not bare CLI" question had no way to control for "same
# container, different code path" vs "different container entirely"
# without them. `docker compose -f docker-compose.node.yml exec node
# python3 weed.py` (bare `shell.py` has no __main__ block — it's only
# ever meant to be imported by weed.py, running it directly just exits)
# now gets an interactive shell in this exact container.
#
# pyproject.toml is here purely so node.weed_version() has something real
# to read (see its own docstring) -- this image never `pip install`s the
# package itself (just its runtime deps below), so importlib.metadata has
# no entry to find either.
COPY node.py web_ui.py poc_reputation.py weed.py shell.py discovery_relay.py lightning_settle.py dht.py pyproject.toml ./
COPY web/ ./web/
RUN pip install --no-cache-dir btcvm cryptography qrcode pillow kademlia
# The commit hash node.weed_banner() shows (see _git_commit_hash's own
# docstring for why that matters) has no way to compute itself inside the
# container -- no .git directory is ever copied in here, deliberately, so
# there's nothing for a live `git rev-parse` to find. docker-compose.node.yml
# passes the *host's* commit hash in as this build arg instead, computed
# once at image-build time from wherever `make node` actually runs, and
# baked in as an env var _git_commit_hash checks first.
ARG GIT_COMMIT=
ENV WEED_GIT_COMMIT=$GIT_COMMIT
# Identity key, reputation store, and library manifest are all read/written
# via os.path.expanduser('~/...') (see node.py's IDENTITY_PATH and
# web_ui.py's LIBRARY_PATH) -- pointing $HOME at the mounted volume means
# one `-v weed-node-data:/data` covers all three, so this container's
# identity (and everything vouching for it) survives a restart instead of
# generating a fresh throwaway pubkey every time. DOWNLOADS_DIR is
# script-relative instead (/app/downloads), so it gets its own symlink into
# the same volume.
ENV HOME=/data
RUN ln -s /data/downloads /app/downloads
VOLUME /data
# 127.0.0.1 is web_ui.py's own default bind (see its docstring: no auth
# built, so it refuses to face the network unless told to) -- --bind 0.0.0.0
# here is what makes that safe *inside* a container, since the container's
# network namespace is already the isolation boundary; nothing external
# reaches this port unless you publish it yourself.
EXPOSE 8080
# A named volume mounts *empty* at /data, which leaves /app/downloads (the
# symlink above) dangling until something creates its real target -- and
# web_ui.py's own os.makedirs(DOWNLOADS_DIR, exist_ok=True) can't recover
# from that itself (exist_ok's fallback check is os.path.isdir(), which is
# False for a broken symlink, so it raises FileExistsError anyway instead of
# treating it as already there). mkdir -p the real target before Python
# ever imports web_ui.py, once per container start, not once per image
# build, since the volume's contents don't exist until runtime.
ENTRYPOINT ["sh", "-c", "mkdir -p /data/downloads && exec python3 web_ui.py --bind 0.0.0.0 \"$@\"", "--"]