> ## Content Index
> Fetch the complete content index at: https://www.process-one.net/llms.txt
> Use this file to discover other available public pages before exploring further.

# Docker: Keep ejabberd automagically updated with Watchtower
- URL: https://www.process-one.net/blog/docker-ejabberd-watchtower/
- Published: 2024-11-12T14:15:18.000Z
- Updated: 2026-03-19T15:01:06.000Z
- Description: Learn how to set up ejabberd with Docker, automate updates with Watchtower, and maintain control of updates for a secure and stable server setup.
- Author: Adrien
- Tags: XMPP Academy

This blog post will guide you through the process of setting up an **ejabberd Community Server** using *Docker* and *Docker Compose*, and will also introduce **Watchtower** for automatic updates. This approach ensures that your configuration remains secure and up to date.

Furthermore, we will examine the potential risks associated with automatic updates and suggest **Diun** as an alternative tool for notification-based updates.

## 1\. Prerequisites

Please ensure that Docker and Docker Compose are installed on your system.  
It would be beneficial to have a basic understanding of Docker concepts, including containers, volumes, and bind-mounts.

## 2\. Set up ejabberd in a docker container

Let’s first create a minimal Docker Compose configuration to start an ejabberd instance.

### 2.1: Prepare the directories

For this setup, we will create a directory structure to store the configuration, database, and logs. This will assist in maintaining an organised setup, facilitating data management and backup.

```bash
mkdir ejabberd-setup && cd ejabberd-setup
touch docker-compose.yml
mkdir conf
touch conf/ejabberd.yml
mkdir database
mkdir logs

```

This should give you the following structure:

```bash
ejabberd-setup/
├── conf
│   └── ejabberd.yml
├── database
├── docker-compose.yml
└── logs

```

To verify the structure, use the `tree` command. It is a very useful tool which we use on a daily basis.

#### Set permissions

Since we'll be using bind mounts in this example, it’s important to ensure that specific directories (like database and logs) have the correct permissions for the ejabberd user inside the container (UID `9000`, GID `9000`).

Customize or skip depending on your needs:

```bash
sudo chown -R 9000:9000 database
sudo chown -R 9000:9000 logs

```

