Docker: git add <filename> like feature - docker

Suppose I have 10 files changes in my existing docker image. How would I commit only 2 specific files and create a separate tag?
Something Like:
docker commit -m file1 file2
Edited: see my request has been closed by docker members.
https://github.com/docker/docker/issues/20897

You cannot, man docker commit tells you why does not offer this operation.
Edit
It just that the command does not offer this operation and usually the man page does not details what and why the tool does not offer. Nevertheless, my guess is: it is programmatically possible to perform this operation but may lead in inconsistent images, or incoherent, and might be dangerous. Let's say you installed a package, and want to commit these files but forget a conf-file (or anything else) the image would be in a weird-not-so-clean state. Also, using docker commit is far away from the best practice to create image. Prefer a Dockerfile which make image lighter to build

If you modify the contents of a container, you can use the docker commit command to save the current state of the container as a new tag.
$ docker commit <CONTAINER_ID> <IMAGE_NAME>:<NEW_TAG>

Related

Forcing Kubernetes to redeploy a deployment YAML if docker image updates? [duplicate]

This question already has answers here:
Kubernetes how to make Deployment to update image
(8 answers)
Closed 1 year ago.
I have this workflow where I write some code and a docker image is deployed under latest. Currently, it deploys to my container registry and then I run this kubectl apply file.yaml after the container deploys, but K8s doesn't seem to recognize that it needs to re-pull and rollout a new deployment with the newly pulled image.
How can I basically feed in the YAML spec of my deployments and just rollout restart the deployments?
Alternatively, is there a better approach? I unconditionally am rolling out deployment restarts on all my deployments this way.
#daniel-mann is correct to discourage the use of :latest.
Don't read the word 'latest' when you see the tag latest. It's a default tag and it breaks the ability to determine whether the image's content has changed.
A better mechanism is to tag your images by some invariant value... your code's hash, for example. This is what Docker does with its image hashes and that's the definitive best (but not easiest) way to identify images: [[image]]#sha256:.....
You can use some SemVer value. Another common mechanism is to use the code's git commit for its tag: git rev-parse HEAD or similar.
So, assuming you're now uniquely identify images by tags, how to update the Deployment? The docs provide various approaches:
https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#updating-a-deployment
But these aren't good for robust deployments (lowercase-D). What you should also do is create unique Deployment manifests each time you change the image. Then, if you make a mistake and inadvertently deploy something untoward, you have a copy of what you did and you can correct it (making another manifest) and apply that. This is a principle behind immutable infrastructure.
So...
TAG=$(git rev-parse HEAD)
docker build \
--tag=${REPO}/${IMAGE}:${TAG} \
...
docker push ${REPO}/${IMAGE}:${TAG}
Then change the manifest (and commit the change to source control):
sed --in-place "s|image: IMAGE|image: ${REPO}/${IMAGE}:${TAG}|g" path/to/manifest.yaml
git add /path/to/manifest.yaml
git commit --message=...
Then apply the revised (but unique!) manifest to the cluster:
kubectl apply \
--filename=/path/to/manifest.yaml \
--namespace=${NAMESPACE}

Searching docker hub registry images/layers by their SHA digest

If you ever attentively browse for docker images on https://hub.docker.com you may have once dissect all the commands composing an image of interest within a certain tag.
Great, but then you may have seen this kind of "translated" command when you click on a specific line of a command:
I may be wrong here because I'm not a Docker expert, but this seems to be an SHA-256 digest which refers to... something else inside the Hub.
My question is; how to find what exactly does it refer to, knowing the SHA value (3a7bff4e139bcacc5831fd70a035c130a91b5da001dd91c08b2acd635c7064e8)?
The SHA value you see is the digest of the file that was added.
For example, suppose you have the following dockerfile:
FROM scratch
ADD foo.txt /foo.txt
If you were to push that to dockerhub, you would see something like:
ADD file:b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c in /
where b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c is the digest of foo.txt.
There's no definitive way to reverse this information to obtain the file, considering ADD can do things like unpack tar archives.
With modern versions of Docker/buildkit, you might see the filename instead.
This is the same thing you see when using docker image history.

How to merge Docker Compose in one image? [duplicate]

I'm hoping to use docker to set up some bioinformatic analysis.
I have found two docker images that I would like to use:
jupyter/datascience-notebook
bioconductor/devel_base
I have been successful in running each of these images independently, however I don't know how to merge them together.
Is merging two docker containers possible? Or do you start with one, and then manually install the features of the other?
You can't just merge the images. You have to recreate your own based on what was in each of the images you want. You can download both images and re-create the Docker files for each like this:
docker history --no-trunc=true image1 > image1-dockerfile
docker history --no-trunc=true image2 > image2-dockerfile
Substitute the image1 and image2 with the images you want to see the history for. After this you can use those dockerfiles to build your own image that is the combination of the two.
The fly in the ointment here is that any ADD or COPY commands will not reveal what was copied because you don't have access to the local file system from which the original images were created. With any luck that won't be necessary or you can get any missing bits from the images themselves.
If there are specific files or directories that you want to cherry-pick from the one of the two images, you can create a new Dockerfile that builds FROM one of them and copy over specific paths from the other using COPY's --from option. For example:
FROM bioconductor/devel_base
COPY --from=jupyter/datascience-notebook /path/to/something-you-want /path
However, a quick investigation of those images shows that in this specific case there isn't a lot that can easily be cherry picked.
Alternatively, you can just look at the original Dockerfiles and combine them yourself:
https://github.com/jupyter/docker-stacks/blob/master/base-notebook/Dockerfile
https://github.com/Bioconductor/bioc_docker/blob/master/out/devel_base/Dockerfile
Fortunately they are both based one APT-based distros: Ubuntu and Debian. So most of the apt-get install commands should work fine if you pick either base image.
You start with one then manually install the features of the other one. Merging would be far to complex, and too many unknowns.

How do I save changes to a docker container and image

I ran a container and it was missing command alias like ll. So I Typed alias ll="ls -lta" in the terminal while I was inside the container. After that, I ran docker commit to commit changes to the container and image. I got a new image (outside container), deleted the old image and ran a new container from the image I committed to. But was not able to use ll alias. What am I missing here?
Container state is only persisted through files.
alias ll="ls -lts" made no file changes and thus no state change was persisted by the docker commit....
You may achieve the result you intend by editing one of the files that the shell uses to define its state when opened, e.g. e.g. ~/.bashrc and ~/.bash_profile. You'll need to determine which to use for your environment|OS.

Is there a way to create/add files to docker image manually?

I'm trying to build a ruby-on-rails project, using rails 1.9.3 on Debian image.
After I've built it, using dockerfile, it appears that a directory is missing. So the container doesn't start. So, can I add it manually? I've tried to use "docker run -it sh" to run it as shell, but for some reason, after I add a directory with mkdir it vanishes, when I exit.
I'm kinda new to this stuff (just did some tutorials), so apologize for any mixed up details.
You are going to need to add the dir, and then commit the changes in the container to make a new image out of it to use the directory in the new image. Its much better to use a repeatable DockerFile to create the image
Documentation for DockerFile -> https://docs.docker.com/engine/reference/builder/
Have a look at the documentation for commit here -> https://docs.docker.com/engine/reference/commandline/commit/

Resources