Streamlining Updates with Watchtower and GitLab CI/CD

Robin Steiner
09/03/2025

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.

Überzeugt? Kontaktieren Sie uns!

Schicken Sie uns einfach eine Email an office@vorstieg.eu oder füllen Sie das folgende Kontakt-Formular aus: