How to copy docker container directories to Google Compute Engine instance - docker

I'm new to Google Cloud and Docker and I can't for the life of me figure out how to copy directories from the Docker container (pushed to the Container Registry) to the Google Compute Engine instance. I think I need to mount the volume but I don't really know how. In the docker container the main directory is /app which has my files. Basically I want to do this to see the docker container's files in Google Cloud.
I assumed that if i did: docker pull [HOSTNAME]/[PROJECT-ID]/[IMAGE]:[TAG] inside the cloud shell that the files would show up somewhere in the cloud shell i.e. in var/lib/docker but when I cd to var/lib/docker and type in: ls I get
ls: cannot open directory '.': Permission denied
Just to add I've tried following the "Connecting to Cloud Storage buckets" tutorial https://cloud.google.com/compute/docs/disks/gcs-buckets
But realised that this is for single files. Is it possible to copy over the whole root directory of the Docker image using gsutil? Do I need to use something else instead, like persistent disks?

You need to have docker installed in order to run your images and of course be able to copy anything from inside the image to your host filesystem.
Use docker cp CONTAINER:SRC_PATH DEST_PATH to copy files.
Have a look at the official Docker Documentation on how to use this command.
Simillar topic was also discussed here on StackOverflow and has a very good answer.

Related

Docker container copy files from local path into container

I need to copy my customized keycloak themes into keycloak container to use it like mention here:
https://medium.com/#auscunningham/change-login-theme-in-keycloak-docker-image-55b5fa5ceec4
After identifying my container id: docker container ls and making a list of files like this: docker exec 7e3a420017a8 ls ./keycloak/themes
It returns the list of themes correctly, but using this to copy my files from local to container:
docker cp ./mycustomthem 7e3a420017a8:/keycloak/themes/
or
docker cp ./mycustomthem 7e3a420017a8:./keycloak/themes/
I get the following error:
Error: No such container:path: 7e3a420017a8:/keycloak
I cannot imagine where the error is, since I can list the files into the folder and container, could you help me?
Thank you in advance.
Works on my computer.
docker cp mycustomthem e67f76e8740b:/opt/jboss/keycloak/themes/raincatcher-theme
You have added the wrong path in command add full path /opt/jboss/keycloak/themes/raincatcher-theme.
This seems like a weird way to approach this problem. Why not just have a Dockerfile that uses the Keycloak container as the base image and then copies the theme into the container at build time? Then just run the image you build? This will also be a more stable pattern in the long term if you ever decide to add any plugins or customizations and it provides an easy upgrade path to new versions by just changing the base image in your Dockerfile.
Update according to your new question update:
Try the following:
docker cp ./mycustomthem 7e3a420017a8:/opt/jboss/keycloak/themes/
The correct path in Keycloak is actually /opt/jboss/keycloak/themes/

how to share an external file in the disk into a running docker container?

I am currently running a docker container with a specific folder shared to it. However, I need to access other folders which are not in the shared folder.
Does docker mount or docker volume help in any way to mount a file into a running docker container?
You can do this in two ways.
just copy the file and paste it the shared location, it will be available for use in docker mount location.
copy the host file to the container where you want, using
docker cp your_local_file containerid:/path/to/container
There are other ways around but that will not be that easy as these two approaches.
You can check this details article but I think it will take your handsome time to that each and every time.
mount-volumes-into-a-running-container
You can also check
docker-mount-dynamic-volumes/
I was thinking one alternative could be to use soft links by placing them inside your mounted volume but it won't work as documented in this post. A suggested alternative is to mount your folders as different volumes:
-v /home/test/:/home/test -v /mnt/mountedfile:/mnt/mountedfile

Equivalent of -v in the Dockerfile?

So I want to mount my Docker container on my Windows PC using a Dockerfile. So far I have been able to do this using the following command:
docker run -v %userprofile%\mounted-docker\:/tmp/ container-name
This would mount /tmp/ from my Docker container into my C:\Users\USERNAME\mounted-docker\ folder. However, I can't seem to find the equivalent instruction in the Dockerfile documentation.
The only documentation is probably VOLUME in the Dockerfile documentation, which specifies:
Volumes on Windows-based containers: When using Windows-based containers, the destination of a volume inside the container must be one of:
a non-existing or empty directory
a drive other than C:
That's fine and all... but how exactly do I specify that? Let's say I want to mount either / or /tmp/ in a specified folder or drive, how do I do that?
The Dockerfile is used to build the image. To define how you'd like to run that image, you'll want to use a docker-compose.yml file.
In a Dockerfile, you cannot specify where a volume will be mounted from in the host. Doing so would open up docker to malicious image exploits where images from the Docker hub could mount the root filesystem and send private content to remote locations, or even perform a ransomware exploit. Specifying what elevated access a container can have is left up to the user running the image, from docker run or with the docker-compose.yml file.

