Docker Oracle12c Enterprise image created from container symlink broken - docker

We are trying to create a docker image from a container based on the Oracle 12c Enterprise Edition image from docker store (https://store.docker.com/images/oracle-database-enterprise-edition). We have the container working ok and then, after stopping the container we create an image based on that container with the following command.
docker commit Oracle_12 oracle/oradb:1
Then, we try to run a container using the commited image with the following command:
docker run -d -it --name oradb_cont -p 1512:1521 -p 5500:5500 oracle/oradb:1
This container fails with the following error:
Start up Oracle Database
Wed Nov 15 10:31:29 UTC 2017
start database
start listener
The database is ready for use .
tail: cannot open '/u01/app/oracle/diag/rdbms/orclcdb/ORCLCDB/trace/alert_ORCLCDB.log' for reading: No such file or directory
tail: no files remaining
The container is "Exited" although the message "The database is ready for use".
We have attached a bash to the container to inspect where the missing file is. And the result seems to be that the "/diag" folder is a broken symlink:
Starting the original Oracle 12c container and attaching a bash, the folder is present. It seems symlink is broken or the file is not present only in the image created from the container.

The problem is that /ORCL is a data volume. The commit operation does not include any files that are inside volumes. You can check the commit documentation for more info.
Thus when starting the new instance, it appears that somehow the log file is being referenced and has not been yet created. Your current container is in an inconsistent state, as the files under '/ORCL' that were present in the commited container are missing from the new instance.
If you are running the new instance on a new machine you need to migrate the old volume into the new machine. You can find the volume of the old container by running docker inspect -f '{{ .Mounts }}' <old-container-name>, and migrate as specified in How to port data-only volumes from one host to another?
If you are running the new instance on the same machine, just mount the old volume using: <volume-name-or-id>:/ORCL
In general, as a best practice, you shouldn't rely on the commit command to get identical instances of a container. Rather build a DockerFile which extends the base image, and then add customizations by selecting only the necessary files to copy over on the new instance.

Related

Docker NodeRed committed container does not maintain flows and modules

I'm working on a project using NodeRed deployed with docker and I would like to save the state of my deployment, including flows, settings and new added modules so that I can save the image and load it on another host replicating exactly the same NodeRed instance.
I created the container using:
docker run -itd --name my-nodered node-red
After implementing the flows and installing some custom modules, with the container running I used this command:
docker commit my-nodered my-project-nodered/my-nodered:version1
docker save my-project-nodered/my-nodered:version1 > tar-archive.tar.gz
And on another machine I'd imported the image using:
docker load < tar-archive.tar.gz
And run it using:
docker run -itd my-project-nodered/my-nodered:version1
And I obtain a vanilla NodeRed docker container with a default /data directory and just the files on the data directory maintained.
What am I missing? It could be possibile that my /data directory is overwrittenm as well as my settings.js file in the home directory? And in this case, which is the best practice to achieve my target?
Thank you a lot in advance
commit will not work, as you can see that there is volume defined in the Dockerfile.
# User configuration directory volume
VOLUME ["/data"]
That makes it impossible to create a derived image with any different content in that directory tree. (This is the same reason you can't create a mysql or postgresql image with prepopulated data.)
docker commit doesn't consider volumes at all, so you'll get an unchanged image with nothing preloaded in it.
You can see the offical documentation
Managing User Data
Once you have Node-RED running with Docker, we need to ensure any
added nodes or flows are not lost if the container is destroyed. This
user data can be persisted by mounting a data directory to a volume
outside the container. This can either be done using a bind mount or a
named data volume.
Node-RED uses the /data directory inside the container to store user
configuration data.
nodered-user-data-in-docker
one way is to restore the your config file on another machine, for example backup-config then
docker run -it -p 1880:1880 -v $PWD/backup-config/:/data --name mynodered nodered/node-red-docker
or if you want to full for some repo then you can try
docker run -it --rm -v "$PWD/$(wget https://raw.githubusercontent.com/openenergymonitor/oem_node-red/master/flows_emonpi.json)":/data/ nodered/node-red-docker

How to start a existing mysql container in docker (toolbox)?

I have a container (i'm using this container https://hub.docker.com/_/mysql/) which had started before, with ID 5f96e9570d1b1475a888d7a615acdd9a7715c1ed6f0c40900f2e9c1ab485c7cf, but now how can i restart it ? I tried this command but not work
$ docker run --name mysql -e MYSQL_ROOT_PASSWORD=*Abcd1234 -d mysql:5.7
D:\CWindow10\Docker Toolbox\docker.exe: Error response from daemon: Conflict. The container name "/mysql" is already in use by container "5f96e9570d1b1475a888d7a615acdd9a7715c1ed6f0c40900f2e9c1ab485c7cf". You have to remove (or rename) that container to be able to reuse that name.
See 'D:\CWindow10\Docker Toolbox\docker.exe run --help'.
If i delete the container and retype the command, will the old data still exist in new container?
To restart an existing container, simply run docker start <container_name_or_id>.
Regarding the data: docker uses the concept of volumes to put data. For the mysql image, there's a section "Where to Store Data" on the docker hub site. If you don't manually declare where the image should go, docker will create one for you. If you want your data to be kept, the easiest way is to create a folder and tell the docker run command to map that volume. That way, you can still use it if you throw away your container.
use this command to restart container docker restart <CONTAINER>
starting new container will not preserve your data unless you have mounted external volume and stored data on it. Have a look at this blog http://blog.arungupta.me/docker-mysql-persistence/

docker does not preserve state

I made a docker pull jenkins:latest
then I ran the container: docker run --name jenk -p 8080:8080 jenkins
I set up all the jobs, configurations, etc within jenkins. Afterwards I committed the change:
docker commit jenk myrepo/jenkins
when I now pull the image and start it: docker run myrepo/jenkins all the configuration is lost. I thought it would preserve it.
You also need to push it to your (remote) repository before you can pull it again. The commit only saves the state to your local drive. A pull always goes to a repository.
Some free advice:
It is mostly advisable to make changes by doing this through a Dockerfile though, by extending the jenkins:latest and adding your own changes to it. This makes it much more maintainable and changeable.
Question:
Did you do this all inside the image or also on mounted volumes?
according to the documentation those settings will not be included
The commit operation will not include any data contained in volumes mounted inside the container.
Have fun :-)
As described in the docker commit documentation:
The commit operation will not include any data contained in volumes
mounted inside the container.
The jenkins image declared the jenkins home as a volume VOLUME /var/jenkins_home. The volume container all the configuration and jobs created. Thus when you commit the container, all this configuration willnot be persisted in the
commited image.
If you are running the new image on the same machine, you can use the jenkins_home volume from the older container and get exactly the same jenkins instance:
docker volume ls //To determine the old container volume name
docker run -v <old-volume-name>:/var/jenkins_home -p 8080:8080 myrepo/jenkins
If you are running the commited intance on a new machine:
docker cp <old-container>:/var/jenkins_home ./jenkins_home
Now copy the jenkins_home folder onto the new machine, and mount it onto the new container:
docker run -v ./jenkins_home:/var/jenkins_home -p 8080:8080 myrepo/jenkins

Do docker containers retain file changes?

This is a very basic question, but I'm struggling a bit and would like to make sure I understand properly.
After a container is started from an image and some changes done to files within (i.e.: some data stored in the DB of a WebApp running on the container), what's the appropriate way to continue working with the same data between container stop and restart?
Is my understanding correct that once the container is stopped/finished (i.e.: exit after an interactive session), then that container is gone together with all file changes?
So if I want to keep some file changes I have to commit the state of the container into a new image / new version of the image?
Is my understanding correct that once the container is stopped/finished (i.e.: exit after an interactive session), then that container is gone together with all file changes?
No, a container persists after it exits, unless you started it using the --rm argument to docker run. Consider this:
$ docker run -it busybox sh
/ # date > example_file
/ # exit
Since we exited our shell, the container is no longer running:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
But if we had the -a option, we can see it:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
79aee3e2774e busybox:latest "sh" About a minute ago Exited (0) 54 seconds ago loving_fermat
And we can restart it and re-attach to it:
$ docker start 79aee3e2774e
$ docker attach 79aee3e2774e
<i press RETURN>
/ #
And the file we created earlier is still there:
/ # cat example_file
Wed Feb 18 01:51:38 UTC 2015
/ #
You can use the docker commit command to save the contents of the container into a new image, which you can then use to start new containers, or share with someone else, etc. Note, however, that if you find yourself regularly using docker commit you are probably doing yourself a disservice. In general, it is more manageable to consider containers to be read-only and generate new images using a Dockerfile and docker build.
Using this model, data is typically kept external to the container,
either through host volume mounts or using a data-only container.
You can see finished containers with docker ps -a
You can save a finished container, with the filesystem changes, into an image using docker commit container_name new_image_name
You can also extract data files from the finished container with: docker cp containerID:/path/to/find/files /path/to/put/copy
Note that you can also "plan ahead" and avoid trapping data you'll need permanently within a temporary container by having the container mount a directory from the host, e.g.
docker run -v /dir/on/host:/dir/on/container -it ubuntu:14.04

Docker.IO Filesystem Consistancy

I created a docker container, and then I created a file and exited the container.
When I restart the container with:
docker run -i -t ubuntu /bin/bash
the file is nowhere to be found. I checked /var/lib/docker/ and there is another folder created which has my file in it. I know it's something to do with Union FS.
How do I start the same container again with my file in it?
How do I export a container with file change?
I don't know if this will answer your question completely, but...
Doing
docker run -i -t ubuntu /bin/bash
will not restart any container. Instead, it will create and start a new container based on the ubuntu image.
If you started a container and stopped it you can use docker start ${CONTAINER_ID}. If you did not stop it yet you can use restart.
You can also commit (export) the container to a new image: see http://docs.docker.io/en/latest/commandline/command/commit/ for the correct syntax. docker export is a option as well, but all that will do is archive your container. By creating a new image using docker commit you can create multiple instances (containers) of it afterwards, all having your file in it.

Resources