mirror of
https://github.com/processone/docker-ejabberd
synced 2024-11-14 18:12:51 +00:00
542 lines
16 KiB
Markdown
542 lines
16 KiB
Markdown
|
|
[![Docker Image Version (latest by date)](https://img.shields.io/docker/v/ejabberd/ecs)](https://hub.docker.com/r/ejabberd/ecs/)
|
|
[![Docker Image Size (latest by date)](https://img.shields.io/docker/image-size/ejabberd/ecs)](https://hub.docker.com/r/ejabberd/ecs/)
|
|
[![Docker Stars](https://img.shields.io/docker/stars/ejabberd/ecs)](https://hub.docker.com/r/ejabberd/ecs/)
|
|
[![Docker Pulls](https://img.shields.io/docker/pulls/ejabberd/ecs)](https://hub.docker.com/r/ejabberd/ecs/)
|
|
[![Build Status](https://github.com/processone/docker-ejabberd/actions/workflows/tests.yml/badge.svg)](https://github.com/processone/docker-ejabberd/actions/workflows/tests.yml)
|
|
[![GitHub stars](https://img.shields.io/github/stars/processone/docker-ejabberd?style=social)](https://github.com/processone/docker-ejabberd)
|
|
|
|
# ejabberd Community Server
|
|
|
|
ejabberd is an open-source XMPP server, robust, scalable and modular,
|
|
built using Erlang/OTP, and also includes MQTT Broker and SIP Service.
|
|
|
|
This container image allows you to run a single node ejabberd instance in a container.
|
|
|
|
There is an [Alternative Image in GitHub Packages](HUB-README.md#alternative-image-in-github), built using a different method and some improvements.
|
|
|
|
If you are using a Windows operating system, check the tutorials mentioned in
|
|
[ejabberd Docs > Docker Image](https://docs.ejabberd.im/admin/installation/#docker-image).
|
|
|
|
# Start ejabberd
|
|
|
|
## With default configuration
|
|
|
|
You can start ejabberd in a new container with the following command:
|
|
|
|
```bash
|
|
docker run --name ejabberd -d -p 5222:5222 ejabberd/ecs
|
|
```
|
|
|
|
This command will run the container image as a daemon,
|
|
using ejabberd default configuration file and XMPP domain "localhost".
|
|
|
|
To stop the running container, you can run:
|
|
|
|
```bash
|
|
docker stop ejabberd
|
|
```
|
|
|
|
If needed, you can restart the stopped ejabberd container with:
|
|
|
|
```bash
|
|
docker restart ejabberd
|
|
```
|
|
|
|
## Start with Erlang console attached
|
|
|
|
If you would like to start ejabberd with an Erlang console attached you can use the `live` command:
|
|
|
|
```bash
|
|
docker run -it -p 5222:5222 ejabberd/ecs live
|
|
```
|
|
|
|
This command will use default configuration file and XMPP domain "localhost".
|
|
|
|
## Start with your configuration and database
|
|
|
|
This command passes the configuration file using the volume feature
|
|
and shares the local directory to store database:
|
|
|
|
```bash
|
|
mkdir database
|
|
docker run -d --name ejabberd -v $(pwd)/ejabberd.yml:/home/ejabberd/conf/ejabberd.yml -v $(pwd)/database:/home/ejabberd/database -p 5222:5222 ejabberd/ecs
|
|
```
|
|
|
|
# Next steps
|
|
|
|
## Register the administrator account
|
|
|
|
The default ejabberd configuration has already granted admin privilege
|
|
to an account that would be called `admin@localhost`,
|
|
so you just need to register such an account
|
|
to start using it for administrative purposes.
|
|
You can register this account using the `ejabberdctl` script, for example:
|
|
|
|
```bash
|
|
docker exec -it ejabberd bin/ejabberdctl register admin localhost passw0rd
|
|
```
|
|
|
|
## Check ejabberd log files
|
|
|
|
Check the ejabberd log file in the container:
|
|
|
|
```bash
|
|
docker exec -it ejabberd tail -f logs/ejabberd.log
|
|
```
|
|
|
|
## Inspect the container files
|
|
|
|
The container uses Alpine Linux. You can start a shell there with:
|
|
|
|
```bash
|
|
docker exec -it ejabberd sh
|
|
```
|
|
|
|
## Open ejabberd debug console
|
|
|
|
You can open a live debug Erlang console attached to a running container:
|
|
|
|
```bash
|
|
docker exec -it ejabberd bin/ejabberdctl debug
|
|
```
|
|
|
|
## CAPTCHA
|
|
|
|
ejabberd includes two example CAPTCHA scripts.
|
|
If you want to use any of them, first install some additional required libraries:
|
|
|
|
```bash
|
|
docker exec --user root ejabberd apk add imagemagick ghostscript-fonts bash
|
|
```
|
|
|
|
Now update your ejabberd configuration file, for example:
|
|
```bash
|
|
docker exec -it ejabberd vi conf/ejabberd.yml
|
|
```
|
|
|
|
and add this option:
|
|
```yaml
|
|
captcha_cmd: /home/ejabberd/lib/ejabberd-21.1.0/priv/bin/captcha.sh
|
|
```
|
|
|
|
Finally, reload the configuration file or restart the container:
|
|
```bash
|
|
docker exec ejabberd bin/ejabberdctl reload_config
|
|
```
|
|
|
|
If the CAPTCHA image is not visible, there may be a problem generating it
|
|
(the ejabberd log file may show some error message);
|
|
or the image URL may not be correctly detected by ejabberd,
|
|
in that case you can set the correct URL manually, for example:
|
|
```yaml
|
|
captcha_url: https://localhost:5443/captcha
|
|
```
|
|
|
|
For more details about CAPTCHA options, please check the
|
|
[CAPTCHA](https://docs.ejabberd.im/admin/configuration/basic/#captcha)
|
|
documentation section.
|
|
|
|
|
|
## Use ejabberdapi
|
|
|
|
When the container is running (and thus ejabberd), you can exec commands inside the container
|
|
using `ejabberdctl` or any other of the available interfaces, see
|
|
[Understanding ejabberd "commands"](https://docs.ejabberd.im/developer/ejabberd-api/#understanding-ejabberd-commands)
|
|
|
|
Additionally, this container image includes the `ejabberdapi` executable.
|
|
Please check the [ejabberd-api homepage](https://github.com/processone/ejabberd-api)
|
|
for configuration and usage details.
|
|
|
|
For example, if you configure ejabberd like this:
|
|
```yaml
|
|
listen:
|
|
-
|
|
port: 5282
|
|
module: ejabberd_http
|
|
request_handlers:
|
|
"/api": mod_http_api
|
|
|
|
acl:
|
|
loopback:
|
|
ip:
|
|
- 127.0.0.0/8
|
|
- ::1/128
|
|
- ::FFFF:127.0.0.1/128
|
|
|
|
api_permissions:
|
|
"admin access":
|
|
who:
|
|
access:
|
|
allow:
|
|
acl: loopback
|
|
what:
|
|
- "register"
|
|
```
|
|
|
|
Then you could register new accounts with this query:
|
|
|
|
```bash
|
|
docker exec -it ejabberd bin/ejabberdapi register --endpoint=http://127.0.0.1:5282/ --jid=admin@localhost --password=passw0rd
|
|
```
|
|
|
|
# Advanced container configuration
|
|
|
|
## Ports
|
|
|
|
This container image exposes the ports:
|
|
|
|
- `5222`: The default port for XMPP clients.
|
|
- `5269`: For XMPP federation. Only needed if you want to communicate with users on other servers.
|
|
- `5280`: For admin interface.
|
|
- `5443`: With encryption, used for admin interface, API, CAPTCHA, OAuth, Websockets and XMPP BOSH.
|
|
- `1883`: Used for MQTT
|
|
- `4369-4399`: EPMD and Erlang connectivity, used for `ejabberdctl` and clustering
|
|
|
|
## Volumes
|
|
|
|
ejabberd produces two types of data: log files and database (Mnesia).
|
|
This is the kind of data you probably want to store on a persistent or local drive (at least the database).
|
|
|
|
Here are the volume you may want to map:
|
|
|
|
- `/home/ejabberd/conf/`: Directory containing configuration and certificates
|
|
- `/home/ejabberd/database/`: Directory containing Mnesia database.
|
|
You should back up or export the content of the directory to persistent storage
|
|
(host storage, local storage, any storage plugin)
|
|
- `/home/ejabberd/logs/`: Directory containing log files
|
|
- `/home/ejabberd/upload/`: Directory containing uploaded files. This should also be backed up.
|
|
|
|
All these files are owned by ejabberd user inside the container. Corresponding
|
|
`UID:GID` is `9000:9000`. If you prefer bind mounts instead of volumes, then
|
|
you need to map this to valid `UID:GID` on your host to get read/write access on
|
|
mounted directories.
|
|
|
|
## Commands on start
|
|
|
|
The ejabberdctl script reads the `CTL_ON_CREATE` environment variable
|
|
the first time the container is started,
|
|
and reads `CTL_ON_START` every time the container is started.
|
|
Those variables can contain one ejabberdctl command,
|
|
or several commands separated with the blankspace and `;` characters.
|
|
|
|
By default failure of any of commands executed that way would
|
|
abort start, this can be disabled by prefixing commands with `!`
|
|
|
|
Example usage (or check the [full example](#customized-example)):
|
|
```yaml
|
|
environment:
|
|
- CTL_ON_CREATE=\! register admin localhost asd
|
|
- CTL_ON_START=stats registeredusers ;
|
|
check_password admin localhost asd ;
|
|
status
|
|
```
|
|
|
|
## Clustering
|
|
|
|
When setting several containers to form a
|
|
[cluster of ejabberd nodes](https://docs.ejabberd.im/admin/guide/clustering/),
|
|
each one must have a different
|
|
[Erlang Node Name](https://docs.ejabberd.im/admin/guide/security/#erlang-node-name)
|
|
and the same
|
|
[Erlang Cookie](https://docs.ejabberd.im/admin/guide/security/#erlang-cookie).
|
|
For this you can either:
|
|
- edit `conf/ejabberdctl.cfg` and set variables `ERLANG_NODE` and `ERLANG_COOKIE`
|
|
- set the environment variables `ERLANG_NODE_ARG` and `ERLANG_COOKIE`
|
|
|
|
Once you have the ejabberd nodes properly set and running,
|
|
you can tell the secondary nodes to join the master node using the
|
|
[`join_cluster`](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/#join-cluster)
|
|
API call.
|
|
|
|
Example using environment variables (see the full
|
|
[`docker-compose.yml` clustering example](#clustering-example)):
|
|
```yaml
|
|
environment:
|
|
- ERLANG_NODE_ARG=ejabberd@replica
|
|
- ERLANG_COOKIE=dummycookie123
|
|
- CTL_ON_CREATE=join_cluster ejabberd@main
|
|
```
|
|
|
|
## Change Mnesia Node Name
|
|
|
|
To use the same Mnesia database in a container with a different hostname,
|
|
it is necessary to change the old hostname stored in Mnesia.
|
|
|
|
This section is equivalent to the ejabberd Documentation
|
|
[Change Computer Hostname](https://docs.ejabberd.im/admin/guide/managing/#change-computer-hostname),
|
|
but particularized to containers that use this
|
|
ecs container image from ejabberd 23.01 or older.
|
|
|
|
### Setup Old Container
|
|
|
|
Let's assume a container running ejabberd 23.01 (or older) from
|
|
this ecs container image, with the database directory binded
|
|
and one registered account.
|
|
This can be produced with:
|
|
```bash
|
|
OLDCONTAINER=ejaold
|
|
NEWCONTAINER=ejanew
|
|
|
|
mkdir database
|
|
sudo chown 9000:9000 database
|
|
docker run -d --name $OLDCONTAINER -p 5222:5222 \
|
|
-v $(pwd)/database:/home/ejabberd/database \
|
|
ejabberd/ecs:23.01
|
|
docker exec -it $OLDCONTAINER bin/ejabberdctl started
|
|
docker exec -it $OLDCONTAINER bin/ejabberdctl register user1 localhost somepass
|
|
docker exec -it $OLDCONTAINER bin/ejabberdctl registered_users localhost
|
|
```
|
|
|
|
Methods to know the Erlang node name:
|
|
```bash
|
|
ls database/ | grep ejabberd@
|
|
docker exec -it $OLDCONTAINER bin/ejabberdctl status
|
|
docker exec -it $OLDCONTAINER grep "started in the node" logs/ejabberd.log
|
|
```
|
|
|
|
### Change Mnesia Node
|
|
|
|
First of all let's store the Erlang node names and paths in variables.
|
|
In this example they would be:
|
|
```bash
|
|
OLDCONTAINER=ejaold
|
|
NEWCONTAINER=ejanew
|
|
OLDNODE=ejabberd@95145ddee27c
|
|
NEWNODE=ejabberd@localhost
|
|
OLDFILE=/home/ejabberd/database/old.backup
|
|
NEWFILE=/home/ejabberd/database/new.backup
|
|
```
|
|
|
|
1. Start your old container that can still read the Mnesia database correctly.
|
|
If you have the Mnesia spool files,
|
|
but don't have access to the old container anymore, go to
|
|
[Create Temporary Container](#create-temporary-container)
|
|
and later come back here.
|
|
|
|
2. Generate a backup file and check it was created:
|
|
```bash
|
|
docker exec -it $OLDCONTAINER bin/ejabberdctl backup $OLDFILE
|
|
ls -l database/*.backup
|
|
```
|
|
|
|
3. Stop ejabberd:
|
|
```bash
|
|
docker stop $OLDCONTAINER
|
|
```
|
|
|
|
4. Create the new container. For example:
|
|
```bash
|
|
docker run \
|
|
--name $NEWCONTAINER \
|
|
-d \
|
|
-p 5222:5222 \
|
|
-v $(pwd)/database:/home/ejabberd/database \
|
|
ejabberd/ecs:latest
|
|
```
|
|
|
|
5. Convert the backup file to new node name:
|
|
```bash
|
|
docker exec -it $NEWCONTAINER bin/ejabberdctl mnesia_change_nodename $OLDNODE $NEWNODE $OLDFILE $NEWFILE
|
|
```
|
|
|
|
6. Install the backup file as a fallback:
|
|
```bash
|
|
docker exec -it $NEWCONTAINER bin/ejabberdctl install_fallback $NEWFILE
|
|
```
|
|
|
|
7. Restart the container:
|
|
```bash
|
|
docker restart $NEWCONTAINER
|
|
```
|
|
|
|
8. Check that the information of the old database is available.
|
|
In this example, it should show that the account `user1` is registered:
|
|
```bash
|
|
docker exec -it $NEWCONTAINER bin/ejabberdctl registered_users localhost
|
|
```
|
|
|
|
9. When the new container is working perfectly with the converted Mnesia database,
|
|
you may want to remove the unneeded files:
|
|
the old container, the old Mnesia spool files, and the backup files.
|
|
|
|
### Create Temporary Container
|
|
|
|
In case the old container that used the Mnesia database is not available anymore,
|
|
a temporary container can be created just to read the Mnesia database
|
|
and make a backup of it, as explained in the previous section.
|
|
|
|
This method uses `--hostname` command line argument for docker,
|
|
and `ERLANG_NODE_ARG` environment variable for ejabberd.
|
|
Their values must be the hostname of your old container
|
|
and the Erlang node name of your old ejabberd node.
|
|
To know the Erlang node name please check
|
|
[Setup Old Container](#setup-old-container).
|
|
|
|
Command line example:
|
|
```bash
|
|
OLDHOST=${OLDNODE#*@}
|
|
docker run \
|
|
-d \
|
|
--name $OLDCONTAINER \
|
|
--hostname $OLDHOST \
|
|
-p 5222:5222 \
|
|
-v $(pwd)/database:/home/ejabberd/database \
|
|
-e ERLANG_NODE_ARG=$OLDNODE \
|
|
ejabberd/ecs:latest
|
|
```
|
|
|
|
Check the old database content is available:
|
|
```bash
|
|
docker exec -it $OLDCONTAINER bin/ejabberdctl registered_users localhost
|
|
```
|
|
|
|
Now that you have ejabberd running with access to the Mnesia database,
|
|
you can continue with step 2 of previous section
|
|
[Change Mnesia Node](#change-mnesia-node).
|
|
|
|
# Generating ejabberd release
|
|
|
|
## Configuration
|
|
|
|
Image is built by embedding an ejabberd Erlang/OTP standalone release in the image.
|
|
|
|
The configuration of ejabberd Erlang/OTP release is customized with:
|
|
|
|
- `rel/config.exs`: Customize ejabberd release
|
|
- `rel/dev.exs`: ejabberd environment configuration for development release
|
|
- `rel/prod.exs`: ejabberd environment configuration for production release
|
|
- `vars.config`: ejabberd compilation configuration options
|
|
- `conf/ejabberd.yml`: ejabberd default config file
|
|
|
|
Build ejabberd Community Server base image from ejabberd master on Github:
|
|
|
|
```bash
|
|
docker build -t ejabberd/ecs .
|
|
```
|
|
|
|
Build ejabberd Community Server base image for a given ejabberd version:
|
|
|
|
```bash
|
|
./build.sh 18.03
|
|
```
|
|
|
|
# Composer Examples
|
|
|
|
## Minimal Example
|
|
|
|
This is the barely minimal file to get a usable ejabberd.
|
|
Store it as `docker-compose.yml`:
|
|
|
|
```yaml
|
|
services:
|
|
main:
|
|
image: ejabberd/ecs
|
|
container_name: ejabberd
|
|
ports:
|
|
- "5222:5222"
|
|
- "5269:5269"
|
|
- "5280:5280"
|
|
- "5443:5443"
|
|
```
|
|
|
|
Create and start the container with the command:
|
|
```bash
|
|
docker-compose up
|
|
```
|
|
|
|
## Customized Example
|
|
|
|
This example shows the usage of several customizations:
|
|
it uses a local configuration file,
|
|
stores the mnesia database in a local path,
|
|
registers an account when it's created,
|
|
and checks the number of registered accounts every time it's started.
|
|
|
|
Download or copy the ejabberd configuration file:
|
|
```bash
|
|
wget https://raw.githubusercontent.com/processone/ejabberd/master/ejabberd.yml.example
|
|
mv ejabberd.yml.example ejabberd.yml
|
|
```
|
|
|
|
Create the database directory and allow the container access to it:
|
|
```bash
|
|
mkdir database
|
|
sudo chown 9000:9000 database
|
|
```
|
|
|
|
Now write this `docker-compose.yml` file:
|
|
```yaml
|
|
version: '3.7'
|
|
|
|
services:
|
|
|
|
main:
|
|
image: ejabberd/ecs
|
|
container_name: ejabberd
|
|
environment:
|
|
- CTL_ON_CREATE=register admin localhost asd
|
|
- CTL_ON_START=registered_users localhost ;
|
|
status
|
|
ports:
|
|
- "5222:5222"
|
|
- "5269:5269"
|
|
- "5280:5280"
|
|
- "5443:5443"
|
|
volumes:
|
|
- ./ejabberd.yml:/home/ejabberd/conf/ejabberd.yml:ro
|
|
- ./database:/home/ejabberd/database
|
|
```
|
|
|
|
## Clustering Example
|
|
|
|
In this example, the main container is created first.
|
|
Once it is fully started and healthy, a second container is created,
|
|
and once ejabberd is started in it, it joins the first one.
|
|
|
|
An account is registered in the first node when created (and
|
|
we ignore errors that can happen when doing that - for example
|
|
when account already exists),
|
|
and it should exist in the second node after join.
|
|
|
|
Notice that in this example the main container does not have access
|
|
to the exterior; the replica exports the ports and can be accessed.
|
|
|
|
```yaml
|
|
version: '3.7'
|
|
|
|
services:
|
|
|
|
main:
|
|
image: ejabberd/ecs
|
|
container_name: main
|
|
environment:
|
|
- ERLANG_NODE_ARG=ejabberd@main
|
|
- ERLANG_COOKIE=dummycookie123
|
|
- CTL_ON_CREATE=\! register admin localhost asd
|
|
healthcheck:
|
|
test: netstat -nl | grep -q 5222
|
|
start_period: 5s
|
|
interval: 5s
|
|
timeout: 5s
|
|
retries: 120
|
|
|
|
replica:
|
|
image: ejabberd/ecs
|
|
container_name: replica
|
|
depends_on:
|
|
main:
|
|
condition: service_healthy
|
|
ports:
|
|
- "5222:5222"
|
|
- "5269:5269"
|
|
- "5280:5280"
|
|
- "5443:5443"
|
|
environment:
|
|
- ERLANG_NODE_ARG=ejabberd@replica
|
|
- ERLANG_COOKIE=dummycookie123
|
|
- CTL_ON_CREATE=join_cluster ejabberd@main
|
|
- CTL_ON_START=registered_users localhost ;
|
|
status
|
|
```
|