-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathContainerfile
More file actions
102 lines (84 loc) · 3.94 KB
/
Containerfile
File metadata and controls
102 lines (84 loc) · 3.94 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
# ==============================================================================
# 0. THE ASTRAL PLANE
# ==============================================================================
# We define an alias 'uv' for the image containing the uv binary.
# This allows us to "borrow" the tool later without downloading it into our layers.
FROM ghcr.io/astral-sh/uv:0.5.22 AS uv
# ==============================================================================
# STAGE I: BUILDER
# ==============================================================================
FROM python:3.13-slim-bookworm AS builder
# Configure uv for container usage:
# - LINK_MODE=copy: Essential for cache mounts (hardlinks fail across filesystems).
# - COMPILE_BYTECODE: Compiles .pyc files for faster startup.
# - PYTHON_DOWNLOADS=0: Use the system python, don't download a managed one.
ENV UV_LINK_MODE=copy \
UV_COMPILE_BYTECODE=1 \
UV_PYTHON_DOWNLOADS=0 \
UV_NO_DEV=1
WORKDIR /app
# --- 1. Install Dependencies (Cached Layer) ---
# We mount the 'uv' binary and cache directories to install libs without copying source files yet.
# This layer is reused unless uv.lock or pyproject.toml changes.
RUN --mount=from=uv,source=/uv,target=/bin/uv \
--mount=type=cache,target=/root/.cache/uv \
--mount=type=bind,source=uv.lock,target=uv.lock \
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
/bin/uv sync --frozen --no-install-project --extra server
# --- 2. Install Project (Frequent Change Layer) ---
# Copy the actual source code. This breaks cache whenever you change code.
COPY . .
# Install the project package itself into the environment with server dependencies.
RUN --mount=from=uv,source=/uv,target=/bin/uv \
--mount=type=cache,target=/root/.cache/uv \
/bin/uv sync --frozen --extra server
# ==============================================================================
# STAGE II: RUNNER (The Production Artifact)
# ==============================================================================
FROM python:3.13-slim-bookworm
# --- Security & Identity Setup ---
RUN groupadd --system --gid 1001 lich && \
useradd --system --uid 1001 --gid 1001 --create-home --home-dir /home/lich lich
# --- Geography (XDG Standards) ---
ENV HOME=/home/lich \
XDG_CONFIG_HOME=/home/lich/.config \
XDG_DATA_HOME=/home/lich/.local/share
WORKDIR /app
# --- The Transplant ---
COPY --from=builder --chown=lich:lich /app/.venv /app/.venv
COPY --from=builder --chown=lich:lich /app/src /app/src
# --- THE GREAT SEAL (Immutability) ---
# We strip write access (-w) from the entire /app directory (Source + Libraries).
#
# Why is this safe?
# Because we set UV_COMPILE_BYTECODE=1 in the Builder Stage.
# All .pyc files are already pre-compiled. The runtime has no need to write here.
#
# Why do this?
# 1. Security: The Agent cannot 'pip install' malicious packages or modify libs at runtime.
# 2. Integrity: The Body is immutable. Evolution/Autopoiesis must happen in the Lab.
RUN chmod -R a-w /app
# --- Environment Activation ---
ENV PATH="/app/.venv/bin:$PATH" \
LITESTAR_APP="lychd.app:create_app" \
PYTHONPATH="/app/src:$PYTHONPATH"
# --- Domain and Sphere Preparation ---
# We create the skeletal structure of the Crypt and Codex.
# These specific paths match the symmetric layout defined in the Laws of the Great Work.
#
# /home/lich/.config/lychd -> The Law (Codex)
# /home/lich/.local/share/lychd -> The Body (Crypt)
#
# Note: We do NOT create 'core' or 'postgres' here because those are
# usually sub-ritual mount points managed by the Binding.
RUN mkdir -p /home/lich/.config/lychd \
/home/lich/.local/share/lychd/lab \
/home/lich/.local/share/lychd/extensions \
/home/lich/library \
/home/lich/work && \
chown -R lich:lich /home/lich
USER lich
# The threshold of the Sepulcher.
EXPOSE 8000
# The Final Awakening.
CMD ["granian", "--interface", "asgi", "--host", "0.0.0.0", "--port", "8000", "lychd.app:create_app"]