- Background: I run my docker container with
docker run -it ubuntu. - What I want to do: I would like to install any software from the repos persistantly inside that container (lets take
gjitenfor example). - Problem: After
exiting the container the installed software is gone. - Question: How do I persistently install software (e.g.
gjiten) within my container?
Misc
- Afaik volumes don't work because I can't tell
aptwhere to install the package. (Ifaptwould allow the specification of a target dir, this would be the best solution, though.) - I know I could use appimages in docker volumes, but then I cannot use
aptand updating software becomes painfull. - I know I could create a chroot on a docker volume, but that turns out to be pretty painful.
Edit: Answer:
Exited docker containers are still around and the changes from inside the containers are not lost. I created an answer for this.
14 Answers
You need to create a Dockerfile and script your own container from an existing image. The syntax goes like this.
FROM UBUNTU:LATEST
RUN <some command like apt install>You will need to RTFM to understand it fully, because there is more to it then that. Best way to learn, take a look at any project which is present both on dockerhub and github. This way you can see the "finished product" and also the way the container was made.
HTH a little bit, s1mmel
Here is a live example. This is the Dockerfile from my only Repo I build some while ago. A Minecraft papermc server. This will not get you all the way, but for a starter I think it is good enough.
I figured, my perception of the docker environment was not correct, therefore giving birth to this question.
Important
Information from an exited container is not lost! Installed programs are persistent even after exiting *. Therefore, this question is basically obsolete.
In the following I try to clearify how docker works in this regard.
*This is opposing to Kulfy's comment "When you exit out of the instance or terminate the docker service, the changes and files are lost unless changes are committed while image was in use.".
How Docker works in general
docker run ubuntucreates a container from the imageubuntu.- The container will run as long as the main process runs.
- As the main process in the ubuntu image will finish immediately, the container will exit immediately (so the call immediate returns in the shell).
- Exiting a container is like a system shutdown only. The container is not lost. Data/system changes are still persistent.
- You can verify this with
docker ps -awhich will show you even exited containers.
- You can verify this with
Question related
docker run -it ubuntucreates a container from the imageubuntuand starts interactive mode in a shell.- You can do anything in that container now. (e.g. run
touch aaaor installgjiten) - If you type
exitwithin the container, you will exit the terminal (TTY) within that container. As that terminal was the main process of that container, that now exits, the container will exit ( = shutdown the OS inside the container). - Your data is not lost now. The system is just shut down.
- If you run
docker ps -anow, you can still see your container there. All changes are still effective; It's just not running at the moment. - You can now restart the container (like "rebooting the system") with
docker container start -i [containerID](-ifor interactive). - You should now be inside the container.
- Type
lsto see your fileaaais still there. - From another terminal you could run
docker psand it will show you the currently running container.
Btw: Note, that you need to create a container with -it in order to use -i in docker container start -i [containerID]
One Solution
If there is access to the host machine, one solution might be to commit the changes. Though, this will create a completely new image.
- start a container
- change something inside the container
- Figure out the container ID
- E.g. the right part of
root@9a20cddf27c0within the container
- E.g. the right part of
- On the host, run
docker commit [container ID] [new image name]
Props: @Kulfy from the comments.
I think you need to grasp the idea of a container image. There is a clear distinction between containers and container images.
Every container runs from a static image. The image itself is a compressed package that has everything you need to run a given software (binaries, direct dependencies, 3rd party dependencies, configuration files, users, file permisssions, all of it).
Once a container is running, everything it creates is ephemeral, and user data is persisted into volumes outside the container.
If you need a specific library or package persistently installed, you need to modify the image. In practice, that means creating your own Dockerfile and inherit FROM the base image you wish to modify. With your image created, you can run containers based on it.
The official docs are quite clear these days: