Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
gentoo:containers [2024/02/05 13:45] – willy | gentoo:containers [2025/03/13 13:25] (current) – [Using Containers on Gentoo] willy | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Using Containers on Gentoo ====== | + | ====== |
- | Containers are a great tool that caters to some specific, and important, needs. But be aware that // | + | Containers are a great tool that caters to some specific, and important, needs. But be aware that // |
- | Bear in mind, always, that **containers** while being an astounding piece of technology, are **NOT** meant and have **NOT** been created with self-hosting in mind. | + | Bear in mind, always, that **containers** while being an astounding piece of technology, are **NOT** meant and have **NOT** been created with self-hosting in mind. Since it's easy and simple to use them for self-hosting, |
Containerization technology can roughly be divided into two big categories: | Containerization technology can roughly be divided into two big categories: | ||
Line 15: | Line 15: | ||
* For developers, it's easier to provide a // | * For developers, it's easier to provide a // | ||
- | But are these really positive points of containers? | + | I am realizing more and more the added value of using containers, so i have changed my mind over time. I still think there are negative points |
- | + | ||
- | Now, let's see the negative points | + | |
* All services running as //root// (against Linux policies) | * All services running as //root// (against Linux policies) | ||
* Lots of duplicated services (how many postgress databases have you running around?) | * Lots of duplicated services (how many postgress databases have you running around?) | ||
- | * You don't understand what's going on | ||
* You don't learn anything new deploying your services | * You don't learn anything new deploying your services | ||
* When it breaks, it breaks hard because you don't know what broke | * When it breaks, it breaks hard because you don't know what broke | ||
Line 26: | Line 23: | ||
* It's back to Windows approach: black boxes everywhere that you can only roll-back or reinstall | * It's back to Windows approach: black boxes everywhere that you can only roll-back or reinstall | ||
- | Granted, all this **could** be fixed by fixing the docker images and maybe fixing your docker-compose files to improve things a bit, but who is really doing that? Wouldn' | + | In short, the spreading usage of Docker in the self-hosting world bring to Linux some bad practices and philosophy of the Windows world. Is this really necessary? Do we really want to become forced to be idiot-users who don't know any better? Is this really what means to be Linux users? |
- | + | ||
- | In short, the spreading usage of Docker in the self-hosting world bring to Linux the very worst practices and philosophy of the Windows world. Is this really necessary? Do we really want to become forced to be idiot-users who don't know any better? Is this really what means to be Linux users? | + | |
Question for your thoughts, now let's see how, at least, to use containers in a slightly better way. | Question for your thoughts, now let's see how, at least, to use containers in a slightly better way. | ||
Line 34: | Line 29: | ||
==== " | ==== " | ||
- | I prefer to avoid containers at all. But we are already at the point where some services are provided **only** as containers, and this is what i think the the **worse possible outcome** of this using containers more and more. **Where is the choice?** Why would i be forced to use some semi-proprietary technology to deploy Open Source services? | + | We are already at the point where some services are provided **only** as containers, and this is what i think the the **worse possible outcome** of this using containers more and more. **Where is the choice?** Why would i be forced to use some semi-proprietary technology to deploy Open Source services? |
I think that this is a trend that should be stopped. Please do provide containers and docker files, it's good and why not, but always also support bare-metal installations which means, please always provide **binary distributions** and **installation instructions** because without those, we will be nothing better than idiot-users and your service cannot be really called //open//. | I think that this is a trend that should be stopped. Please do provide containers and docker files, it's good and why not, but always also support bare-metal installations which means, please always provide **binary distributions** and **installation instructions** because without those, we will be nothing better than idiot-users and your service cannot be really called //open//. | ||
- | |||
===== Docker ===== | ===== Docker ===== | ||
Line 66: | Line 60: | ||
Overall **Podman** is much more adherent to the Linux/Unix way of doing things. | Overall **Podman** is much more adherent to the Linux/Unix way of doing things. | ||
- | Installing Podman is pretty easy since it's in Portage repository, but let's enable docker wrapper: | + | Installing Podman is pretty easy since it's in Portage repository, but let's enable docker wrapper |
<code bash> | <code bash> | ||
- | > | + | echo " |
- | > emerge podman | + | emerge |
</ | </ | ||
Line 85: | Line 79: | ||
which i suggest to run as un-priviledged user to verify everything is working as non-root too. | which i suggest to run as un-priviledged user to verify everything is working as non-root too. | ||
- | Now, install **podman-compose** | + | Now, install **podman-compose**, and thanks to a few user contributed inputs (see [[https:// |
+ | <code bash> | ||
+ | emerge -vp podman-compose | ||
+ | </ | ||
- | Follow my [[gentoo: | + | beware that it might be masked for your arch, in this case, just unmask it with your keyword, ex ~amd64. |
- | <file - podman-compose-1.0.6.ebuild> | + | |
- | # Copyright 2024 Gentoo Authors | + | |
- | # Distributed under the terms of the GNU General Public License v2 | + | |
- | EAPI=8 | + | === Podman rootless users === |
- | DISTUTILS_USE_SETUPTOOLS=rdepend | + | When running a container rootless, which is the main point behind Podman, you might end up having some issues with user IDs. |
- | PYTHON_COMPAT=( python3_{10..11} ) | + | |
- | inherit distutils-r1 | + | [[https:// |
- | DESCRIPTION=" | + | In short: when running rootless, the //user 0//, or root, of the container, will be mapped to your user ID, and any //additional// user will be remapped according to the content of **/etc/subuid** and **/ |
- | HOMEPAGE=" | + | |
- | SRC_URI=" | + | |
- | # | + | |
- | LICENSE=" | + | The easiest way to fix it, is to force your container to run... **as user 0**! In fact, since we are using rootless podman, that only means **as your own user** nad not actually root. |
- | SLOT="0" | + | |
- | KEYWORDS=" | + | |
- | DEPEND="" | + | |
- | RDEPEND=" | + | ==== Podman networks ==== |
- | ${DEPEND} | + | |
- | | + | Since you want to run containers as non-root, you need to create as root the networks. My approach is to create one subnetwork for each group of containers, and each group of containers will run a non-root user. |
- | | + | |
- | " | + | To create a Podman subnet you need to run the following command after each reboot, as root: |
- | BDEPEND="" | + | <code bash> |
+ | podman network create my-container-net | ||
+ | </ | ||
+ | |||
+ | Inside your // | ||
+ | < | ||
+ | services: | ||
+ | | ||
+ | environment: | ||
+ | .... | ||
+ | ports: | ||
+ | - xxx:yyy | ||
+ | volumes: | ||
+ | - my-volume:/ | ||
+ | networks: | ||
+ | - my-container-net | ||
+ | |||
+ | .... | ||
+ | |||
+ | networks: | ||
+ | my-container-net: | ||
+ | </ | ||
+ | |||
+ | I strongly suggest that you edit your docker compose files and ensure each service has it's own independent network. I will give more details for each service on it's respective page. | ||
+ | |||
+ | |||
+ | ==== Podman containers autostart ==== | ||
+ | |||
+ | Autostarting containers is pretty easy if you use SystemD, but even if you don't, and i don't, it's easy enough too. | ||
+ | |||
+ | <file - / | ||
+ | # | ||
+ | # Copyright 2024 Willy Garidol | ||
+ | # Distributed under the terms of the GNU General Public License v3 | ||
+ | |||
+ | depend() { | ||
+ | need localmount net | ||
+ | } | ||
+ | |||
+ | UC_LOG_PATH=/ | ||
+ | UC_SLOT="${SVCNAME# | ||
+ | UC_USER=${USER: | ||
+ | UC_COMPOSER_FILE=${COMPOSER_FILE: | ||
+ | UC_CHOWN_DIR=${CHOWN_DIR} | ||
+ | if [ "${UC_SLOT}" | ||
+ | then | ||
+ | | ||
+ | fi | ||
+ | |||
+ | extra_commands=" | ||
+ | update() { | ||
+ | | ||
+ | then | ||
+ | COMMAND=" | ||
+ | stop | ||
+ | ebegin " | ||
+ | su - ${UC_USER} -c " | ||
+ | start | ||
+ | else | ||
+ | ebegin " | ||
+ | eend 255 | ||
+ | fi | ||
+ | } | ||
+ | |||
+ | description=${DESCRIPTION: | ||
+ | pidfile=" | ||
+ | |||
+ | start_pre() { | ||
+ | if [ "${UC_SLOT}" != " | ||
+ | | ||
+ | test -e " | ||
+ | test -e " | ||
+ | mkdir " | ||
+ | } && chown -R ${UC_USER} " | ||
+ | if [ -n "${UC_CHOWN_DIR}" | ||
+ | | ||
+ | chown -R ${UC_USER} ${UC_CHOWN_DIR} | ||
+ | fi | ||
+ | else | ||
+ | ebegin " | ||
+ | eend 255 | ||
+ | fi | ||
+ | } | ||
+ | |||
+ | |||
+ | start() { | ||
+ | ebegin " | ||
+ | COMMAND="$(which podman)" | ||
+ | ARGUMENTS=(compose -f ${UC_COMPOSER_FILE} up) | ||
+ | ebegin " ... ensuring nat table is loaded ..." | ||
+ | iptables -L -t nat &> /dev/null | ||
+ | ebegin " ... creating ' | ||
+ | podman network create ${UC_SLOT}-net &> /dev/null | ||
+ | su - " | ||
+ | start-stop-daemon -p ${pidfile} \ | ||
+ | -1 " | ||
+ | -2 " | ||
+ | -u ${UC_USER} \ | ||
+ | -d ${UC_HOME} \ | ||
+ | -b -m \ | ||
+ | --start | ||
+ | -- ${ARGUMENTS[@]} | ||
+ | eend $? | ||
+ | } | ||
+ | |||
+ | stop() { | ||
+ | ebegin " ... running ' | ||
+ | su - " | ||
+ | start-stop-daemon -p ${pidfile} \ | ||
+ | -u ${UC_USER} \ | ||
+ | -d ${UC_HOME} \ | ||
+ | --stop ${UC_SLOT} | ||
+ | eend $? | ||
+ | } | ||
</ | </ | ||
- | as //app-containers/ | + | I assume you have a**service_name** that runs with a podman compose file as user **myuser**. |
+ | |||
+ | Just link the above script to your new service file: | ||
+ | <code bash> | ||
+ | ln -s /etc/init.d/user-containers /etc/ | ||
+ | </code> | ||
+ | |||
+ | and create | ||
+ | <file - /etc/conf.d/ | ||
+ | USER=myuser | ||
+ | DESCRIPTION=" | ||
+ | </file> | ||
+ | |||
+ | and add the service to your desired runlevel: | ||
+ | <code bash> | ||
+ | rc-update add user-containers.service_name default | ||
+ | </ | ||
+ | |||
+ | That's it. | ||
- | I hope that this ebuild | + | The above script also provide an " |
Line 134: | Line 253: | ||
* always run Podman as unpriviledged user | * always run Podman as unpriviledged user | ||
* Podman containers are not restarted at boot: i will give you instructions for those services as needed. | * Podman containers are not restarted at boot: i will give you instructions for those services as needed. | ||
- | * | + | * Networks needs to be explicitly declared and created as root. |
+ | |||
==== Migration from Docker to Podman ==== | ==== Migration from Docker to Podman ==== | ||
Line 145: | Line 266: | ||
> chown service: | > chown service: | ||
</ | </ | ||
+ | |||
+ | At this point you might want to edit the //network// part of the docker compose file according to what i wrote above. | ||
Now, most probably all you need to do is the classic (but rewritten): | Now, most probably all you need to do is the classic (but rewritten): | ||
Line 153: | Line 276: | ||
and enjoy. | and enjoy. | ||
+ | |||
+ | (remember to create the network, as root) | ||
=== Migrating Images Podman === | === Migrating Images Podman === | ||
- | |||
If you need to export your images from Docker to Podman (you don't if they are public images), as root, export all docker images relevant to your service (you can see them in the composer file), use //docker image ls// to list images and //docker save -o ...// to save each one of them as a tar file: | If you need to export your images from Docker to Podman (you don't if they are public images), as root, export all docker images relevant to your service (you can see them in the composer file), use //docker image ls// to list images and //docker save -o ...// to save each one of them as a tar file: | ||
Line 215: | Line 339: | ||
This can be made permanent in **/ | This can be made permanent in **/ | ||
- | - Podman containers are not restarted at boot. To achieve the same behaviour as Docker, my suggestion is to create a startup file under **/etc/local.d/** where you **su** as your unpriviledged user and simply do a **podman compose up**, that's it. | + | - Podman containers are not restarted at boot. To achieve the same behaviour as Docker, my suggestion is to follow my lead on leveraging |
- | + | ||
+ | If you want to do things manually, just keen in mind that you need to ensure **nat** ip-table is loaded. While it is not used by podman, it seems to be necessary somehow to exist: | ||
+ | < | ||
+ | modprobe iptable_nat | ||
+ | iptable -L -t nat | ||
+ | </ | ||