Fossil SCM
Added section numbers to the containers doc (it was getting confusing) and added a few internal fragment IDs.
Commit
4d51d52417a3ec058c327274279ec398dc1f6515d61163cc1670165779b7ca8e
Parent
9c96e49995a5b5c…
1 file changed
+20
-20
+20
-20
| --- www/containers.md | ||
| +++ www/containers.md | ||
| @@ -8,11 +8,11 @@ | ||
| 8 | 8 | |
| 9 | 9 | [Docker]: https://www.docker.com/ |
| 10 | 10 | [OCI]: https://opencontainers.org/ |
| 11 | 11 | |
| 12 | 12 | |
| 13 | -## Quick Start | |
| 13 | +## 1. Quick Start | |
| 14 | 14 | |
| 15 | 15 | Fossil ships a `Dockerfile` at the top of its source tree which you can |
| 16 | 16 | build like so: |
| 17 | 17 | |
| 18 | 18 | ``` |
| @@ -57,11 +57,11 @@ | ||
| 57 | 57 | applications since they avoid a conflict with past versions; it lets you |
| 58 | 58 | keep old containers around for quick roll-backs while replacing them |
| 59 | 59 | with fresh ones. |
| 60 | 60 | |
| 61 | 61 | |
| 62 | -## <a id="storage"></a>Repository Storage Options | |
| 62 | +## 2. <a id="storage"></a>Repository Storage Options | |
| 63 | 63 | |
| 64 | 64 | If you want the container to serve an existing repository, there are at |
| 65 | 65 | least two right ways to do it. |
| 66 | 66 | |
| 67 | 67 | The wrong way is to use the `Dockerfile COPY` command, because by baking |
| @@ -74,11 +74,11 @@ | ||
| 74 | 74 | |
| 75 | 75 | The correct ways put the repo into the _container_ created from the |
| 76 | 76 | _image_, not in the image itself. |
| 77 | 77 | |
| 78 | 78 | |
| 79 | -### Storing the Repo Inside the Container | |
| 79 | +### <a id="repo-inside"></a> 2.1 Storing the Repo Inside the Container | |
| 80 | 80 | |
| 81 | 81 | The simplest method is to stop the container if it was running, then |
| 82 | 82 | say: |
| 83 | 83 | |
| 84 | 84 | ``` |
| @@ -110,11 +110,11 @@ | ||
| 110 | 110 | privileges after it enters the chroot. (See [below](#args) for how to |
| 111 | 111 | change this default.) You don’t have to restart the server after fixing |
| 112 | 112 | this with `chmod`: simply reload the browser, and Fossil will try again. |
| 113 | 113 | |
| 114 | 114 | |
| 115 | -### <a id="bind-mount"></a>Storing the Repo Outside the Container | |
| 115 | +### 2.2 <a id="bind-mount"></a>Storing the Repo Outside the Container | |
| 116 | 116 | |
| 117 | 117 | The simple storage method above has a problem: Docker containers are |
| 118 | 118 | designed to be killed off at the slightest cause, rebuilt, and |
| 119 | 119 | redeployed. If you do that with the repo inside the container, it gets |
| 120 | 120 | destroyed, too. The solution is to replace the “run” command above with |
| @@ -145,13 +145,13 @@ | ||
| 145 | 145 | remapped into the new container when you recreate it with `-v`. |
| 146 | 146 | |
| 147 | 147 | [dbcorr]: https://www.sqlite.org/howtocorrupt.html |
| 148 | 148 | |
| 149 | 149 | |
| 150 | -## <a id="security"></a>Security | |
| 150 | +## 3. <a id="security"></a>Security | |
| 151 | 151 | |
| 152 | -### <a id="chroot"></a>Why Chroot? | |
| 152 | +### 3.1 <a id="chroot"></a>Why Chroot? | |
| 153 | 153 | |
| 154 | 154 | A potentially surprising feature of this container is that it runs |
| 155 | 155 | Fossil as root. Since that causes [the chroot jail feature](./chroot.md) |
| 156 | 156 | to kick in, and a Docker container is a type of über-jail already, you |
| 157 | 157 | may be wondering why we bother. Instead, why not either: |
| @@ -196,11 +196,11 @@ | ||
| 196 | 196 | become when dropping root privileges. |
| 197 | 197 | |
| 198 | 198 | [th1docrisk]: https://fossil-scm.org/forum/forumpost/42e0c16544 |
| 199 | 199 | |
| 200 | 200 | |
| 201 | -### <a id="caps"></a>Dropping Unnecessary Capabilities | |
| 201 | +### 3.2 <a id="caps"></a>Dropping Unnecessary Capabilities | |
| 202 | 202 | |
| 203 | 203 | The example commands above create the container with [a default set of |
| 204 | 204 | Linux kernel capabilities][defcap]. Although Docker strips away almost |
| 205 | 205 | all of the traditional root capabilities by default, and Fossil doesn’t |
| 206 | 206 | need any of those it does take away, Docker does leave some enabled that |
| @@ -310,11 +310,11 @@ | ||
| 310 | 310 | [defcap]: https://docs.docker.com/engine/security/#linux-kernel-capabilities |
| 311 | 311 | [capchg]: https://stackoverflow.com/a/45752205/142454 |
| 312 | 312 | |
| 313 | 313 | |
| 314 | 314 | |
| 315 | -## <a id="static"></a>Extracting a Static Binary | |
| 315 | +## 4. <a id="static"></a>Extracting a Static Binary | |
| 316 | 316 | |
| 317 | 317 | Our 2-stage build process uses Alpine Linux only as a build host. Once |
| 318 | 318 | we’ve got everything reduced to the two key static binaries — Fossil and |
| 319 | 319 | BusyBox — we throw all the rest of it away. |
| 320 | 320 | |
| @@ -336,13 +336,13 @@ | ||
| 336 | 336 | at about 4 MiB. (It’s built stripped and packed with [UPX].) |
| 337 | 337 | |
| 338 | 338 | [UPX]: https://upx.github.io/ |
| 339 | 339 | |
| 340 | 340 | |
| 341 | -## <a id="args"></a>Container Build Arguments | |
| 341 | +## 5. <a id="args"></a>Container Build Arguments | |
| 342 | 342 | |
| 343 | -### Package Versions | |
| 343 | +### <a id="pkg-vers"></a> 5.1 Package Versions | |
| 344 | 344 | |
| 345 | 345 | You can override the default versions of Fossil and BusyBox that get |
| 346 | 346 | fetched in the build step. To get the latest-and-greatest of everything, |
| 347 | 347 | you could say: |
| 348 | 348 | |
| @@ -383,11 +383,11 @@ | ||
| 383 | 383 | rather than let it default to the generic “`trunk`” tag: so the URL will |
| 384 | 384 | change each time you update your Fossil source tree, forcing Docker to |
| 385 | 385 | pull a fresh tarball. |
| 386 | 386 | |
| 387 | 387 | |
| 388 | -### <a id="uids"></a>User & Group IDs | |
| 388 | +### 5.2 <a id="uids"></a>User & Group IDs | |
| 389 | 389 | |
| 390 | 390 | The “`fossil`” user and group IDs inside the container default to 499. |
| 391 | 391 | Why? Regular user IDs start at 500 or 1000 on most Unix type systems, |
| 392 | 392 | leaving those below it for system users like this Fossil daemon owner. |
| 393 | 393 | Since it’s typical for these to start at 0 and go upward, we started at |
| @@ -405,11 +405,11 @@ | ||
| 405 | 405 | file permissions. You may therefore wish them to mean something on both |
| 406 | 406 | sides of the container barrier rather than have “499” appear on the host |
| 407 | 407 | in “`ls -l`” output. |
| 408 | 408 | |
| 409 | 409 | |
| 410 | -## <a id="light"></a>Lightweight Alternatives to Docker | |
| 410 | +## 6. <a id="light"></a>Lightweight Alternatives to Docker | |
| 411 | 411 | |
| 412 | 412 | Those afflicted with sticker shock at seeing the size of a [Docker |
| 413 | 413 | Desktop][DD] installation — 1.65 GB here — might’ve immediately |
| 414 | 414 | “noped” out of the whole concept of containers. The first thing to |
| 415 | 415 | realize is that when it comes to actually serving simple containers like |
| @@ -445,11 +445,11 @@ | ||
| 445 | 445 | [DD]: https://www.docker.com/products/docker-desktop/ |
| 446 | 446 | [DE]: https://docs.docker.com/engine/ |
| 447 | 447 | [DNT]: ./server/debian/nginx.md |
| 448 | 448 | |
| 449 | 449 | |
| 450 | -### <a id="runc" name="containerd"></a>Stripping Docker Engine Down | |
| 450 | +### 6.1 <a id="runc" name="containerd"></a>Stripping Docker Engine Down | |
| 451 | 451 | |
| 452 | 452 | The core of Docker Engine is its [`containerd`][ctrd] daemon and the |
| 453 | 453 | [`runc`][runc] container runner. It’s possible to dig into the subtree |
| 454 | 454 | managed by `containerd` on the build host and extract what we need to |
| 455 | 455 | run our Fossil container elsewhere with `runc`, leaving out all the |
| @@ -652,11 +652,11 @@ | ||
| 652 | 652 | [jq]: https://stedolan.github.io/jq/ |
| 653 | 653 | [sdnsp]: #nspawn |
| 654 | 654 | [runc]: https://github.com/opencontainers/runc |
| 655 | 655 | |
| 656 | 656 | |
| 657 | -### <a id="podman"></a>Podman | |
| 657 | +### 6.2 <a id="podman"></a>Podman | |
| 658 | 658 | |
| 659 | 659 | Although your humble author claims the `runc` methods above are not |
| 660 | 660 | complicated, merely cryptic, you might be fondly recollecting the |
| 661 | 661 | carefree commands at the top of this document, pondering whether you can |
| 662 | 662 | live without the abstractions a proper container runtime system |
| @@ -697,11 +697,11 @@ | ||
| 697 | 697 | [pmwin]: https://github.com/containers/podman/blob/main/docs/tutorials/podman-for-windows.md |
| 698 | 698 | [Podman]: https://podman.io/ |
| 699 | 699 | [whatis]: https://podman.io/whatis.html |
| 700 | 700 | |
| 701 | 701 | |
| 702 | -#### <a id="podman-rootless"></a>Fossil in a Rootless Podman Container | |
| 702 | +#### 6.2.1 <a id="podman-rootless"></a>Fossil in a Rootless Podman Container | |
| 703 | 703 | |
| 704 | 704 | If you build the stock Fossil container under `podman`, it will fail at |
| 705 | 705 | two key steps: |
| 706 | 706 | |
| 707 | 707 | 1. The `mknod` calls in the second stage, which create the `/jail/dev` |
| @@ -742,11 +742,11 @@ | ||
| 742 | 742 | they’ll be connected to the network the container runs on. Once the bad |
| 743 | 743 | guy is inside the house, he doesn’t necessarily have to go after the |
| 744 | 744 | residents directly to cause problems for them. |
| 745 | 745 | |
| 746 | 746 | |
| 747 | -#### <a id="crun"></a>`crun` | |
| 747 | +#### 6.2.2 <a id="crun"></a>`crun` | |
| 748 | 748 | |
| 749 | 749 | In the same way that [Docker Engine is based on `runc`](#runc), Podman’s |
| 750 | 750 | engine is based on [`crun`][crun], a lighter-weight alternative to |
| 751 | 751 | `runc`. It’s only 1.4 MiB on the system I tested it on, yet it will run |
| 752 | 752 | the same container bundles as in my `runc` examples above. |
| @@ -762,11 +762,11 @@ | ||
| 762 | 762 | `sudo crun`, following the examples above. |
| 763 | 763 | |
| 764 | 764 | [crun]: https://github.com/containers/crun |
| 765 | 765 | |
| 766 | 766 | |
| 767 | -#### <a id="podman-rootful"></a>Fossil in a Rootful Podman Container | |
| 767 | +#### 6.2.3 <a id="podman-rootful"></a>Fossil in a Rootful Podman Container | |
| 768 | 768 | |
| 769 | 769 | ##### Simple Method |
| 770 | 770 | |
| 771 | 771 | As we saw above with `runc`, switching to `crun` just to get your |
| 772 | 772 | containers to run as root loses a lot of functionality and requires a |
| @@ -831,12 +831,12 @@ | ||
| 831 | 831 | remote system. You still have to build as root on the local system, but |
| 832 | 832 | as I said above, Docker already does this. What we’re doing is shifting |
| 833 | 833 | the risk of running as root from the public host to the local one. |
| 834 | 834 | |
| 835 | 835 | Once you have the image built on the local machine, create a “`fossil`” |
| 836 | -repository on your container repository of choice, such as [Docker | |
| 837 | -Hub](https://hub.docker.com). Then say: | |
| 836 | +repository on your container repository of choice such as [Docker | |
| 837 | +Hub](https://hub.docker.com), then say: | |
| 838 | 838 | |
| 839 | 839 | ``` |
| 840 | 840 | $ docker login |
| 841 | 841 | $ docker tag fossil:latest mydockername/fossil:latest |
| 842 | 842 | $ docker image push mydockername/fossil:latest |
| @@ -857,11 +857,11 @@ | ||
| 857 | 857 | container images across the Internet, it can be a net win in terms of |
| 858 | 858 | build time. |
| 859 | 859 | |
| 860 | 860 | |
| 861 | 861 | |
| 862 | -### <a id="nspawn"></a>`systemd-nspawn` | |
| 862 | +### 6.3 <a id="nspawn"></a>`systemd-nspawn` | |
| 863 | 863 | |
| 864 | 864 | As of `systemd` version 242, its optional `nspawn` piece |
| 865 | 865 | [reportedly](https://www.phoronix.com/news/Systemd-Nspawn-OCI-Runtime) |
| 866 | 866 | now has the ability to run OCI container bundles directly. You might |
| 867 | 867 | have it installed already, but if not, it’s only about 2 MiB. It’s |
| 868 | 868 |
| --- www/containers.md | |
| +++ www/containers.md | |
| @@ -8,11 +8,11 @@ | |
| 8 | |
| 9 | [Docker]: https://www.docker.com/ |
| 10 | [OCI]: https://opencontainers.org/ |
| 11 | |
| 12 | |
| 13 | ## Quick Start |
| 14 | |
| 15 | Fossil ships a `Dockerfile` at the top of its source tree which you can |
| 16 | build like so: |
| 17 | |
| 18 | ``` |
| @@ -57,11 +57,11 @@ | |
| 57 | applications since they avoid a conflict with past versions; it lets you |
| 58 | keep old containers around for quick roll-backs while replacing them |
| 59 | with fresh ones. |
| 60 | |
| 61 | |
| 62 | ## <a id="storage"></a>Repository Storage Options |
| 63 | |
| 64 | If you want the container to serve an existing repository, there are at |
| 65 | least two right ways to do it. |
| 66 | |
| 67 | The wrong way is to use the `Dockerfile COPY` command, because by baking |
| @@ -74,11 +74,11 @@ | |
| 74 | |
| 75 | The correct ways put the repo into the _container_ created from the |
| 76 | _image_, not in the image itself. |
| 77 | |
| 78 | |
| 79 | ### Storing the Repo Inside the Container |
| 80 | |
| 81 | The simplest method is to stop the container if it was running, then |
| 82 | say: |
| 83 | |
| 84 | ``` |
| @@ -110,11 +110,11 @@ | |
| 110 | privileges after it enters the chroot. (See [below](#args) for how to |
| 111 | change this default.) You don’t have to restart the server after fixing |
| 112 | this with `chmod`: simply reload the browser, and Fossil will try again. |
| 113 | |
| 114 | |
| 115 | ### <a id="bind-mount"></a>Storing the Repo Outside the Container |
| 116 | |
| 117 | The simple storage method above has a problem: Docker containers are |
| 118 | designed to be killed off at the slightest cause, rebuilt, and |
| 119 | redeployed. If you do that with the repo inside the container, it gets |
| 120 | destroyed, too. The solution is to replace the “run” command above with |
| @@ -145,13 +145,13 @@ | |
| 145 | remapped into the new container when you recreate it with `-v`. |
| 146 | |
| 147 | [dbcorr]: https://www.sqlite.org/howtocorrupt.html |
| 148 | |
| 149 | |
| 150 | ## <a id="security"></a>Security |
| 151 | |
| 152 | ### <a id="chroot"></a>Why Chroot? |
| 153 | |
| 154 | A potentially surprising feature of this container is that it runs |
| 155 | Fossil as root. Since that causes [the chroot jail feature](./chroot.md) |
| 156 | to kick in, and a Docker container is a type of über-jail already, you |
| 157 | may be wondering why we bother. Instead, why not either: |
| @@ -196,11 +196,11 @@ | |
| 196 | become when dropping root privileges. |
| 197 | |
| 198 | [th1docrisk]: https://fossil-scm.org/forum/forumpost/42e0c16544 |
| 199 | |
| 200 | |
| 201 | ### <a id="caps"></a>Dropping Unnecessary Capabilities |
| 202 | |
| 203 | The example commands above create the container with [a default set of |
| 204 | Linux kernel capabilities][defcap]. Although Docker strips away almost |
| 205 | all of the traditional root capabilities by default, and Fossil doesn’t |
| 206 | need any of those it does take away, Docker does leave some enabled that |
| @@ -310,11 +310,11 @@ | |
| 310 | [defcap]: https://docs.docker.com/engine/security/#linux-kernel-capabilities |
| 311 | [capchg]: https://stackoverflow.com/a/45752205/142454 |
| 312 | |
| 313 | |
| 314 | |
| 315 | ## <a id="static"></a>Extracting a Static Binary |
| 316 | |
| 317 | Our 2-stage build process uses Alpine Linux only as a build host. Once |
| 318 | we’ve got everything reduced to the two key static binaries — Fossil and |
| 319 | BusyBox — we throw all the rest of it away. |
| 320 | |
| @@ -336,13 +336,13 @@ | |
| 336 | at about 4 MiB. (It’s built stripped and packed with [UPX].) |
| 337 | |
| 338 | [UPX]: https://upx.github.io/ |
| 339 | |
| 340 | |
| 341 | ## <a id="args"></a>Container Build Arguments |
| 342 | |
| 343 | ### Package Versions |
| 344 | |
| 345 | You can override the default versions of Fossil and BusyBox that get |
| 346 | fetched in the build step. To get the latest-and-greatest of everything, |
| 347 | you could say: |
| 348 | |
| @@ -383,11 +383,11 @@ | |
| 383 | rather than let it default to the generic “`trunk`” tag: so the URL will |
| 384 | change each time you update your Fossil source tree, forcing Docker to |
| 385 | pull a fresh tarball. |
| 386 | |
| 387 | |
| 388 | ### <a id="uids"></a>User & Group IDs |
| 389 | |
| 390 | The “`fossil`” user and group IDs inside the container default to 499. |
| 391 | Why? Regular user IDs start at 500 or 1000 on most Unix type systems, |
| 392 | leaving those below it for system users like this Fossil daemon owner. |
| 393 | Since it’s typical for these to start at 0 and go upward, we started at |
| @@ -405,11 +405,11 @@ | |
| 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 |
| @@ -445,11 +445,11 @@ | |
| 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 | ### <a id="runc" name="containerd"></a>Stripping Docker Engine Down |
| 451 | |
| 452 | The core of Docker Engine is its [`containerd`][ctrd] daemon and the |
| 453 | [`runc`][runc] container runner. It’s possible to dig into the subtree |
| 454 | managed by `containerd` on the build host and extract what we need to |
| 455 | run our Fossil container elsewhere with `runc`, leaving out all the |
| @@ -652,11 +652,11 @@ | |
| 652 | [jq]: https://stedolan.github.io/jq/ |
| 653 | [sdnsp]: #nspawn |
| 654 | [runc]: https://github.com/opencontainers/runc |
| 655 | |
| 656 | |
| 657 | ### <a id="podman"></a>Podman |
| 658 | |
| 659 | Although your humble author claims the `runc` methods above are not |
| 660 | complicated, merely cryptic, you might be fondly recollecting the |
| 661 | carefree commands at the top of this document, pondering whether you can |
| 662 | live without the abstractions a proper container runtime system |
| @@ -697,11 +697,11 @@ | |
| 697 | [pmwin]: https://github.com/containers/podman/blob/main/docs/tutorials/podman-for-windows.md |
| 698 | [Podman]: https://podman.io/ |
| 699 | [whatis]: https://podman.io/whatis.html |
| 700 | |
| 701 | |
| 702 | #### <a id="podman-rootless"></a>Fossil in a Rootless Podman Container |
| 703 | |
| 704 | If you build the stock Fossil container under `podman`, it will fail at |
| 705 | two key steps: |
| 706 | |
| 707 | 1. The `mknod` calls in the second stage, which create the `/jail/dev` |
| @@ -742,11 +742,11 @@ | |
| 742 | they’ll be connected to the network the container runs on. Once the bad |
| 743 | guy is inside the house, he doesn’t necessarily have to go after the |
| 744 | residents directly to cause problems for them. |
| 745 | |
| 746 | |
| 747 | #### <a id="crun"></a>`crun` |
| 748 | |
| 749 | In the same way that [Docker Engine is based on `runc`](#runc), Podman’s |
| 750 | engine is based on [`crun`][crun], a lighter-weight alternative to |
| 751 | `runc`. It’s only 1.4 MiB on the system I tested it on, yet it will run |
| 752 | the same container bundles as in my `runc` examples above. |
| @@ -762,11 +762,11 @@ | |
| 762 | `sudo crun`, following the examples above. |
| 763 | |
| 764 | [crun]: https://github.com/containers/crun |
| 765 | |
| 766 | |
| 767 | #### <a id="podman-rootful"></a>Fossil in a Rootful Podman Container |
| 768 | |
| 769 | ##### Simple Method |
| 770 | |
| 771 | As we saw above with `runc`, switching to `crun` just to get your |
| 772 | containers to run as root loses a lot of functionality and requires a |
| @@ -831,12 +831,12 @@ | |
| 831 | remote system. You still have to build as root on the local system, but |
| 832 | as I said above, Docker already does this. What we’re doing is shifting |
| 833 | the risk of running as root from the public host to the local one. |
| 834 | |
| 835 | Once you have the image built on the local machine, create a “`fossil`” |
| 836 | repository on your container repository of choice, such as [Docker |
| 837 | Hub](https://hub.docker.com). Then say: |
| 838 | |
| 839 | ``` |
| 840 | $ docker login |
| 841 | $ docker tag fossil:latest mydockername/fossil:latest |
| 842 | $ docker image push mydockername/fossil:latest |
| @@ -857,11 +857,11 @@ | |
| 857 | container images across the Internet, it can be a net win in terms of |
| 858 | build time. |
| 859 | |
| 860 | |
| 861 | |
| 862 | ### <a id="nspawn"></a>`systemd-nspawn` |
| 863 | |
| 864 | As of `systemd` version 242, its optional `nspawn` piece |
| 865 | [reportedly](https://www.phoronix.com/news/Systemd-Nspawn-OCI-Runtime) |
| 866 | now has the ability to run OCI container bundles directly. You might |
| 867 | have it installed already, but if not, it’s only about 2 MiB. It’s |
| 868 |
| --- www/containers.md | |
| +++ www/containers.md | |
| @@ -8,11 +8,11 @@ | |
| 8 | |
| 9 | [Docker]: https://www.docker.com/ |
| 10 | [OCI]: https://opencontainers.org/ |
| 11 | |
| 12 | |
| 13 | ## 1. Quick Start |
| 14 | |
| 15 | Fossil ships a `Dockerfile` at the top of its source tree which you can |
| 16 | build like so: |
| 17 | |
| 18 | ``` |
| @@ -57,11 +57,11 @@ | |
| 57 | applications since they avoid a conflict with past versions; it lets you |
| 58 | keep old containers around for quick roll-backs while replacing them |
| 59 | with fresh ones. |
| 60 | |
| 61 | |
| 62 | ## 2. <a id="storage"></a>Repository Storage Options |
| 63 | |
| 64 | If you want the container to serve an existing repository, there are at |
| 65 | least two right ways to do it. |
| 66 | |
| 67 | The wrong way is to use the `Dockerfile COPY` command, because by baking |
| @@ -74,11 +74,11 @@ | |
| 74 | |
| 75 | The correct ways put the repo into the _container_ created from the |
| 76 | _image_, not in the image itself. |
| 77 | |
| 78 | |
| 79 | ### <a id="repo-inside"></a> 2.1 Storing the Repo Inside the Container |
| 80 | |
| 81 | The simplest method is to stop the container if it was running, then |
| 82 | say: |
| 83 | |
| 84 | ``` |
| @@ -110,11 +110,11 @@ | |
| 110 | privileges after it enters the chroot. (See [below](#args) for how to |
| 111 | change this default.) You don’t have to restart the server after fixing |
| 112 | this with `chmod`: simply reload the browser, and Fossil will try again. |
| 113 | |
| 114 | |
| 115 | ### 2.2 <a id="bind-mount"></a>Storing the Repo Outside the Container |
| 116 | |
| 117 | The simple storage method above has a problem: Docker containers are |
| 118 | designed to be killed off at the slightest cause, rebuilt, and |
| 119 | redeployed. If you do that with the repo inside the container, it gets |
| 120 | destroyed, too. The solution is to replace the “run” command above with |
| @@ -145,13 +145,13 @@ | |
| 145 | remapped into the new container when you recreate it with `-v`. |
| 146 | |
| 147 | [dbcorr]: https://www.sqlite.org/howtocorrupt.html |
| 148 | |
| 149 | |
| 150 | ## 3. <a id="security"></a>Security |
| 151 | |
| 152 | ### 3.1 <a id="chroot"></a>Why Chroot? |
| 153 | |
| 154 | A potentially surprising feature of this container is that it runs |
| 155 | Fossil as root. Since that causes [the chroot jail feature](./chroot.md) |
| 156 | to kick in, and a Docker container is a type of über-jail already, you |
| 157 | may be wondering why we bother. Instead, why not either: |
| @@ -196,11 +196,11 @@ | |
| 196 | become when dropping root privileges. |
| 197 | |
| 198 | [th1docrisk]: https://fossil-scm.org/forum/forumpost/42e0c16544 |
| 199 | |
| 200 | |
| 201 | ### 3.2 <a id="caps"></a>Dropping Unnecessary Capabilities |
| 202 | |
| 203 | The example commands above create the container with [a default set of |
| 204 | Linux kernel capabilities][defcap]. Although Docker strips away almost |
| 205 | all of the traditional root capabilities by default, and Fossil doesn’t |
| 206 | need any of those it does take away, Docker does leave some enabled that |
| @@ -310,11 +310,11 @@ | |
| 310 | [defcap]: https://docs.docker.com/engine/security/#linux-kernel-capabilities |
| 311 | [capchg]: https://stackoverflow.com/a/45752205/142454 |
| 312 | |
| 313 | |
| 314 | |
| 315 | ## 4. <a id="static"></a>Extracting a Static Binary |
| 316 | |
| 317 | Our 2-stage build process uses Alpine Linux only as a build host. Once |
| 318 | we’ve got everything reduced to the two key static binaries — Fossil and |
| 319 | BusyBox — we throw all the rest of it away. |
| 320 | |
| @@ -336,13 +336,13 @@ | |
| 336 | at about 4 MiB. (It’s built stripped and packed with [UPX].) |
| 337 | |
| 338 | [UPX]: https://upx.github.io/ |
| 339 | |
| 340 | |
| 341 | ## 5. <a id="args"></a>Container Build Arguments |
| 342 | |
| 343 | ### <a id="pkg-vers"></a> 5.1 Package Versions |
| 344 | |
| 345 | You can override the default versions of Fossil and BusyBox that get |
| 346 | fetched in the build step. To get the latest-and-greatest of everything, |
| 347 | you could say: |
| 348 | |
| @@ -383,11 +383,11 @@ | |
| 383 | rather than let it default to the generic “`trunk`” tag: so the URL will |
| 384 | change each time you update your Fossil source tree, forcing Docker to |
| 385 | pull a fresh tarball. |
| 386 | |
| 387 | |
| 388 | ### 5.2 <a id="uids"></a>User & Group IDs |
| 389 | |
| 390 | The “`fossil`” user and group IDs inside the container default to 499. |
| 391 | Why? Regular user IDs start at 500 or 1000 on most Unix type systems, |
| 392 | leaving those below it for system users like this Fossil daemon owner. |
| 393 | Since it’s typical for these to start at 0 and go upward, we started at |
| @@ -405,11 +405,11 @@ | |
| 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 | ## 6. <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 |
| @@ -445,11 +445,11 @@ | |
| 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 | ### 6.1 <a id="runc" name="containerd"></a>Stripping Docker Engine Down |
| 451 | |
| 452 | The core of Docker Engine is its [`containerd`][ctrd] daemon and the |
| 453 | [`runc`][runc] container runner. It’s possible to dig into the subtree |
| 454 | managed by `containerd` on the build host and extract what we need to |
| 455 | run our Fossil container elsewhere with `runc`, leaving out all the |
| @@ -652,11 +652,11 @@ | |
| 652 | [jq]: https://stedolan.github.io/jq/ |
| 653 | [sdnsp]: #nspawn |
| 654 | [runc]: https://github.com/opencontainers/runc |
| 655 | |
| 656 | |
| 657 | ### 6.2 <a id="podman"></a>Podman |
| 658 | |
| 659 | Although your humble author claims the `runc` methods above are not |
| 660 | complicated, merely cryptic, you might be fondly recollecting the |
| 661 | carefree commands at the top of this document, pondering whether you can |
| 662 | live without the abstractions a proper container runtime system |
| @@ -697,11 +697,11 @@ | |
| 697 | [pmwin]: https://github.com/containers/podman/blob/main/docs/tutorials/podman-for-windows.md |
| 698 | [Podman]: https://podman.io/ |
| 699 | [whatis]: https://podman.io/whatis.html |
| 700 | |
| 701 | |
| 702 | #### 6.2.1 <a id="podman-rootless"></a>Fossil in a Rootless Podman Container |
| 703 | |
| 704 | If you build the stock Fossil container under `podman`, it will fail at |
| 705 | two key steps: |
| 706 | |
| 707 | 1. The `mknod` calls in the second stage, which create the `/jail/dev` |
| @@ -742,11 +742,11 @@ | |
| 742 | they’ll be connected to the network the container runs on. Once the bad |
| 743 | guy is inside the house, he doesn’t necessarily have to go after the |
| 744 | residents directly to cause problems for them. |
| 745 | |
| 746 | |
| 747 | #### 6.2.2 <a id="crun"></a>`crun` |
| 748 | |
| 749 | In the same way that [Docker Engine is based on `runc`](#runc), Podman’s |
| 750 | engine is based on [`crun`][crun], a lighter-weight alternative to |
| 751 | `runc`. It’s only 1.4 MiB on the system I tested it on, yet it will run |
| 752 | the same container bundles as in my `runc` examples above. |
| @@ -762,11 +762,11 @@ | |
| 762 | `sudo crun`, following the examples above. |
| 763 | |
| 764 | [crun]: https://github.com/containers/crun |
| 765 | |
| 766 | |
| 767 | #### 6.2.3 <a id="podman-rootful"></a>Fossil in a Rootful Podman Container |
| 768 | |
| 769 | ##### Simple Method |
| 770 | |
| 771 | As we saw above with `runc`, switching to `crun` just to get your |
| 772 | containers to run as root loses a lot of functionality and requires a |
| @@ -831,12 +831,12 @@ | |
| 831 | remote system. You still have to build as root on the local system, but |
| 832 | as I said above, Docker already does this. What we’re doing is shifting |
| 833 | the risk of running as root from the public host to the local one. |
| 834 | |
| 835 | Once you have the image built on the local machine, create a “`fossil`” |
| 836 | repository on your container repository of choice such as [Docker |
| 837 | Hub](https://hub.docker.com), then say: |
| 838 | |
| 839 | ``` |
| 840 | $ docker login |
| 841 | $ docker tag fossil:latest mydockername/fossil:latest |
| 842 | $ docker image push mydockername/fossil:latest |
| @@ -857,11 +857,11 @@ | |
| 857 | container images across the Internet, it can be a net win in terms of |
| 858 | build time. |
| 859 | |
| 860 | |
| 861 | |
| 862 | ### 6.3 <a id="nspawn"></a>`systemd-nspawn` |
| 863 | |
| 864 | As of `systemd` version 242, its optional `nspawn` piece |
| 865 | [reportedly](https://www.phoronix.com/news/Systemd-Nspawn-OCI-Runtime) |
| 866 | now has the ability to run OCI container bundles directly. You might |
| 867 | have it installed already, but if not, it’s only about 2 MiB. It’s |
| 868 |