I want to deploy on my VPS a collection of services comprised of Docker containers with applications like nginx, prosody, postgresql. I’m going to use docker-compose for this task. All these containers will be using systemd user service providing daemon for Docker’s rootless mode.
Should I use regular administrator account I use for ssh and run docker compose up -d or create a separate system user like docker for this task?
Does creating a separate user per each LXC/Podman/Docker container have real security benefits in production servers when more security is more desired than convenience?
I’m a little confused. Rootless mode means you run the docker daemon as a non root user while processes in the container can still run processes as root from their point of view, except that is not a real root on the host under the daemon. That is for protecting your host machine as Docker running as root would have permission to mount system folders and if you don’t trust the image you use, or if you want o make sure not even bugs or hacked software can harm your host, you can use rootless mode.
But I don’t see wh you would want to run each container in a separate rootless docker daemon if that is what you meant by “separate user per each LXC/Podman/Docker container”. Than using Docker compose has a small benefit and your containers could not even communicate with eachother on Docker networks.
If you mean running processes in containers (rootless container) as a non-root user, that is generally recommended unless you need something in the container that can be executed only as root.
Note that rootless mode has its own limitations so whether it works for you depends on your project
Could you clarify what you mean? rootless docker indeed runs under your user’s systemd, but containers are not “using” systemd unless you install systemd in the container which is not recommended usually and could be tricky
I mean there will be running docker.service systemd user service on the host necessary to run containers inside Docker in rootless mode, not systemd inside containers. Putting it simply, I want to use Docker rootless mode.
Can you tell if it’s better to run all Docker containers under the non-root user I use for administrating server through ssh, on which I run sudo <command> or create a separate docker user for running containers using Docker rootless mode?
Test your app with rootless Docker. If it works and you have no problem with the limitations I linked, you can do it on the server. If rootless was always the best, it would be the default, but it isn’t. I don’t recommend starting with Rootless mode in production if you have no experience in it, but you should definitely learn about it.
Alternative approach is using user namespaces which is part of the rootless mode as well, but your daemon could still run as root The usernamespace support was recently added to Kubernetes as well. Even if a container tries to mount a system folder it won’t be able to write it or not even read it depending on the permission flags on the file. And the daemon cans till use the standard network driver and even host network if necessary. Configuring rootless mode is much more challenging.
Running system-wide docker daemon seems to me a bit unsecure way compared to the way how podman handles containers or lxc in unprivileged mode. I want to run docker containers on server with public IP, not on development machine.
I think you are still referring to rootless containers in LXC. Even podman requires root access when you want to use features that are available only for root. For example publishing services on privileged ports like port 80 or 443. One difference is that Docker has a daemon process so your user running docker client commands could be a non-root user while restricting what API calls that user can send to the daemon.
It doesn’t happen by default, that is why running the docker daemon as root could be risky when you have untrusted users even if you are not afraid of hacked software running in containers started by rootful Docker. If you are the only user managing Docker containers or you have others with admin privileges, you only have to worry about what the containers can do. A container could be dangerous if you mount system folders or give too many capabilities to the container so the process can break out from the container. The risk is much much lower when you drop unnecessary capabilities and use user namespaces which is used for the unprivileged LXC containers if I’m not mistaken.
But again, if you test what you want to run, you can choose rootless Docker. Then you would need to add SSH access to container rmanagers to that user. If you already ran the containers with Podman, rootless Docker will likely work too.
My point is that we cannot decide it for you. It depends on your needs and expertise.
What danger do you see in running the daemon as root when container processes are running as non-root? Assuming of course that you don’t mount any system folder and don’t add extra privileges to the container or evend rop the unnecessary ones.
I’m afraid of potential vulnerabilities in hosted stuff like web applications and script kiddies trying to do some stuff like sql injection attacks. I want to host things like web stuff, prosody on vps. I’m the only administrator of my server
That has almost nothing to do with how the daemon is running. Please, use the link I shared and learn about the concept of “rootless mode” (Rootless Docker) and “Rootless container”
I also recommend this third link from the documentation that refers to Rootless mode as well, but also capabilities.
The main systemd with PID 1 runs as root and that doesn’t make your entire operating system unsecure. It is just necessary but it can start processes as non-root like processes that allow you to log in. Docker daemon does that too. Needs root access for special operations which can be necessary for your goals or not. If not and you feel more safe by running Rootless Docker, then you can doo that. If you encounter any issues while running rootless Docker, you can still feel safe by making sure you only allow trusted users logging in to the host machine and using user namespaces so no pocesses inside containers will have real root user.
In fact, the root user inside the container will only have the permissions of the non-root user that you configure for the host, except it will “feel” to be root inside the container, not outside.
If that is not enough, you could drop capabilities,
I’m new in Docker and I’ve recently started playing with it. I know only basics like how to create volumes, bind mounts, write Dockerfile. The main motivation to learn Docker was testing my Python application inside clean isolated environment with its own libraries etc. The idea of trying to apply the knowledge how the basic commands and Dockerfile works to containerize stuff on my VPS came further.
Thank you anyway for helpful answers. I’ll try to do things like using user namespaces gradually when I grasp more understanding how exactly each docker command and mechanisms work.
if the application does not require writing files, make sure you run your container with a read-only file system (e.g. when the data is stored in a database external to this container).
if you need to write files into the container file system, make sure to mount a volume into the container path to persist data outside the container file system.
make sure to drop all capabilities, and only add those absolutely required by you app to work. Start off with providing no capability at all
make sure your container starts as unprivileged user.
make sure your container does not start as a privligied container.
avoid including a package manager, or tools that can be used for downloads like curl and wget in your final image.
run vulnerability scanners on your image regularly (e.g. with Docker Scout), patch dependencies and build your image to get rid of vulnerabilities frequently (e.g. with Renovate)
-use a hardened base image if possible (e.g. one from dhi.io).