Skip Navigation

What's the deal with Docker?

I never understood how to use Docker, what makes it so special? I would really like to use it on my Rapsberry Pi 3 Model B+ to ease the setup process of selfhosting different things.

I'm currently running these things without Docker:

  • Mumble server with a Discord bridge and a music bot
  • Maubot, a plugin-based Matrix bot
  • FTP server
  • Two Discord Music bots

All of these things are running as systemd services in the background. Should I change this? A lot of the things I'm hosting offer Docker images.

It would also be great if someone could give me a quick-start guide for Docker. Thanks in advance!

98 comments
  • There have been some great answers on this so far, but I want to highlight my favourite part of Docker: the disposability.

    When you have a running Docker container, you can hop in, fuck about with files, break stuff as you try to figure something out, and then kill the container and all of the mess you've created is gone. Now tweak your config and spin up a fresh one exactly the way you need it.

    You've been running a service for 6 months and there's a new upgrade. Delete your instance and just start up the new one. Worried that there might be some cruft left over from before? Don't be! Every new instance is a clean slate. Regular, reproducible deployments are the norm now.

    As a developer it's even better: the thing you develop locally is identical to the thing that's built, tested, and deployed in CI.

    I <3 Docker!

  • I feel that a lot of people here are missing the point. Docker is popular for selfhosted services for a few main reasons:

    1. It is one package that can be used on any distribution (or even OS with a Linux VM).
    2. The package contains all dependencies required to run the software so it is pretty reliable.
    3. It provides some basic sandboxing against non-malicious services. Basically the service can't scribble all over your filesystem. It can only write to specific directories that you have given it access to (via volumes) other than by exploiting security vulnerabilities.
    4. The volume system also makes it very obvious what data is important and needs to be backed up or similar, you have a short list.

    Docker also has lots of downsides. I would generally say that if your distribution packages software I would prefer the distribution's package over the docker image. A good distribution package will also solve all of these problems. The main issue you will see with distribution packages is a longer delay before new versions are made available.

    What Docker completely dominates was previous cross-distribution packaging options which typically took one of the previous strategies.

    1. Self-contained compiled tarball. Run the program inside as your user. It probably puts its data in the extracted directory, maybe. How do you upgrade? Extract and copy a data directory? Self-update? Code is mutable and mixed with data, gross.
    2. Install script. Probably runs as root. Makes who-knows what changes to your system. Where is the data, is the service running? Will it auto-start on boot. Hope that install script supports your distro.
    3. Source tarball. Figure out the dependencies. Hope they don't conflict with the versions your distro has. Set up users and setup scripts yourself. Hope the build doesn't take too long.
  • When I asked this question

    So there are many reasons, and this is something I nowadays almost always do. But keep in mind that some of us have used Docker for our applications at work for over half a decade now. Some of these points might be relevant to you, others might seem or be unimportant.

    • The first and most important thing you gain is a declarative way to describe the environment (OS, dependencies, environment variables, configuration).
    • Then there is the packaging format. Containers are a way to package an application with its dependencies, and distribute it easily through the docker hub (or other registries). Redeploying is a matter of running a script and specifying the image and the tag (never use latest) of the image. You will never ask yourself again "What did I need to do to install this again? Run some random install.sh script off a github URL?".
    • Networking with docker is a bit hit and miss, but the big thing about it is that you can have whatever software running on any port inside the container, and expose it on another port on the host. Eg two apps run on port :8080 natively, and one of them will fail to start due to the port being taken. You can keep them running on their preferred ports, but expose one on 18080 and another on 19080 instead.
    • You keep your host simple and empty of installed software and packages. Less of a problem with apps that come packaged as native executables, but there are languages out there which will require you to install a runtime to be able to start the app. Think .NET, Java but there is also Python out there which requires you to install it on the host and have the versions be compatible (there are virtual environments for that but im going into too much detail already).

    I am also new to self hosting, check my bio and post history for a giggle at how new I am, but I have taken advantage of all these points. I do use "latest" though, looking forward to seeing how that burns me later on.

    But to add one more:- my system is robust, in that I can really break my containers (and I do), and to recover is a couple clicks in Portainer. Then I can try again, no harm done.

    • The thing with using the "latest" tag is you might get lucky and nothing bad happens (the apps are pretty stable, fault tolerant, and/or backward compatible), but you also might get unlucky and a container update does break something (think a 1.x going to 2.x one day). Without pinning the container to a specific version, you might have an outage suddenly due to that container becoming incompatible with one of your other applications. I've seen this happen a number of times. One example is a frontend (UI) container that updates to no longer be compatible with older versions of the backend and crashes as a result.

      If all your apps are pretty much standalone and you trust them to update properly every time a new version of the container is downloaded, then you may never run into the problems that make people say "never use latest". But just keep an eye out for something like that to happen at some point. You'll save yourself some time if you have records of what versions are running when everything's working, and take regular backups of all their data.

      • I guessed it was a "once bitten twice shy" kind of thing. This is all a hobby to me so the cost-benefit, I think, is vastly different, nothing on my setup is critical. Keeping all those records and up to date on what version everything is on, and when updates are available and what those updates do and... sound like a whole lot of effort when currently my efforts can be better spent in other areas.

        In my arrogance I just installed Watchtower, and accepted it can all come crashing down. When that happens I'll probably realise it's not so much effort after all.

        That said I'm currently learning, so if something is going to be breaking my stuff, it's probably going to be me and not an update. Not to discredit your comment, it was informative and useful.

      • I used to have this with homeassistant and zwavejs. Every time I'd pull a new homeassistant, the zwave integration would fail, because it required a newer version of zwavejs. Taught me to build the chain of services into one docker-compose, so they'd all update together. That's become one of the rationales for me to use docker: got a chain of dependent processes? wrap them in a docker so you're working with (probably) the same dependencies as the devs.

        My other rationale is just portability, and docker is just one of many solutions there. In my little home environment, where servers are either retired desktops or gee-that-seems-cool SBCs, it's nice to be able to easily move stuff independent of architecture or OS.

  • The thing that confused me when first learning about docker was, that everybody compares it to a virtual machine. It's not. Containers dont virtualize anything. They take a (single) process from the host OS and separate that into its own environment. All system calls, memory access, file writes etc are still handled by the same os (same kernel). However the process is separated both on the file system and process level. It can't see other processes outside of the container and it also doesn't see the real filesystem. It sees a filesystem provided by the container. This also means it sees different file and user permissions. When you run a alpine Linux docker container on an Ubuntu system, the container only containes the (few) files for alpine but no Linux kernel no desktop environment. A process inside that container only sees the alpine files and not the Ubuntu files. It also means all containers see a filesystem independent of each other and can use libraries and dependencies of different versions (they are only files after all).

    For administration it makes running complex services easy. You define how to setup that service (what base Linux distro to use, what packages to install, what commands to run, and how to start the process). You can then be save to assume the setup of that service did not interfere with the setup of any other service. "Service 1 needs a certain system wide config changed? Service 2 needs that config in the default state? And both need a different version of the same library?" In containers you can have all at the same time because they each see a different version of the same config and library.

    And all this is provided by the kernel itself. All docker does is provide an "easy" way to create and manage containers but could could do all of that using chroot, runc and a few other.

    As a note, containers usually don't come with systemd as they don't need an init system. You would run the service directly inside the container and then use systemd outside the container to make sure the container is started/restarted, or just docker as it can already do that.

    I found a great article demystifying containers recently

    • While you are technically right there is very little logical difference between containers and VMs. Really the only fundamental difference is that containers use the same kernel while VMs run their own. (let's not even worry about para-virtualization right now).

      In practice I would say the biggest difference is that there is better memory sharing so total memory usage will often be less. But honestly this mostly comes down to the fact that the average container bundles less software than the average VM image. Easier management of volumes is also nice because typically you will just bind-mount a host directory, but it also isn't hard to mount a block device on a Linux host.

  • I started self-hosting a bit prior to when Docker took off, and getting multiple services running was much harder. Service A wants a certain version of PHP installed with certain plugins while Service B wants a different version. You'd follow a tutorial for installing Service C and desperately hope that it wouldn't somehow break Service A or B. You installed Service D for a bit despite all the installation pain and now want to uninstall it - I hope you tracked exactly what config changes you made throughout the system so you can undo it.

    Docker fixed all of this by making each service independent through containers which made self-hosting 10x easier. I'd also add that I love how easy it is to transfer my setup to a new server - I keep all of my container volumes in a specific directory and my docker-compose files in another and that's all I need to backup / transfer. Without Docker you'd have to specifically handle each & every configuration file and database location, and if you later upgrade to a newer version of the OS or a different distro you'd have to handle possible conflicts between your versions and what the distro expects.

  • Docker is amazing but not needed. You can compare it to a simpler VM. You can take a docker and run it on any machine. You have an environment that is separate from your host and you and the container can only access it via defined points (volumes and ports).

    Imagine you need to run a 2nd Mumble Server. I never set on up but its often that a 2nd instance is not that easy. With docker its easy. The only difference is that you need to use different ports, when you have only one network access or you use a reverse proxy. You can create a 2nd instance to test stuff, without interrupting your productive system. Its a security benefit, because its isolated to some degree and you can remove one easily.

    I started using it with MSSQL Server, because I hated how invasive it is on a windows machine, especially I just needed it temporarily to do stuff with it. I'm not a microsoft admin and I know that Servers from Microsoft are a different level. Docker allowed me to start and stop it and remove it very easily. After that I started using it for a lot of and brought my NAS on the next level.

    Also one thing worth mentioning are Linux Containerx (LXC). They are in Proxmox but I have less knowledge. It feels more like a full VM than docker but uses less resources. This is the reason why containers in general are more popular. They are less resource hungry than a full VM but have some benefits than running everything on one machine. LXC feels more like a full system, than docker. With docker you rarely get into the system. You may execute some commands, like a create user command or a one time job but don't access it via a shell from the inside (its possible). LXC on the other hand, you use the shell.

  • Docker of one version of software that uses Linux containers to encapsulate software and that software's dependencies, while limiting that software's access to the underlying OS. It's chroot, but for more of the system. It can make running software that has a lot of moving parts and dependencies easier. It can also improve your security running that software.

    For how-tos, watch one of the 875,936 YouTube tutorials, or read one of the 3 million text tutorials. Or ask ChatGPT, if you really need hand-holding.

  • The thing with Docker is that people don't want to learn how to use Linux and are buying into an overhyped solution that makes their life easier without understanding the long term consequences. Most of the pro-Docker arguments go around security and that's mostly BS because 1) systemd can provide as much isolation a docker containers and 2) there are other container solutions that are at least as safe as Docker and nobody cares about them.

    Companies such as Microsoft and GitHub are all about re-creating and reconfiguring the way people develop software so everyone will be hostage of their platforms. We see this in everything now Docker/DockerHub/Kubernetes and GitHub actions were the first sign of this cancer. We now have a generation that doesn’t understand the basic of their tech stack, about networking, about DNS, about how to deploy a simple thing into a server that doesn’t use some Docker BS or isn’t a 3rd party cloud xyz deploy-from-github service.

    Before anyone comments that Docker isn’t totally proprietary and there’s Podman consider the following: It doesn’t really matter if there are truly open-source and open ecosystems of containerization technologies. In the end people/companies will pick the proprietary / closed option just because “it’s easier to use” or some other specific thing that will be good on the short term and very bad on the long term.

    Docker may make development and deployment very easy and lowered the bar for newcomers have the dark side of being designed to reconfigure and envelope the way development gets done so someone can profit from it. That is sad and above all set dangerous precedents and creates generations of engineers and developers that don’t have truly open tools like we did. There's LOT of money into transitioning everyone to the "deploy-from-github-to-cloud-x-with-hooks" model so those companies will keep pushing for it.

    Note that technologies such as Docker keep commoditizing development - it’s a negative feedback loop that never ends. Yes I say commoditizing development because if you look at it those techs only make it easier for the entry level developer and companies instead of hiring developers for their knowledge and ability to develop they’re just hiring “cheap monkeys” that are able to configure those technologies and cloud platforms to deliver something. At the end of the they the business of those cloud companies is transforming developer knowledge into products/services that companies can buy with a click.

    • Most of the pro-Docker arguments go around security

      Actually Docker and the success of containers is mostly due to the ease of shipping code that carries its own dependencies and can be run anywhere. Security is a side-effect and definitely not the reason why containers picked-up.

      systemd can provide as much isolation a docker containers and 2) there are other container solutions that are at least as safe as Docker and nobody cares about them.

      Yes, and it's much harder to achieve the same. In systemd you need to use 30 different options to get what using containers you achieve almost instantly and with much less hussle. I made an example on my blog where I decided to run blocky in Systemd and not in Docker. It's just less convenient and accessible, harder to debug and also relies on each individual user to do it, while with containers a lot gets packed into the image and therefore harder to mess up.

      Docker isn’t totally proprietary

      There are a many container runtimes (CRI-O, podman, mirantis, containerd, etc.). Docker is just a convenient API, containers are fully implemented just with Linux native features (namespaces, seccomp, capabilities, cgroups) and images follow an open standard (OCI).

      I will avoid comment what looks like a rant, but I want to simply remind you that containers are the successor of VMs (virtualize everything!), platforms that were completely proprietary and in the hands of a handful of vendors, while containers use only native OS features and are therefore a step towards openness.

      • Docker and the success of containers is mostly due to the ease of shipping code that carries its own dependencies and can be run anywhere

        I don't disagree with you, but that also shows that most modern software is poorly written. Usually a bunch of solutions that hardly work and nobody is able to reproduce their setup in a quick, sane and secure way.

        There are a many container runtimes (CRI-O, podman, mirantis, containerd, etc.). Docker is just a convenient API, containers are fully implemented just with Linux native features (namespaces, seccomp, capabilities, cgroups) and images follow an open standard (OCI).

        Yes, that's exactly point point. There are many options, yet people stick with Docker and DockerHub (that is everything but open).

        In systemd you need to use 30 different options to get what using containers you achieve almost instantly and with much less hussle.

        Yes... maybe we just need some automation/orchestration tool for that. This is like saying that it's way too hard to download the rootfs of some distro, unpack it and then use unshare to launch a shell on a isolated namespace... Docker as you said provides a convenient API but it doesn't mean we can't do the same for systemd.

        but I want to simply remind you that containers are the successor of VMs (virtualize everything!), platforms that were completely proprietary and in the hands of a handful of vendor

        Completely proprietary... like QEMU/libvirt? :P

      • but I want to simply remind you that containers are the successor of VMs

        Successor implies replacement. I think containers are another tool in the toolkit of servers/hosting, but not a replacement for VMs

98 comments