Rebuild Docker container on file changes

前端 未结 3 1000
再見小時候
再見小時候 2020-12-22 18:49

For running an ASP.NET Core application, I generated a dockerfile which build the application and copys the source code in the container, which is fetched by Git using Jenki

相关标签:
3条回答
  • 2020-12-22 18:53

    Whenever changes are made in dockerfile or compose or requirements , re-Run it using docker-compose up --build . So that images get rebuild and refreshed

    0 讨论(0)
  • 2020-12-22 18:58

    After some research and testing, I found that I had some misunderstandings about the lifetime of Docker containers. Simply restarting a container doesn't make Docker use a new image, when the image was rebuilt in the meantime. Instead, Docker is fetching the image only before creating the container. So the state after running a container is persistent.

    Why removing is required

    Therefore, rebuilding and restarting isn't enough. I thought containers works like a service: Stopping the service, do your changes, restart it and they would apply. That was my biggest mistake.

    Because containers are permanent, you have to remove them using docker rm <ContainerName> first. After a container is removed, you can't simply start it by docker start. This has to be done using docker run, which itself uses the latest image for creating a new container-instance.

    Containers should be as independent as possible

    With this knowledge, it's comprehensible why storing data in containers is qualified as bad practice and Docker recommends data volumes/mounting host directorys instead: Since a container has to be destroyed to update applications, the stored data inside would be lost too. This cause extra work to shutdown services, backup data and so on.

    So it's a smart solution to exclude those data completely from the container: We don't have to worry about our data, when its stored safely on the host and the container only holds the application itself.

    Why -rf may not really help you

    The docker run command, has a Clean up switch called -rf. It will stop the behavior of keeping docker containers permanently. Using -rf, Docker will destroy the container after it has been exited. But this switch has two problems:

    1. Docker also remove the volumes without a name associated with the container, which may kill your data
    2. Using this option, its not possible to run containers in the background using -d switch

    While the -rf switch is a good option to save work during development for quick tests, it's less suitable in production. Especially because of the missing option to run a container in the background, which would mostly be required.

    How to remove a container

    We can bypass those limitations by simply removing the container:

    docker rm --force <ContainerName>
    

    The --force (or -f) switch which use SIGKILL on running containers. Instead, you could also stop the container before:

    docker stop <ContainerName>
    docker rm <ContainerName>
    

    Both are equal. docker stop is also using SIGTERM. But using --force switch will shorten your script, especially when using CI servers: docker stop throws an error if the container is not running. This would cause Jenkins and many other CI servers to consider the build wrongly as failed. To fix this, you have to check first if the container is running as I did in the question (see containerRunning variable).

    Full script for rebuilding a Docker container

    According to this new knowledge, I fixed my script in the following way:

    #!/bin/bash
    imageName=xx:my-image
    containerName=my-container
    
    docker build -t $imageName -f Dockerfile  .
    
    echo Delete old container...
    docker rm -f $containerName
    
    echo Run new container...
    docker run -d -p 5000:5000 --name $containerName $imageName
    

    This works perfectly :)

    0 讨论(0)
  • 2020-12-22 19:08

    You can run build for a specific service by running docker-compose up --build <service name> where the service name must match how did you call it in your docker-compose file.

    Example Let's assume that your docker-compose file contains many services (.net app - database - let's encrypt... etc) and you want to update only the .net app which named as application in docker-compose file. You can then simply run docker-compose up --build application

    Extra parameters In case you want to add extra parameters to your command such as -d for running in the background, the parameter must be before the service name: docker-compose up --build -d application

    0 讨论(0)
提交回复
热议问题