Fossil SCM

Added the "Lightweight Alternatives to Docker" section to the new containers doc, currently limited to a tutorial on converting the stock Dockerfile to work under Podman in its default mode, creating a rootless container. This brings in the second container-related file at the root of the repo, the patch file for this, so we don't have to maintain two nearly-parallel Dockerfiles. As a bonus, it allows us to point to the patch from the prose, making explicit what we had to change.

wyoung 2022-09-04 02:01 trunk
Commit f0399ea9cace1d092aecca3f6b62a9a63fd69ad40fc44f0bde348930f032234a
--- a/containers/Dockerfile-nojail.patch
+++ b/containers/Dockerfile-nojail.patch
@@ -0,0 +1,7 @@
1
+Index: Doc62,13 +.in
2
+busybox /bin/
3
+ etc/os-rel -84,19 +84,17 @@
4
+ 61,13 +.in
++++ Dockerfile.in
5
+@@ -27,37 +27,35 @@
6
+ && if apk add upx ; then upx -9
--- a/containers/Dockerfile-nojail.patch
+++ b/containers/Dockerfile-nojail.patch
@@ -0,0 +1,7 @@
 
 
 
 
++++ Dockerfile.in
 
 
--- a/containers/Dockerfile-nojail.patch
+++ b/containers/Dockerfile-nojail.patch
@@ -0,0 +1,7 @@
1 Index: Doc62,13 +.in
2 busybox /bin/
3 etc/os-rel -84,19 +84,17 @@
4 61,13 +.in
++++ Dockerfile.in
5 @@ -27,37 +27,35 @@
6 && if apk add upx ; then upx -9
--- www/containers.md
+++ www/containers.md
@@ -404,7 +404,110 @@
404404
Docker volume since the IDs “leak” out into the host environment via
405405
file permissions. You may therefore wish them to mean something on both
406406
sides of the container barrier rather than have “499” appear on the host
407407
in “`ls -l`” output.
408408
409
+
410
+## <a id="light"></a>Lightweight Alternatives to Docker
411
+
412
+Those afflicted with sticker shock at seeing the size of a [Docker
413
+Desktop][DD] installation — 1.65 GB here — might’ve immediately
414
+“noped” out of the whole concept of containers. The first thing to
415
+realize is that when it comes to actually serving simple containers like
416
+the ones shown above is that [Docker Engine][DE] suffices, at about a
417
+quarter of the size.
418
+
419
+Yet on a small server — say, a $4/month 10 GiB Digital Ocean droplet —
420
+that’s still a big chunk of your storage budget. It takes 100:1 overhead
421
+just to run a 4 MiB Fossil server container? Once again, I wouldn’t
422
+blame you if you noped right on out of here, but if you will be patient,
423
+you will find that there are ways to run Fossil inside a container even
424
+on entry-level cloud VPSes. These are well-suited to running Fossil; you
425
+don’t have to resort to [raw Fossil service](./server/) to succeed,
426
+leaving the benefits of containerization to those with bigger budgets.
427
+
428
+For the sake of simple examples in this section, we’ll assume you’re
429
+integrating Fossil into a larger web site, such as with our [Debian +
430
+nginx + TLS][DNT] plan. The Fossil server instance listens on a
431
+high-numbered port, on localhost only, and the front-end web server
432
+reverse-proxies this out to the public. Containers are a fine addition
433
+to such a system, isolating those elements of the site, thus greatly
434
+reducing the chance that they’ll ever be used to break into the host as
435
+a whole.
436
+
437
+(If you wanted to be double-safe, you could put the web server into
438
+another container, restricting it only to reading from the static web
439
+site directory and connecting across localhost to back-end dynamic
440
+content servers such as Fossil. That’s way outside the scope of this
441
+document, but you can find ready advice for that elsewhere. Seeing how
442
+we do this with Fossil should help you bridge the gap in extending
443
+this idea to the rest of your site.)
444
+
445
+[DD]: https://www.docker.com/products/docker-desktop/
446
+[DE]: https://docs.docker.com/engine/
447
+[DNT]: ./server/debian/nginx.md
448
+
449
+
450
+
451
+### <a id="runc" name="containerd"></a>Stripping Docker Engine Down
452
+
453
+The core of Docker Engine is its [containerd] daemon and the [runc]
454
+container runner. It’s possible to run our Fossil container using only
455
+these tools, leaving out all the rest. Those two pieces come to about a
456
+tenth the size of Docker Engine on the system where I tested this.
457
+
458
+**TODO:** Work out how to do this and document it.
459
+
460
+[containerd]: https://containerd.io/
461
+[runc]: https://github.com/opencontainers/runc
462
+
463
+
464
+### <a id="podman"></a>Podman
465
+
466
+The biggest downside of that method is that you don’t have all of the
467
+userland tools for managing the containers.
468
+
469
+A lighter-weight alternative to Docker Engine that doesn’t give up so
470
+much of its administrator affordances is [Podman], initially created by
471
+Red Hat and thus popular on that family of OSes, although it will run on
472
+any flavor of Linux. On Ubuntu 22.04, it’s about a quarter the size of
473
+Docker Engine.
474
+
475
+Although Podman [bills itself][whatis] as a drop-in replacement for the
476
+`docker` command and everything that sits behind it, some of the tool’s
477
+design decisions affect how our Fossil containers run, as compared to
478
+using Docker. The most important of these is that, by default, Podman
479
+wants to run your container “rootless,” meaning that it runs as a
480
+regular user. This is generally better for security, but [we dealt with
481
+that risk differently above](#chroot) already. Since neither choice is
482
+unassailably correct in all conditions, we’ll document both options
483
+here.
484
+
485
+
486
+#### <a id="podman-rootless"></a>Fossil in a Rootless Podman Container
487
+
488
+If you build the stock Fossil container under `podman`, it will fail at
489
+two key steps:
490
+
491
+1. The `mknod` calls in the second stage, which create the `/jail/dev`
492
+ nodes. For a rootless container, we want it to use the “real” `/dev`
493
+ tree mounted into the container’s root filesystem instead.
494
+
495
+2. Anything that depends on the `/jail` directory and the fact that it
496
+ becomes the root once the Fossil server is up and running.
497
+
498
+[The changes to fix this](/file/containers/Dockerfile-nojail.patch)
499
+aren’t complicated. Simply apply that patch to our stock `Dockerfile`
500
+and rebuild.
501
+
502
+Do realize that by doing this, if an attacker ever managed to get shell
503
+access on your container, they’d have a BusyBox installation to play
504
+around in. That shouldn’t be enough to let them break out of the
505
+container entirely, but they’ll have powerful tools like `wget`, and
506
+they’ll be connected to the network the container runs on. Once the bad
507
+guy is inside the house, he doesn’t necessarily have to go after the
508
+residents directly to cause problems for them.
509
+
510
+[Podman]: https://podman.io/
511
+[whatis]: https://podman.io/whatis.html
409512
410513
<div style="height:50em" id="this-space-intentionally-left-blank"></div>
411514
--- www/containers.md
+++ www/containers.md
@@ -404,7 +404,110 @@
404 Docker volume since the IDs “leak” out into the host environment via
405 file permissions. You may therefore wish them to mean something on both
406 sides of the container barrier rather than have “499” appear on the host
407 in “`ls -l`” output.
408
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
409
410 <div style="height:50em" id="this-space-intentionally-left-blank"></div>
411
--- www/containers.md
+++ www/containers.md
@@ -404,7 +404,110 @@
404 Docker volume since the IDs “leak” out into the host environment via
405 file permissions. You may therefore wish them to mean something on both
406 sides of the container barrier rather than have “499” appear on the host
407 in “`ls -l`” output.
408
409
410 ## <a id="light"></a>Lightweight Alternatives to Docker
411
412 Those afflicted with sticker shock at seeing the size of a [Docker
413 Desktop][DD] installation — 1.65 GB here — might’ve immediately
414 “noped” out of the whole concept of containers. The first thing to
415 realize is that when it comes to actually serving simple containers like
416 the ones shown above is that [Docker Engine][DE] suffices, at about a
417 quarter of the size.
418
419 Yet on a small server — say, a $4/month 10 GiB Digital Ocean droplet —
420 that’s still a big chunk of your storage budget. It takes 100:1 overhead
421 just to run a 4 MiB Fossil server container? Once again, I wouldn’t
422 blame you if you noped right on out of here, but if you will be patient,
423 you will find that there are ways to run Fossil inside a container even
424 on entry-level cloud VPSes. These are well-suited to running Fossil; you
425 don’t have to resort to [raw Fossil service](./server/) to succeed,
426 leaving the benefits of containerization to those with bigger budgets.
427
428 For the sake of simple examples in this section, we’ll assume you’re
429 integrating Fossil into a larger web site, such as with our [Debian +
430 nginx + TLS][DNT] plan. The Fossil server instance listens on a
431 high-numbered port, on localhost only, and the front-end web server
432 reverse-proxies this out to the public. Containers are a fine addition
433 to such a system, isolating those elements of the site, thus greatly
434 reducing the chance that they’ll ever be used to break into the host as
435 a whole.
436
437 (If you wanted to be double-safe, you could put the web server into
438 another container, restricting it only to reading from the static web
439 site directory and connecting across localhost to back-end dynamic
440 content servers such as Fossil. That’s way outside the scope of this
441 document, but you can find ready advice for that elsewhere. Seeing how
442 we do this with Fossil should help you bridge the gap in extending
443 this idea to the rest of your site.)
444
445 [DD]: https://www.docker.com/products/docker-desktop/
446 [DE]: https://docs.docker.com/engine/
447 [DNT]: ./server/debian/nginx.md
448
449
450
451 ### <a id="runc" name="containerd"></a>Stripping Docker Engine Down
452
453 The core of Docker Engine is its [containerd] daemon and the [runc]
454 container runner. It’s possible to run our Fossil container using only
455 these tools, leaving out all the rest. Those two pieces come to about a
456 tenth the size of Docker Engine on the system where I tested this.
457
458 **TODO:** Work out how to do this and document it.
459
460 [containerd]: https://containerd.io/
461 [runc]: https://github.com/opencontainers/runc
462
463
464 ### <a id="podman"></a>Podman
465
466 The biggest downside of that method is that you don’t have all of the
467 userland tools for managing the containers.
468
469 A lighter-weight alternative to Docker Engine that doesn’t give up so
470 much of its administrator affordances is [Podman], initially created by
471 Red Hat and thus popular on that family of OSes, although it will run on
472 any flavor of Linux. On Ubuntu 22.04, it’s about a quarter the size of
473 Docker Engine.
474
475 Although Podman [bills itself][whatis] as a drop-in replacement for the
476 `docker` command and everything that sits behind it, some of the tool’s
477 design decisions affect how our Fossil containers run, as compared to
478 using Docker. The most important of these is that, by default, Podman
479 wants to run your container “rootless,” meaning that it runs as a
480 regular user. This is generally better for security, but [we dealt with
481 that risk differently above](#chroot) already. Since neither choice is
482 unassailably correct in all conditions, we’ll document both options
483 here.
484
485
486 #### <a id="podman-rootless"></a>Fossil in a Rootless Podman Container
487
488 If you build the stock Fossil container under `podman`, it will fail at
489 two key steps:
490
491 1. The `mknod` calls in the second stage, which create the `/jail/dev`
492 nodes. For a rootless container, we want it to use the “real” `/dev`
493 tree mounted into the container’s root filesystem instead.
494
495 2. Anything that depends on the `/jail` directory and the fact that it
496 becomes the root once the Fossil server is up and running.
497
498 [The changes to fix this](/file/containers/Dockerfile-nojail.patch)
499 aren’t complicated. Simply apply that patch to our stock `Dockerfile`
500 and rebuild.
501
502 Do realize that by doing this, if an attacker ever managed to get shell
503 access on your container, they’d have a BusyBox installation to play
504 around in. That shouldn’t be enough to let them break out of the
505 container entirely, but they’ll have powerful tools like `wget`, and
506 they’ll be connected to the network the container runs on. Once the bad
507 guy is inside the house, he doesn’t necessarily have to go after the
508 residents directly to cause problems for them.
509
510 [Podman]: https://podman.io/
511 [whatis]: https://podman.io/whatis.html
512
513 <div style="height:50em" id="this-space-intentionally-left-blank"></div>
514

Keyboard Shortcuts

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