Docker Autoreload with CompileDaemon - docker

I am working on trying to improve my development environment using Docker and Go but I am struggling to get auto reloading in my containers working when there is a file change. I am on Windows running Docker Desktop version 18.09.1 if that matters.
I am using CompileDaemon for reloading and my DockerFile is defined as follows
FROM golang:1.11-alpine
RUN apk add --no-cache ca-certificates git
RUN go get github.com/githubnemo/CompileDaemon
WORKDIR /go/src/github.com/testrepo/app
COPY . .
EXPOSE 8080
ENTRYPOINT CompileDaemon -log-prefix=false -directory="." -build="go build /go/src/github.com/testrepo/app/cmd/api/main.go" -command="/go/src/github.com/testrepo/app/main"
My project structure follows
app
api
main.go
In my docker-compose file I have the correct volumes set and the files are being updated in my container on when I make changes locally.
The application is also started correctly using CompileDaemon on its first load, its just not ever updated on file changes.
On first load I see...
Running build command!
Build ok.
Restarting the given command.
Then any changes I make are not resulting in a restart even though I can connect to the container and see that the changes are reflected in the expected files.

Ensure that you have volumes mounted for the services you are using, it is what makes the hot reloading work inside of a Docker container
See the full explanation

Proper way of installing the Compile Daemon is
RUN go install -mod=mod github.com/githubnemo/CompileDaemon
Reference: https://github.com/githubnemo/CompileDaemon/issues/45#issuecomment-1218054581

Related

Docker container doesn't update when file changes are made on host

I'm using a docker image as my dev environment for a specific version of PHP. I am using PHP for a command line script so every time I make a change to the script I would like it to automatically make changes in the container.
I'm not sure if this is even possible. I assumed it was. I mostly use docker-compose and I can add VOLUMES easily to achieve this, but not in this instance with docker.
My Dockerfile:
FROM php:7.2-cli
COPY ./app /usr/src/app/
WORKDIR /usr/src/app
ENTRYPOINT [ "php" ]
CMD [ "./index.php" ]
I first run:
docker build -t app .
And then
docker run app
Everything works well. But if I change something in index.php I have to run the steps again. Is this expected behaviour or is there any way to have docker watch for changes?
docker run -v /home/user/location:/usr/src/app app
Use a volume so that the files within the container reflect local changes.
https://docs.docker.com/storage/volumes/#choose-the--v-or---mount-flag
If you are editing a file using vim/sublime outside docker in your host, this is normal, because vim/sublime does not simple "edit" that file, but create a new file. see : https://github.com/moby/moby/issues/15793
solution:
After some googling, Sublime text has atomic_save instead so Adding "atomic_save": false to user preferences worked (After a restart).
if you are using docker-compose, use this command:
$ docker-compose run --build

docker create Linux with my own application

I developed an HTTP server which implements RESTful API specified by our client. Currently my workstation (Centos 7.4 x86_64) and everything else is working. Now I need to ship it as Centos 7.4 docker image.
I read the getting started guide and spent some time browsing the documentation but am still not sure how to proceed with this.
Basic Steps
Download Centos image from here
Run Centos image on my workstation and copy everything into it.
Make an appropriate changes so that server is started via systemd.
In step 3 : I am not sure how to do root/sudo inside the docker image.
I think what you are looking for is the Dockerfile reference https://docs.docker.com/engine/reference/builder/#understand-how-arg-and-from-interact
It's a file name Dockerfile that sits in the root of your project. You specify in this file which commands you want to run on top of the base image.
for example, from your use case:
FROM centos7.4.1708
COPY <your files> /opt/
CMD ["program.exe" "-arg" "argument"]
FROM - defines the base image
COPY - copies files from the folder you run the command from to the image
CMD - runs this command when the container starts
Build with docker build . -t image-name
Run with docker run image-name

webpack improve automation via improving dockerfile

I run want to know how to automate my npm project better with docker.
I'm using webpack with a Vue.js project. When I run npm run buld I get a output folder ./dist this is fine. If I then build a docker image via docker build -t projectname . and run this container all is working perfectly.
This is my Dockerfile (found here)
FROM httpd:2.4
COPY ./dist /usr/local/apache2/htdocs/
But it would be nice if I could just build the docker image and not have to build the project manually via npm run build. Do you understand my problem?
What could be possible solutions?
If you're doing all of your work (npm build and others) outside of the container, and have infrequent changes you could use a simple shell script to wrap the two commands.
If you're doing more frequent iterative development you might consider using a task runner (grunt maybe?) as a container service (or running it locally).
If you want to do the task running/building inside of Docker, you might look at docker-compose. The exact details of how to set this would would require more detail about your workflow, but docker-compose makes it relatively easy to define & link multiple services in a single file, and start and stop them with a simple set of commands.

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

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.

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.

Resources