containrrr / watchtower

A process for automating Docker container base image updates.
https://containrrr.dev/watchtower/
Apache License 2.0
18.53k stars 834 forks source link

Manualy tag what containers to look for in order to provide support for buid: . in docker file #1455

Closed Muchaszewski closed 1 year ago

Muchaszewski commented 1 year ago

Is your feature request related to a problem? Please describe.

I would like to use the watchtower to restart provided service in below described docker-compose

docker-compose.yml

services:
  from-build:
    build: .
  watch-tower:
    image: containrrr/watchtower
    ...

Dockerfile

FROM container-first:latest as base

FROM container-second:latest as source
COPY --from=base . .
CMD entrypoint.sh

Expected behavior: The watchtower will watch dependencies in the build/Dockerfile and request an update when needed.

Describe the solution you'd like

I see this 2 ways. Either watchtower would be smart about it and monitor images and directories that are provided in the docker file, or add labels that would suggest what is should watch for this given container. The second could look like this:

docker-compose.yml

services:
  from-build:
    build: .
    labels:
     - com.centurylinklabs.watchtower.deps = "container-first:latest container-second:latest /some/path/to/watch"
  watch-tower:
    image: containrrr/watchtower
    ...

Describe alternatives you've considered

This can be overcome by creating a new docker image for each change of the master image with some CI script, but then all 3 of those containers would need to be stored in some hub.

Pseudocode

if build_is_successful then 
  docker build -f merge-file -t merge:latest .
  docker push merge:latest
fi

For us this would be annoying as the whole point of separating the two images is that they can be pulled independently from each other.

Another alternative that I'm thinking of is to share a volume between the two containers running independently, and that's what I will probably do in the end, without support for such a use case.

version: '3.6'
services:
  container-first:
    image: container-first:latest
    volumes:
        - sharedVolume:/app

  container-first:
    image: container-first:latest
    volumes:
        - sharedVolume:/app2 <-- will have content of the /app from the first container

        /// add watchtower do the compose

volumes:
  sharedVolume:
    external: false

Additional context

No response

github-actions[bot] commented 1 year ago

Hi there! 👋🏼 As you're new to this repo, we'd like to suggest that you read our code of conduct as well as our contribution guidelines. Thanks a bunch for opening your first issue! 🙏

Valentin-Metz commented 1 year ago

I also have this issue. Example: Nextcloud setup with docker compose:

version: "3.9"                                                                                                                                                                                                                               
services:                                                                                                                                                                                                                                    
  nextcloud:                                                                                                                                                                                                                                 
    build: ./nextcloud                                                                                                                                                                                                                       
    restart: always                                                                                                                                                                                                                          
    env_file: ./env.txt
    depends_on:
      - db
      - redis
...

However, I need to install dependencies that allow Nextcloud to interact with an SMB share. Dockerfile of the ./nextcloud folder:

FROM nextcloud:fpm

RUN apt-get update && apt-get install -y smbclient libsmbclient-dev
RUN pecl install smbclient
RUN docker-php-ext-enable smbclient

watchtower does not understand how to check the root nextcloud:fpm image for changes:

time="2023-02-28T07:10:15+01:00" level=warning msg="Could not do a head request for \"nextcloud_compose-nextcloud:latest\", falling back to regular pull." container=/nextcloud_compose-nextcloud-1 image="nextcloud_compose-nextcloud:latest"
time="2023-02-28T07:10:15+01:00" level=warning msg="Reason: registry responded to head request with \"401 Unauthorized\", auth: \"Bearer realm=\\\"https://auth.docker.io/token\\\",service=\\\"registry.docker.io\\\",scope=\\\"repository:library/nextcloud_compose-nextcloud:pull\\\",error=\\\"insufficient_scope\\\"\"" container=/nextcloud_compose-nextcloud-1 image="nextcloud_compose-nextcloud:latest"
time="2023-02-28T07:10:16+01:00" level=info msg="Unable to update container \"/nextcloud_compose-nextcloud-1\": Error response from daemon: pull access denied for nextcloud_compose-nextcloud, repository does not exist or may require 'docker login': denied: requested access to the resource is denied. Proceeding to next."

Is there any way I can tell it to update the compose container (including rebuild), if the mentioned image changes?

piksel commented 1 year ago

This is simply not what watchtower does. It asks the docker daemon (the only channel of communication it has with your environment) for running containers and then checks if those containers have a newer image in their specified repository. It has no knowledge of any Dockerfiles or how the images were created. It's not that your use case is invalid, it's just that it's really far from how watchtower was built. Even if it could tell if the upstream layer that your local image used had been updated, it would have no way of building your new image.

Valentin-Metz commented 1 year ago

Hmm, yes. I understand why this is hard. I might try to write an extension for this in the weekend if I find some time. What do you think about the idea of mounting the folder where docker compose would be executed from and then doing a docker compose pull, along with a docker compose up --force-recreate --build -d in there? The build process could easily be done with https://hub.docker.com/_/docker. And since the host docker socket is mounted anyways, I suppose we could make the docker compose up attach correctly to the host.

simskij commented 1 year ago

As @piksel said, this is outside of the scope of watchtower currently. If anyone provides a PR, however, I'm happy to help with reviews and testing.