How to mount current directory as read-only but still allow changes inside the container?

I have a situation where:
I want to mount a directory ~/tmp/mycode to /mycode readonly
I want to be able to edit the files in the directory, so I can't just run -v /my/local/path/tmp/mycode:/mycode
I want it to not persist changes on the host filesystem though so I can't mount it read/write
~/tmp/mycode is rather large
Basically I want to be able to edit the files in the mounted volume but not have those changes persisted.
My current workflow is to create a dummy container using a dockerfile:
ADD . /mycode
and then execute that container.
However as the repository grows, this step takes longer and longer to perform, because the only way I can think is to make a complete copy of ~/tmp/mycode in order to be able to manipulate the files in the container.
I've also thought about mounting the directory and copying it inside the container and committing that container, but that has the same issue.
Is there a way to run a docker container to allow file edits without persisting them on the host short of copying the whole directory?
I am using the latest docker for mac, currently Version 17.03.1-ce-mac5 (16048).
This is fairly trivial to do with docker and overlay:
docker run --name myenv --privileged -v /my/local/path/tmp/mycode:/mnt/rocode:ro -it ubuntu /bin/bash
docker exec -d myenv /sbin/mount -t overlay overlay -o lowerdir=/mnt/rocode,upperdir=/mycode,workdir=/mnt/code-workdir /mycode
This should mount the code from your directory read only and create the overlay inside the container so that /mnt/rocode is read only, but /mycode is writable.
Make sure that your kernel is 3.18+ and that you have overlay in your /proc/filesystems.

Docker volume content does not persist

I am trying to capture the state of a docker container as an image, in a way that includes files I have added to a volume within the container. So, if I run the original container in this way:
$ docker run -ti -v /cookbook ubuntu:14.04 /bin/bash
root#b78f3599d936:/# cd cookbook
root#b78f3599d936:/cookbook# touch foo.txt
Now, if I either export, or commit the container as a new docker image, and then run a container from the new image, then the file, foo.txt is never included in the /cookbook directory.
My question is whether there is a way to create an image from a container in a way that allows the image to include file content within its volumes.
whether there is a way to create an image from a container in a way that allows the image to include file content within its volumes?
No, because volume is designed to manage data inside and between your Docker containers, it's used to persist and share data. What's in image is usually your program(artifacts, executables, libs. e.g) with its whole environment, building/updating data to image does not make much sense.
And in docs of volumes, they told us:
Changes to a data volume will not be included when you update an image.
Also in docs of docker commit:
The commit operation will not include any data contained in volumes mounted inside the container.
Well, by putting the changes in a volume, you're excluding them from the actual container. The documentation for docker export includes this:
The docker export command does not export the contents of volumes associated with the container. If a volume is mounted on top of an existing directory in the container, docker export will export the contents of the underlying directory, not the contents of the volume.
Refer to Backup, restore, or migrate data volumes in the user guide for examples on exporting data in a volume.
This points to this documentation. Please follow the steps there to export the information stored in the volume.
You're probably looking for something like this:
docker run --rm --volumes-from <containerId> -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /cookbook
This would create a file backup.tar with the contents of the container's /cookbook directory and store it in the current directory of the host. You could then use this tar file to import it in another container.
Essentially, there are three ways to do persistence in Docker:
You can keep files in a volume, which is a filesystem managed by Docker. This is what happens in your example: because the /cookbook directory is part of a volume, your file does not get commited/exported with the image. It does however get stored in the volume, so if you remount the same volume in a different container, you will find your file there. You can list your volumes using docker volume ls. As you can see, you should probably give your volumes names if you plan to reuse them. You can mount an existing volume, or create a new one, if the name does not exist, with
docker run -v name:/directory ubuntu
You can keep files as part of the image. If you commit the container, all changes to its file hierarchy are stored in the new image except those made to mounted volumes. So if you just get rid of the -v flag, your file shows up in the commit.
You can bind mount a directory from the host machine to the container, by using the -v /hostdir:/targetdir syntax. The container then simply has access to a directory of the host machine.
Docker commit allows you to create an image from a container and its data (mounted volumes will be ignored)

Resources