I use docker pull ubuntu to get the ubuntu:latest docker
Once I had deploy some artifacts in this container, and I want to use it to other place, then I used docker commit ${container_id}
However I found that when I use command of docker commit, it push all the files, including the application logs.
I've google for some cases, it may use docker file, and set the .dockerignore file to ignore those files I don't need.
But it matters that I've deployed the application with a license, so could I use this container with the only docker commit to commit the changes?
docker commit will always capture EVERYTHING in the container filesystem. It's just the way it works.
.dockerignore only applies to the docker build command. docker build uses a Dockerfile to take an existing image (like ubuntu:latest), run some modification on it, and commit the result.
If you want to build a container for use somewhere else, a Dockerfile is the way to approach it. You didn't provide much info, so here is a SUPER sparse example...
# Dockerfile
FROM ubuntu:latest
ADD myartifact /src
CMD /src/my_script.sh
and then...
docker build -t myOrg/myImage .
After which you can run the image with
docker run myOrg/myImage
Related
Is it possible only to modify the FROM value while executing docker commit ?
Say my active container is of Ubuntu 16.04 and I wanted to create an image off it, but Ubuntu version should be of 18.04, rest remains the same.
Does Docker support this scenario ?
Expecting like : docker commit —change=FROM ubuntu:18.04
The answer is no. You can't modify the base image with docker commit --change=FROM command.
The FROM instruction is not supported for --change option.
Here is the excerpt from the docs:
The --change option will apply Dockerfile instructions to the image
that is created. Supported Dockerfile instructions:
CMD|ENTRYPOINT|ENV|EXPOSE|LABEL|ONBUILD|USER|VOLUME|WORKDIR
If you don't have dockerfile for your container then, I would suggest to use either:
docker history command to generate Dockerfile. As mentioned here.
OR
Use dfimage utiliyy as mentioned here.
And then change the FROM instruction in your new generated dockerfile.
This is a strong reason to never use docker commit.
If you have a commit-based workflow, you need to docker run a container from some base image, perform some steps, and commit the result. Once you've done this, though, Docker has no idea what happened in between; it just knows that there's an image, and some opaque set of filesystem changes, and it's being asked to create an image from that.
Say you're using an old version of Ubuntu, and you want to upgrade to something newer. In a commit-based workflow, it's up to you to do all of the steps by hand. To keep track of this, you might write down a text file of the steps you want to perform:
# `docker run` a container using this base image
FROM ubuntu:18.04
# `docker cp` this file into the image
COPY package.deb /
# Run this command in the container shell
RUN dpkg -i /package.deb
# After committing the image, `docker run` the new image with this command
CMD some_command
That specific format is exactly the Dockerfile format, though: you can check it into source control, run docker build, and get the image back. Your coworker can do that too even if they don't have the exact setup you do, and even if they don't type the commands exactly the same way. And when you do need to upgrade the base image, you can just change the first line to FROM ubuntu:20.04 and docker build it again.
As I want to make my existing application as a Docker images. And I have to install lot of installation which I can't do using Docker file. How I am doing is I created a Docker container with OS, and log-in in to that and I Installed all the software I needed. Now I want to make the image out of it.
You can use docker commit.
Check out Docker commit official documentation:
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
--author , -a Author (e.g., “John Hannibal Smith hannibal#a-team.com”)
--change , -c Apply Dockerfile instruction to the created image
--message , -m Commit message
--pause , -p true Pause container during commit
Note this important remark:
By default, the container being committed and its processes will be paused while the image is committed. This reduces the likelihood of encountering data corruption during the process of creating the commit.
However this is not the best practice. You should build everything using a dockerfile for maintainability.
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
See the doc for more detailed explanation
Unless you have very specific need which prevents using Dockerfile to build your image, you should prefer the Dockerfile with the docker build command
I am working on Flask app running on ec2 server inside a docker image.
The old dev seems to have removed the original Dockerfile, and I can't seem to find any instructions on a way to push my changes into to the docker image with out the original.
I can copy my changes manually using:
docker cp newChanges.py doc:/root/doc/server_python/
but I can't seem to find a way to restart flask. I know this is not the ideal solution but it's the only idea I have.
There is one way to add newChanges.py to existing image and commit that image with a new tag so you will have a fall back option if you face any issue.
Suppose you run alpine official image and you don't have DockerFile
Everytime you restart the image you will not have your newChanges.py
docker run --rm -name alpine alpine
Use ls inside the image to see a list of existing files that are created in Dockerfile.
docker cp newChanges.py alpine:/
Run ls and verify your file was copied over
Next Step
To commit these changes to your running container do the following:
Docker ps
Get the container ID and run:
docker commit 4efdd58eea8a updated_alpine_image
Now run your alpine image and you will the see the updated changes as suppose
docker run -it updated_alpine_image
This is what you will see in your update_alpine_image with having DockerFile
This is how you can rebuild the image from existing image. You can also try #uncletall answer as well.
If you just want to restart after docker cp, you can just docker stop $your_container, then docker start $your_container.
If you want to update newChanges.py to docker image without original Dockerfile, you can use docker export -o $your_tar_name.tar $your_container, then docker import $your_tar_name.tar $your_new_image:tag. Later, always reserve the tar to backup server for future use.
If you want continue to develop later use a Dockerfile in the future for further changes:
you can use docker commit to generate a new image, and use docker push to push it to dockerhub with the name something like my_docker_id/my_image_name:v1.0
Your new Dockerfile:
FROM my_docker_id/my_image_name:v1.0
# your new thing here
ADD another_new_change.py /root/
# others
You can try to examine the history of the image, from there you can probably re-create the Dockerfile. Try using docker history --no-trunc image-name
See this answer for more details
I am trying to create a docker image using the below command .
docker build -t mytestapp .
My DockerFile looks like this
# Set the base image
FROM rhel7:latest
USER root
# Dockerfile author / maintainer
MAINTAINER Name <email.id#example.com>
# Update application repository list and install the Redis server.
RUN mkdir /usr/local/myapp/
ADD myapp-0.0.1-jar /usr/local/myapp/
RUN java -Dspring.profiles.active=qa -jar /usr/local/myapp/myapp-0.0.1.jar
# Expose default port
EXPOSE 8080
Questions:
1) Is it fine the way I am adding the JAR file. Will it be available inside /usr/local on the container after I prepared am image from the above build.
2) When I build the image using docker build command , is the build image is pushed to docker repository hub by default.
Since the WAR file contains credentials, I don't want to push the image to Docker Hub but we would like to push to our local Docker registry using Docker distribution and pushing with docker push.
Please clarify.
Answering your questions:
Docker recommends using the COPY instructions for adding single files into an image. It will be available inside the container at /usr/local/myapp/myapp-0.0.1-jar
When you build the image it will be available on your local docker-host. It won't leave the server unless you explicitly tell it so.
Another tip I want to give you is the recommended docker image naming convention, which is [Repository/Author]/[Imagename]:[Version].
So for your image it might be called zama/mytestapp:1.0
If you want to push it into your local registry, you'll have to name your image after the syntax [LocalRegistry:Port]/[Repository/Author]/[Imagename]:[Version].
So your image might now be called registry.example.com:5000/zama/mystestapp:1.0
If you have authentication on your registry, you need to docker login first and then simply push the image with docker push registry.example.com:5000/zama/mystestapp:1.0.
I would like to run a test a parse-dashboard via Docker, as documented in the readme.
I am getting the error message, "Parse Dashboard can only be remotely accessed via HTTPS." Normally, you can bypass this by adding the line "allowInsecureHTTP": true in your parse-dashboard-config.json file. But even if I have added this option to my config file, the same message is displayed.
I tried to edit the config file in the Docker container, whereupon I discovered that none of my local file changes where present in the container. It appeared as though my project was an unmodified version of the code from the github repository.
Why do the changes that I make to the files in my working directory on the host machine not show up in the Docker container?
But what it is upload to my docker, it's in fact the config file of my master branch.
It depends:
what that "docker" is: the official DockerHub or a private docker registry?
how it is uploaded: do you build an image and then use docker push, or do you simply do a git push back to your GitHub repo?
Basically, if you want to see the right files in your Docker container that you run, you must be sure to run an image you have built (docker build) after a Dockerfile which COPY files from your current workspace.
If you do a docker build from a folder where your Git repo is checked out at the right branch, you will get an image with the right files.
The Dockerfile from the parse-dashboard repository you linked uses ADD . /src. This is a bad practice (because of the problems you're running into). Here are two different approaches you could take to work around it:
Rebuild the Image Each Time
Any time you change anything in the working directory (which the Dockerfile ADDs to /src), you need to rebuild for the change to take effect. The exception to this is src/Parse-Dashbaord/parse-dashboard-config.json, which we'll mount in with a volume. The workflow would be nearly identical to the one in the readme:
$ docker build -t parse-dashboard .
$ docker run -d -p 8080:4040 -v ./src/Parse-Dashbaord/parse-dashboard-config.json:/src/Parse-Dashboard/parse-dashboard-config.json parse-dashboard
Use a Volume
If we're going to use a volume to do this, we don't even need the custom Dockerfile shipped with the project. We'll just use the official Node image, upon which the Dockerfile is based.
In this case, Docker will not run the build process for you, so you should do it yourself on the host machine before starting Docker:
$ npm install
$ npm run build
Now, we can start the generic Node Docker image, and ask it do serve our project directory.
$ docker run -d -p 8080:4040 -v ./:/src node:4.7.2 "cd /src && npm run dashboard"
Changes will take effect immediately because you mount ./ into the image as a volume. Because it's not done with ADD, you don't need to rebuild the image each time. We can use the generic node image because if we're not ADDing a directory and running the build commands, there's nothing our image will do differently than the official one.