Zum Inhalt springen

Streamlining Updates with Watchtower and GitLab CI/CD

13. März 2025 durch
Streamlining Updates with Watchtower and GitLab CI/CD
Robin Steiner

In my previous blog post, "Lightweight Dockerized Gitlab Setup with CI-CD on Ubuntu" we explored setting up a basic GitLab instance with CI/CD capabilities. Now, let's take it a step further and integrate Watchtower for automatic container updates, enhancing our deployment workflow.


What is Watchtower?


Watchtower is a handy tool that monitors your running Docker containers and automatically updates them to the latest available image. This eliminates the manual process of pulling new images and restarting containers, saving you time and effort.


Integrating Watchtower


To add Watchtower to our existing GitLab setup, we'll modify our docker-compose.yaml file:


version: '3.8'  
services:
# ... (GitLab and GitLab Runner services as before)
my-project-frontend:   
​image: registry.gitlab.example.com/<my-group>/<my-project>/frontend
​container_name: my-project-frontend    # ... (other necessary configurations)   
​labels:
​- "com.centurylinklabs.watchtower.enable=true" # This label enables Watchtower to monitor this service

​my-project-backend:   
​image: registry.gitlab.example.com/<my-group>/<my-project>/backend
​container_name: my-project-backend    # ... (other necessary configurations)   
​labels:     
​- "com.centurylinklabs.watchtower.enable=true" # This label enables Watchtower to monitor this service

​watchtower:   
​image: containrrr/watchtower   
​volumes:       
​- /var/run/docker.sock:/var/run/docker.sock       
​- /root/.docker/config.json:/config.json # Mount Docker config for registry credentials   
​environment:       
​- WATCHTOWER_LABEL_ENABLE=true  # Enable monitoring based on labels     
​- WATCHTOWER_CLEANUP=true  # Remove old images after updating       
​- WATCHTOWER_TIMEOUT=30s  # Set timeout for update process       
​- WATCHTOWER_INCLUDE_RESTARTING=true  # Include restarting containers 
​- WATCHTOWER_ROLLING_RESTART=true  # Enable rolling restarts       
​- WATCHTOWER_INCLUDE_STOPPED=true  # Include stopped containers   
​command: --interval 30  # Check for updates every 30 seconds


This adds my-project-frontend and my-project-backend services, labeled for Watchtower to monitor and update. The watchtower service uses your Docker credentials to pull images.


Logging in to the GitLab Registry


First, log in to your GitLab registry to save your credentials:


docker login registry.gitlab.example.com -u <your-username> -p <your-password>


GitLab CI for Automated Builds


Use GitLab CI to automate builds and push updates, triggering Watchtower to update your services. Here's an example .gitlab-ci.yml:


stages:   
​- build

before_script:
​- echo "$CI_REGISTRY_PASSWORD" | docker login $CI_REGISTRY -u $CI_REGISTRY_USER --password-stdin

build frontend:
    image: docker:20.10.16   
    stage: build   
    services:     
    ​- docker:20.10.16-dind   
    script:       
    ​- echo "FRONTEND_VAR=$FRONTEND_VAR" >> ./frontend/.env       
    ​- docker build -t $CI_REGISTRY_IMAGE/frontend:latest ./frontend 
    ​- docker push $CI_REGISTRY_IMAGE/frontend:latest

build backend:
    image: docker:20.10.16   
    stage: build   
    services:     
    ​- docker:20.10.16-dind   

script:       
​- echo "BACKEND_VAR=$BACKEND_VAR" >> ./backend/.env       
​- docker build -t $CI_REGISTRY_IMAGE/backend:latest ./backend       
​- docker push $CI_REGISTRY_IMAGE/backend:latest


Explanation:


  • This configuration defines a build stage with two jobs: build frontend and build backend.
  • The before_script section logs in to the GitLab registry using CI/CD variables.
  • Each job builds a Docker image for the respective component (frontend or backend) and pushes it to the registry.
  • The line - echo "BACKEND_VAR=$BACKEND_VAR" >> ./backend/.env utilize CI/CD variables, such as BACKEND_VAR and FRONTEND_VAR, which are automatically populated during the build process. These variables are then written to a .env file, making them accessible to the application. The advantage of populating the environment variables in this way is that they can be easily edited from the GitLab web interface.


Automated Updates and Considerations


With this setup, whenever you push code changes to your GitLab repository, the CI pipeline will automatically build and push updated images to the registry. Watchtower, monitoring your running containers, will detect these new images and seamlessly update your services. This combination of Watchtower and GitLab CI streamlines the update process, ensuring your applications are always running the latest versions without manual intervention.


However, keep in mind that this approach might introduce brief downtime during updates. Automatic updates also offer less control than manual updates, so thorough testing and a rollback strategy are crucial. Additionally, Watchtower consumes some system resources, which could be a concern in resource-constrained environments. As your system grows in complexity, consider exploring more robust solutions like Kubernetes, which offer features like canary deployments and automated rollbacks for more sophisticated update management.


Stichwörter