0

My question is related to this topic but I have more of a specific question wrt to Docker in general. My configuration looks like this:

container_name: foo
    image: foo/bar
    volumes:
        - ".cachedir:/cachedir"
    env_file: 
        - .env
    ports:
        - "50052:50052"
    restart: always
    entrypoint: ["python", "serve.py"]
    logging:
        options:
            max-size: "10m"
            max-file: "3"

I made some changes in serve.py, does that mean I need to completely rebuild my docker image in order to have those changes take effect? I tried restarting the docker instance, but no luck. I've tried "up --force-recreate" but that didn't seem to do anything either.

Outside of that, if I do need to rebuild and somehow do it wrong - obviously I'm doing something wrong - what would be a faster way to test my code changes?

I ssh'ed into the machine just to verify that indeed the serve.py did not have any changes in it, it probably depends on the docker image itself, but I have no nano,vi,vim available so I can't edit anything in there either.

I am aware that this is probably a very common/basic question, but I'm currently completely stuck as to how I can get my docker instance to run the latest serve.py code.

rok
  • 9,403
  • 17
  • 70
  • 126
jlos
  • 1,010
  • 1
  • 8
  • 12
  • You can bind mount the files/directories that are subject to change into the container. Then any changes made on the outside are instantly reflected in the container. I use that in combination with some sort of automatic restart tool. Like nodemon for node. Not sure what the equivalent for python is. – super Sep 08 '21 at 16:11

4 Answers4

2

If I understood you correctly, you are looking for the way to apply some code changes within the file in the container. If this is the case, then let me help:

If you will restart this container, or apply up --force-recreate the code changes you have made will take no effect. The reason for this is that container itself is an additional layer on top of image layers. Problem - this additional layer is not persistable, it dies along with the container. If you want to change the state (in general) of the running container and then persist it, you should therefore persist this additional top layer created by the container. You can do it via docker commit command. The official documentation is there.

Still, I do not recommend this approach - do not make the changes outside of SVC. In you case - if you want to change the code, then put it your SVC and rebuild an image.

But the way, container is alive as soon as it main process (with PID 1) is alive. I am not experienced at Python, and I do not know a lot of details about your case - if this change you have applied requires this main process to stop then start again - it will not work, unfortunately. So, rebuild the image.

Hope it helped, have a nice day.

Mikhail2048
  • 1,715
  • 1
  • 9
  • 26
2

Typically, for production, you are suggested to rebuild out a foo/bar to include the update. But, for development, I often use bind mount to override the files in images to have a quick test. A minimal example for your reference:

Structure:

# tree
.
├── docker-compose.yaml
├── Dockerfile
└── run.py

0 directories, 3 files

run.py:

print("helloworld")

Dockerfile:

FROM python:3
WORKDIR /prod
COPY run.py .
CMD python run.py

docker-compose.yaml:

version: "3"

services:
  app:
    build: .

Execution:

# docker-compose up --build
app_1  | helloworld

For local development, I used next:

Change run.py:

print("helloworld!!!")

Change docker-compose.yaml to bind mount local source folder:

version: "3"

services:
  app:
    build: .
    volumes:
      - $PWD:/prod

Execution:

# docker-compose up
app_1  | helloworld!!!

You could see I see new !!! output without build for the second time execution.

atline
  • 28,355
  • 16
  • 77
  • 113
  • Thanks! When I have the time I'll confirm that this solves my issue, but this looks very intuitive with respect to the difference between a production and development environment! – jlos Sep 09 '21 at 09:23
0

When you build a Docker image for a codebase, there would be a layer in Dockerfile that use the COPY command to copy all the files of your codebase to the docker image when you build the image.

When you run a container from this image, the container will only reflect the code which was there in your codebase at the time you ran docker build....

Now when you make changes in your codebase at a later time, it won't be there in the image unless you rebuild the image and then run another container from this newly built image. This new container will have your changes in the codebase.

Making any changes inside the container is actually an antipattern but if you really would like to take that route, then exec -it into your container, install an editor like vim or nano and then go ahead to make the changes in your codebase inside the container.

sxddhxrthx
  • 587
  • 5
  • 13
0

To get fast feedback on workspace changes in web application without rebuilding docker image you need to:

  • map you workspace to docker container using docker volumes
  • reload web server to pick up those changes using file system watcher like nodemon.

To see an example of doing both steps, see this post.

Sample github project you can play with.

rok
  • 9,403
  • 17
  • 70
  • 126