Copy files to docker image after build - shell

I do have an already build docker image and wan't to add files to it AFTER the build was done. Is there a way to add files without rebuilding it (or maybe to add it and save it with an new tag)? I did find docker cp but if I understand that right it does only work in running containers.

docker cp but if I understand that right it does only work in running containers
Still, that might work considering you can then commit a container into a new image.
See docker commit.
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]

Related

Is there a way to automate the creation of Docker Image?

I needed to create a Docker image of a Springboot application and I achieved that by creating a Dockerfile and building it into an image. Then, I used "docker run" to bring up a container. This container is used for all the activities for which my application was written.
My problem, however, is that the JAR file that I have used needs constant changes and that requires me to rebuild the Docker image everytime. Furthermore, I need to take the contents of the earlier running Docker container and transfer it into a container created from the newly built image.
I know this whole process can be written as a Shell script and exected every time I have changes on my JAR file. But, is there any tool I can use to somehow automate it in a simple manner?
Here is my Dockerfile:
FROM java:8
WORKDIR /app
ADD ./SuperApi ./SuperApi
ADD ./config ./config
ADD ./Resources ./Resources
EXPOSE 8000
CMD java -jar SuperApi/SomeName.jar --spring.config.location=SuperApi/application.properties
If you have a JAR file that you need to copy into an otherwise static Docker image, you can use a bind mount to save needing to rebuild repeatedly. This allows for directories to be shared from the host into the container.
Say your project directory (the build location where the JAR file is located) on the host machine is /home/vishwas/projects/my_project, and you need to have the contents placed at /opt/my_project inside the container. When starting the container from the command line, use the -v flag:
docker run -v /home/vishwas/projects/my_project:/opt/my_project [...]
Changes made to files under /home/vishwas/projects/my_project locally will be visible immediately inside the container1, so no need to rebuild (and probably no need to restart) the container.
If using docker-compose, this can be expressed using a volumes stanza under the services listing for that container:
volumes:
- type: bind
source: /home/vishwas/projects/my_project
target: /opt/my_project
This works for development, but later on, it's likely you'll want to bundle the JAR file into the image instead of sharing from the host system (so it can be placed into production). When that time comes, just re-build the image and add a COPY directive to the Dockerfile:
COPY /home/vishwas/projects/my_project /opt/my_project
1: Worth noting that it will default to read/write, so the container will also be able to modify your project files. To mount as read-only, use: docker run -v /home/vishwas/projects/my_project:/opt/my_project:ro
You are looking for docker compose
You can build and start containers with a single command using compose.

How to delete images on disk for Docker mac?

I see a lot of info on deleting Docker images and containers that are 'dangling/unused', but how can I delete images that aren't running as a container that I've downloaded using docker-compose -f my-compose-file.yaml?
When I exec 'docker system prune', and then run docker-compose again, I'm getting messages that the images already exist. I'm trying to remove all existing images from my system that were previously downloaded with 'docker-compose'.
Check this Post. It'll give you a good idea on how to deal with images.
Or in short and general:
docker rmi $(docker images -aq)
You can clean up docker artifacts by using the following command (depending on what you need to clean up):
docker container prune
docker image prune
docker network prune
docker volume prune
These commands support '-a' option that will delete all of the artifacts if specified (for example docker container prune -a will remove all the containers)
In case you need to clean up everything you may want to use:
docker system prune -a
The description of docker system prune in the docs is very brief
Remove unused data
Can you try running docker system prune --all which according to the docs removes all unused images, the options for --all flag
--all , -a Remove all unused images not just dangling ones
You could also try using docker image prune --all which is used to delete only unused images, for more see this.
I am new to Docker and still learning it.. Why not try docker image prune -a for removing unused images which are not being referenced by any container, for details see this . Although I think that your docker system prune should have worked.

Dockerfile for a newly committed docker image

I downloaded an image of ubuntu os in my system and after about committing 3 images from it(every image has an incremental change from before image), I now have my final image. Now I want the Dockerfile of this final image so that I can include commands like starting service at the start of container.
I have used this command,
sudo docker commit --change='CMD service apache2 start' 172d6dc34471 server_startup
to make the apache service start when the container is run. This starts the service in the container but doesn't go inside the container. It just starts the apache and exits to my local environment.
I would like to know how to get the Dockerfile for my final image so that I can include startup commands.
I have also tried this dockerfile from image, but its not working. It just throws error that .sock file is missing. I have tried this with both the new image and the parent image that I first downloaded.
Any help is much appreciated. Thanks.
you can use
docker history --no-trunc your_image
it will show you (in reverse order) what has been done
It is less user friendly than dockerfile from image, but it is basically the same thing.
I have somewhere a Python script that does that cleanly, I will check and post it.
Edit: Just this should show a lot
docker history your_image | docker inspect $(awk ' NR>1 {print $1}')
As CMD you need to provide a no-daemon program that keeps in foreground. That is not accomplished by service.
You should try:
sudo docker commit --change='CMD apache2 -DFOREGROUND' 172d6dc34471 server_startup
Sorry for the late reply, I used the --change argument while committing the image to point to the custom script(which I added within the container with the list of commands to be run at the start) that I want to run when the image is run for the first time.
sudo docker commit --change='ENTRYPOINT ["/test.sh"]' containerId autostart
I didn't know much about the dockerfile that everyone is suggesting but it is also a very good solution.

