Fossil SCM

Commit [cda5d6a7] invalidated the BusyBox steps in the Tcl and Python examples in §3.2 of the containers doc.

wyoung 2023-03-30 14:51 trunk
Commit ddcdc6f30bbc1e84c05b5e0e2f48e6363774b20fd9d5b8faa3009c15483fa7ef
1 file changed +15 -18
+15 -18
--- www/containers.md
+++ www/containers.md
@@ -231,11 +231,11 @@
231231
for the sake of discussion, we’ll say you’ve chosen [Method
232232
2](./alerts.md#db), which requires a Tcl interpreter and its SQLite
233233
extension to push messages into the outbound email queue DB, presumably
234234
bind-mounted into the container.
235235
236
-One way to do that is to replace STAGE 2 and 3 in the stock `Dockerfile`
236
+You can do that by replacing STAGEs 2 and 3 in the stock `Dockerfile`
237237
with this:
238238
239239
```
240240
## ---------------------------------------------------------------------
241241
## STAGE 2: Pare that back to the bare essentials, plus Tcl.
@@ -242,10 +242,11 @@
242242
## ---------------------------------------------------------------------
243243
FROM alpine AS run
244244
ARG UID=499
245245
ENV PATH "/sbin:/usr/sbin:/bin:/usr/bin"
246246
COPY --from=builder /tmp/fossil /bin/
247
+ COPY tools/email-sender.tcl /bin/
247248
RUN set -x \
248249
&& echo "fossil:x:${UID}:${UID}:User:/museum:/false" >> /etc/passwd \
249250
&& echo "fossil:x:${UID}:fossil" >> /etc/group \
250251
&& install -d -m 700 -o fossil -g fossil log museum \
251252
&& apk add --no-cache tcl sqlite-tcl
@@ -258,29 +259,26 @@
258259
echo 'puts [info patchlevel]' |
259260
docker exec -i $(make container-version) tclsh
260261
8.6.12
261262
```
262263
263
-You can remove the installation of `busybox-static` in STAGE 1 since
264
-Alpine is already based on BusyBox.(^We can’t do “`FROM busybox`” since
265
-we need `apk` in this new second stage. Although this means we end up
266
-with back-to-back Alpine stages, it isn’t redundant; the second one
267
-starts fresh, allowing us to copy in only what we absolutely need from
268
-the first.) You should also remove the `PATH` override in the “RUN”
264
+You should remove the `PATH` override in the “RUN”
269265
stage, since it’s written for the case where everything is in `/bin`.
266
+With these additions, we need the longer `PATH` shown above to have
267
+ready access to them all.
270268
271269
Another useful case to consider is that you’ve installed a [server
272270
extension](./serverext.wiki) and you need an interpreter for that
273271
script. The first option above won’t work except in the unlikely case that
274272
it’s written for one of the bare-bones script interpreters that BusyBox
275273
ships.(^BusyBox’s `/bin/sh` is based on the old 4.4BSD Lite Almquist
276274
shell, implementing little more than what POSIX specified in 1989, plus
277
-equally stripped-down versions of AWK and `sed`.)
275
+equally stripped-down versions of `awk` and `sed`.)
278276
279277
Let’s say the extension is written in Python. While you could handle it
280
-the same way we do with the Tcl example above, because Python is more
281
-popular, we have more options. Let’s inject a Python environment into
278
+the same way we do with the Tcl example above, Python is more
279
+popular, giving us more options. Let’s inject a Python environment into
282280
the stock Fossil container via a suitable “[distroless]” image instead:
283281
284282
```
285283
## ---------------------------------------------------------------------
286284
## STAGE 2: Pare that back to the bare essentials, plus Python.
@@ -296,26 +294,25 @@
296294
&& echo "fossil:x:${UID}:${UID}:User:/museum:/false" >> /etc/passwd \
297295
&& echo "fossil:x:${UID}:fossil" >> /etc/group \
298296
&& install -d -m 700 -o fossil -g fossil log museum
299297
```
300298
299
+You will also have to add `busybox-static` to the APK package list in
300
+STAGE 1 for the `RUN` script at the end of that stage to work, since the
301
+[Chainguard Python image][cgimgs] lacks a shell, on purpose. The need to
302
+install root-level binaries is why we change `USER` temporarily here.
303
+
301304
Build it and test that it works like so:
302305
303306
```
304307
$ make container-run &&
305308
docker exec -i $(make container-version) python --version
306309
3.11.2
307310
```
308311
309
-Relative to the Tcl example, the change from “`alpine`” to [Chainguard’s
310
-Python image][cgimgs] means we have no BusyBox environment to execute
311
-the `RUN` command with, so we have to copy the `busybox.static` binary
312
-in from STAGE 1 and install it in this new STAGE 2 for the same reason
313
-the stock container does.(^This is the main reason we change `USER`
314
-temporarily to `root` here.) There are a few other steps required to
315
-avoid causing a conflict between our previously bare-bones “OS” layer
316
-and what the Chainguard image provides. The compensation for this hassle
312
+The compensation for the hassle of using Chainguard over something more
313
+general purpose like Alpine + “`apk add python`”
317314
is huge: we no longer leave a package manager sitting around inside the
318315
container, waiting for some malefactor to figure out how to abuse it.
319316
320317
Beware that there’s a limit to this über-jail’s ability to save you when
321318
you go and provide a more capable OS layer like this. The container
322319
--- www/containers.md
+++ www/containers.md
@@ -231,11 +231,11 @@
231 for the sake of discussion, we’ll say you’ve chosen [Method
232 2](./alerts.md#db), which requires a Tcl interpreter and its SQLite
233 extension to push messages into the outbound email queue DB, presumably
234 bind-mounted into the container.
235
236 One way to do that is to replace STAGE 2 and 3 in the stock `Dockerfile`
237 with this:
238
239 ```
240 ## ---------------------------------------------------------------------
241 ## STAGE 2: Pare that back to the bare essentials, plus Tcl.
@@ -242,10 +242,11 @@
242 ## ---------------------------------------------------------------------
243 FROM alpine AS run
244 ARG UID=499
245 ENV PATH "/sbin:/usr/sbin:/bin:/usr/bin"
246 COPY --from=builder /tmp/fossil /bin/
 
247 RUN set -x \
248 && echo "fossil:x:${UID}:${UID}:User:/museum:/false" >> /etc/passwd \
249 && echo "fossil:x:${UID}:fossil" >> /etc/group \
250 && install -d -m 700 -o fossil -g fossil log museum \
251 && apk add --no-cache tcl sqlite-tcl
@@ -258,29 +259,26 @@
258 echo 'puts [info patchlevel]' |
259 docker exec -i $(make container-version) tclsh
260 8.6.12
261 ```
262
263 You can remove the installation of `busybox-static` in STAGE 1 since
264 Alpine is already based on BusyBox.(^We can’t do “`FROM busybox`” since
265 we need `apk` in this new second stage. Although this means we end up
266 with back-to-back Alpine stages, it isn’t redundant; the second one
267 starts fresh, allowing us to copy in only what we absolutely need from
268 the first.) You should also remove the `PATH` override in the “RUN”
269 stage, since it’s written for the case where everything is in `/bin`.
 
 
270
271 Another useful case to consider is that you’ve installed a [server
272 extension](./serverext.wiki) and you need an interpreter for that
273 script. The first option above won’t work except in the unlikely case that
274 it’s written for one of the bare-bones script interpreters that BusyBox
275 ships.(^BusyBox’s `/bin/sh` is based on the old 4.4BSD Lite Almquist
276 shell, implementing little more than what POSIX specified in 1989, plus
277 equally stripped-down versions of AWK and `sed`.)
278
279 Let’s say the extension is written in Python. While you could handle it
280 the same way we do with the Tcl example above, because Python is more
281 popular, we have more options. Let’s inject a Python environment into
282 the stock Fossil container via a suitable “[distroless]” image instead:
283
284 ```
285 ## ---------------------------------------------------------------------
286 ## STAGE 2: Pare that back to the bare essentials, plus Python.
@@ -296,26 +294,25 @@
296 && echo "fossil:x:${UID}:${UID}:User:/museum:/false" >> /etc/passwd \
297 && echo "fossil:x:${UID}:fossil" >> /etc/group \
298 && install -d -m 700 -o fossil -g fossil log museum
299 ```
300
 
 
 
 
 
301 Build it and test that it works like so:
302
303 ```
304 $ make container-run &&
305 docker exec -i $(make container-version) python --version
306 3.11.2
307 ```
308
309 Relative to the Tcl example, the change from “`alpine`” to [Chainguard’s
310 Python image][cgimgs] means we have no BusyBox environment to execute
311 the `RUN` command with, so we have to copy the `busybox.static` binary
312 in from STAGE 1 and install it in this new STAGE 2 for the same reason
313 the stock container does.(^This is the main reason we change `USER`
314 temporarily to `root` here.) There are a few other steps required to
315 avoid causing a conflict between our previously bare-bones “OS” layer
316 and what the Chainguard image provides. The compensation for this hassle
317 is huge: we no longer leave a package manager sitting around inside the
318 container, waiting for some malefactor to figure out how to abuse it.
319
320 Beware that there’s a limit to this über-jail’s ability to save you when
321 you go and provide a more capable OS layer like this. The container
322
--- www/containers.md
+++ www/containers.md
@@ -231,11 +231,11 @@
231 for the sake of discussion, we’ll say you’ve chosen [Method
232 2](./alerts.md#db), which requires a Tcl interpreter and its SQLite
233 extension to push messages into the outbound email queue DB, presumably
234 bind-mounted into the container.
235
236 You can do that by replacing STAGEs 2 and 3 in the stock `Dockerfile`
237 with this:
238
239 ```
240 ## ---------------------------------------------------------------------
241 ## STAGE 2: Pare that back to the bare essentials, plus Tcl.
@@ -242,10 +242,11 @@
242 ## ---------------------------------------------------------------------
243 FROM alpine AS run
244 ARG UID=499
245 ENV PATH "/sbin:/usr/sbin:/bin:/usr/bin"
246 COPY --from=builder /tmp/fossil /bin/
247 COPY tools/email-sender.tcl /bin/
248 RUN set -x \
249 && echo "fossil:x:${UID}:${UID}:User:/museum:/false" >> /etc/passwd \
250 && echo "fossil:x:${UID}:fossil" >> /etc/group \
251 && install -d -m 700 -o fossil -g fossil log museum \
252 && apk add --no-cache tcl sqlite-tcl
@@ -258,29 +259,26 @@
259 echo 'puts [info patchlevel]' |
260 docker exec -i $(make container-version) tclsh
261 8.6.12
262 ```
263
264 You should remove the `PATH` override in the “RUN”
 
 
 
 
 
265 stage, since it’s written for the case where everything is in `/bin`.
266 With these additions, we need the longer `PATH` shown above to have
267 ready access to them all.
268
269 Another useful case to consider is that you’ve installed a [server
270 extension](./serverext.wiki) and you need an interpreter for that
271 script. The first option above won’t work except in the unlikely case that
272 it’s written for one of the bare-bones script interpreters that BusyBox
273 ships.(^BusyBox’s `/bin/sh` is based on the old 4.4BSD Lite Almquist
274 shell, implementing little more than what POSIX specified in 1989, plus
275 equally stripped-down versions of `awk` and `sed`.)
276
277 Let’s say the extension is written in Python. While you could handle it
278 the same way we do with the Tcl example above, Python is more
279 popular, giving us more options. Let’s inject a Python environment into
280 the stock Fossil container via a suitable “[distroless]” image instead:
281
282 ```
283 ## ---------------------------------------------------------------------
284 ## STAGE 2: Pare that back to the bare essentials, plus Python.
@@ -296,26 +294,25 @@
294 && echo "fossil:x:${UID}:${UID}:User:/museum:/false" >> /etc/passwd \
295 && echo "fossil:x:${UID}:fossil" >> /etc/group \
296 && install -d -m 700 -o fossil -g fossil log museum
297 ```
298
299 You will also have to add `busybox-static` to the APK package list in
300 STAGE 1 for the `RUN` script at the end of that stage to work, since the
301 [Chainguard Python image][cgimgs] lacks a shell, on purpose. The need to
302 install root-level binaries is why we change `USER` temporarily here.
303
304 Build it and test that it works like so:
305
306 ```
307 $ make container-run &&
308 docker exec -i $(make container-version) python --version
309 3.11.2
310 ```
311
312 The compensation for the hassle of using Chainguard over something more
313 general purpose like Alpine + “`apk add python`”
 
 
 
 
 
 
314 is huge: we no longer leave a package manager sitting around inside the
315 container, waiting for some malefactor to figure out how to abuse it.
316
317 Beware that there’s a limit to this über-jail’s ability to save you when
318 you go and provide a more capable OS layer like this. The container
319

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button