*Based on this [Issue](https://github.com/processone/docker-ejabberd/issues/26?ref=process-one.net)*.

### 2.2: The `docker-compose.yml` file

Now, create a `docker-compose.yml` file inside, containing:

```yaml
services:
  ejabberd:
    image: ejabberd/ecs:latest
    container_name: ejabberd
    ports:
      - "5222:5222"  # XMPP Client
      - "5280:5280"  # Web Admin Interface, optional
    volumes:
      - ./database:/home/ejabberd/database
      - ./ejabberd.yml:/home/ejabberd/conf/ejabberd.yml
      - ./logs:/home/ejabberd/logs
    restart: unless-stopped

```

### 2.3: The `ejabberd.yml` file

A basic configuration file for ejabberd will be required. we will name it `conf/ejabberd.yml`.

```yaml
loglevel: 4
hosts:
- "localhost"

acl:
  admin:
    user:
      - "admin@localhost"

access_rules:
  local:
    allow: all

listen
  -
    port: 5222
    module: ejabberd_c2s

  -
    port: 5280                       # optional
    module: ejabberd_http            # optional
    request_handlers:                # optional
      "/admin": ejabberd_web_admin   # optional

```

> Did you know? Since [23.10](https://docs.ejabberd.im/archive/23.10/?ref=process-one.net), ejabberd now offers users the option to create or update the relevant MySQL, PostgreSQL or SQLite tables automatically with each update. You can read more about it [here](https://docs.ejabberd.im/tutorials/mysql/?ref=process-one.net#use-automatic-schema-update).

## 3: Starting ejabberd

Finally, we're set: you can run the following command to start your stack: `docker-compose up -d`

Your ejabberd instance should now running in a Docker container! Good job! 🎉

From there, customize ejabberd to your liking! Naturally, in this example we're going to keep ejabberd in its barebones configuration, but we recommend that you configure it as you wish at this stage, to suit your needs (Domains, SSL, favorite modules, chosen database, admin accounts, etc.)

### Example: You could register your admin account at this stage

To use the admin interface, you need to create an admin account. You can do so by running the following command:

```bash
$ docker exec -it ejabberd bin/ejabberdctl register admin localhost very_secret_password
> User admin@localhost successfully registered

```

Once this step is complete, you will then be able to access the web admin interface at [http://localhost:5280/admin](http://localhost:5280/admin?ref=process-one.net).

## 4\. Set up automatic updates

Finally, we come to the most interesting part: **how do I keep my containers up to date?**

To keep your ejabberd instance up-to-date, you can use [Watchtower](https://github.com/containrrr/watchtower/?ref=process-one.net), a Docker container that automatically updates other containers when new versions are available.

> Warning: Auto-updates are undoubtedly convenient, but they can occasionally cause issues if an update includes breaking changes. Always test updates in a staging environment and back up your data before enabling auto-updates. Further information can be found at the end of this post.

If greater control over updates is required (for example, for mission-critical production servers or clusters), we recommend using [Diun](https://github.com/crazy-max/diun?ref=process-one.net), which can notify you of available updates and allow you to decide when to apply them.

### 4.1: Add Watchtower to your `docker-compose.yml`

To include [Watchtower](https://github.com/containrrr/watchtower/?ref=process-one.net), add it as a service in `docker-compose.yml`:

```yaml
services:
  ejabberd:
    image: ejabberd/ecs:latest
    container_name: ejabberd
    ports:
      - "5222:5222"  # XMPP Client
      - "5280:5280"  # Web Admin Interface, optional
    volumes:
      - ./database:/home/ejabberd/database
      - ./ejabberd.yml:/home/ejabberd/conf/ejabberd.yml
      - ./logs:/home/ejabberd/logs
    restart: unless-stopped

  watchtower:
    image: containrrr/watchtower
    container_name: watchtower
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - WATCHTOWER_POLL_INTERVAL=3600 # Sets how often Watchtower checks for updates (in seconds).
      - WATCHTOWER_CLEANUP=true # Ensures old images are cleaned up after updating.
    restart: unless-stopped

```

[Watchtower](https://github.com/containrrr/watchtower/?ref=process-one.net) offers a wide range of additional features, including the ability to set up notifications, exclude specific containers, and more. For further information, please refer to the [Watchtower Docs](https://containrrr.dev/watchtower/usage-overview/?ref=process-one.net).

Once the `docker-compose.yml` has been updated, please bring it up using the following command: `docker-compose up -d`

And.... here you go, you're all set!

## 5\. Best Practices & closing words

Now [Watchtower](https://github.com/containrrr/watchtower/?ref=process-one.net) will now perform periodic checks for updates to your `ejabberd` container and apply them automatically.

Well to be fair, by default if other containers are running on the same server, Watchtower will also update them. This behaviour can be controlled with the help of environment variables (see [Container Selection](https://containrrr.dev/watchtower/container-selection/?ref=process-one.net)), which will assist in excluding containers from updates.

---

One important thing to understand is that Watchtower will only update containers tagged with the `:latest` tag.

In an environment with numerous Docker containers, using the `latest` tag streamlines the process of automatic updates. However, it may introduce unanticipated changes with each new, disruptive update. Ideally, we recommend always setting a speficic version like `ejabberd/ecs:24.10` and deciding how/when to update it manually (especially if you're into [infra-as-code](https://fr.wikipedia.org/wiki/Infrastructure%5Fas%5Fcode?ref=process-one.net)).

However, we recognise that some users may prefer the convenience of automatic updates, personnally that's what I do my homelab but I'm not scared to dig in if stuff breaks.

---

**tl;dr:** For a small community server/homelab/personnal instance, Watchtower will help keep things up to date with minimal effort. However, for bigger production environments, it is advisable to tag specific versions to ensure greater control and resilience and update them manually.

With this setup, you now have a fully functioning XMPP server using ejabberd, with automatic updates. You can now start building your chat applications or integrate it with your existing services! 🚀