Docker how to clean partial failed downloads for images?

I am using docker toolbox in OS X. When I run docker-compose pull and the network cuts out, the download does not resume after I fix the issue. Is there a way to purge or invalidate partial downloads for docker images?
As noted in the comments, incomplete images would not be present anyway.
Since PR 18353 and docs-v1.11.2-2016-06-10, the next pull would reload missing/incommplete layers and build the complete image.
For purging images (dangling or not used): docker image prune -a
For purging containers: docker container prune
See more here.

How to edit files in stopped/not starting docker container

Trying to fix errors and debug problems with my application that is split over several containers, I frequently edit files in containers:
either I am totally lazy and install nano and edit directly in container or
I docker cp the file out of the container, edit it, copy it back and restart the container
Those are intermediate steps before coming to new content for container build, which takes a lot longer than doing the above (which of course is only intermediate/fiddling around).
Now I frequently break the starting program of the container, which in the breaking cases is either a node script or a python webserver script, both typically fail from syntax errors.
Is there any way to save those containers? Since they do not start, I cannot docker exec into them, and thus they are lost to me. I then go the rm/rmi/build/run route after fixing the offending file in the build input.
How can I either edit files in a stopped container, or cp them in or start a shell in a stopped container - anything that allows me to fix this container?
(It seems a bit like working on a remote computer and breaking the networking configuration - connection is lost "forever" this way and one has to use a fallback, if that exists.)
How to edit Docker container files from the host? looks relevant but is outdated.
I had a problem with a container which wouldn't start due to a bad config change I made.
I was able to copy the file out of the stopped container and edit it. something like:
docker cp docker_web_1:/etc/apache2/sites-enabled/apache2.conf .
(correct the file)
docker cp apache.conf docker_web_1:/etc/apache2/sites-enabled/apache2.conf
Answering my own question.. still hoping for a better answer from a more knowledgable person!!
There are 2 possibilities.
1) Editing file system on host directly. This is somewhat dangerous and has a chance of completely breaking the container, possibly other data depending on what goes wrong.
2) Changing the startup script to something that never fails like starting a bash, doing the fixes/edits and then changing the startup program again to the desired one (like node or whatever it was before).
More details:
1) Using
docker ps
to find the running containers or
docker ps -a
to find all containers (including stopped ones) and
docker inspect (containername)
look for the "Id", one of the first values.
This is the part that contains implementation detail and might change, be aware that you may lose your container this way.
Go to
/var/lib/docker/aufs/diff/9bc343a9..(long container id)/
and there you will find all files that are changed towards the image the container is based upon. You can overwrite files, add or edit files.
Again, I would not recommend this.
2) As is described at https://stackoverflow.com/a/32353134/586754 you can find the configuration json config.json at a path like
/var/lib/docker/containers/9bc343a99..(long container id)/config.json
There you can change the args from e. g. "nodejs app.js" to "/bin/bash". Now restart the docker service and start the container (you should see that it now correctly starts up). You should use
docker start -i (containername)
to make sure it does not quit straight away. You can now work with the container and/or later attach with
docker exec -ti (containername) /bin/bash
Also, docker cp is rather useful for copying files that were edited outside of the container.
Also, one should only fall back to those measures if the container is more or less "lost" anyway, so any change would be an improvement.
You can edit container file-system directly, but I don't know if it is a good idea.
First you need to find the path of directory which is used as runtime root for container.
Run docker container inspect id/name.
Look for the key UpperDir in JSON output.
That is your directory.
If you are trying to restart an stopped container and need to alter the container because of misconfiguration but the container isn't starting you can do the following which works using the "docker cp" command (similar to previous suggestion). This procedure lets you remove files and do any other changes needed. With luck you can skip a lot of the steps below.
Use docker inspect to find entrypoint, (named Path in some versions)
Create a clone of the using docker run
Enter clone using docker exec -ti bash (if *nix container)
Locate entrypoint file location by looking though the clone to find
Copy the old entrypoint script using docker cp : ./
Modify or create a new entrypoint script for instance
#!/bin/bash
tail -f /etc/hosts
ensure the script has execution rights
Replace the old entrypoint using docker cp ./ :
start the old container using start
redo steps 6-9 until the starts
Fix issues in container
Restore entrypoint if needed and redo steps 6-9 as required
Remove clone if needed

Resources