Hi everyone,
Does anyone know how can I use “snap” in Dockerfile? RUN snap install firefox
My guess would be that i need to (somehow) add /run/snapd.socket: volume to build command. Can anybody help please how to do that?
$ cat Dockerfile
FROM ubuntu:22.04
RUN apt-get update -y && apt-get install snapd -y && apt-get install xauth -y
RUN snap install firefox
CMD ["/usr/bin/firefox"]
$ docker build . -t my-app:1.0
[+] Building 60.5s (6/6) FINISHED
=> [internal] load build definition from Dockerfile 0.1s
=> => transferring dockerfile: 185B 0.0s
=> [internal] load .dockerignore 0.1s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/ubuntu:22.04 1.3s
=> [1/3] FROM docker.io/library/ubuntu:22.04@sha256:0bced47fffa3361afa981854fcabcd4577cd43cebbb808cea2b1f33a3dd7f508 6.3s
=> => resolve docker.io/library/ubuntu:22.04@sha256:0bced47fffa3361afa981854fcabcd4577cd43cebbb808cea2b1f33a3dd7f508 0.0s
=> => sha256:0bced47fffa3361afa981854fcabcd4577cd43cebbb808cea2b1f33a3dd7f508 1.13kB / 1.13kB 0.0s
=> => sha256:b060fffe8e1561c9c3e6dea6db487b900100fc26830b9ea2ec966c151ab4c020 424B / 424B 0.0s
=> => sha256:5a81c4b8502e4979e75bd8f91343b95b0d695ab67f241dbed0d1530a35bde1eb 2.30kB / 2.30kB 0.0s
=> => sha256:3153aa388d026c26a2235e1ed0163e350e451f41a8a313e1804d7e1afb857ab4 29.53MB / 29.53MB 3.6s
=> => extracting sha256:3153aa388d026c26a2235e1ed0163e350e451f41a8a313e1804d7e1afb857ab4 2.4s
=> [2/3] RUN apt-get update -y && apt-get install snapd -y && apt-get install xauth -y 52.0s
=> ERROR [3/3] RUN snap install firefox 0.6s
------
> [3/3] RUN snap install firefox:
#0 0.478 error: cannot communicate with server: Post "http://localhost/v2/snaps/firefox": dial unix /run/snapd.socket: connect: no such file or directory
------
Dockerfile:3
--------------------
1 | FROM ubuntu:22.04
2 | RUN apt-get update -y && apt-get install snapd -y && apt-get install xauth -y
3 | >>> RUN snap install firefox
4 | CMD ["/usr/bin/firefox"]
5 |
--------------------
ERROR: failed to solve: process "/bin/sh -c snap install firefox" did not complete successfully: exit code: 1
I wouldn’t even try it. Snap requires systemd and not just requires it, systemd has to run as the first process. Even if you solve that (which is challenging itself), snap requires capabilities to manage linux kernel namespaces. It would be like Docker in Docker which exists, but in that case the Docker daemon is the first process and it doesn§t require systemd. Maybe you could run snapd as the first process as you would do with the Docker daemon, but you can’t use the snap command until the daemon is running and you can’t start snapd during the build, only maybe in same very nasty way in a single layer (single RUN instruction) so you can’t install firefox.
We say it very often, because it is true and important to know. A container is NOT a virtual machine and it shouldn’t be used like that. The other thing that I say sometimes is that if you want to use a container similarly to a virtual machine, use LXD and run a full operating system with Systemd in it in an LXC container. Docker was not designed for that. It is for running a single process or a couple of processes with a process manager as the first process.
It is probably unclear in my opening post why I am asking for “snap” in Dockefile and it is NOT that I want to use Docker container as VM
In future Ubuntu releases, Canonical will be pushing more and more apps to “snap”.
Firefox is know snap app in ubuntu 20.04.
The reason is: I wanted to test/check how Docker deals with “snap”.
From your answer I understand it does not allow any “snap” installs (at least not any official ways).
Side question: does that mean that in future Ubuntu should be avoided as Docker image (due to migrating to snap)?
No. The Docker way for installing softwares was never the package manager and we usually don’t install graphical apps in containers. The package manager is fine for libraries and since I don’t want to build an entire operating system from scratch, I wouldn’t build a library from source unless there is security issue. However, when we want to install an application we often build it from source code or download a specific version. You can check official images like the Apache HTTPD image
Some other images are indeed built using the package manager but not from the repository of the Linux distribution but the repository of the product. An example is the Nginx image
Ubuntu can switch to Snap in desktop operating systems, but you can still download the softwares from other sources. In case of firefox, you can download the latest release as an archive from here for Linux:
then you can extract it and move to its final location
You might need to find out what libraries it needs if not included in the archive.
Or you can use another container that runs Firefox based on another Operating system. I for example like the one created by LinuxServer.io: https://hub.docker.com/r/linuxserver/firefox
You can share the network namespaces or volumes with other containers so you can use it even for accessing services inside another container listening on localhost.
In my previous post i was trying to underline that i do NOT have intention of using any graphical apps in Docker container.
But I see that Firefox was very unfortunate example of what I wanted to ask.
Thanks anyway for your answer.
It is new to me that package managers is not the way to install software in the images (but I am also very fresh to Docker).
Still, I have question to the logic/way of not using package managers:
in future, when Ubuntu is fully switched to Snap, how will you install all dependencies required for package that you install outside of distribution repo?
I am not sure if I share that view. Though, I agree that we often end up in a situation where no package is available, or the package is outdated.
If a repository provides the package → add the repo to your repo list and install the package
if a package exists, but it’s not in a repository → download the package and install it manually
if a downloadable release exists → download it and optionally extract it,
If none of this exists → download or clone the sources and build the binaries yourself
Of course each of these options needs to be automated with commands, so it can be done inside a RUN instruction of a Dockerfile.
Like @rimelek said, snap is not suited for containers as it’s deeply tied into the system, and after all a container is just an isolated process: a container doesn’t boot, and does not start any os services like a normal os would do, which makes it restricted compared to a full os.
Even if snap would run, there is no guarantee that a snap installs all required dependencies. Try to install the intellij snap on a fresh system… it will not start, unless you manually install the required dependencies using apt.
I wouldn’t care so much whether a package exists or not (I would consider a snap package as not existing in this scenario). We already have the situation today where the desired packages don’t exist, and Docker Hub is still full of container images for various os flavors where people managed to build images for it anyway.
I admit, my answer was not perfectly appropriate so thank you for sharing your view. To be honest I myself use the package manager sometimes not only for libraries but for command line utilities or sometimes for the application that I intend to run in the container in the foreground like crond or even a squid proxy. ON the other hand when I want to support multiple versions of an application as Docker images, I don’t remember any case when I chose to install it from a package manager. It’s because I don’t like to rely on those and the different ways to specify a specific version when the way itself changes in time. My other reason is that when I build the app from source or download a binary, I can save it wherever I want it to be. Using a package manager I could easily have 3 different folders for different parts of the application which could be required or not. I just like to have more control over what I have and where. It could also be useful when I need to create volumes and I want to be able to manage it with one volume instead of three, but it depends on the application so you might never have these problems or prefer to solve it by changing the folder structure after the installation.
If the requirements are not documented, I try, fail, recognize missing libraries in the error message and add it to my Dockerfile. I had to do that when I created my PHP Docker image, but this method is not specific to Docker images. I had to do the same even before Docker. when I wanted to install multiple PHP versions in one virtual machine. I also don’t think Ubuntu will fully switch to Snap. It started long time ago and it still didn’t happen. Ubuntu is a Debian based distribution and the default package manager on Debian is APT. It would be a huge change so if I had to do that, I would probably also rename the distribution. Of course, even if it doesn’t happen, the maintainers of Ubuntu can change the installation method of enough applictions causing you a headache when you want to install it in a container without snap. I thought you used firefox as an example because you wanted to install a desktop app, but Ubuntu maintainers wouldn’t make Ubuntu useless for using it as a container base image so they would probably provide a way for containers as well.