Fossil SCM
Finished all the new topics planned for the new containers doc, adding sections on rootful Podman containers and on building via Docker but running via Podman, using Docker Hub as an intermediary to avoid building on the remote host.
Commit
9c96e49995a5b5c7feec839db6c5da77bec2bf1500a95ea2e9a26b7362a2bb84
Parent
3dfa458167a6e32…
1 file changed
+95
+95
| --- www/containers.md | ||
| +++ www/containers.md | ||
| @@ -760,10 +760,105 @@ | ||
| 760 | 760 | |
| 761 | 761 | This suggests one method around the problem of rootless Podman containers: |
| 762 | 762 | `sudo crun`, following the examples above. |
| 763 | 763 | |
| 764 | 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 | |
| 773 | +bunch of cryptic commands to get the same effect as a single command | |
| 774 | +under Podman. | |
| 775 | + | |
| 776 | +Fortunately, it’s easy enough to have it both ways. Simply run your | |
| 777 | +`podman` commands as root: | |
| 778 | + | |
| 779 | +``` | |
| 780 | + $ sudo podman build -t fossil --cap-add MKNOD . | |
| 781 | + $ sudo podman create \ | |
| 782 | + --name fossil \ | |
| 783 | + --cap-drop AUDIT_WRITE \ | |
| 784 | + --cap-drop CHOWN \ | |
| 785 | + --cap-drop FSETID \ | |
| 786 | + --cap-drop KILL \ | |
| 787 | + --cap-drop NET_BIND_SERVICE \ | |
| 788 | + --cap-drop NET_RAW \ | |
| 789 | + --cap-drop SETFCAP \ | |
| 790 | + --cap-drop SETPCAP \ | |
| 791 | + --publish 9999:8080 \ | |
| 792 | + localhost/fossil | |
| 793 | + $ sudo podman start fossil | |
| 794 | +``` | |
| 795 | + | |
| 796 | +It’s obvious why we have to start the container as root, but why create | |
| 797 | +and build it as root, too? Isn’t that a regression from the modern | |
| 798 | +practice of doing as much as possible with a normal user? | |
| 799 | + | |
| 800 | +We have to do the build under `sudo` in part because we’re doing rootly | |
| 801 | +things with the file system image layers we’re building up. Just because | |
| 802 | +it’s done inside a container runtime’s build environment doesn’t mean we | |
| 803 | +can get away without root privileges to do things like create the | |
| 804 | +`/jail/dev/null` node. | |
| 805 | + | |
| 806 | +The other reason we need “`sudo podman build`” is because it puts the result | |
| 807 | +into root’s Podman image repository, where the next steps look for it. | |
| 808 | + | |
| 809 | +That in turn explains why we need “`sudo podman create`:” because it’s | |
| 810 | +creating a container based on an image that was created by root. If you | |
| 811 | +ran that step without `sudo`, it wouldn’t be able to find the image. | |
| 812 | + | |
| 813 | +If Docker is looking better and better to you as a result of all this, | |
| 814 | +realize that it’s doing the same thing. It just hides it better by | |
| 815 | +creating the `docker` group, so that when your user gets added to that | |
| 816 | +group, you get silent root privilege escalation on your build machine. | |
| 817 | +This is why Podman defaults to rootless containers. If you can get away | |
| 818 | +with it, it’s a better way to work. We would not be recommending | |
| 819 | +running `podman` under `sudo` if it didn’t buy us [something we wanted | |
| 820 | +badly](#chroot). | |
| 821 | + | |
| 822 | +Notice that we had to add the ability to run `mknod(8)` during the | |
| 823 | +build. Unlike Docker, Podman sensibly denies this by default, which | |
| 824 | +lets us leave off the corresponding `--cap-drop` option. | |
| 825 | + | |
| 826 | + | |
| 827 | +##### <a id="pm-root-workaround"></a>Building Under Docker, Running Under Podman | |
| 828 | + | |
| 829 | +If you have a remote host where the Fossil instance needs to run, it’s | |
| 830 | +possible to get around this need to build the image as root on the | |
| 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 | |
| 843 | +``` | |
| 844 | + | |
| 845 | +That will push the image up to your account, so that you can then switch | |
| 846 | +to the remote machine and say: | |
| 847 | + | |
| 848 | +``` | |
| 849 | + $ sudo podman create \ | |
| 850 | + --any-options-you-like \ | |
| 851 | + docker.io/mydockername/fossil | |
| 852 | +``` | |
| 853 | + | |
| 854 | +This round-trip through the public image repository has another side | |
| 855 | +benefit: your local system might be a lot faster than your remote one, | |
| 856 | +as when the remote is a small VPS. Even with the overhead of schlepping | |
| 857 | +container images across the Internet, it can be a net win in terms of | |
| 858 | +build time. | |
| 859 | + | |
| 765 | 860 | |
| 766 | 861 | |
| 767 | 862 | ### <a id="nspawn"></a>`systemd-nspawn` |
| 768 | 863 | |
| 769 | 864 | As of `systemd` version 242, its optional `nspawn` piece |
| 770 | 865 |
| --- www/containers.md | |
| +++ www/containers.md | |
| @@ -760,10 +760,105 @@ | |
| 760 | |
| 761 | This suggests one method around the problem of rootless Podman containers: |
| 762 | `sudo crun`, following the examples above. |
| 763 | |
| 764 | [crun]: https://github.com/containers/crun |
| 765 | |
| 766 | |
| 767 | ### <a id="nspawn"></a>`systemd-nspawn` |
| 768 | |
| 769 | As of `systemd` version 242, its optional `nspawn` piece |
| 770 |
| --- www/containers.md | |
| +++ www/containers.md | |
| @@ -760,10 +760,105 @@ | |
| 760 | |
| 761 | This suggests one method around the problem of rootless Podman containers: |
| 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 |
| 773 | bunch of cryptic commands to get the same effect as a single command |
| 774 | under Podman. |
| 775 | |
| 776 | Fortunately, it’s easy enough to have it both ways. Simply run your |
| 777 | `podman` commands as root: |
| 778 | |
| 779 | ``` |
| 780 | $ sudo podman build -t fossil --cap-add MKNOD . |
| 781 | $ sudo podman create \ |
| 782 | --name fossil \ |
| 783 | --cap-drop AUDIT_WRITE \ |
| 784 | --cap-drop CHOWN \ |
| 785 | --cap-drop FSETID \ |
| 786 | --cap-drop KILL \ |
| 787 | --cap-drop NET_BIND_SERVICE \ |
| 788 | --cap-drop NET_RAW \ |
| 789 | --cap-drop SETFCAP \ |
| 790 | --cap-drop SETPCAP \ |
| 791 | --publish 9999:8080 \ |
| 792 | localhost/fossil |
| 793 | $ sudo podman start fossil |
| 794 | ``` |
| 795 | |
| 796 | It’s obvious why we have to start the container as root, but why create |
| 797 | and build it as root, too? Isn’t that a regression from the modern |
| 798 | practice of doing as much as possible with a normal user? |
| 799 | |
| 800 | We have to do the build under `sudo` in part because we’re doing rootly |
| 801 | things with the file system image layers we’re building up. Just because |
| 802 | it’s done inside a container runtime’s build environment doesn’t mean we |
| 803 | can get away without root privileges to do things like create the |
| 804 | `/jail/dev/null` node. |
| 805 | |
| 806 | The other reason we need “`sudo podman build`” is because it puts the result |
| 807 | into root’s Podman image repository, where the next steps look for it. |
| 808 | |
| 809 | That in turn explains why we need “`sudo podman create`:” because it’s |
| 810 | creating a container based on an image that was created by root. If you |
| 811 | ran that step without `sudo`, it wouldn’t be able to find the image. |
| 812 | |
| 813 | If Docker is looking better and better to you as a result of all this, |
| 814 | realize that it’s doing the same thing. It just hides it better by |
| 815 | creating the `docker` group, so that when your user gets added to that |
| 816 | group, you get silent root privilege escalation on your build machine. |
| 817 | This is why Podman defaults to rootless containers. If you can get away |
| 818 | with it, it’s a better way to work. We would not be recommending |
| 819 | running `podman` under `sudo` if it didn’t buy us [something we wanted |
| 820 | badly](#chroot). |
| 821 | |
| 822 | Notice that we had to add the ability to run `mknod(8)` during the |
| 823 | build. Unlike Docker, Podman sensibly denies this by default, which |
| 824 | lets us leave off the corresponding `--cap-drop` option. |
| 825 | |
| 826 | |
| 827 | ##### <a id="pm-root-workaround"></a>Building Under Docker, Running Under Podman |
| 828 | |
| 829 | If you have a remote host where the Fossil instance needs to run, it’s |
| 830 | possible to get around this need to build the image as root on the |
| 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 |
| 843 | ``` |
| 844 | |
| 845 | That will push the image up to your account, so that you can then switch |
| 846 | to the remote machine and say: |
| 847 | |
| 848 | ``` |
| 849 | $ sudo podman create \ |
| 850 | --any-options-you-like \ |
| 851 | docker.io/mydockername/fossil |
| 852 | ``` |
| 853 | |
| 854 | This round-trip through the public image repository has another side |
| 855 | benefit: your local system might be a lot faster than your remote one, |
| 856 | as when the remote is a small VPS. Even with the overhead of schlepping |
| 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 |