Why do the changes I make in my working directory not show up in my Docker container? - docker

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.

Related

How to run a Docker Compose image pulled from GitHub Packages

I have pushed a Docker image on GitHub Packages and now I would like to pull it and use it.
To run the image locally, I used to go to the related folder and run it with the command docker-compose up.
However now, by pulling from GitHub Packages, I just get the Docker image without any folder and I don't know how I can run it.
By inspecting the image it has all the files related to the original folder but, when I try to run the docker-compose up ghcr.io/giuliomat/bdt-project command, I get an error saying that there is no docker-compose.yml in the directory. If I just use the command docker run ghcr.io/giuliomat/bdt-project it runs one of the two services specified in the docker-compose.yml file. How can I run the Docker Compose image correctly? Thanks in advance!
Update: I try to explain myself better. In the image there is a Dockerfile (that now I've uploaded in the question) which is used to build the web service. I developed the image locally and I have no problem running it with docker-compose up, but now I wanted to see what it has to be done in order to run it when a user pulls it from my GitHub Packages, and this is my problem. The pulled image should have all the elements needed to run but I don't know what command to use in order to tell Docker to run both services specified in the docker-compose.yml file, since when a user pulls from GitHub Packages it only gets the image and no folder where run docker-compose up.
Dockerfile:
docker-compose.yml:
content of the pulled docker image:
Update:
Docker image repository does not store yml files, therefore either you provide a README.md for the user in the image registry (with yml verbosely copy-pasted there) and/or you provide also the link to the version control repository where the rest of the files reside, so the user can clone and use docker-compose up.
docker-compose up [options] [--scale SERVICE=NUM...] [SERVICE...] means "find [service...](if specified, otherwise run all) indocker-compose.yml` in the current working directory and run it.
So if you move out of the folder with docker-compose.yml it won't pick the compose file and therefore won't work.
Also for the image using you need to specify image property of a service instead of build because build works with the Dockerfile locally and attempts to build an image instead of pulling it from GitHub Docker image registry:
web:
image: "ghcr.io/giuliomat/bdt-project:latest"
It'd be the same way you have it for redis service.
Also make sure you can pull the image locally first (otherwise docker login would be necessary prior to compose commands) by:
docker pull ghcr.io/giuliomat/bdt-project

How to put the code to docker image while building

I want to clone the code to docker image while building it
I am thinking to pass the ssh keys while git clone, which is not working. below is the command i am using, showing permission denied
ssh-agent bash -c 'ssh-add /home/username/.ssh/id_rsa.pub my keys; git clone ssh://git#location.git'
I can't use the cloning using https
ALSO say if the code is cloned on image, CAN WE GIT PULL WHILE RUNNING IT ON CONTAINER
So there are two real paradigms here:
I am working on my local machine.
In this scenario, you more than likely already have the code checked out onto your local machine. Here, just use the COPY directive to take the entire folder and put it somewhere into the container. No need to worry about git or anything of the sort.
I am having a build server perform the build
In this scenario, it makes sense to let the build server check the code out and then perform the same action as above. We just copy the checked out code into the image
Lastly, another alternative that works for dynamic languages like PHP, JS etc, is to NOT put the code into the image, but MOUNT the code onto the container at runtime.
Let's take PHP for example. If the webserver is looking in /var/www/html for the code, you can run your image like this:
docker run -d --name {containername} -p 80:80 -p 443:443 -v /my/dir/where/code/is:/var/www/html {your base image}
The above will create the image, but will pass your local directory through to the /var/www/html directory, meaning any changes you make locally would appear in the source code for the container. This was much more prominently used back with Vagrant and the early days of docker before composer was stable.
I Think the way to do is
in your build machine
git clone <repo>
git archive --format=tar.gz <commit_hash/branch> --output=code.tar.gz
docker build
in the Dockerfile you'll have to add
ADD code.tar.gz <directory>
This will make sure that you're not adding any .git stuff into your container and it'll be small in size as possible.

how to ignore logs with docker commit

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

Copy files from host to docker container then commit and push

I'm using docker in Ubuntu. During development phase I cloned all source code from Git in host, edit them in WebStorm, and them run with Node.js inside a docker container with -v /host_dev_src:/container_src so that I can test.
Then when I wanted to send them for testing: I committed the container and pushed a new version. But when I pulled and ran the image on the test machine, the source code was missing. That makes sense as in test machine there's no /host_src available.
My current workaround is to clone the source code on the test machine and run docker with -v /host_test_src:/container_src. But I'd like to know if it's possible to copy the source code directly into the container and avoid that manipulation. I'd prefer to just copy, paste and run the image file with the source code, especially since there's no Internet connection on our testing machines.
PS: Seems docker cp only supports copying file from container to host.
One solution is to have a git clone step in the Dockerfile which adds the source code into the image. During development, you can override this code with your -v argument to docker run so that you can make changes without rebuilding. When it comes to testing, you just check your changes in and build a new image. Now you have a fully standalone alone image for testing.
Note that if you have a VOLUME instruction in your Dockerfile, you will need to make sure it occurs after the git clone step.
The problem with this approach is that if you are using a compiled language, you only want your binaries to live in the final image. In this case, the git clone needs to be replaced with some code that either fetches or compiles the binaries.
Please treat your source codes are data, then package them as data container , see https://docs.docker.com/userguide/dockervolumes/
Step 1 Create app_src docker image
Put one Dockerfile inside your git repo like
FROM BUSYBOX
ADD . /container_src
VOLUME /container_src
Then you can build source image like
docker build -t app_src .
During development period, you can always use your old solution -v /host_dev_src:/container_src.
Step 2 Transfer this docker image like app image
You can transfer this app_src image to test system similar to your application image, probably via docker registry
Step 3 Run as data container
In test system, run app container above it. (I use ubuntu for demo)
docker run -d -v /container_src --name code app_src
docker run -it --volumes-from code ubuntu bash
root#dfb2bb8456fe:/# ls /container_src
Dockerfile hello.c
root#dfb2bb8456fe:/#
Hope it gives help
(give credits to https://github.com/toffer/docker-data-only-container-demo , which I get detail ideas)
Adding to Adrian's answer, I do git clone, and then do
CMD git pull && start-my-service
so the latest code at the checked out branch gets run. This is obviously not for everyone, but it works in some software release models.
You could try and have two Dockerfiles. The base one would know how to run your app from a predevined folder, but not declare it a volume. When developing you will be running this container with your host folder mounted as a volume. Another one, the package one, will inherit the base one and copy/add the files from your host directory, again without volumes, so that you would carry all the files to the tester's host.

Docker rails app and git

Lets say I have a container that is fully equipped to serve a Rails app with Passenger and Apache, and I have a vhost that routes to /var/www/app/public in my container. Since a container is supposed to be sort of like a process, what would I do when my Rails code changes? If the app was cloned with Git, and there are pending changes in the repo, how can the container pull in these changes automatically?
You have a choice on how you want to structure your container, depending on your deployment philosophy:
Minimal: You install all your rails pre-reqs in the Docker file (RUN commands), but have the ENTRYPOINT be something like "git pull && bundle install --deployment && rails run". At container boot time it will get your latest code.
Snapshot: Same as above, but have the ENTRYPOINT also be a RUN command. This way, the container has a pre-installed snapshot of the code, but it will still update when the container is booted. Sometimes this can speed up boot time (i.e. if most of the gems are already installed).
Container as Deployment: Same as above, but change the ENTRYPOINT to be "rails run" only. This way, your container is your code. You'll have to make new containers every time you change rails (automation!). The advantage is that your container won't need to contact your code repo at all. The downside is that you have to always remember what the latest container is. (Tags can help) And right now, Docker doesn't have a good story on cleaning up old containers.
In this scenario, it sounds like you have built an image and are now running this image in a container.
Using the image your running container originates from, you could add another build step to git pull your most up to date code. I'd consider this an incremental update as your building upon a preexisting image. I'd recommend tagging and pushing to your (assuming your using a private index) appropriately. The new image would be available to run.
Depending on the need, you could also rebuild the base image of your software. I'm assuming your using a Dockerfile to build your original image which includes a git checkout of your software. You could then tag and push to your index for use appropriately.
In docker v0.8, It will be possible to start a new command in a running container, so you will be able to do what you want.
In the meantime, one solution would consist in using volumes.
Option 1: Docker managed volumes
FROM ubuntu
...
VOLUME ["/var/www/app/public"]
ADD host/src/path /var/www/app/public
CMD start rails
Start and run your container, then when you need to git pull, you can simply:
$ docker ps # -> retrieve the id of the running container
$ docker run -volumes-from <container id> <your image with git installed> sh -c 'cd/var/www/app/public && git pull -u'
This will result in your first running container to have the sources updated.
Option 2: Host volumes
You can start your container with:
$ docker run -v `pwd`/srcs:/var/www/app/public <yourimage>
and then simply git pull in your host's sources directory, it will update the container's sources.

Resources