-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathContainerfile
More file actions
291 lines (276 loc) · 13.3 KB
/
Copy pathContainerfile
File metadata and controls
291 lines (276 loc) · 13.3 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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
# generated — edit Containerfile.d/*.containerfile instead
ARG BASE_IMAGE="ghcr.io/ublue-os/bluefin-dx"
ARG TAG="stable"
FROM ${BASE_IMAGE}:${TAG}
# ── Framework laptop & Intel-specific ────────────────────────────────────────
RUN rpm-ostree install \
thermald \
fprintd \
fprintd-pam \
powertop \
&& ostree container commit
# ── Developer tooling ────────────────────────────────────────────────────────
# rpm-ostree doesn't support @group syntax in container builds; use dnf5
RUN dnf5 group install -y development-tools && dnf5 clean all && \
ostree container commit
RUN rpm-ostree install \
emacs \
python3 \
neovim \
tmux \
pandoc \
plantuml \
aspell \
aspell-en \
texlive-latex \
texlive-latex-bin \
texlive-collection-latexrecommended \
fish \
alacritty \
firefox \
sqlite-devel \
stow \
the_silver_searcher \
rlwrap \
xclip \
fd-find \
bat \
eza \
zoxide \
fzf \
jq \
yq \
httpie \
ripgrep \
btop \
tldr \
fossil \
&& ostree container commit
# GitHub CLI — official RPM repo; not in Fedora repos
RUN curl -fsSL https://cli.github.com/packages/rpm/gh-cli.repo \
-o /etc/yum.repos.d/gh-cli.repo && \
dnf5 install -y gh && \
dnf5 clean all && \
ostree container commit
# Set fish as the default shell for new users (read by Anaconda at install time)
RUN sed -i 's|^SHELL=.*|SHELL=/usr/bin/fish|' /etc/default/useradd && \
ostree container commit
# zellij: not in Fedora 44 repos, install musl binary from GitHub releases
RUN curl -fsSL \
"https://github.com/zellij-org/zellij/releases/latest/download/zellij-x86_64-unknown-linux-musl.tar.gz" \
| tar -xz -C /usr/bin zellij && \
ostree container commit
# lazygit: git TUI, not in Fedora repos
RUN LAZYGIT_VERSION=$(curl -sL "https://api.github.com/repos/jesseduffield/lazygit/releases/latest" | \
jq -r '.tag_name') && \
curl -fsSL "https://github.com/jesseduffield/lazygit/releases/download/${LAZYGIT_VERSION}/lazygit_${LAZYGIT_VERSION#v}_Linux_x86_64.tar.gz" \
| tar -xz -C /usr/bin lazygit && \
ostree container commit
# fastfetch: tarball is fastfetch-linux-amd64/{usr/bin,usr/share,...}; strip the top dir
RUN curl -fsSL \
"https://github.com/fastfetch-cli/fastfetch/releases/latest/download/fastfetch-linux-amd64.tar.gz" \
| tar -xz --strip-components=1 -C / && \
ostree container commit
# starship: not in Fedora repos; /usr/local/bin doesn't exist in ostree images
RUN curl -fsSL \
"https://github.com/starship/starship/releases/latest/download/starship-x86_64-unknown-linux-musl.tar.gz" \
| tar -xz -C /usr/bin starship && \
ostree container commit
# Nyxt browser — not in Fedora repos; ships as an AppImage inside a tarball
# /opt is a symlink in ostree images; use /usr/lib instead
RUN curl -fsSL \
"https://github.com/atlas-engineer/nyxt/releases/latest/download/Linux-Nyxt-x86_64.tar.gz" \
-o /tmp/nyxt.tar.gz && \
mkdir -p /usr/lib/nyxt && \
tar -xzf /tmp/nyxt.tar.gz -C /usr/lib/nyxt && \
chmod +x /usr/lib/nyxt/*.AppImage && \
ln -sf /usr/lib/nyxt/Nyxt-x86_64.AppImage /usr/bin/nyxt && \
rm /tmp/nyxt.tar.gz && \
ostree container commit
# Homebrew — cloned to /home/linuxbrew/.linuxbrew (/home → /var/home in ostree)
# The image's /var is used to initialize a fresh install, so brew is available on first boot.
# wheel group owns the prefix so the default admin user can run brew install without sudo.
RUN mkdir -p /var/home/linuxbrew && \
git clone --depth=1 https://github.com/Homebrew/brew /var/home/linuxbrew/.linuxbrew && \
chown -R root:wheel /var/home/linuxbrew/.linuxbrew && \
chmod -R g+rwX /var/home/linuxbrew/.linuxbrew && \
ostree container commit
# SDKMAN! — installed to /var/sdkman (mutable, persists across bootc updates)
# wheel group owns the prefix so the default admin user can run sdk install without sudo.
# /root -> /var/roothome (symlink); pre-create .bashrc so the installer script can finish
# (it appends to .bashrc at the end — harmless, but errors if the file doesn't exist).
# sdkman-for-fish provides a native fish sdk function in /etc/fish/functions/sdk.fish.
RUN mkdir -p /var/roothome && \
touch /var/roothome/.bashrc /var/roothome/.bash_profile /var/roothome/.profile && \
curl -fsSL "https://get.sdkman.io" | SDKMAN_DIR=/var/sdkman SDKMAN_NONINTERACTIVE=true bash && \
chown -R root:wheel /var/sdkman && \
chmod -R g+rwX /var/sdkman && \
mkdir -p /etc/fish/functions /etc/fish/completions && \
curl -fsSL "https://raw.githubusercontent.com/reitzig/sdkman-for-fish/main/functions/sdk.fish" \
-o /etc/fish/functions/sdk.fish && \
curl -fsSL "https://raw.githubusercontent.com/reitzig/sdkman-for-fish/main/completions/sdk.fish" \
-o /etc/fish/completions/sdk.fish && \
ostree container commit
# Pi coding agent — use dnf5 (not rpm-ostree) so nodejs is immediately available
# for the subsequent npm call within the same RUN step
RUN dnf5 install -y nodejs pnpm && \
dnf5 clean all && \
npm install -g --prefix /usr --ignore-scripts @earendil-works/pi-coding-agent && \
ostree container commit
# TypeScript toolchain — compiler + LSP server for Emacs/Neovim editor integration
RUN npm install -g --prefix /usr --ignore-scripts \
typescript \
typescript-language-server && \
ostree container commit
# Claude Code CLI
RUN npm install -g --prefix /usr @anthropic-ai/claude-code && \
ostree container commit
# Clojure — use dnf5 so java is immediately available when the installer runs;
# use --prefix /usr (ostree has no /usr/local/bin)
RUN dnf5 install -y java-25-openjdk && \
dnf5 clean all && \
curl -fsSL "https://github.com/clojure/brew-install/releases/latest/download/linux-install.sh" \
-o /tmp/clojure-install.sh && \
chmod +x /tmp/clojure-install.sh && \
/tmp/clojure-install.sh --prefix /usr && \
rm /tmp/clojure-install.sh && \
ostree container commit
# Handy — open-source push-to-talk speech-to-text; not in Fedora repos
# gtk-layer-shell is a runtime dependency missing from the handy RPM metadata
RUN dnf5 install -y gtk-layer-shell && \
HANDY_RPM_URL=$(curl -sL "https://api.github.com/repos/cjpais/Handy/releases/latest" | \
jq -r '.assets[] | select(.name | test("x86_64\\.rpm$")) | .browser_download_url') && \
curl -fsSL "$HANDY_RPM_URL" -o /tmp/handy.rpm && \
dnf5 install -y /tmp/handy.rpm && \
dnf5 clean all && \
rm /tmp/handy.rpm && \
ostree container commit
# ── Spatial / GIS tooling ─────────────────────────────────────────────────────
RUN rpm-ostree install \
gdal \
gdal-devel \
gdal-libs \
python3-gdal \
mapnik \
mapnik-devel \
python3-mapnik \
qgis \
grass \
grass-devel \
proj \
proj-devel \
geos \
geos-devel \
libspatialite \
libspatialite-devel \
spatialite-tools \
&& ostree container commit
# ── Wine ──────────────────────────────────────────────────────────────────────
RUN rpm-ostree install \
wine \
winetricks \
&& ostree container commit
# ── Fonts ─────────────────────────────────────────────────────────────────────
RUN rpm-ostree install \
jetbrains-mono-fonts \
cascadia-code-fonts \
google-noto-emoji-fonts \
&& ostree container commit
RUN mkdir -p /usr/share/fonts/inter && \
INTER_URL=$(curl -sL "https://api.github.com/repos/rsms/inter/releases/latest" | \
jq -r '.assets[] | select(.name | endswith(".zip")) | .browser_download_url') && \
curl -fsSL "$INTER_URL" -o /tmp/inter.zip && \
unzip -q /tmp/inter.zip -d /tmp/inter-extracted && \
find /tmp/inter-extracted -name "*.otf" -exec cp {} /usr/share/fonts/inter/ \; && \
rm -rf /tmp/inter.zip /tmp/inter-extracted && \
fc-cache -f && \
ostree container commit
# Download JetBrains Mono Nerd Font (patched version, not in Fedora repos)
RUN NERD_FONT_VERSION="v3.2.1" && \
mkdir -p /usr/share/fonts/nerd-fonts/JetBrainsMono && \
curl -fsSL "https://github.com/ryanoasis/nerd-fonts/releases/download/${NERD_FONT_VERSION}/JetBrainsMono.tar.xz" \
| tar -xJ -C /usr/share/fonts/nerd-fonts/JetBrainsMono && \
fc-cache -f && \
ostree container commit
# ── Better font rendering ─────────────────────────────────────────────────────
COPY config/files/ /
# Enable first-boot services
RUN systemctl enable install-1password.service && \
ostree container commit
# ── Sway — minimal Wayland tiling WM alongside GNOME ─────────────────────────
# All packages are in standard Fedora repos — no COPR needed.
# GDM auto-detects /usr/share/wayland-sessions/sway.desktop (installed by the
# sway package) and offers it as a login session choice — no display manager
# changes needed. All tools are session-scoped and do not conflict with GNOME.
#
# NOTE: Hyprland was evaluated but its solopasha COPR packages currently fail
# on bluefin-dx because they require libdisplay-info.so.2 while the base image
# ships libdisplay-info-0.3.0 (.so.3), which mutter also depends on. Revisit
# once the COPR rebuilds against .so.3.
#
# sway-config-fedora must be requested explicitly — plain `dnf install sway`
# defaults to sway-config-upstream, whose vanilla config wires up foot/wmenu
# and a built-in bar instead of the waybar/wofi/mako below.
# kanshi auto-switches output profiles on hotplug (e.g. disabling eDP-1 when the
# ViewSonic XG3220 external monitor is connected) — see /etc/kanshi/config.
# gnome-monitor-config is the equivalent manual CLI for the GNOME/mutter
# session, where kanshi's wlr-output-management protocol isn't available.
# blueman and network-manager-applet ship XDG autostart entries and launch
# automatically via sway-xdg-autostart.target (no exec needed in sway config).
# gammastep (GNOME Night Light equivalent) ships a systemd user service and is
# enabled globally here so it starts with the sway session.
RUN dnf5 install -y \
sway \
sway-config-fedora \
swaylock \
swaybg \
swayidle \
xdg-desktop-portal-wlr \
waybar \
wofi \
mako \
kanshi \
gnome-monitor-config \
blueman \
network-manager-applet \
gammastep \
&& dnf5 clean all \
&& systemctl --global enable kanshi.service \
&& systemctl --global enable gammastep.service \
&& ostree container commit
# ── elementary GTK theme ──────────────────────────────────────────────────────
# elementary-icon-theme is packaged natively in Fedora, but the GTK stylesheet
# itself isn't (only Arch/Ubuntu package it) — built from source per upstream's
# own instructions (meson + sassc). Upstream (8.2.2+) only ships accent-color
# variants now, no plain "io.elementary.stylesheet" theme; slate is the
# neutral/gray variant, closest to the classic elementary look.
RUN dnf5 install -y elementary-icon-theme meson ninja-build sassc \
&& dnf5 clean all \
&& ostree container commit
RUN STYLESHEET_VERSION="8.2.2" && \
curl -fsSL "https://github.com/elementary/stylesheet/archive/refs/tags/${STYLESHEET_VERSION}.tar.gz" \
| tar -xz && \
cd "stylesheet-${STYLESHEET_VERSION}" && \
meson setup build --prefix=/usr && \
ninja -C build install && \
cd .. && rm -rf "stylesheet-${STYLESHEET_VERSION}" && \
dnf5 remove -y meson ninja-build sassc \
&& dnf5 clean all \
&& ostree container commit
# ── llama.cpp — local LLM inference ──────────────────────────────────────────
# Uses official pre-built Linux x86_64 binaries (CPU backend).
# The tarball ships its own libggml*/libllama* .so files with RUNPATH=$ORIGIN,
# so binaries find their libs via /usr/lib/llama.cpp/ without needing ldconfig.
# Symlinks expose llama-cli, llama-server, and llama-bench on PATH.
#
# To switch to GPU acceleration, replace the asset selector with:
# ubuntu-vulkan-x64.tar.gz (Vulkan — Intel Iris Xe / Arc supported)
# ubuntu-sycl-fp16-x64 (SYCL — Intel GPU, requires oneAPI runtime)
RUN LLAMA_URL=$(curl -sL "https://api.github.com/repos/ggml-org/llama.cpp/releases/latest" | \
jq -r '.assets[] | select(.name | test("bin-ubuntu-x64\\.tar\\.gz$")) | .browser_download_url') && \
mkdir -p /usr/lib/llama.cpp && \
curl -fsSL "$LLAMA_URL" | tar -xz --strip-components=1 -C /usr/lib/llama.cpp && \
ln -sf /usr/lib/llama.cpp/llama-cli /usr/bin/llama-cli && \
ln -sf /usr/lib/llama.cpp/llama-server /usr/bin/llama-server && \
ln -sf /usr/lib/llama.cpp/llama-bench /usr/bin/llama-bench && \
ostree container commit