├── .github
└── workflows
│ ├── code-server.yml
│ ├── devcontainer.yml
│ └── tests.yml
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── README.md
├── code-server
└── Dockerfile
├── devcontainer
└── Dockerfile
├── ecs
├── .gitignore
├── Dockerfile
├── HUB-README.md
├── README.md
├── bin
│ ├── ejabberdctl
│ └── erl
├── build.sh
├── conf
│ ├── dhparams.pem
│ ├── ejabberd.yml
│ ├── ejabberdctl.cfg
│ ├── inetrc
│ └── server.pem
├── config.exs
├── ejabberd-docker-install.bat
├── hooks
│ └── build
├── rel
│ ├── config.exs
│ ├── dev.exs
│ └── prod.exs
└── vars.config
└── mix
├── Dockerfile
└── README.md
/.github/workflows/code-server.yml:
--------------------------------------------------------------------------------
1 | name: code-server
2 |
3 | on:
4 | push:
5 | paths:
6 | - '.github/workflows/code-server.yml'
7 | - 'code-server/**'
8 |
9 | jobs:
10 |
11 | code-server:
12 |
13 | runs-on: ubuntu-latest
14 | permissions:
15 | contents: read
16 | packages: write
17 |
18 | steps:
19 |
20 | - uses: actions/checkout@v4
21 |
22 | - name: Build image
23 | run: docker build
24 | code-server
25 | --tag code-server
26 |
27 | - name: Login to GitHub Container Registry
28 | uses: docker/login-action@v3
29 | with:
30 | registry: ghcr.io
31 | username: ${{ github.repository_owner }}
32 | password: ${{ secrets.GITHUB_TOKEN }}
33 |
34 | - name: Push image
35 | run: |
36 | IMAGE_ID=ghcr.io/${{ github.repository_owner }}/code-server
37 | # Strip git ref prefix from version
38 | VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,')
39 | # Use Docker `latest` tag convention
40 | [ "$VERSION" == "master" ] && VERSION=latest
41 | docker tag code-server $IMAGE_ID:$VERSION
42 | docker push $IMAGE_ID:$VERSION
43 |
--------------------------------------------------------------------------------
/.github/workflows/devcontainer.yml:
--------------------------------------------------------------------------------
1 | name: devcontainer
2 |
3 | on:
4 | push:
5 | paths:
6 | - '.github/workflows/devcontainer.yml'
7 | - 'devcontainer/**'
8 |
9 | jobs:
10 |
11 | devcontainer:
12 |
13 | runs-on: ubuntu-latest
14 | permissions:
15 | contents: read
16 | packages: write
17 |
18 | steps:
19 |
20 | - uses: actions/checkout@v4
21 |
22 | - name: Build image
23 | run: docker build
24 | devcontainer
25 | --tag devcontainer
26 |
27 | - name: Login to GitHub Container Registry
28 | uses: docker/login-action@v3
29 | with:
30 | registry: ghcr.io
31 | username: ${{ github.repository_owner }}
32 | password: ${{ secrets.GITHUB_TOKEN }}
33 |
34 | - name: Push image
35 | run: |
36 | IMAGE_ID=ghcr.io/${{ github.repository_owner }}/devcontainer
37 | # Strip git ref prefix from version
38 | VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,')
39 | # Use Docker `latest` tag convention
40 | [ "$VERSION" == "master" ] && VERSION=latest
41 | docker tag devcontainer $IMAGE_ID:$VERSION
42 | docker push $IMAGE_ID:$VERSION
43 |
--------------------------------------------------------------------------------
/.github/workflows/tests.yml:
--------------------------------------------------------------------------------
1 | name: Tests
2 |
3 | on:
4 | push:
5 | paths:
6 | - '.github/workflows/tests.yml'
7 | - 'ecs/**'
8 | - 'mix/**'
9 | pull_request:
10 | paths:
11 | - '.github/workflows/tests.yml'
12 | - 'ecs/**'
13 | - 'mix/**'
14 |
15 | env:
16 | REGISTRY_GHCR: ghcr.io
17 | REGISTRY_LOCAL: localhost:5000
18 | REGISTRY_DOCKER: docker.io
19 | MIX_IMAGENAME_GHCR: ${{ github.repository_owner }}/mix
20 | ECS_IMAGENAME_GHCR: ${{ github.repository_owner }}/ecs
21 | MIX_IMAGENAME_DOCKERHUB: ejabberd/mix
22 | ECS_IMAGENAME_DOCKERHUB: ejabberd/ecs
23 |
24 | jobs:
25 |
26 | build:
27 | name: Build
28 | runs-on: ubuntu-24.04
29 | strategy:
30 | fail-fast: true
31 | max-parallel: 1
32 | permissions:
33 | packages: write
34 | services:
35 | registry:
36 | image: registry:2
37 | ports:
38 | - 5000:5000
39 |
40 | steps:
41 |
42 | - name: Checkout code
43 | uses: actions/checkout@v4
44 | with:
45 | fetch-depth: 0
46 |
47 | - name: Login to GHCR
48 | uses: docker/login-action@v3
49 | with:
50 | registry: ${{ env.REGISTRY_GHCR }}
51 | username: ${{ github.actor }}
52 | password: ${{ secrets.GITHUB_TOKEN }}
53 |
54 | - name: Login to Docker Hub
55 | uses: docker/login-action@v3
56 | with:
57 | username: ${{ secrets.DOCKERHUB_USERNAME }}
58 | password: ${{ secrets.DOCKERHUB_TOKEN }}
59 |
60 | - name: Get git describe
61 | id: gitdescribe
62 | run: echo "ver=$(git describe --tags --exact-match 2>/dev/null || echo latest)" >> $GITHUB_OUTPUT
63 |
64 | - name: Extract mix metadata (tags, labels)
65 | id: mixmeta
66 | if: github.ref_type == 'tag'
67 | uses: docker/metadata-action@v5
68 | with:
69 | images: |
70 | ${{ env.REGISTRY_GHCR }}/${{ env.MIX_IMAGENAME_GHCR }}
71 | ${{ env.REGISTRY_DOCKER }}/${{ env.MIX_IMAGENAME_DOCKERHUB }}
72 | labels: |
73 | org.opencontainers.image.revision=${{ steps.gitdescribe.outputs.ver }}
74 | org.opencontainers.image.licenses=GPL-2.0
75 | org.opencontainers.image.vendor=ProcessOne
76 |
77 | - name: Extract ecs metadata (tags, labels)
78 | id: ecsmeta
79 | if: github.ref_type == 'tag'
80 | uses: docker/metadata-action@v5
81 | with:
82 | images: |
83 | ${{ env.REGISTRY_GHCR }}/${{ env.ECS_IMAGENAME_GHCR }}
84 | ${{ env.REGISTRY_DOCKER }}/${{ env.ECS_IMAGENAME_DOCKERHUB }}
85 | labels: |
86 | org.opencontainers.image.revision=${{ steps.gitdescribe.outputs.ver }}
87 | org.opencontainers.image.licenses=GPL-2.0
88 | org.opencontainers.image.vendor=ProcessOne
89 |
90 | - name: Prepare local tags
91 | id: localreg
92 | run: |
93 | tag="$(echo ${{ github.ref_name }} | sed -e 's|[/]\+|-|g')"
94 | echo "mixlocaltag=${{ env.REGISTRY_LOCAL }}/${{ env.MIX_IMAGENAME_GHCR }}:$tag" >> $GITHUB_OUTPUT
95 | echo "ecslocaltag=${{ env.REGISTRY_LOCAL }}/${{ env.ECS_IMAGENAME_GHCR }}:$tag" >> $GITHUB_OUTPUT
96 |
97 | - name: Set up Docker Buildx
98 | uses: docker/setup-buildx-action@v3
99 | with:
100 | driver-opts: network=host
101 |
102 | - name: Build and push local mix image
103 | uses: docker/build-push-action@v5
104 | with:
105 | build-args: |
106 | VERSION=${{ steps.gitdescribe.outputs.ver }}
107 | cache-from: type=gha
108 | cache-to: type=gha,mode=max
109 | context: mix
110 | labels: ${{ steps.mixmeta.outputs.labels }}
111 | platforms: linux/amd64
112 | push: true
113 | tags: |
114 | ${{ steps.localreg.outputs.mixlocaltag }}
115 |
116 | - name: Prepare ecs Dockerfile
117 | run: sed -i 's|docker.io/ejabberd/mix|${{ steps.localreg.outputs.mixlocaltag }}|g' ecs/Dockerfile
118 |
119 | - name: Build and push local ecs image
120 | uses: docker/build-push-action@v5
121 | with:
122 | build-args: |
123 | VERSION=${{ steps.gitdescribe.outputs.ver }}
124 | cache-from: type=gha
125 | cache-to: type=gha,mode=max
126 | context: ecs
127 | labels: ${{ steps.ecsmeta.outputs.labels }}
128 | platforms: linux/amd64
129 | push: true
130 | tags: |
131 | ${{ steps.localreg.outputs.ecslocaltag }}
132 |
133 | - name: Run ecs image
134 | run: |
135 | docker images
136 | docker run --name ejabberd -d -p 5222:5222 ${{ steps.localreg.outputs.ecslocaltag }}
137 |
138 | - name: Wait ejabberd started
139 | run: |
140 | docker exec ejabberd bin/ejabberdctl started
141 |
142 | - name: Check ecs results
143 | if: always()
144 | run: |
145 | docker ps -s
146 | docker logs ejabberd
147 | docker logs ejabberd | grep -q "Start accepting TCP connections" || exit 1
148 | docker logs ejabberd | grep -q "error" && exit 1 || exit 0
149 | docker logs ejabberd | grep -q "Error" && exit 1 || exit 0
150 |
151 | - name: Save image
152 | run: |
153 | docker image save ${{ steps.localreg.outputs.ecslocaltag }} --output ejabberd-latest.tar
154 |
155 | - name: Upload image
156 | uses: actions/upload-artifact@v4
157 | with:
158 | name: ejabberd-image
159 | path: ejabberd-latest.tar
160 |
161 | - run: |
162 | echo "::notice::To get this image, download ejabberd-image.zip, "\
163 | "uncompress it and run: " \
164 | "docker image load -i ejabberd-latest.tar"
165 |
166 | - name: Build and push mix image
167 | uses: docker/build-push-action@v5
168 | if: github.ref_type == 'tag'
169 | with:
170 | build-args: |
171 | VERSION=${{ steps.gitdescribe.outputs.ver }}
172 | cache-from: type=gha
173 | cache-to: type=gha,mode=max
174 | context: mix
175 | labels: ${{ steps.mixmeta.outputs.labels }}
176 | platforms: linux/amd64
177 | push: true
178 | tags: |
179 | ${{ steps.mixmeta.outputs.tags }}
180 |
181 | - name: Build and push ecs image
182 | uses: docker/build-push-action@v5
183 | if: github.ref_type == 'tag'
184 | with:
185 | build-args: |
186 | VERSION=${{ steps.gitdescribe.outputs.ver }}
187 | cache-from: type=gha
188 | cache-to: type=gha,mode=max
189 | context: ecs
190 | labels: ${{ steps.ecsmeta.outputs.labels }}
191 | platforms: linux/amd64
192 | push: true
193 | tags: |
194 | ${{ steps.ecsmeta.outputs.tags }}
195 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Version 19.08
2 |
3 | - Update default configuration
4 | - Add sqlite libs
5 | - Fix sample Let's Encrypt configuration
6 | - Add badges and links docker README
7 | - Allow mapping of upload dir as volume
8 | - Fix INET_DIST_INTERFACE
9 | - Add travis support
10 | - Add STUN/TURN & SIP support
11 | - Add libgd for image manupilation
12 | - Add Dockerhub build hook
13 | - Keep SQL init scripts in database volume
14 | - Update use of new distillery
15 |
16 | # Version 19.05
17 |
18 | - Update default configuration
19 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
6 |
7 | ## Our Standards
8 |
9 | Examples of behavior that contributes to creating a positive environment include:
10 |
11 | * Using welcoming and inclusive language
12 | * Being respectful of differing viewpoints and experiences
13 | * Gracefully accepting constructive criticism
14 | * Focusing on what is best for the community
15 | * Showing empathy towards other community members
16 |
17 | Examples of unacceptable behavior by participants include:
18 |
19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances
20 | * Trolling, insulting/derogatory comments, and personal or political attacks
21 | * Public or private harassment
22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission
23 | * Other conduct which could reasonably be considered inappropriate in a professional setting
24 |
25 | ## Our Responsibilities
26 |
27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
28 |
29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
30 |
31 | ## Scope
32 |
33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
34 |
35 | ## Enforcement
36 |
37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at conduct@process-one.net. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
38 |
39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
40 |
41 | ## Attribution
42 |
43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
44 |
45 | [homepage]: http://contributor-covenant.org
46 | [version]: http://contributor-covenant.org/version/1/4/
47 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | We'd love for you to contribute to our source code and to make our project even better than it is
4 | today! Here are the guidelines we'd like you to follow:
5 |
6 | * [Code of Conduct](#coc)
7 | * [Questions and Problems](#question)
8 | * [Issues and Bugs](#issue)
9 | * [Feature Requests](#feature)
10 | * [Issue Submission Guidelines](#submit)
11 | * [Pull Request Submission Guidelines](#submit-pr)
12 | * [Signing the CLA](#cla)
13 |
14 | ## Code of Conduct
15 |
16 | Help us keep our community open-minded and inclusive. Please read and follow our [Code of Conduct][coc].
17 |
18 | ## Questions, Bugs, Features
19 |
20 | ### Got a Question or Problem?
21 |
22 | Do not open issues for general support questions as we want to keep GitHub issues for bug reports
23 | and feature requests. You've got much better chances of getting your question answered on dedicated
24 | support platforms, the best being [Stack Overflow][stackoverflow].
25 |
26 | Stack Overflow is a much better place to ask questions since:
27 |
28 | - there are thousands of people willing to help on Stack Overflow
29 | - questions and answers stay available for public viewing so your question / answer might help
30 | someone else
31 | - Stack Overflow's voting system assures that the best answers are prominently visible.
32 |
33 | To save your and our time, we will systematically close all issues that are requests for general
34 | support and redirect people to the section you are reading right now.
35 |
36 | ### Found an Issue or Bug?
37 |
38 | If you find a bug in the source code, you can help us by submitting an issue to our
39 | [GitHub Repository][github]. Even better, you can submit a Pull Request with a fix.
40 |
41 | ### Missing a Feature?
42 |
43 | You can request a new feature by submitting an issue to our [GitHub Repository][github-issues].
44 |
45 | If you would like to implement a new feature then consider what kind of change it is:
46 |
47 | * **Major Changes** that you wish to contribute to the project should be discussed first in an
48 | [GitHub issue][github-issues] that clearly outlines the changes and benefits of the feature.
49 | * **Small Changes** can directly be crafted and submitted to the [GitHub Repository][github]
50 | as a Pull Request. See the section about [Pull Request Submission Guidelines](#submit-pr).
51 |
52 | ## Issue Submission Guidelines
53 |
54 | Before you submit your issue search the archive, maybe your question was already answered.
55 |
56 | If your issue appears to be a bug, and hasn't been reported, open a new issue. Help us to maximize
57 | the effort we can spend fixing issues and adding new features, by not reporting duplicate issues.
58 |
59 | The "[new issue][github-new-issue]" form contains a number of prompts that you should fill out to
60 | make it easier to understand and categorize the issue.
61 |
62 | ## Pull Request Submission Guidelines
63 |
64 | By submitting a pull request for a code or doc contribution, you need to have the right
65 | to grant your contribution's copyright license to ProcessOne. Please check [ProcessOne CLA][cla]
66 | for details.
67 |
68 | Before you submit your pull request consider the following guidelines:
69 |
70 | * Search [GitHub][github-pr] for an open or closed Pull Request
71 | that relates to your submission. You don't want to duplicate effort.
72 | * Make your changes in a new git branch:
73 |
74 | ```shell
75 | git checkout -b my-fix-branch master
76 | ```
77 | * Test your changes and, if relevant, expand the automated test suite.
78 | * Create your patch commit, including appropriate test cases.
79 | * If the changes affect public APIs, change or add relevant documentation.
80 | * Commit your changes using a descriptive commit message.
81 |
82 | ```shell
83 | git commit -a
84 | ```
85 | Note: the optional commit `-a` command line option will automatically "add" and "rm" edited files.
86 |
87 | * Push your branch to GitHub:
88 |
89 | ```shell
90 | git push origin my-fix-branch
91 | ```
92 |
93 | * In GitHub, send a pull request to `master` branch. This will trigger the continuous integration and run the test.
94 | We will also notify you if you have not yet signed the [contribution agreement][cla].
95 |
96 | * If you find that the continunous integration has failed, look into the logs to find out
97 | if your changes caused test failures, the commit message was malformed etc. If you find that the
98 | tests failed or times out for unrelated reasons, you can ping a team member so that the build can be
99 | restarted.
100 |
101 | * If we suggest changes, then:
102 |
103 | * Make the required updates.
104 | * Test your changes and test cases.
105 | * Commit your changes to your branch (e.g. `my-fix-branch`).
106 | * Push the changes to your GitHub repository (this will update your Pull Request).
107 |
108 | You can also amend the initial commits and force push them to the branch.
109 |
110 | ```shell
111 | git rebase master -i
112 | git push origin my-fix-branch -f
113 | ```
114 |
115 | This is generally easier to follow, but separate commits are useful if the Pull Request contains
116 | iterations that might be interesting to see side-by-side.
117 |
118 | That's it! Thank you for your contribution!
119 |
120 | ## Signing the Contributor License Agreement (CLA)
121 |
122 | Upon submitting a Pull Request, we will ask you to sign our CLA if you haven't done
123 | so before. It's a quick process, we promise, and you will be able to do it all online
124 |
125 | You can read [ProcessOne Contribution License Agreement][cla] in PDF.
126 |
127 | This is part of the legal framework of the open-source ecosystem that adds some red tape,
128 | but protects both the contributor and the company / foundation behind the project. It also
129 | gives us the option to relicense the code with a more permissive license in the future.
130 |
131 |
132 | [coc]: https://github.com/processone/docker-ejabberd/blob/master/CODE_OF_CONDUCT.md
133 | [stackoverflow]: https://stackoverflow.com/
134 | [github]: https://github.com/processone/docker-ejabberd
135 | [github-issues]: https://github.com/processone/docker-ejabberd/issues
136 | [github-new-issue]: https://github.com/processone/docker-ejabberd/issues/new
137 | [github-pr]: https://github.com/processone/docker-ejabberd/pulls
138 | [cla]: https://www.process-one.net/resources/ejabberd-cla.pdf
139 | [license]: https://github.com/processone/docker-ejabberd/blob/master/LICENSE.txt
140 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | [](https://github.com/processone/docker-ejabberd/actions/workflows/tests.yml)
3 |
4 | # docker-ejabberd
5 |
6 | This repository contains a set of container images to run or develop ejabberd:
7 |
8 | - [mix](mix/) (published in [docker.io/ejabberd/mix](https://hub.docker.com/r/ejabberd/mix/)
9 | and [ghcr.io/processone/mix](https://github.com/processone/docker-ejabberd/pkgs/container/mix)):
10 |
11 | Build a development environment for ejabberd. See [mix README](mix/README.md) file for details.
12 |
13 | - [ecs](ecs/) (published in [docker.io/ejabberd/ecs](https://hub.docker.com/r/ejabberd/ecs/)
14 | and [ghcr.io/processone/ecs](https://github.com/processone/docker-ejabberd/pkgs/container/ecs)):
15 |
16 | Run ejabberd in a container with simple setup.
17 | See [ecs README](ecs/README.md) file for details.
18 |
19 | - [code-server](code-server/) (published in [ghcr.io/processone/code-server](https://github.com/orgs/processone/packages/container/package/code-server)):
20 |
21 | Run Coder's code-server with a local ejabberd git clone.
22 | See [VSCode section](https://docs.ejabberd.im/developer/vscode/) in ejabberds Docs.
23 |
24 | - [devcontainer](devcontainer/) (published in [ghcr.io/processone/devcontainer](https://github.com/orgs/processone/packages/container/package/devcontainer)):
25 |
26 | Use as a Dev Container for ejabberd in Visual Studio Code.
27 | See [VSCode section](https://docs.ejabberd.im/developer/vscode/) in ejabberds Docs.
28 |
29 | The [ejabberd source code repository](https://github.com/processone/ejabberd) also provides:
30 |
31 | - [ejabberd](https://github.com/processone/ejabberd/tree/master/.github/container) (published in [ghcr.io/processone/ejabberd](https://github.com/processone/ejabberd/pkgs/container/ejabberd)):
32 |
33 | Run ejabberd in a container with simple setup.
34 | See [ejabberd's CONTAINER](https://github.com/processone/ejabberd/blob/master/CONTAINER.md) file for details.
35 | Check the [differences between this image and `ecs`](https://github.com/processone/docker-ejabberd/blob/master/ecs/HUB-README.md#alternative-image-in-github).
36 |
--------------------------------------------------------------------------------
/code-server/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM debian:sid-slim
2 |
3 | RUN apt-get update \
4 | && apt-get -y --no-install-recommends install \
5 | curl ca-certificates \
6 | autoconf automake git make gcc g++ \
7 | erlang erlang-dev elixir rebar3 \
8 | libexpat1-dev libgd-dev libpam0g-dev \
9 | libsqlite3-dev libwebp-dev libyaml-dev \
10 | libssl-dev
11 |
12 | RUN curl -fsSL https://code-server.dev/install.sh | sh
13 |
14 | RUN addgroup vscode --gid 1000 \
15 | && adduser --shell /bin/bash --ingroup vscode vscode -u 1000
16 |
17 | USER vscode
18 |
19 | RUN /usr/bin/code-server --install-extension erlang-ls.erlang-ls
20 |
21 | WORKDIR /home/vscode
22 | RUN echo "export PATH=/workspaces/ejabberd/_build/relive:$PATH" >>.bashrc \
23 | && echo "COOKIE" >.erlang.cookie \
24 | && chmod 400 .erlang.cookie
25 |
26 | WORKDIR /workspaces/ejabberd
27 | VOLUME ["workspaces/ejabberd"]
28 | EXPOSE 1870 1883 4369-4399 5210 5222 5269 5280 5443
29 |
30 | ENTRYPOINT ["code-server", "--bind-addr", "0.0.0.0:1870", "--auth", "none", "/workspaces/ejabberd"]
31 |
--------------------------------------------------------------------------------
/devcontainer/Dockerfile:
--------------------------------------------------------------------------------
1 | # [Choice] Alpine version: 3.16, 3.15, 3.14, 3.13
2 | ARG VARIANT=latest
3 | FROM alpine:${VARIANT}
4 |
5 | RUN apk upgrade --update musl \
6 | && apk add \
7 | autoconf \
8 | automake \
9 | bash \
10 | build-base \
11 | curl \
12 | elixir \
13 | erlang-debugger \
14 | erlang-observer \
15 | erlang-odbc \
16 | erlang-reltool \
17 | expat-dev \
18 | file \
19 | gd-dev \
20 | git \
21 | jpeg-dev \
22 | libpng-dev \
23 | libwebp-dev \
24 | linux-pam-dev \
25 | openssl \
26 | openssl-dev \
27 | sqlite-dev \
28 | yaml-dev \
29 | zlib-dev
30 |
31 | # [Option] Install zsh
32 | ARG INSTALL_ZSH="true"
33 |
34 | # Install needed packages and setup non-root user. Use a separate RUN statement to add your own dependencies.
35 | ARG USERNAME=vscode
36 | ARG USER_UID=1000
37 | ARG USER_GID=$USER_UID
38 | ARG COMMON_SCRIPT_SOURCE="https://raw.githubusercontent.com/devcontainers/images/v0.2.31/src/base-alpine/.devcontainer/library-scripts/common-alpine.sh"
39 | RUN apk update \
40 | && curl -sSL ${COMMON_SCRIPT_SOURCE} -o /tmp/common-alpine.sh \
41 | && ash /tmp/common-alpine.sh "${INSTALL_ZSH}" "${USERNAME}" "${USER_UID}" "${USER_GID}" \
42 | && rm -rf /tmp/common-alpine.sh
43 |
44 | RUN mix local.hex --force \
45 | && mix local.rebar --force
46 |
47 | RUN apk add \
48 | expat \
49 | freetds \
50 | gd \
51 | jpeg \
52 | libgd \
53 | libpng \
54 | libstdc++ \
55 | libwebp \
56 | linux-pam \
57 | ncurses-libs \
58 | openssl \
59 | sqlite \
60 | sqlite-libs \
61 | unixodbc \
62 | yaml \
63 | zlib \
64 | && ln -fs /usr/lib/libtdsodbc.so.0 /usr/lib/libtdsodbc.so \
65 | && rm -rf /var/cache/apk/*
66 |
--------------------------------------------------------------------------------
/ecs/.gitignore:
--------------------------------------------------------------------------------
1 | db/
2 | ejbuild/
3 | log/
4 | *.tar.gz
5 |
6 |
--------------------------------------------------------------------------------
/ecs/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM docker.io/golang:1.22-alpine AS api
2 | RUN go install -v \
3 | github.com/processone/ejabberd-api/cmd/ejabberd@latest \
4 | && mv bin/ejabberd bin/ejabberdapi
5 |
6 | FROM docker.io/ejabberd/mix AS builder
7 | ARG VERSION
8 | ENV VERSION=${VERSION:-latest} \
9 | MIX_ENV=prod
10 | LABEL maintainer="ProcessOne " \
11 | product="Ejabberd Community Server builder"
12 |
13 | # Get ejabberd sources, dependencies, configuration
14 | RUN git clone https://github.com/processone/ejabberd.git
15 | WORKDIR /ejabberd
16 | COPY vars.config .
17 | COPY config.exs config/
18 | COPY rel/*exs rel/
19 | RUN git checkout ${VERSION/latest/HEAD} \
20 | \
21 | && if [[ "$VERSION" =~ ^[0-9]+\.[0-9]+$ ]]; then \
22 | echo '{vsn, "'"$VERSION.0"'"}.' >> vars.config; \
23 | else \
24 | echo '{vsn, "0.0.0"}.' >> vars.config; \
25 | fi \
26 | \
27 | && mix deps.get \
28 | && (cd deps/eimp; ./configure)
29 |
30 | # Compile
31 | RUN MIX_ENV=prod mix release
32 |
33 | # Prepare runtime environment
34 | RUN mkdir runtime \
35 | && tar -C runtime -zxf _build/prod/ejabberd-*.tar.gz \
36 | && cd runtime \
37 | && cp releases/*/start.boot bin \
38 | && cp releases/*/start_clean.boot bin \
39 | && echo 'beam_lib:strip_files(filelib:wildcard("lib/*/ebin/*beam")), init:stop().' | erl >/dev/null \
40 | && mv erts*/bin/* bin \
41 | && EJABBERD_VERSION=`(cd releases; ls -1 -d *.*.*)` \
42 | && rm -rf releases erts* bin/*src bin/dialyzer bin/typer etc \
43 | && rm bin/ejabberd \
44 | && mkdir lib/ejabberd-$EJABBERD_VERSION/priv/bin \
45 | && cp /usr/lib/elixir/bin/* bin/ \
46 | && sed -i 's|ERL_EXEC="erl"|ERL_EXEC="/home/ejabberd/bin/erl"|' bin/elixir \
47 | && cp /ejabberd/tools/captcha*sh bin/ \
48 | && cp -r /ejabberd/sql lib/ejabberd-*/priv
49 |
50 | # Runtime container
51 | FROM docker.io/alpine:3.19
52 | ARG VERSION
53 | ARG VCS_REF
54 | ARG BUILD_DATE
55 | ENV TERM=xterm \
56 | LC_ALL=C.UTF-8 \
57 | LANG=en_US.UTF-8 \
58 | LANGUAGE=en_US.UTF-8 \
59 | REPLACE_OS_VARS=true \
60 | HOME=/home/ejabberd \
61 | PATH="$PATH:/home/ejabberd/bin" \
62 | VERSION=${VERSION:-latest}
63 | LABEL maintainer="ProcessOne " \
64 | product="Ejabberd Community Server Official Docker Image" \
65 | version=$VERSION \
66 | org.label-schema.vcs-ref=$VCS_REF \
67 | org.label-schema.vcs-url="https://github.com/processone/docker-ejabberd" \
68 | org.label-schema.build-date=$BUILD_DATE \
69 | org.label-schema.name="Ejabberd Community Server Official Docker Image" \
70 | org.label-schema.description="Robust, Scalable and Extensible Realtime Server using XMPP, MQTT and SIP" \
71 | org.label-schema.url="https://www.ejabberd.im/" \
72 | org.label-schema.vendor="ProcessOne" \
73 | org.label-schema.version=$VERSION \
74 | org.label-schema.schema-version="1.0"
75 |
76 | # Create directory structure and user for ejabberd
77 | RUN addgroup ejabberd -g 9000 \
78 | && adduser -s /bin/sh -D -G ejabberd ejabberd -u 9000 \
79 | && mkdir -p /home/ejabberd/conf /home/ejabberd/database /home/ejabberd/logs /home/ejabberd/upload \
80 | && chown -R ejabberd:ejabberd /home/ejabberd \
81 | && ln -fs /home/ejabberd /opt/ejabberd \
82 | && ln -fs /home/ejabberd /opt/ejabberd-$VERSION
83 |
84 | # Install required dependencies
85 | RUN apk upgrade --update-cache --no-progress \
86 | && apk add \
87 | expat \
88 | freetds \
89 | gd \
90 | jpeg \
91 | libgd \
92 | libpng \
93 | libstdc++ \
94 | libwebp \
95 | ncurses-libs \
96 | openssl \
97 | sqlite \
98 | sqlite-libs \
99 | tini \
100 | unixodbc \
101 | yaml \
102 | zlib \
103 | && ln -fs /usr/lib/libtdsodbc.so.0 /usr/lib/libtdsodbc.so \
104 | && rm -rf /var/cache/apk/*
105 |
106 | # Install ejabberd
107 | WORKDIR $HOME
108 | COPY --from=builder /ejabberd/runtime .
109 | COPY bin/* bin/
110 | COPY --from=api /go/bin/ejabberdapi bin/ejabberdapi
111 | RUN chmod 755 bin/ejabberdctl bin/ejabberdapi bin/erl bin/captcha*.sh \
112 | && mkdir -p /home/ejabberd/sql \
113 | && cp /home/ejabberd/lib/ejabberd-*/priv/sql/* /home/ejabberd/database/ \
114 | && cp /home/ejabberd/lib/ejabberd-*/priv/sql/* /home/ejabberd/sql/
115 | COPY --chown=ejabberd:ejabberd conf conf/
116 | ADD --chown=ejabberd:ejabberd https://download.process-one.net/cacert.pem conf/cacert.pem
117 |
118 | # Setup runtime environment
119 | USER ejabberd
120 | VOLUME ["$HOME/database","$HOME/conf","$HOME/logs","$HOME/upload"]
121 | EXPOSE 1880 1883 4369-4399 5210 5222 5269 5280 5443
122 |
123 | ENTRYPOINT ["/sbin/tini","--","/home/ejabberd/bin/ejabberdctl"]
124 | CMD ["foreground"]
125 |
--------------------------------------------------------------------------------
/ecs/HUB-README.md:
--------------------------------------------------------------------------------
1 | # ejabberd Community Server Docker Image
2 |
3 | ## What is ejabberd
4 |
5 | [ejabberd][im] is an open-source,
6 | robust, scalable and extensible realtime platform built using [Erlang/OTP][erlang],
7 | that includes [XMPP][xmpp] Server, [MQTT][mqtt] Broker and [SIP][sip] Service.
8 |
9 | Check the features in [ejabberd.im][im], [ejabberd Docs][features],
10 | [ejabberd at ProcessOne][p1home], and a list of [supported protocols and XEPs][xeps].
11 |
12 | [im]: https://ejabberd.im/
13 | [erlang]: https://www.erlang.org/
14 | [xmpp]: https://xmpp.org/
15 | [mqtt]: https://mqtt.org/
16 | [sip]: https://en.wikipedia.org/wiki/Session_Initiation_Protocol
17 | [features]: https://docs.ejabberd.im/admin/introduction/
18 | [p1home]: https://www.process-one.net/en/ejabberd/
19 | [xeps]: https://www.process-one.net/en/ejabberd/protocols/
20 |
21 |
22 | ## What is `ejabberd/ecs`
23 |
24 | This `ejabberd/ecs` Docker image is built for stable ejabberd releases using
25 | [docker-ejabberd/ecs](https://github.com/processone/docker-ejabberd/tree/master/ecs).
26 | It's based in Alpine Linux, and is aimed at providing a simple image to setup and configure.
27 |
28 | Please report problems related to this `ejabberd/ecs` image packaging in
29 | [docker-ejabberd Issues](https://github.com/processone/docker-ejabberd/issues),
30 | and general ejabberd problems in
31 | [ejabberd Issues](https://github.com/processone/ejabberd/issues).
32 |
33 |
34 | ## How to use the ejabberd/ecs image
35 |
36 | Please check [ejabberd/ecs README](https://github.com/processone/docker-ejabberd/tree/master/ecs#readme)
37 |
38 |
39 | ## Supported Architectures
40 |
41 | This `ejabberd/ecs` docker image is built for the `linux/amd64` architecture.
42 |
43 |
44 | ## Alternative Image in GitHub
45 |
46 | There is another container image published in
47 | [ejabberd GitHub Packages](https://github.com/processone/ejabberd/pkgs/container/ejabberd),
48 | that you can download from the GitHub Container Registry.
49 |
50 | Its usage is similar to this `ejabberd/ecs` image, with some benefits and changes worth noting:
51 |
52 | - it's available for `linux/amd64` and `linux/arm64` architectures
53 | - it's built also for `master` branch, in addition to the stable ejabberd releases
54 | - it includes less customizations to the base ejabberd compared to `ejabberd/ecs`
55 | - it stores data in `/opt/ejabberd/` instead of `/home/ejabberd/`
56 |
57 | See its documentation in [CONTAINER](https://github.com/processone/ejabberd/blob/master/CONTAINER.md).
58 |
59 |
--------------------------------------------------------------------------------
/ecs/README.md:
--------------------------------------------------------------------------------
1 |
2 | [](https://github.com/processone/ejabberd/tags)
3 | [](https://github.com/processone/ejabberd/pkgs/container/ejabberd)
4 | [](https://hub.docker.com/r/ejabberd/ecs/)
5 |
6 | ejabberd Container Images
7 | =========================
8 |
9 | [ejabberd][home] is an open-source,
10 | robust, scalable and extensible realtime platform built using [Erlang/OTP][erlang],
11 | that includes [XMPP][xmpp] Server, [MQTT][mqtt] Broker and [SIP][sip] Service.
12 |
13 | [home]: https://www.ejabberd.im/
14 | [erlang]: https://www.erlang.org/
15 | [xmpp]: https://xmpp.org/
16 | [mqtt]: https://mqtt.org/
17 | [sip]: https://en.wikipedia.org/wiki/Session_Initiation_Protocol
18 |
19 | This page documents those container images ([images comparison](#images-comparison)):
20 |
21 | - [](https://github.com/processone/ejabberd/pkgs/container/ejabberd)
22 | published in [ghcr.io/processone/ejabberd](https://github.com/processone/ejabberd/pkgs/container/ejabberd),
23 | built using [ejabberd](https://github.com/processone/ejabberd/tree/master/.github/container) repository,
24 | both for stable ejabberd releases and the `master` branch, in x64 and arm64 architectures.
25 |
26 | - [](https://hub.docker.com/r/ejabberd/ecs/)
27 | published in [docker.io/ejabberd/ecs](https://hub.docker.com/r/ejabberd/ecs/),
28 | built using [docker-ejabberd/ecs](https://github.com/processone/docker-ejabberd/tree/master/ecs) repository
29 | for ejabberd stable releases in x64 architectures.
30 |
31 | For Microsoft Windows, see
32 | [Docker Desktop for Windows 10](https://www.process-one.net/blog/install-ejabberd-on-windows-10-using-docker-desktop/),
33 | and [Docker Toolbox for Windows 7](https://www.process-one.net/blog/install-ejabberd-on-windows-7-using-docker-toolbox/).
34 |
35 | For Kubernetes Helm, see [help-ejabberd](https://github.com/sando38/helm-ejabberd).
36 |
37 |
38 | Start ejabberd
39 | --------------
40 |
41 | ### daemon
42 |
43 | Start ejabberd in a new container:
44 |
45 | ```bash
46 | docker run --name ejabberd -d -p 5222:5222 docker.io/ejabberd/ecs
47 | ```
48 |
49 | That runs the container as a daemon,
50 | using ejabberd default configuration file and XMPP domain `localhost`.
51 |
52 | Restart the stopped ejabberd container:
53 |
54 | ```bash
55 | docker restart ejabberd
56 | ```
57 |
58 | Stop the running container:
59 |
60 | ```bash
61 | docker stop ejabberd
62 | ```
63 |
64 | Remove the ejabberd container:
65 |
66 | ```bash
67 | docker rm ejabberd
68 | ```
69 |
70 |
71 | ### with Erlang console
72 |
73 | Start ejabberd with an interactive Erlang console attached using the `live` command:
74 |
75 | ```bash
76 | docker run --name ejabberd -it -p 5222:5222 docker.io/ejabberd/ecs live
77 | ```
78 |
79 | That uses the default configuration file and XMPP domain `localhost`.
80 |
81 |
82 | ### with your data
83 |
84 | Pass a configuration file as a volume
85 | and share the local directory to store database:
86 |
87 | ```bash
88 | mkdir conf && cp ejabberd.yml.example conf/ejabberd.yml
89 |
90 | mkdir database && chown ejabberd database
91 |
92 | docker run --name ejabberd -it \
93 | -v $(pwd)/conf/ejabberd.yml:/opt/ejabberd/conf/ejabberd.yml \
94 | -v $(pwd)/database:/opt/ejabberd/database \
95 | -p 5222:5222 docker.io/ejabberd/ecs live
96 | ```
97 |
98 | Notice that ejabberd runs in the container with an account named `ejabberd`
99 | with UID 9000 and group `ejabberd` with GID 9000,
100 | and the volumes you mount must grant proper rights to that account.
101 |
102 |
103 | Next steps
104 | ----------
105 |
106 | ### Register admin account
107 |
108 | #### [](https://github.com/processone/ejabberd/pkgs/container/ejabberd) [:orange_circle:](#images-comparison)
109 |
110 | If you set the `REGISTER_ADMIN_PASSWORD` environment variable,
111 | an account is automatically registered with that password,
112 | and admin privileges are granted to it.
113 | The account created depends on what variables you have set:
114 |
115 | - `EJABBERD_MACRO_ADMIN=juliet@example.org` -> `juliet@example.org`
116 | - `EJABBERD_MACRO_HOST=example.org` -> `admin@example.org`
117 | - None of those variables are set -> `admin@localhost`
118 |
119 | The account registration is shown in the container log:
120 |
121 | ```
122 | :> ejabberdctl register admin example.org somePassw0rd
123 | User admin@example.org successfully registered
124 | ```
125 |
126 | Alternatively, you can register the account manually yourself
127 | and edit `conf/ejabberd.yml` and add the ACL as explained in
128 | [ejabberd Docs: Administration Account](https://docs.ejabberd.im/admin/install/next-steps/#administration-account).
129 |
130 | ---
131 |
132 | #### [](https://hub.docker.com/r/ejabberd/ecs/)
133 |
134 | The default ejabberd configuration has already granted admin privilege
135 | to an account that would be called `admin@localhost`,
136 | so you just need to register it, for example:
137 |
138 | ```bash
139 | docker exec -it ejabberd ejabberdctl register admin localhost passw0rd
140 | ```
141 |
142 | ### Check ejabberd log
143 |
144 | Check the content of the log files inside the container,
145 | even if you do not put it on a shared persistent drive:
146 |
147 | ```bash
148 | docker exec -it ejabberd tail -f logs/ejabberd.log
149 | ```
150 |
151 |
152 | ### Inspect container files
153 |
154 | The container uses Alpine Linux. Start a shell inside the container:
155 |
156 | ```bash
157 | docker exec -it ejabberd sh
158 | ```
159 |
160 |
161 | ### Open debug console
162 |
163 | Open an interactive debug Erlang console attached to a running ejabberd in a running container:
164 |
165 | ```bash
166 | docker exec -it ejabberd ejabberdctl debug
167 | ```
168 |
169 |
170 | ### CAPTCHA
171 |
172 | ejabberd includes two example CAPTCHA scripts.
173 | If you want to use any of them, first install some additional required libraries:
174 |
175 | ```bash
176 | docker exec --user root ejabberd apk add imagemagick ghostscript-fonts bash
177 | ```
178 |
179 | Now update your ejabberd configuration file, for example:
180 | ```bash
181 | docker exec -it ejabberd vi conf/ejabberd.yml
182 | ```
183 |
184 | and add this option:
185 | ```yaml
186 | captcha_cmd: "$HOME/bin/captcha.sh"
187 | ```
188 |
189 | Finally, reload the configuration file or restart the container:
190 | ```bash
191 | docker exec ejabberd ejabberdctl reload_config
192 | ```
193 |
194 | If the CAPTCHA image is not visible, there may be a problem generating it
195 | (the ejabberd log file may show some error message);
196 | or the image URL may not be correctly detected by ejabberd,
197 | in that case you can set the correct URL manually, for example:
198 | ```yaml
199 | captcha_url: https://localhost:5443/captcha
200 | ```
201 |
202 | For more details about CAPTCHA options, please check the
203 | [CAPTCHA](https://docs.ejabberd.im/admin/configuration/basic/#captcha)
204 | documentation section.
205 |
206 |
207 | Advanced
208 | --------
209 |
210 | ### Ports
211 |
212 | The container image exposes several ports
213 | (check also [Docs: Firewall Settings](https://docs.ejabberd.im/admin/guide/security/#firewall-settings)):
214 |
215 | - `5222`: The default port for XMPP clients.
216 | - `5269`: For XMPP federation. Only needed if you want to communicate with users on other servers.
217 | - `5280`: For admin interface (URL is `admin/`).
218 | - `1880`: For admin interface (URL is `/`, useful for [podman-desktop](https://podman-desktop.io/) and [docker-desktop](https://www.docker.com/products/docker-desktop/)) [:orange_circle:](#images-comparison)
219 | - `5443`: With encryption, used for admin interface, API, CAPTCHA, OAuth, Websockets and XMPP BOSH.
220 | - `1883`: Used for MQTT
221 | - `4369-4399`: EPMD and Erlang connectivity, used for `ejabberdctl` and clustering
222 | - `5210`: Erlang connectivity when `ERL_DIST_PORT` is set, alternative to EPMD [:orange_circle:](#images-comparison)
223 |
224 |
225 | ### Volumes
226 |
227 | ejabberd produces two types of data: log files and database spool files (Mnesia).
228 | This is the kind of data you probably want to store on a persistent or local drive (at least the database).
229 |
230 | The volumes you may want to map:
231 |
232 | - `/opt/ejabberd/conf/`: Directory containing configuration and certificates
233 | - `/opt/ejabberd/database/`: Directory containing Mnesia database.
234 | You should back up or export the content of the directory to persistent storage
235 | (host storage, local storage, any storage plugin)
236 | - `/opt/ejabberd/logs/`: Directory containing log files
237 | - `/opt/ejabberd/upload/`: Directory containing uploaded files. This should also be backed up.
238 |
239 | All these files are owned by an account named `ejabberd` with group `ejabberd` in the container.
240 | Its corresponding `UID:GID` is `9000:9000`.
241 | If you prefer bind mounts instead of volumes, then
242 | you need to map this to valid `UID:GID` on your host to get read/write access on
243 | mounted directories.
244 |
245 | If using Docker, try:
246 | ```bash
247 | mkdir database
248 | sudo chown 9000:9000 database
249 | ```
250 |
251 | If using Podman, try:
252 | ```bash
253 | mkdir database
254 | podman unshare chown 9000:9000 database
255 | ```
256 |
257 | It's possible to install additional ejabberd modules using volumes, check
258 | [this Docs tutorial](https://docs.ejabberd.im/developer/extending-ejabberd/modules/#your-module-in-ejabberd-modules-with-ejabberd-container).
259 |
260 |
261 | ### Commands on start
262 |
263 | The ejabberdctl script reads the `CTL_ON_CREATE` environment variable
264 | the first time the container is started,
265 | and reads `CTL_ON_START` every time the container is started.
266 | Those variables can contain one ejabberdctl command,
267 | or several commands separated with the blankspace and `;` characters.
268 |
269 | If any of those commands returns a failure, the container starting gets aborted.
270 | If there is a command with a result that can be ignored,
271 | prefix that command with `!`
272 |
273 | This example, registers an `admin@localhost` account when the container is first created.
274 | Everytime the container starts, it shows the list of registered accounts,
275 | checks that the admin account exists and password is valid,
276 | changes the password of an account if it exists (ignoring any failure),
277 | and shows the ejabberd starts (check also the [full example](#customized-example)):
278 | ```yaml
279 | environment:
280 | - CTL_ON_CREATE=register admin localhost asd
281 | - CTL_ON_START=stats registeredusers ;
282 | check_password admin localhost asd ;
283 | ! change_password bot123 localhost qqq ;
284 | status
285 | ```
286 |
287 |
288 | ### Macros in environment [:high_brightness:](#images-comparison)
289 |
290 | ejabberd reads `EJABBERD_MACRO_*` environment variables
291 | and uses them to define the corresponding
292 | [macros](https://docs.ejabberd.im/admin/configuration/file-format/#macros-in-configuration-file),
293 | overwriting the corresponding macro definition if it was set in the configuration file.
294 | This is supported since ejabberd 24.12.
295 |
296 | For example, if you configure this in `ejabberd.yml`:
297 |
298 | ```yaml
299 | acl:
300 | admin:
301 | user: ADMIN
302 | ```
303 |
304 | now you can define the admin account JID using an environment variable:
305 | ```yaml
306 | environment:
307 | - EJABBERD_MACRO_ADMIN=admin@localhost
308 | ```
309 |
310 | Check the [full example](#customized-example) for other example.
311 |
312 |
313 | ### ejabberdapi
314 |
315 | When the container is running (and thus ejabberd), you can exec commands inside the container
316 | using `ejabberdctl` or any other of the available interfaces, see
317 | [Understanding ejabberd "commands"](https://docs.ejabberd.im/developer/ejabberd-api/#understanding-ejabberd-commands)
318 |
319 | Additionally, the container image includes the `ejabberdapi` executable.
320 | Please check the [ejabberd-api homepage](https://github.com/processone/ejabberd-api)
321 | for configuration and usage details.
322 |
323 | For example, if you configure ejabberd like this:
324 | ```yaml
325 | listen:
326 | -
327 | port: 5282
328 | module: ejabberd_http
329 | request_handlers:
330 | "/api": mod_http_api
331 |
332 | acl:
333 | loopback:
334 | ip:
335 | - 127.0.0.0/8
336 | - ::1/128
337 | - ::FFFF:127.0.0.1/128
338 |
339 | api_permissions:
340 | "admin access":
341 | who:
342 | access:
343 | allow:
344 | acl: loopback
345 | what:
346 | - "register"
347 | ```
348 |
349 | Then you could register new accounts with this query:
350 |
351 | ```bash
352 | docker exec -it ejabberd ejabberdapi register --endpoint=http://127.0.0.1:5282/ --jid=admin@localhost --password=passw0rd
353 | ```
354 |
355 |
356 | ### Clustering
357 |
358 | When setting several containers to form a
359 | [cluster of ejabberd nodes](https://docs.ejabberd.im/admin/guide/clustering/),
360 | each one must have a different
361 | [Erlang Node Name](https://docs.ejabberd.im/admin/guide/security/#erlang-node-name)
362 | and the same
363 | [Erlang Cookie](https://docs.ejabberd.im/admin/guide/security/#erlang-cookie).
364 |
365 | For this you can either:
366 |
367 | - edit `conf/ejabberdctl.cfg` and set variables `ERLANG_NODE` and `ERLANG_COOKIE`
368 | - set the environment variables `ERLANG_NODE_ARG` and `ERLANG_COOKIE`
369 |
370 | ---
371 |
372 | Example to connect a local `ejabberdctl` to a containerized ejabberd:
373 |
374 | 1. When creating the container, export port 5210, and set `ERLANG_COOKIE`:
375 | ```sh
376 | docker run --name ejabberd -it \
377 | -e ERLANG_COOKIE=`cat $HOME/.erlang.cookie` \
378 | -p 5210:5210 -p 5222:5222 \
379 | docker.io/ejabberd/ecs
380 | ```
381 | 2. Set `ERL_DIST_PORT=5210` in `ejabberdctl.cfg` of container and local ejabberd
382 | 3. Restart the container
383 | 4. Now use `ejabberdctl` in your local ejabberd deployment
384 |
385 | To connect using a local `ejabberd` script:
386 | ```sh
387 | ERL_DIST_PORT=5210 _build/dev/rel/ejabberd/bin/ejabberd ping
388 | ```
389 |
390 | Example using environment variables (see full example [docker-compose.yml](https://github.com/processone/docker-ejabberd/issues/64#issuecomment-887741332)):
391 | ```yaml
392 | environment:
393 | - ERLANG_NODE_ARG=ejabberd@node7
394 | - ERLANG_COOKIE=dummycookie123
395 | ```
396 |
397 | ---
398 |
399 | Once you have the ejabberd nodes properly set and running,
400 | you can tell the secondary nodes to join the master node using the
401 | [`join_cluster`](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/#join-cluster)
402 | API call.
403 |
404 | Example using environment variables (see the full
405 | [`docker-compose.yml` clustering example](#clustering-example)):
406 | ```yaml
407 | environment:
408 | - ERLANG_NODE_ARG=ejabberd@replica
409 | - ERLANG_COOKIE=dummycookie123
410 | - CTL_ON_CREATE=join_cluster ejabberd@main
411 | ```
412 |
413 | ### Change Mnesia Node Name
414 |
415 | To use the same Mnesia database in a container with a different hostname,
416 | it is necessary to change the old hostname stored in Mnesia.
417 |
418 | This section is equivalent to the ejabberd Documentation
419 | [Change Computer Hostname](https://docs.ejabberd.im/admin/guide/managing/#change-computer-hostname),
420 | but particularized to containers that use this
421 | ecs container image from ejabberd 23.01 or older.
422 |
423 | #### Setup Old Container
424 |
425 | Let's assume a container running ejabberd 23.01 (or older) from
426 | this ecs container image, with the database directory binded
427 | and one registered account.
428 | This can be produced with:
429 | ```bash
430 | OLDCONTAINER=ejaold
431 | NEWCONTAINER=ejanew
432 |
433 | mkdir database
434 | sudo chown 9000:9000 database
435 | docker run -d --name $OLDCONTAINER -p 5222:5222 \
436 | -v $(pwd)/database:/opt/ejabberd/database \
437 | docker.io/ejabberd/ecs:23.01
438 | docker exec -it $OLDCONTAINER ejabberdctl started
439 | docker exec -it $OLDCONTAINER ejabberdctl register user1 localhost somepass
440 | docker exec -it $OLDCONTAINER ejabberdctl registered_users localhost
441 | ```
442 |
443 | Methods to know the Erlang node name:
444 | ```bash
445 | ls database/ | grep ejabberd@
446 | docker exec -it $OLDCONTAINER ejabberdctl status
447 | docker exec -it $OLDCONTAINER grep "started in the node" logs/ejabberd.log
448 | ```
449 |
450 | #### Change Mnesia Node
451 |
452 | First of all let's store the Erlang node names and paths in variables.
453 | In this example they would be:
454 | ```bash
455 | OLDCONTAINER=ejaold
456 | NEWCONTAINER=ejanew
457 | OLDNODE=ejabberd@95145ddee27c
458 | NEWNODE=ejabberd@localhost
459 | OLDFILE=/opt/ejabberd/database/old.backup
460 | NEWFILE=/opt/ejabberd/database/new.backup
461 | ```
462 |
463 | 1. Start your old container that can still read the Mnesia database correctly.
464 | If you have the Mnesia spool files,
465 | but don't have access to the old container anymore, go to
466 | [Create Temporary Container](#create-temporary-container)
467 | and later come back here.
468 |
469 | 2. Generate a backup file and check it was created:
470 | ```bash
471 | docker exec -it $OLDCONTAINER ejabberdctl backup $OLDFILE
472 | ls -l database/*.backup
473 | ```
474 |
475 | 3. Stop ejabberd:
476 | ```bash
477 | docker stop $OLDCONTAINER
478 | ```
479 |
480 | 4. Create the new container. For example:
481 | ```bash
482 | docker run \
483 | --name $NEWCONTAINER \
484 | -d \
485 | -p 5222:5222 \
486 | -v $(pwd)/database:/opt/ejabberd/database \
487 | docker.io/ejabberd/ecs:latest
488 | ```
489 |
490 | 5. Convert the backup file to new node name:
491 | ```bash
492 | docker exec -it $NEWCONTAINER ejabberdctl mnesia_change_nodename $OLDNODE $NEWNODE $OLDFILE $NEWFILE
493 | ```
494 |
495 | 6. Install the backup file as a fallback:
496 | ```bash
497 | docker exec -it $NEWCONTAINER ejabberdctl install_fallback $NEWFILE
498 | ```
499 |
500 | 7. Restart the container:
501 | ```bash
502 | docker restart $NEWCONTAINER
503 | ```
504 |
505 | 8. Check that the information of the old database is available.
506 | In this example, it should show that the account `user1` is registered:
507 | ```bash
508 | docker exec -it $NEWCONTAINER ejabberdctl registered_users localhost
509 | ```
510 |
511 | 9. When the new container is working perfectly with the converted Mnesia database,
512 | you may want to remove the unneeded files:
513 | the old container, the old Mnesia spool files, and the backup files.
514 |
515 | #### Create Temporary Container
516 |
517 | In case the old container that used the Mnesia database is not available anymore,
518 | a temporary container can be created just to read the Mnesia database
519 | and make a backup of it, as explained in the previous section.
520 |
521 | This method uses `--hostname` command line argument for docker,
522 | and `ERLANG_NODE_ARG` environment variable for ejabberd.
523 | Their values must be the hostname of your old container
524 | and the Erlang node name of your old ejabberd node.
525 | To know the Erlang node name please check
526 | [Setup Old Container](#setup-old-container).
527 |
528 | Command line example:
529 | ```bash
530 | OLDHOST=${OLDNODE#*@}
531 | docker run \
532 | -d \
533 | --name $OLDCONTAINER \
534 | --hostname $OLDHOST \
535 | -p 5222:5222 \
536 | -v $(pwd)/database:/opt/ejabberd/database \
537 | -e ERLANG_NODE_ARG=$OLDNODE \
538 | docker.io/ejabberd/ecs:latest
539 | ```
540 |
541 | Check the old database content is available:
542 | ```bash
543 | docker exec -it $OLDCONTAINER ejabberdctl registered_users localhost
544 | ```
545 |
546 | Now that you have ejabberd running with access to the Mnesia database,
547 | you can continue with step 2 of previous section
548 | [Change Mnesia Node](#change-mnesia-node).
549 |
550 |
551 | Build Container Image
552 | ----------------
553 |
554 | The container image includes ejabberd as a standalone OTP release built using Elixir.
555 |
556 | ### Build `ejabberd` [](https://github.com/processone/ejabberd/pkgs/container/ejabberd)
557 |
558 | The ejabberd Erlang/OTP release is configured with:
559 |
560 | - `mix.exs`: Customize ejabberd release
561 | - `vars.config`: ejabberd compilation configuration options
562 | - `config/runtime.exs`: Customize ejabberd paths
563 | - `ejabberd.yml.template`: ejabberd default config file
564 |
565 | #### Direct build
566 |
567 | Build ejabberd Community Server container image from ejabberd master git repository:
568 |
569 | ```bash
570 | docker buildx build \
571 | -t personal/ejabberd \
572 | -f .github/container/Dockerfile \
573 | .
574 | ```
575 |
576 | #### Podman build
577 |
578 | To build the image using Podman, please notice:
579 |
580 | - `EXPOSE 4369-4399` port range is not supported, remove that in Dockerfile
581 | - It mentions that `healthcheck` is not supported by the Open Container Initiative image format
582 | - to start with command `live`, you may want to add environment variable `EJABBERD_BYPASS_WARNINGS=true`
583 |
584 | ```bash
585 | podman build \
586 | -t ejabberd \
587 | -f .github/container/Dockerfile \
588 | .
589 |
590 | podman run --name eja1 -d -p 5222:5222 localhost/ejabberd
591 |
592 | podman exec eja1 ejabberdctl status
593 |
594 | podman exec -it eja1 sh
595 |
596 | podman stop eja1
597 |
598 | podman run --name eja1 -it -e EJABBERD_BYPASS_WARNINGS=true -p 5222:5222 localhost/ejabberd live
599 | ```
600 |
601 | ### Build `ecs` [](https://hub.docker.com/r/ejabberd/ecs/)
602 |
603 | The ejabberd Erlang/OTP release is configured with:
604 |
605 | - `rel/config.exs`: Customize ejabberd release
606 | - `rel/dev.exs`: ejabberd environment configuration for development release
607 | - `rel/prod.exs`: ejabberd environment configuration for production release
608 | - `vars.config`: ejabberd compilation configuration options
609 | - `conf/ejabberd.yml`: ejabberd default config file
610 |
611 | Build ejabberd Community Server base image from ejabberd master on Github:
612 |
613 | ```bash
614 | docker build -t personal/ejabberd .
615 | ```
616 |
617 | Build ejabberd Community Server base image for a given ejabberd version:
618 |
619 | ```bash
620 | ./build.sh 18.03
621 | ```
622 |
623 | Composer Examples
624 | -----------------
625 |
626 | ### Minimal Example
627 |
628 | This is the barely minimal file to get a usable ejabberd.
629 |
630 | If using Docker, write this `docker-compose.yml` file
631 | and start it with `docker-compose up`:
632 |
633 | ```yaml
634 | services:
635 | main:
636 | image: docker.io/ejabberd/ecs
637 | container_name: ejabberd
638 | ports:
639 | - "5222:5222"
640 | - "5269:5269"
641 | - "5280:5280"
642 | - "5443:5443"
643 | ```
644 |
645 | If using Podman, write this `minimal.yml` file
646 | and start it with `podman kube play minimal.yml`:
647 |
648 | ```yaml
649 | apiVersion: v1
650 |
651 | kind: Pod
652 |
653 | metadata:
654 | name: ejabberd
655 |
656 | spec:
657 | containers:
658 |
659 | - name: ejabberd
660 | image: docker.io/ejabberd/ecs
661 | ports:
662 | - containerPort: 5222
663 | hostPort: 5222
664 | - containerPort: 5269
665 | hostPort: 5269
666 | - containerPort: 5280
667 | hostPort: 5280
668 | - containerPort: 5443
669 | hostPort: 5443
670 | ```
671 |
672 |
673 | ### Customized Example
674 |
675 | This example shows the usage of several customizations:
676 | it uses a local configuration file,
677 | defines a configuration macro using an environment variable,
678 | stores the mnesia database in a local path,
679 | registers an account when it's created,
680 | and checks the number of registered accounts every time it's started.
681 |
682 | Prepare an ejabberd configuration file:
683 | ```bash
684 | mkdir conf && cp ejabberd.yml.example conf/ejabberd.yml
685 | ```
686 |
687 | Create the database directory and allow the container access to it:
688 |
689 | - Docker:
690 | ```bash
691 | mkdir database && sudo chown 9000:9000 database
692 | ```
693 | - Podman:
694 | ```bash
695 | mkdir database && podman unshare chown 9000:9000 database
696 | ```
697 |
698 | If using Docker, write this `docker-compose.yml` file
699 | and start it with `docker-compose up`:
700 |
701 | ```yaml
702 | version: '3.7'
703 |
704 | services:
705 |
706 | main:
707 | image: docker.io/ejabberd/ecs
708 | container_name: ejabberd
709 | environment:
710 | - EJABBERD_MACRO_HOST=example.com
711 | - EJABBERD_MACRO_ADMIN=admin@example.com
712 | - REGISTER_ADMIN_PASSWORD=somePassw0rd
713 | - CTL_ON_START=registered_users example.com ;
714 | status
715 | ports:
716 | - "5222:5222"
717 | - "5269:5269"
718 | - "5280:5280"
719 | - "5443:5443"
720 | volumes:
721 | - ./conf/ejabberd.yml:/opt/ejabberd/conf/ejabberd.yml:ro
722 | - ./database:/opt/ejabberd/database
723 | ```
724 |
725 | If using Podman, write this `custom.yml` file
726 | and start it with `podman kube play custom.yml`:
727 |
728 | ```yaml
729 | apiVersion: v1
730 |
731 | kind: Pod
732 |
733 | metadata:
734 | name: ejabberd
735 |
736 | spec:
737 | containers:
738 |
739 | - name: ejabberd
740 | image: docker.io/ejabberd/ecs
741 | env:
742 | - name: EJABBERD_MACRO_HOST
743 | value: example.com
744 | - name: EJABBERD_MACRO_ADMIN
745 | value: admin@example.com
746 | - name: REGISTER_ADMIN_PASSWORD
747 | value: somePassw0rd
748 | - name: CTL_ON_START
749 | value: registered_users example.com ;
750 | status
751 | ports:
752 | - containerPort: 5222
753 | hostPort: 5222
754 | - containerPort: 5269
755 | hostPort: 5269
756 | - containerPort: 5280
757 | hostPort: 5280
758 | - containerPort: 5443
759 | hostPort: 5443
760 | volumeMounts:
761 | - mountPath: /opt/ejabberd/conf/ejabberd.yml
762 | name: config
763 | readOnly: true
764 | - mountPath: /opt/ejabberd/database
765 | name: db
766 |
767 | volumes:
768 | - name: config
769 | hostPath:
770 | path: ./conf/ejabberd.yml
771 | type: File
772 | - name: db
773 | hostPath:
774 | path: ./database
775 | type: DirectoryOrCreate
776 | ```
777 |
778 |
779 | ### Clustering Example
780 |
781 | In this example, the main container is created first.
782 | Once it is fully started and healthy, a second container is created,
783 | and once ejabberd is started in it, it joins the first one.
784 |
785 | An account is registered in the first node when created (and
786 | we ignore errors that can happen when doing that - for example
787 | when account already exists),
788 | and it should exist in the second node after join.
789 |
790 | Notice that in this example the main container does not have access
791 | to the exterior; the replica exports the ports and can be accessed.
792 |
793 | If using Docker, write this `docker-compose.yml` file
794 | and start it with `docker-compose up`:
795 |
796 | ```yaml
797 | version: '3.7'
798 |
799 | services:
800 |
801 | main:
802 | image: docker.io/ejabberd/ecs
803 | container_name: main
804 | environment:
805 | - ERLANG_NODE_ARG=ejabberd@main
806 | - ERLANG_COOKIE=dummycookie123
807 | - CTL_ON_CREATE=! register admin localhost asd
808 | healthcheck:
809 | test: netstat -nl | grep -q 5222
810 | start_period: 5s
811 | interval: 5s
812 | timeout: 5s
813 | retries: 120
814 |
815 | replica:
816 | image: docker.io/ejabberd/ecs
817 | container_name: replica
818 | depends_on:
819 | main:
820 | condition: service_healthy
821 | environment:
822 | - ERLANG_NODE_ARG=ejabberd@replica
823 | - ERLANG_COOKIE=dummycookie123
824 | - CTL_ON_CREATE=join_cluster ejabberd@main
825 | - CTL_ON_START=registered_users localhost ;
826 | status
827 | ports:
828 | - "5222:5222"
829 | - "5269:5269"
830 | - "5280:5280"
831 | - "5443:5443"
832 | ```
833 |
834 | If using Podman, write this `cluster.yml` file
835 | and start it with `podman kube play cluster.yml`:
836 |
837 | ```yaml
838 | apiVersion: v1
839 |
840 | kind: Pod
841 |
842 | metadata:
843 | name: cluster
844 |
845 | spec:
846 | containers:
847 |
848 | - name: first
849 | image: docker.io/ejabberd/ecs
850 | env:
851 | - name: ERLANG_NODE_ARG
852 | value: main@cluster
853 | - name: ERLANG_COOKIE
854 | value: dummycookie123
855 | - name: CTL_ON_CREATE
856 | value: register admin localhost asd
857 | - name: CTL_ON_START
858 | value: stats registeredusers ;
859 | status
860 | - name: EJABBERD_MACRO_PORT_C2S
861 | value: 6222
862 | - name: EJABBERD_MACRO_PORT_C2S_TLS
863 | value: 6223
864 | - name: EJABBERD_MACRO_PORT_S2S
865 | value: 6269
866 | - name: EJABBERD_MACRO_PORT_HTTP_TLS
867 | value: 6443
868 | - name: EJABBERD_MACRO_PORT_HTTP
869 | value: 6280
870 | - name: EJABBERD_MACRO_PORT_MQTT
871 | value: 6883
872 | - name: EJABBERD_MACRO_PORT_PROXY65
873 | value: 6777
874 | volumeMounts:
875 | - mountPath: /opt/ejabberd/conf/ejabberd.yml
876 | name: config
877 | readOnly: true
878 |
879 | - name: second
880 | image: docker.io/ejabberd/ecs
881 | env:
882 | - name: ERLANG_NODE_ARG
883 | value: replica@cluster
884 | - name: ERLANG_COOKIE
885 | value: dummycookie123
886 | - name: CTL_ON_CREATE
887 | value: join_cluster main@cluster ;
888 | started ;
889 | list_cluster
890 | - name: CTL_ON_START
891 | value: stats registeredusers ;
892 | check_password admin localhost asd ;
893 | status
894 | ports:
895 | - containerPort: 5222
896 | hostPort: 5222
897 | - containerPort: 5280
898 | hostPort: 5280
899 | volumeMounts:
900 | - mountPath: /opt/ejabberd/conf/ejabberd.yml
901 | name: config
902 | readOnly: true
903 |
904 | volumes:
905 | - name: config
906 | hostPath:
907 | path: ./conf/ejabberd.yml
908 | type: File
909 |
910 | ```
911 |
912 |
913 | Images Comparison
914 | -----------------
915 |
916 | Let's summarize the differences between both container images. Legend:
917 |
918 | - :sparkle: is the recommended alternative
919 | - :orange_circle: added in the latest release (ejabberd 25.03)
920 | - :high_brightness: added in the previous release (ejabberd 24.12)
921 | - :low_brightness: added in the pre-previous release (ejabberd 24.10)
922 |
923 | | | [](https://github.com/processone/ejabberd/pkgs/container/ejabberd) | [](https://hub.docker.com/r/ejabberd/ecs/) |
924 | |:----------------------|:------------------|:-----------------------|
925 | | Source code | [ejabberd/.github/container](https://github.com/processone/ejabberd/tree/master/.github/container) | [docker-ejabberd/ecs](https://github.com/processone/docker-ejabberd/tree/master/ecs) |
926 | | Generated by | [container.yml](https://github.com/processone/ejabberd/blob/master/.github/workflows/container.yml) | [tests.yml](https://github.com/processone/docker-ejabberd/blob/master/.github/workflows/tests.yml) |
927 | | Built for | stable releases
`master` branch | stable releases
[`master` branch zip](https://github.com/processone/docker-ejabberd/actions/workflows/tests.yml) |
928 | | Architectures | `linux/amd64`
`linux/arm64` | `linux/amd64` |
929 | | Software | Erlang/OTP 27.3.2-alpine
Elixir 1.18.3 | Alpine 3.19
Erlang/OTP 26.2
Elixir 1.15.7 |
930 | | Published in | [ghcr.io/processone/ejabberd](https://github.com/processone/ejabberd/pkgs/container/ejabberd) | [docker.io/ejabberd/ecs](https://hub.docker.com/r/ejabberd/ecs/)
[ghcr.io/processone/ecs](https://github.com/processone/docker-ejabberd/pkgs/container/ecs) |
931 | | :black_square_button: **Additional content** |
932 | | [ejabberd-contrib](https://docs.ejabberd.im/admin/guide/modules/#ejabberd-contrib) | included | not included |
933 | | [ejabberdapi](#ejabberdapi) | included :orange_circle: | included |
934 | | :black_square_button: **Ports** |
935 | | [1880](#ports) for WebAdmin | yes :orange_circle: | yes :orange_circle: |
936 | | [5210](#ports) for `ERL_DIST_PORT` | supported | supported :orange_circle: |
937 | | :black_square_button: **Paths** |
938 | | `$HOME` | `/opt/ejabberd/` | `/home/ejabberd/` |
939 | | User data | `$HOME` :sparkle:
`/home/ejabberd/` :orange_circle: | `$HOME`
`/opt/ejabberd/` :sparkle: :low_brightness: |
940 | | `ejabberdctl` | `ejabberdctl` :sparkle:
`bin/ejabberdctl` :orange_circle: | `bin/ejabberdctl`
`ejabberdctl` :sparkle: :low_brightness: |
941 | | [`captcha.sh`](#captcha) | `$HOME/bin/captcha.sh` :orange_circle: | `$HOME/bin/captcha.sh` :orange_circle: |
942 | | `*.sql` files | `$HOME/sql/*.sql` :sparkle: :orange_circle:
`$HOME/database/*.sql` :orange_circle: | `$HOME/database/*.sql`
`$HOME/sql/*.sql` :sparkle: :orange_circle: |
943 | | Mnesia spool files | `$HOME/database/` :sparkle:
`$HOME/database/NODENAME/` :orange_circle: | `$HOME/database/NODENAME/`
`$HOME/database/` :sparkle: :orange_circle: |
944 | | :black_square_button: **Variables** |
945 | | [`EJABBERD_MACRO_*`](#macros-in-environment) | supported :high_brightness: | supported :high_brightness: |
946 | | Macros used in `ejabberd.yml` | yes :orange_circle: | yes :orange_circle: |
947 | | [`EJABBERD_MACRO_ADMIN`](#register-admin-account) | Grant admin rights :orange_circle:
(default `admin@localhost`)
| Hardcoded `admin@localhost` |
948 | | [`REGISTER_ADMIN_PASSWORD`](#register-admin-account) | Register admin account :orange_circle: | unsupported |
949 | | `CTL_OVER_HTTP` | enabled :orange_circle: | unsupported |
950 |
--------------------------------------------------------------------------------
/ecs/bin/ejabberdctl:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # define default configuration
4 | POLL=true
5 | ERL_MAX_PORTS=32000
6 | ERL_PROCESSES=250000
7 | ERL_MAX_ETS_TABLES=1400
8 | FIREWALL_WINDOW="4370-4379"
9 | INET_DIST_INTERFACE=""
10 | ERLANG_NODE=ejabberd@localhost
11 | EJABBERD_BYPASS_WARNINGS=true
12 |
13 | # define default environment variables
14 | ROOT_DIR="/home/ejabberd"
15 | HOME_DIR="$ROOT_DIR"
16 | ERL="$ROOT_DIR"/bin/erl
17 | IEX="$ROOT_DIR"/bin/iex
18 | EPMD="$ROOT_DIR"/bin/epmd
19 | INSTALLUSER=ejabberd
20 |
21 | # check the proper system user is used
22 | case $(id -un) in
23 | "$INSTALLUSER")
24 | EXEC_CMD="as_current_user"
25 | [ -e "$HOME"/conf/ejabberd.yml ] && HOME_DIR="$HOME"
26 | ;;
27 | root)
28 | if [ -n "$INSTALLUSER" ] ; then
29 | EXEC_CMD="as_install_user"
30 | HOME=$(su - ejabberd -c pwd)
31 | [ -e "$HOME"/conf/ejabberd.yml ] && HOME_DIR="$HOME"
32 | else
33 | EXEC_CMD="as_current_user"
34 | echo "WARNING: It is not recommended to run ejabberd as root" >&2
35 | fi
36 | ;;
37 | *)
38 | if [ -n "$INSTALLUSER" ] ; then
39 | echo "ERROR: This command can only be run by root or the user $INSTALLUSER" >&2
40 | exit 7
41 | else
42 | EXEC_CMD="as_current_user"
43 | fi
44 | ;;
45 | esac
46 |
47 | # parse command line parameters
48 | while [ $# -gt 0 ]; do
49 | case $1 in
50 | -n|--node) ERLANG_NODE_ARG=$2; shift 2;;
51 | -s|--spool) SPOOL_DIR=$2; shift 2;;
52 | -l|--logs) LOGS_DIR=$2; shift 2;;
53 | -f|--config) EJABBERD_CONFIG_PATH=$2; shift 2;;
54 | -c|--ctl-config) EJABBERDCTL_CONFIG_PATH=$2; shift 2;;
55 | -d|--config-dir) ETC_DIR=$2; shift 2;;
56 | -t|--no-timeout) NO_TIMEOUT="--no-timeout"; shift;;
57 | *) break;;
58 | esac
59 | done
60 |
61 | # define ejabberd variables if not already defined from the command line
62 | : "${ETC_DIR:="$HOME_DIR/conf"}"
63 | : "${LOGS_DIR:="$HOME_DIR/logs"}"
64 | : "${EJABBERD_CONFIG_PATH:="$ETC_DIR/ejabberd.yml"}"
65 | : "${EJABBERDCTL_CONFIG_PATH:="$ETC_DIR/ejabberdctl.cfg"}"
66 | # Allows passing extra Erlang command-line arguments in vm.args file
67 | : "${VMARGS:="$ETC_DIR/vm.args"}"
68 | [ -f "$EJABBERDCTL_CONFIG_PATH" ] && . "$EJABBERDCTL_CONFIG_PATH"
69 | [ -n "$ERLANG_NODE_ARG" ] && ERLANG_NODE="$ERLANG_NODE_ARG"
70 | [ "$ERLANG_NODE" = "${ERLANG_NODE%.*}" ] && S="-s"
71 | : "${SPOOL_DIR:="$HOME_DIR/database"}"
72 | : "${EJABBERD_LOG_PATH:="$LOGS_DIR/ejabberd.log"}"
73 |
74 | # backward support for old mnesia spool dir path
75 | : "${SPOOL_DIR_OLD:="$SPOOL_DIR/$ERLANG_NODE"}"
76 | [ -r "$SPOOL_DIR_OLD/schema.DAT" ] && [ ! -r "$SPOOL_DIR/schema.DAT" ] && SPOOL_DIR="$SPOOL_DIR_OLD"
77 |
78 | [ -n "$ERLANG_COOKIE" ] && [ ! -f "$HOME"/.erlang.cookie ] && {
79 | echo "$ERLANG_COOKIE" > "$HOME"/.erlang.cookie
80 | chmod 400 "$HOME"/.erlang.cookie
81 | }
82 |
83 | # define erl parameters
84 | ERLANG_OPTS="-boot_var RELEASE_LIB ../lib +K $POLL -smp $SMP +P $ERL_PROCESSES $ERL_OPTIONS"
85 | if [ -n "$FIREWALL_WINDOW" ] ; then
86 | ERLANG_OPTS="$ERLANG_OPTS -kernel inet_dist_listen_min ${FIREWALL_WINDOW%-*} inet_dist_listen_max ${FIREWALL_WINDOW#*-}"
87 | fi
88 | if [ -n "$INET_DIST_INTERFACE" ] ; then
89 | INET_DIST_INTERFACE2=$("$ERL" -boot start_clean -noshell -eval 'case inet:parse_address("'$INET_DIST_INTERFACE'") of {ok,IP} -> io:format("~p",[IP]); _ -> ok end.' -s erlang halt)
90 | if [ -n "$INET_DIST_INTERFACE2" ] ; then
91 | ERLANG_OPTS="$ERLANG_OPTS -kernel inet_dist_use_interface $INET_DIST_INTERFACE2"
92 | fi
93 | fi
94 | [ -n "$ERL_DIST_PORT" ] && ERLANG_OPTS="$ERLANG_OPTS -erl_epmd_port $ERL_DIST_PORT -start_epmd false"
95 | ERL_LIBS="$ROOT_DIR/lib"
96 | # if vm.args file exists in config directory, pass it to Erlang VM
97 | [ -f "$VMARGS" ] && ERLANG_OPTS="$ERLANG_OPTS -args_file $VMARGS"
98 | ERL_CRASH_DUMP="$LOGS_DIR"/erl_crash_$(date "+%Y%m%d-%H%M%S").dump
99 | ERL_INETRC="$ETC_DIR"/inetrc
100 |
101 | # define ejabberd parameters
102 | EJABBERD_OPTS="\
103 | $(sed '/^log_rotate_size/!d;s/:[ \t]*\([0-9]\{1,\}\).*/ \1/;s/:[ \t]*\(infinity\).*/ \1 /;s/^/ /' "$EJABBERD_CONFIG_PATH")\
104 | $(sed '/^log_rotate_count/!d;s/:[ \t]*\([0-9]*\).*/ \1 /;s/^/ /' "$EJABBERD_CONFIG_PATH")\
105 | $(sed '/^log_burst_limit_count/!d;s/:[ \t]*\([0-9]*\).*/ \1 /;s/^/ /' "$EJABBERD_CONFIG_PATH")\
106 | $(sed '/^log_burst_limit_window_time/!d;s/:[ \t]*\([0-9]*[a-z]*\).*/ \1 /;s/^/ /' "$EJABBERD_CONFIG_PATH")\
107 | $EJABBERD_OPTS"
108 | [ -n "$EJABBERD_OPTS" ] && EJABBERD_OPTS="-ejabberd $EJABBERD_OPTS"
109 | EJABBERD_OPTS="-mnesia dir \"$SPOOL_DIR\" $MNESIA_OPTIONS $EJABBERD_OPTS -s ejabberd"
110 |
111 | # export global variables
112 | export EJABBERD_CONFIG_PATH
113 | export EJABBERD_LOG_PATH
114 | export EJABBERD_PID_PATH
115 | export ERL_CRASH_DUMP
116 | export ERL_EPMD_ADDRESS
117 | export ERL_DIST_PORT
118 | export ERL_INETRC
119 | export ERL_MAX_PORTS
120 | export ERL_MAX_ETS_TABLES
121 | export CONTRIB_MODULES_PATH
122 | export CONTRIB_MODULES_CONF_DIR
123 | export ERL_LIBS
124 |
125 | set_dist_client()
126 | {
127 | [ -n "$ERL_DIST_PORT" ] && ERLANG_OPTS="$ERLANG_OPTS -dist_listen false"
128 | }
129 |
130 | # run command either directly or via su $INSTALLUSER
131 | run_cmd()
132 | {
133 | case $EXEC_CMD in
134 | as_install_user) su -s /bin/sh -c '"$0" "$@"' "$INSTALLUSER" -- "$@" ;;
135 | as_current_user) "$@" ;;
136 | esac
137 | }
138 | exec_cmd()
139 | {
140 | case $EXEC_CMD in
141 | as_install_user) su -s /bin/sh -c '"$0" "$@"' "$INSTALLUSER" -- "$@" ;;
142 | as_current_user) exec "$@" ;;
143 | esac
144 | }
145 | run_erl()
146 | {
147 | NODE=$1; shift
148 | run_cmd "$ERL" ${S:--}name "$NODE" $ERLANG_OPTS "$@"
149 | }
150 | exec_erl()
151 | {
152 | NODE=$1; shift
153 | exec_cmd "$ERL" ${S:--}name "$NODE" $ERLANG_OPTS "$@"
154 | }
155 | exec_iex()
156 | {
157 | NODE=$1; shift
158 | exec_cmd "$IEX" -${S:--}name "$NODE" --erl "$ERLANG_OPTS" "$@"
159 | }
160 |
161 | # usage
162 | debugwarning()
163 | {
164 | if [ "$EJABBERD_BYPASS_WARNINGS" != "true" ] ; then
165 | echo "--------------------------------------------------------------------"
166 | echo ""
167 | echo "IMPORTANT: we will attempt to attach an INTERACTIVE shell"
168 | echo "to an already running ejabberd node."
169 | echo "If an ERROR is printed, it means the connection was not successful."
170 | echo "You can interact with the ejabberd node if you know how to use it."
171 | echo "Please be extremely cautious with your actions,"
172 | echo "and exit immediately if you are not completely sure."
173 | echo ""
174 | echo "To exit and detach this shell from ejabberd, press:"
175 | echo " control+g and then q"
176 | echo ""
177 | #vt100 echo "Please do NOT use control+c in this debug shell !"
178 | #vt100 echo ""
179 | echo "--------------------------------------------------------------------"
180 | echo "To bypass permanently this warning, add to ejabberdctl.cfg the line:"
181 | echo " EJABBERD_BYPASS_WARNINGS=true"
182 | echo "Press return to continue"
183 | read -r _
184 | echo ""
185 | fi
186 | }
187 |
188 | livewarning()
189 | {
190 | if [ "$EJABBERD_BYPASS_WARNINGS" != "true" ] ; then
191 | echo "--------------------------------------------------------------------"
192 | echo ""
193 | echo "IMPORTANT: ejabberd is going to start in LIVE (interactive) mode."
194 | echo "All log messages will be shown in the command shell."
195 | echo "You can interact with the ejabberd node if you know how to use it."
196 | echo "Please be extremely cautious with your actions,"
197 | echo "and exit immediately if you are not completely sure."
198 | echo ""
199 | echo "To exit and detach this shell from ejabberd, press:"
200 | echo " control+g and then q"
201 | echo ""
202 | echo "--------------------------------------------------------------------"
203 | echo "To bypass permanently this warning, add to ejabberdctl.cfg the line:"
204 | echo " EJABBERD_BYPASS_WARNINGS=true"
205 | echo "Press return to continue"
206 | read -r _
207 | echo ""
208 | fi
209 | }
210 |
211 | check_etop_result()
212 | {
213 | result=$?
214 | if [ $result -eq 1 ] ; then
215 | echo ""
216 | echo "It seems there was some problem running 'ejabberdctl etop'."
217 | echo "Is the error message something like this?"
218 | echo " Failed to load module 'etop' because it cannot be found..."
219 | echo "Then probably ejabberd was compiled with development tools disabled."
220 | echo "To use 'etop', recompile ejabberd with: ./configure --enable-tools"
221 | echo ""
222 | exit $result
223 | fi
224 | }
225 |
226 | check_iex_result()
227 | {
228 | result=$?
229 | if [ $result -eq 127 ] ; then
230 | echo ""
231 | echo "It seems there was some problem finding 'iex' binary from Elixir."
232 | echo "Probably ejabberd was compiled with Rebar3 and Elixir disabled, like:"
233 | echo " ./configure"
234 | echo "which is equivalent to:"
235 | echo " ./configure --with-rebar=rebar3 --disable-elixir"
236 | echo "To use 'iex', recompile ejabberd enabling Elixir or using Mix:"
237 | echo " ./configure --enable-elixir"
238 | echo " ./configure --with-rebar=mix"
239 | echo ""
240 | exit $result
241 | fi
242 | }
243 |
244 | help()
245 | {
246 | echo ""
247 | echo "Commands to start an ejabberd node:"
248 | echo " start Start in server mode"
249 | echo " foreground Start in server mode (attached)"
250 | echo " foreground-quiet Start in server mode (attached), show only critical messages"
251 | echo " live Start in interactive mode, with Erlang shell"
252 | echo " iexlive Start in interactive mode, with Elixir shell"
253 | echo ""
254 | echo "Commands to interact with a running ejabberd node:"
255 | echo " debug Attach an interactive Erlang shell to a running node"
256 | echo " iexdebug Attach an interactive Elixir shell to a running node"
257 | echo " etop Attach to a running node and start Erlang Top"
258 | echo " ping Send ping to the node, returns pong or pang"
259 | echo " started|stopped Wait for the node to fully start|stop"
260 | echo ""
261 | echo "Optional parameters when starting an ejabberd node:"
262 | echo " --config-dir dir Config ejabberd: $ETC_DIR"
263 | echo " --config file Config ejabberd: $EJABBERD_CONFIG_PATH"
264 | echo " --ctl-config file Config ejabberdctl: $EJABBERDCTL_CONFIG_PATH"
265 | echo " --logs dir Directory for logs: $LOGS_DIR"
266 | echo " --spool dir Database spool dir: $SPOOL_DIR"
267 | echo " --node nodename ejabberd node name: $ERLANG_NODE"
268 | echo ""
269 | }
270 |
271 | # dynamic node name helper
272 | uid()
273 | {
274 | uuid=$(uuidgen 2>/dev/null)
275 | [ -z "$uuid" ] && [ -f /proc/sys/kernel/random/uuid ] && uuid=$(cat /proc/sys/kernel/random/uuid)
276 | [ -z "$uuid" ] && uuid=$(printf "%X" "${RANDOM:-$$}$(date +%M%S)")
277 | uuid=$(printf '%s' $uuid | sed 's/^\(...\).*$/\1/')
278 | [ $# -eq 0 ] && echo "${uuid}-${ERLANG_NODE}"
279 | [ $# -eq 1 ] && echo "${uuid}-${1}-${ERLANG_NODE}"
280 | [ $# -eq 2 ] && echo "${uuid}-${1}@${2}"
281 | }
282 |
283 | # stop epmd if there is no other running node
284 | stop_epmd()
285 | {
286 | [ -n "$ERL_DIST_PORT" ] && return
287 | "$EPMD" -names 2>/dev/null | grep -q name || "$EPMD" -kill >/dev/null
288 | }
289 |
290 | # make sure node not already running and node name unregistered
291 | # if all ok, ensure runtime directory exists and make it current directory
292 | check_start()
293 | {
294 | ECSIMAGE_DBPATH=$HOME/database/$ERLANG_NODE
295 | [ ! -d "$ECSIMAGE_DBPATH" ] && ln -s $HOME/database $HOME/database/$ERLANG_NODE
296 | [ -n "$ERL_DIST_PORT" ] && return
297 | "$EPMD" -names 2>/dev/null | grep -q " ${ERLANG_NODE%@*} " && {
298 | pgrep -f "$ERLANG_NODE" >/dev/null && {
299 | echo "ERROR: The ejabberd node '$ERLANG_NODE' is already running."
300 | exit 4
301 | }
302 | pgrep beam >/dev/null && {
303 | echo "ERROR: The ejabberd node '$ERLANG_NODE' is registered,"
304 | echo " but no related beam process has been found."
305 | echo "Shutdown all other erlang nodes, and call 'epmd -kill'."
306 | exit 5
307 | }
308 | "$EPMD" -kill >/dev/null
309 | }
310 | }
311 |
312 | post_waiter_fork()
313 | {
314 | (FIRST_RUN=$FIRST_RUN "$0" post_waiter)&
315 | }
316 |
317 | post_waiter_waiting()
318 | {
319 | $0 started
320 | [ -n "$FIRST_RUN" ] && [ -n "$CTL_ON_CREATE" ] && (post_waiter_loop $CTL_ON_CREATE)
321 | [ -n "$CTL_ON_START" ] && post_waiter_loop $CTL_ON_START
322 | }
323 |
324 | post_waiter_loop()
325 | {
326 | LIST=$@
327 | HEAD=${LIST%% ; *}
328 | TAIL=${LIST#* ; }
329 | HEAD2=${HEAD#\! *}
330 | echo ":> ejabberdctl $HEAD2"
331 | $0 $HEAD2
332 | ctlstatus=$?
333 | if [ $ctlstatus -ne 0 ] ; then
334 | if [ "$HEAD" != "$HEAD2" ] ; then
335 | echo ":> FAILURE in command '$HEAD2' !!! Ignoring result"
336 | else
337 | echo ":> FAILURE in command '$HEAD' !!! Stopping ejabberd..."
338 | $0 halt > /dev/null
339 | exit $ctlstatus
340 | fi
341 | fi
342 | [ "$HEAD" = "$TAIL" ] || post_waiter_loop $TAIL
343 | }
344 |
345 | # allow sync calls
346 | wait_status()
347 | {
348 | # args: status try delay
349 | # return: 0 OK, 1 KO
350 | timeout="$2"
351 | status=4
352 | while [ "$status" -ne "$1" ] ; do
353 | sleep "$3"
354 | timeout=$((timeout - 1))
355 | if [ $timeout -eq 0 ] ; then
356 | status="$1"
357 | else
358 | run_erl "$(uid ctl)" -hidden -noinput -s ejabberd_ctl -boot start_clean \
359 | -extra "$ERLANG_NODE" $NO_TIMEOUT status > /dev/null
360 | status="$?"
361 | fi
362 | done
363 | [ $timeout -gt 0 ]
364 | }
365 |
366 | # ensure we can change current directory to SPOOL_DIR
367 | [ -d "$SPOOL_DIR" ] || FIRST_RUN=true
368 | [ -d "$SPOOL_DIR" ] || run_cmd mkdir -p "$SPOOL_DIR"
369 | cd "$SPOOL_DIR" || {
370 | echo "ERROR: can not access directory $SPOOL_DIR"
371 | exit 6
372 | }
373 |
374 | # main
375 | case $1 in
376 | start)
377 | check_start
378 | exec_erl "$ERLANG_NODE" $EJABBERD_OPTS -detached
379 | ;;
380 | foreground)
381 | check_start
382 | post_waiter_fork
383 | exec_erl "$ERLANG_NODE" $EJABBERD_OPTS -noinput
384 | ;;
385 | foreground-quiet)
386 | check_start
387 | exec_erl "$ERLANG_NODE" $EJABBERD_OPTS -noinput -ejabberd quiet true
388 | ;;
389 | live)
390 | livewarning
391 | check_start
392 | exec_erl "$ERLANG_NODE" $EJABBERD_OPTS
393 | ;;
394 | debug)
395 | debugwarning
396 | set_dist_client
397 | exec_erl "$(uid debug)" -hidden -remsh "$ERLANG_NODE" \
398 | -boot start_clean
399 | ;;
400 | etop)
401 | set_dist_client
402 | exec_erl "$(uid top)" -hidden -node "$ERLANG_NODE" -s etop \
403 | -s erlang halt -output text \
404 | -boot start_clean
405 | ;;
406 | iexdebug)
407 | debugwarning
408 | set_dist_client
409 | exec_iex "$(uid debug)" --remsh "$ERLANG_NODE" --boot start_clean
410 | ;;
411 | iexlive)
412 | livewarning
413 | exec_iex "$ERLANG_NODE" --erl "$EJABBERD_OPTS" --app ejabberd
414 | ;;
415 | ping)
416 | PEER=${2:-$ERLANG_NODE}
417 | [ "$PEER" = "${PEER%.*}" ] && PS="-s"
418 | set_dist_client
419 | exec_cmd "$ERL" ${PS:--}name "$(uid ping "$(hostname $PS)")" $ERLANG_OPTS \
420 | -noinput -hidden -eval 'io:format("~p~n",[net_adm:ping('"'$PEER'"')])' \
421 | -s erlang halt -output text \
422 | -boot start_clean
423 | ;;
424 | started)
425 | set_dist_client
426 | wait_status 0 30 2 # wait 30x2s before timeout
427 | ;;
428 | stopped)
429 | set_dist_client
430 | wait_status 3 30 2 && stop_epmd # wait 30x2s before timeout
431 | ;;
432 | post_waiter)
433 | post_waiter_waiting
434 | ;;
435 | *)
436 | set_dist_client
437 | run_erl "$(uid ctl)" -hidden -noinput -boot start_clean \
438 | -s ejabberd_ctl -extra "$ERLANG_NODE" $NO_TIMEOUT "$@"
439 | result=$?
440 | case $result in
441 | 2|3) help;;
442 | *) :;;
443 | esac
444 | exit $result
445 | ;;
446 | esac
447 |
--------------------------------------------------------------------------------
/ecs/bin/erl:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -e
3 |
4 | ROOTDIR=/home/ejabberd
5 | BINDIR=$ROOTDIR/bin
6 | EMU=beam
7 | PROGNAME=`echo $0 | sed 's/.*\\///'`
8 | export EMU
9 | export ROOTDIR
10 | export BINDIR
11 | export PROGNAME
12 | exec "$BINDIR/erlexec" ${1+"$@"}
13 |
--------------------------------------------------------------------------------
/ecs/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | current=$(date +%y.%m)
4 | version=${1:-$current}
5 |
6 | docker build \
7 | --build-arg VERSION=$version \
8 | --build-arg VCS_REF=`git rev-parse --short HEAD` \
9 | --build-arg BUILD_DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"` \
10 | -t ejabberd/ecs:$version .
11 |
12 | [ "$version" = "latest" ] || docker tag ejabberd/ecs:$version ejabberd/ecs:latest
13 |
--------------------------------------------------------------------------------
/ecs/conf/dhparams.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN DH PARAMETERS-----
2 | MIIBCAKCAQEA6/sznqAfpkS3X0jBBmYgIm3XAq2mteWVGD3/CbQ2rfk8/38fEGN7
3 | j5G+WnulMkf9WvGtRnFQrsIsnHUyMy4ay1p7ERKCA+TLd+biOIFXOnABpvnVcPjQ
4 | LP/G5t7kJ/kM5G8eHDk1R7rvhA8Xecv7oX6QFqsdYRSM1tO9HR0l53tSPQ0swk6v
5 | PhWZmOSfjugfOKwHMuXwI112pyXI1XEqC/mq+CJNJw0Z3eLcOcJWuFIZuoOwXDdU
6 | GXK0kEypq+bMTVuq1B3WMxFon8PffQ/rmbH6Bk3SXrJz6koKCcBhm019/fuNSGQ5
7 | 6uVCmIbxWeYL6Yn8qRBVMlgC3DEGMzONWwIBAg==
8 | -----END DH PARAMETERS-----
9 |
--------------------------------------------------------------------------------
/ecs/conf/ejabberd.yml:
--------------------------------------------------------------------------------
1 | ###
2 | ### ejabberd configuration file
3 | ###
4 | ### The parameters used in this configuration file are explained at
5 | ###
6 | ### https://docs.ejabberd.im/admin/configuration
7 | ###
8 | ### The configuration file is written in YAML.
9 | ### *******************************************************
10 | ### ******* !!! WARNING !!! *******
11 | ### ******* YAML IS INDENTATION SENSITIVE *******
12 | ### ******* MAKE SURE YOU INDENT SECTIONS CORRECTLY *******
13 | ### *******************************************************
14 | ### Refer to http://en.wikipedia.org/wiki/YAML for the brief description.
15 | ###
16 |
17 | define_macro:
18 | HOST: localhost
19 | ADMIN: "admin@localhost"
20 | PORT_C2S: 5222
21 | PORT_C2S_TLS: 5223
22 | PORT_S2S: 5269
23 | PORT_HTTP_TLS: 5443
24 | PORT_HTTP: 5280
25 | PORT_BROWSER: 1880
26 | PORT_STUN: 5478
27 | PORT_MQTT: 1883
28 | PORT_PROXY65: 7777
29 |
30 | hosts:
31 | - HOST
32 |
33 | loglevel: info
34 |
35 | certfiles:
36 | - /home/ejabberd/conf/server.pem
37 |
38 | ca_file: "/home/ejabberd/conf/cacert.pem"
39 |
40 | ## When using let's encrypt to generate certificates
41 | ##certfiles:
42 | ## - /etc/letsencrypt/live/localhost/fullchain.pem
43 | ## - /etc/letsencrypt/live/localhost/privkey.pem
44 | ##
45 | ##ca_file: "/etc/letsencrypt/live/localhost/fullchain.pem"
46 |
47 | listen:
48 | -
49 | port: PORT_C2S
50 | ip: "::"
51 | module: ejabberd_c2s
52 | max_stanza_size: 262144
53 | shaper: c2s_shaper
54 | access: c2s
55 | starttls_required: true
56 | -
57 | port: PORT_C2S_TLS
58 | ip: "::"
59 | module: ejabberd_c2s
60 | max_stanza_size: 262144
61 | shaper: c2s_shaper
62 | access: c2s
63 | tls: true
64 | -
65 | port: PORT_S2S
66 | ip: "::"
67 | module: ejabberd_s2s_in
68 | max_stanza_size: 524288
69 | shaper: s2s_shaper
70 | -
71 | port: PORT_HTTP_TLS
72 | ip: "::"
73 | module: ejabberd_http
74 | tls: true
75 | request_handlers:
76 | /admin: ejabberd_web_admin
77 | /api: mod_http_api
78 | /bosh: mod_bosh
79 | /captcha: ejabberd_captcha
80 | /upload: mod_http_upload
81 | /ws: ejabberd_http_ws
82 | /oauth: ejabberd_oauth
83 | -
84 | port: PORT_HTTP
85 | ip: "::"
86 | module: ejabberd_http
87 | request_handlers:
88 | /admin: ejabberd_web_admin
89 | -
90 | port: PORT_BROWSER
91 | ip: "::"
92 | module: ejabberd_http
93 | request_handlers:
94 | /: ejabberd_web_admin
95 | -
96 | port: PORT_MQTT
97 | ip: "::"
98 | module: mod_mqtt
99 | backlog: 1000
100 | ##
101 | ## https://docs.ejabberd.im/admin/configuration/#stun-and-turn
102 | ## ejabberd_stun: Handles STUN Binding requests
103 | ##
104 | ##-
105 | ## port: 3478
106 | ## ip: "0.0.0.0"
107 | ## transport: udp
108 | ## module: ejabberd_stun
109 | ## use_turn: true
110 | ## turn_ip: "{{ IP }}"
111 | ## auth_type: user
112 | ## auth_realm: "example.com"
113 | ##-
114 | ## port: 3478
115 | ## ip: "0.0.0.0"
116 | ## module: ejabberd_stun
117 | ## use_turn: true
118 | ## turn_ip: "{{ IP }}"
119 | ## auth_type: user
120 | ## auth_realm: "example.com"
121 | ##-
122 | ## port: 5349
123 | ## ip: "0.0.0.0"
124 | ## module: ejabberd_stun
125 | ## certfile: "/home/ejabberd/conf/server.pem"
126 | ## tls: true
127 | ## use_turn: true
128 | ## turn_ip: "{{ IP }}"
129 | ## auth_type: user
130 | ## auth_realm: "example.com"
131 | ##
132 | ## https://docs.ejabberd.im/admin/configuration/#sip
133 | ## To handle SIP (VOIP) requests:
134 | ##
135 | ##-
136 | ## port: 5060
137 | ## ip: "0.0.0.0"
138 | ## transport: udp
139 | ## module: ejabberd_sip
140 | ##-
141 | ## port: 5060
142 | ## ip: "0.0.0.0"
143 | ## module: ejabberd_sip
144 | ##-
145 | ## port: 5061
146 | ## ip: "0.0.0.0"
147 | ## module: ejabberd_sip
148 | ## tls: true
149 |
150 | s2s_use_starttls: optional
151 |
152 | acl:
153 | local:
154 | user_regexp: ""
155 | loopback:
156 | ip:
157 | - 127.0.0.0/8
158 | - ::1/128
159 | admin:
160 | user:
161 | - ADMIN
162 |
163 | access_rules:
164 | local:
165 | allow: local
166 | c2s:
167 | deny: blocked
168 | allow: all
169 | announce:
170 | allow: admin
171 | configure:
172 | allow: admin
173 | muc_create:
174 | allow: local
175 | pubsub_createnode:
176 | allow: local
177 | trusted_network:
178 | allow: loopback
179 |
180 | api_permissions:
181 | "console commands":
182 | from: ejabberd_ctl
183 | who: all
184 | what: "*"
185 | "webadmin commands":
186 | from: ejabberd_web_admin
187 | who: admin
188 | what: "*"
189 | "admin access":
190 | who:
191 | access:
192 | allow:
193 | - acl: loopback
194 | - acl: admin
195 | oauth:
196 | scope: "ejabberd:admin"
197 | access:
198 | allow:
199 | - acl: loopback
200 | - acl: admin
201 | what:
202 | - "*"
203 | - "!stop"
204 | - "!start"
205 | "public commands":
206 | who:
207 | ip: 127.0.0.1/8
208 | what:
209 | - status
210 | - connected_users_number
211 |
212 | shaper:
213 | normal:
214 | rate: 3000
215 | burst_size: 20000
216 | fast: 100000
217 |
218 | shaper_rules:
219 | max_user_sessions: 10
220 | max_user_offline_messages:
221 | 5000: admin
222 | 100: all
223 | c2s_shaper:
224 | none: admin
225 | normal: all
226 | s2s_shaper: fast
227 |
228 | acme:
229 | contact: "mailto:example-admin@example.com"
230 | ca_url: "https://acme-staging-v02.api.letsencrypt.org/directory"
231 |
232 | modules:
233 | mod_adhoc: {}
234 | mod_admin_extra: {}
235 | mod_announce:
236 | access: announce
237 | mod_avatar: {}
238 | mod_blocking: {}
239 | mod_bosh: {}
240 | mod_caps: {}
241 | mod_carboncopy: {}
242 | mod_client_state: {}
243 | mod_configure: {}
244 | mod_disco: {}
245 | mod_fail2ban: {}
246 | mod_http_api: {}
247 | mod_http_upload:
248 | put_url: https://@HOST@:5443/upload
249 | custom_headers:
250 | "Access-Control-Allow-Origin": "https://@HOST@"
251 | "Access-Control-Allow-Methods": "GET,HEAD,PUT,OPTIONS"
252 | "Access-Control-Allow-Headers": "Content-Type"
253 | mod_last: {}
254 | mod_mam:
255 | ## Mnesia is limited to 2GB, better to use an SQL backend
256 | ## For small servers SQLite is a good fit and is very easy
257 | ## to configure. Uncomment this when you have SQL configured:
258 | ## db_type: sql
259 | assume_mam_usage: true
260 | default: always
261 | mod_mqtt: {}
262 | mod_muc:
263 | access:
264 | - allow
265 | access_admin:
266 | - allow: admin
267 | access_create: muc_create
268 | access_persistent: muc_create
269 | access_mam:
270 | - allow
271 | default_room_options:
272 | allow_subscription: true # enable MucSub
273 | mam: true
274 | mod_muc_admin: {}
275 | mod_muc_occupantid: {}
276 | mod_offline:
277 | access_max_user_messages: max_user_offline_messages
278 | mod_ping: {}
279 | mod_privacy: {}
280 | mod_private: {}
281 | mod_proxy65:
282 | access: local
283 | max_connections: 5
284 | port: PORT_PROXY65
285 | mod_pubsub:
286 | access_createnode: pubsub_createnode
287 | plugins:
288 | - flat
289 | - pep
290 | force_node_config:
291 | ## Avoid buggy clients to make their bookmarks public
292 | storage:bookmarks:
293 | access_model: whitelist
294 | mod_push: {}
295 | mod_push_keepalive: {}
296 | mod_register:
297 | ## Only accept registration requests from the "trusted"
298 | ## network (see access_rules section above).
299 | ## Think twice before enabling registration from any
300 | ## address. See the Jabber SPAM Manifesto for details:
301 | ## https://github.com/ge0rg/jabber-spam-fighting-manifesto
302 | ip_access: trusted_network
303 | mod_roster:
304 | versioning: true
305 | mod_sip: {}
306 | mod_s2s_bidi: {}
307 | mod_s2s_dialback: {}
308 | mod_shared_roster: {}
309 | mod_stream_mgmt:
310 | resend_on_timeout: if_offline
311 | mod_vcard: {}
312 | mod_vcard_xupdate: {}
313 | mod_version:
314 | show_os: false
315 |
316 | ### Local Variables:
317 | ### mode: yaml
318 | ### End:
319 | ### vim: set filetype=yaml tabstop=8
320 |
--------------------------------------------------------------------------------
/ecs/conf/ejabberdctl.cfg:
--------------------------------------------------------------------------------
1 | #
2 | # In this file you can configure options that are passed by ejabberdctl
3 | # to the erlang runtime system when starting ejabberd
4 | #
5 |
6 | #' POLL: Kernel polling ([true|false])
7 | #
8 | # The kernel polling option requires support in the kernel.
9 | # Additionally, you need to enable this feature while compiling Erlang.
10 | #
11 | # Default: true
12 | #
13 | #POLL=true
14 |
15 | #.
16 | #' ERL_MAX_PORTS: Maximum number of simultaneously open Erlang ports
17 | #
18 | # ejabberd consumes two or three ports for every connection, either
19 | # from a client or from another XMPP server. So take this into
20 | # account when setting this limit.
21 | #
22 | # Default: 65536 (or 8196 on Windows)
23 | # Maximum: 268435456
24 | #
25 | #ERL_MAX_PORTS=65536
26 |
27 | #.
28 | #' FIREWALL_WINDOW: Range of allowed ports to pass through a firewall
29 | #
30 | # If ejabberd is configured to run in cluster, and a firewall is blocking ports,
31 | # it's possible to make Erlang use a defined range of port (instead of dynamic
32 | # ports) for node communication.
33 | #
34 | # Default: not defined
35 | # Example: 4200-4210
36 | #
37 | #FIREWALL_WINDOW=
38 |
39 | #.
40 | #' INET_DIST_INTERFACE: IP address where this Erlang node listens other nodes
41 | #
42 | # This communication is used by ejabberdctl command line tool,
43 | # and in a cluster of several ejabberd nodes.
44 | #
45 | # Default: 0.0.0.0
46 | #
47 | #INET_DIST_INTERFACE=127.0.0.1
48 |
49 | #.
50 | #' ERL_DIST_PORT: Port number for Erlang distribution
51 | #
52 | # For Erlang distribution, clustering and ejabberdctl usage, the
53 | # Erlang VM listens in a random TCP port number, and the Erlang Port
54 | # Mapper Daemon (EPMD) is spawned and used to determine this port
55 | # number.
56 | #
57 | # ERL_DIST_PORT can define this port number. In that case, EPMD is
58 | # not spawned during ejabberd startup, and ERL_EPMD_ADDRESS is
59 | # ignored. ERL_DIST_PORT must be set to the same port number during
60 | # ejabberd startup and when calling ejabberdctl. This feature
61 | # requires at least Erlang/OTP 23.1.
62 | #
63 | # Default: not defined
64 | #
65 | #ERL_DIST_PORT=5210
66 |
67 | #.
68 | #' ERL_EPMD_ADDRESS: IP addresses where EPMD listens for connections
69 | #
70 | # This environment variable may be set to a comma-separated
71 | # list of IP addresses, in which case the EPMD daemon
72 | # will listen only on the specified address(es) and on the
73 | # loopback address (which is implicitly added to the list if it
74 | # has not been specified). The default behaviour is to listen on
75 | # all available IP addresses.
76 | #
77 | # Default: 0.0.0.0
78 | #
79 | #ERL_EPMD_ADDRESS=127.0.0.1
80 |
81 | #.
82 | #' ERL_PROCESSES: Maximum number of Erlang processes
83 | #
84 | # Erlang consumes a lot of lightweight processes. If there is a lot of activity
85 | # on ejabberd so that the maximum number of processes is reached, people will
86 | # experience greater latency times. As these processes are implemented in
87 | # Erlang, and therefore not related to the operating system processes, you do
88 | # not have to worry about allowing a huge number of them.
89 | #
90 | # Default: 262144
91 | # Maximum: 268435456
92 | #
93 | #ERL_PROCESSES=262144
94 |
95 | #.
96 | #' ERL_MAX_ETS_TABLES: Maximum number of ETS and Mnesia tables
97 | #
98 | # The number of concurrent ETS and Mnesia tables is limited. When the limit is
99 | # reached, errors will appear in the logs:
100 | # ** Too many db tables **
101 | # You can safely increase this limit when starting ejabberd. It impacts memory
102 | # consumption but the difference will be quite small.
103 | #
104 | # Default: 2053
105 | #
106 | #ERL_MAX_ETS_TABLES=2053
107 |
108 | #.
109 | #' ERL_OPTIONS: Additional Erlang options
110 | #
111 | # The next variable allows to specify additional options passed to
112 | # all commands using erlang interpreter. This applies to starting
113 | # ejabberd server itself but also auxiliary commands like for example
114 | # starting debug shell. See erl(1) for list of commands that can be
115 | # used here.
116 | #
117 | # It might be useful to add "-pa /usr/local/lib/ejabberd/ebin" if you
118 | # want to add local modules in this path.
119 | #
120 | # Default: ""
121 | #
122 | #ERL_OPTIONS=""
123 |
124 | #.
125 | #' EJABBERD_OPTS: Additional Erlang options to start ejabberd
126 | #
127 | # The next variable allows to specify additional options passed to erlang while
128 | # starting ejabberd. Some useful options are -noshell, -detached, -heart. When
129 | # ejabberd is started from an init.d script options -noshell and -detached are
130 | # added implicitly. See erl(1) for more info.
131 | #
132 | # For example you can use value "-heart -env HEART_BEAT_TIMEOUT 120 -env ERL_CRASH_DUMP_SECONDS 60"
133 | #
134 | # Default: ""
135 | #
136 | #EJABBERD_OPTS=""
137 |
138 | #.
139 | #' ERLANG_NODE: Erlang node name
140 | #
141 | # The next variable allows to explicitly specify erlang node for ejabberd
142 | # It can be given in different formats:
143 | # ERLANG_NODE=ejabberd
144 | # Lets erlang add hostname to the node (ejabberd uses short name in this case)
145 | # ERLANG_NODE=ejabberd@hostname
146 | # Erlang uses node name as is (so make sure that hostname is a real
147 | # machine hostname or you'll not be able to control ejabberd)
148 | # ERLANG_NODE=ejabberd@hostname.domainname
149 | # The same as previous, but erlang will use long hostname
150 | # (see erl (1) manual for details)
151 | #
152 | # Default: ejabberd@localhost
153 | #
154 | #ERLANG_NODE=ejabberd@$(hostname -s)
155 |
156 | #.
157 | #' ERLANG_COOKIE: Erlang cookie for inter-node communication
158 | #
159 | # When using ejabberd in cluster, you need all nodes to share
160 | # the same erlang cookie. If not defined, a random value is used
161 | # at node first start, which prevent clustering to work. Setting
162 | # a defined cookie for all your nodes is needed to setup cluster.
163 | #
164 | # Default: ""
165 | #
166 | #ERLANG_COOKIE=""
167 |
168 | #.
169 | #.
170 | #' EJABBERD_PID_PATH: ejabberd PID file
171 | #
172 | # Indicate the full path to the ejabberd Process identifier (PID) file.
173 | # If this variable is defined, ejabberd writes the PID file when starts,
174 | # and deletes it when stops.
175 | # Remember to create the directory and grant write permission to ejabberd.
176 | #
177 | # Default: don't write PID file
178 | #
179 | #EJABBERD_PID_PATH=/var/run/ejabberd/ejabberd.pid
180 |
181 | #.
182 | #' EJABBERD_CONFIG_PATH: ejabberd configuration file
183 | #
184 | # Specify the full path to the ejabberd configuration file. If the file name has
185 | # yml or yaml extension, it is parsed as a YAML file; otherwise, Erlang syntax is
186 | # expected.
187 | #
188 | # Default: $ETC_DIR/ejabberd.yml
189 | #
190 | #EJABBERD_CONFIG_PATH=/etc/ejabberd/ejabberd.yml
191 |
192 | #.
193 | #' CONTRIB_MODULES_PATH: contributed ejabberd modules path
194 | #
195 | # Specify the full path to the contributed ejabberd modules. If the path is not
196 | # defined, ejabberd will use ~/.ejabberd-modules in home of user running ejabberd.
197 | #
198 | # Default: $HOME/.ejabberd-modules
199 | #
200 | #CONTRIB_MODULES_PATH=/opt/ejabberd-modules
201 |
202 | #.
203 | #' CONTRIB_MODULES_CONF_DIR: configuration directory for contributed modules
204 | #
205 | # Specify the full path to the configuration directory for contributed ejabberd
206 | # modules. In order to configure a module named mod_foo, a mod_foo.yml file can
207 | # be created in this directory. This file will then be used instead of the
208 | # default configuration file provided with the module.
209 | #
210 | # Default: $CONTRIB_MODULES_PATH/conf
211 | #
212 | #CONTRIB_MODULES_CONF_DIR=/etc/ejabberd/modules
213 |
214 | #.
215 | #'
216 | # vim: foldmarker=#',#. foldmethod=marker:
217 |
--------------------------------------------------------------------------------
/ecs/conf/inetrc:
--------------------------------------------------------------------------------
1 | {lookup,["file","native"]}.
2 | {host,{127,0,0,1}, ["localhost","@@HOSTNAME@@"]}.
3 | {file, resolv, "/etc/resolv.conf"}.
4 |
--------------------------------------------------------------------------------
/ecs/conf/server.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN PRIVATE KEY-----
2 | MIIJRAIBADANBgkqhkiG9w0BAQEFAASCCS4wggkqAgEAAoICAQDkzs+QWstSzyRN
3 | WaWCYbxyuKzoRfGpxDi54YOLoyISV4ulMVuYn3Uz6AJGH1d4oqh/JAaVOx1h/bdB
4 | nhAYy25c0P7dYtqdco3b1SMZIt3EYwHsgedTVNqZjG1+ExjqUiU8V8r7tGLFBjO/
5 | O7H9z0zXbJ7IYhVdn99ijro8WHdEqNpnWHxVQF/KoVeTvFfcopD9QBhcu1uvwiMU
6 | G4mCOpYbysl/9NQCsNP4TV9pQ/6D6jQjIGTzuXO74cEhtibaLl7e1aPDIyqzicwS
7 | SgneKM/ypG8X9VgM81r3/nfe5us/vrIW0uXvH3qOu+/b76HULdaZ8OAItazzBoUO
8 | tl+/kakCN5J8uoKdP61hzPZWCLT84T79WQpWOa4dDiQPtuOMMlp0KZDDH+fW3WMG
9 | KmF8xiFigmPmb9SYyAVsZH9OsQeglRSS1dEV2vVzH3WpVTrZdPSM6sOhZel9fOXI
10 | kfrlZXlFvQHltvi0jUeeYM8z1e3iFAzJ6IXIKu2Ubbto6khFCZTx4FAJohOoWRJg
11 | ZcMmnGHlJNkRBYH5ImQupLhwSr2XEPPhidW5u87N+ZNk9np/ZykCcI1xiXFfgcnr
12 | CgmEWjXUV8nhgiXyl5EFAqyOlrsjc1LLL3ykzNZXHyQSFjaZe5HCDx2NjxRsdlKf
13 | gcLuifVvaaM5Vmb4GyHLr3R2HNTchwIDAQABAoICABSYVPCOa5zBjmfz+MTanUbK
14 | Pq4NlaoNQnngxaFtBqUWAjjVT4RWXgtVB9dd/Nab9YS0Lm+CSavHVZZvbs18iiuK
15 | mFY/DqR7ai9uaOFbVRDXRJYQP00t5xtJG5XsjCKTUEy1Lk0nuHg5jbDZ47SP0z/U
16 | xBoPUhMCT+4kILlL0Th55mbE/TQDPlwT17kxi8sNSvWwrkCykJcqZ1PpAqCZO2e3
17 | AholZGv1lK7V8A+ekis3iofa45tYhwVTVbn+FlMvN1ThcAMhiDdu4NKInYjErasO
18 | h/1lFQ7dXMPTwOBscqJjPM53H0E92R895WIrmKprkdR7bP77s1yQqqtfWRD6QHcK
19 | CK3dZ4GRYnL/2nsoFEi2UbKkBy+gy8z7fclv5NUfZG1mjPFMgsVC2m+6xNS1Owld
20 | YFx8pxrudxEoKOzDYd5SBDfpGkda3+1IqsPBme+Mqu4Q1fluQLBBP/oIt+RIqHMu
21 | J3ZZYPJVKUBJHKKGqnYeIsh2Ju/8IrT9dhWWRzfzhh0+hMHJjW7sXrbVm8OYpge0
22 | WBGkDf5zoBL2Kpbf6NIk68JTh+jpDYOvZbYjnPHji8zpDaxFaOgpX/WLaOVxMm10
23 | pw1kAgRhDeV87gjVdW+4NOhWfRjW/m71YAZ3NNTYk7x0KlwNNI//MvwdvHX969Td
24 | T6kUmW9Kg2ezolSs/aphAoIBAQD5Ya6lcuQuBLTBQIS7+eMM1N0j6QhBvd5Tzyr+
25 | 6oXND3vA08skDd2Zi7m8JiPUn7ywcu+yo+H+MJAqKqPMARWSJQQ/CYQ1N+i/uZN7
26 | 1xqnTWubNtxJtikbRnCWCmVNzCSl+H9Z41eWygrO+V4c6HT9Zx1X6VOSArPlJkWw
27 | fCHzuJ3N5W8bR7RmOuVHZ/3/ZD1APkkOnqBmUZREBfiQNbGmYK3NG1Xa49MRGM3f
28 | 7YRTx3A3sucj9gKV/N1YyaLUcTAy0OUtqqcSBsUTfBPU/ztY0yg3+Xdn5WYRM1ZL
29 | Pim8OMtEP3ZdyKAb07RQr3OM04gximWesxiG74rYVVMyk0u3AoIBAQDq4VliNJya
30 | 7Gb9UyzjCiLfovpVbNSheP/KDSk2mBMwJpzMczMzhuvfIReFQFxefORALpgAmpPq
31 | bD79cOEKfknrseSLfPMGKB38RCkaBXrnaPQZ3aaXktMlrk2rOVIcawrYK3He6j0l
32 | 5fh+6uXws0jeifXzzMAmDvpkFRIGVjeJYZFdXQHMZW2ZdZFpJZj+eiWkTMDtv0L3
33 | Pl2GQVRWma/J4SH5pcHg5kLdTv8CoLRnXkDQt/BgT1Vblj8P92oArLN1zKzd/Vbu
34 | l7kFICwkn91FC0PdzWpoJAWtKlQbX19TWZ0YQLkVPB+DSjiJn+zu5+P1STKoy4eS
35 | V+mnVwS9dJWxAoIBAQDRI0NkywpjMV0pKGNohXMNQsLGJ9rdz05ReM61A5b8VrzR
36 | BI07CknKSCyWhmHMIb4LOAifBuMy2iU8x4+gOVSOwG5kMyXlv6J4jzgJRma64amZ
37 | fJOXWaX1ksg+fC9i5A3kBpc+mfLNqVkRJH3xvlzGWqB4JlwIei3Fwaf2DtQmYbAt
38 | iPj5ptO6XDAGB0cy1Cyt4M5B7XPU+xtdRKikv/Lg9fkrpn4E2MUcdHHLFpS/8eTB
39 | QU6okNqwUGSM3mSoxtfF9fwMpS4BZx4Fbivvl7B8mHEFKDgkMHS9fhEjftlfWT3W
40 | WWZ51hO34n44oDtGYeu4qDj6s3WhS+hj7oKcSnzXAoIBAQChywkfNM6LiTyIU7sf
41 | yeOr2UBHh+gQMqFANUCmcqsFCBQKYXBrlgz0bn8dMvBtxeoUrAPYpqItYNMjEZZy
42 | +/s/eBLOYwukug2tr+YAHrZCoXFEQAJ5dpIr6p1lzN5a5QFbVtHhk8j7SiaahoRO
43 | AbG4WaAqiGfzz217c2gvJUSsRaE0htSuT0/n3ayEmXmCEfHL83MSUiV22mbiDC5k
44 | WQlWLtaQeTXMDdERUVEoJjse2TYckBfsv7k0lZJrFSrXvB8CjjKl19UCFVFFzpuZ
45 | vuVUoiXlq5IYmneuiPHWySOI7rnf8vWLQxcSARZg9uDm0KWeWQWkcE666APzWWXS
46 | e3SBAoIBAQCtRv8ruFBDuv99l4WKn0ZEODdY+Uxbz1rREzVJx7hEzkif5viJl9Hi
47 | AZnqJPd8I0MMEvplDhe2X6TnF1jjxx+z4U72boY8IPY0rw+kYzBqMwywkCzb+Jn2
48 | qmBtX1XXRsSO1U7pW/ej6RyLQqtMt+lKd5vVxu7fOo3OYmcEJxD4AylUNU7cCFwP
49 | ZtFxe+uddzWYM3O55OrjHEj1LIcJb5n/46Owd2OUXMRNxQ3lv0fBKDWN/1bXiNEh
50 | efb02fSq5nIpoxmHMG/s+PEHB1uDqUjNkNZK42DyrMkwQwnN9M8ZetRWhqu5QgxX
51 | LQheTRhu+UYYcbxy+AHQ8pqBBdnRsxLZ
52 | -----END PRIVATE KEY-----
53 | -----BEGIN CERTIFICATE-----
54 | MIIFnDCCA4SgAwIBAgIJANCgN0JN5H4RMA0GCSqGSIb3DQEBCwUAMGMxCzAJBgNV
55 | BAYTAkZSMQ4wDAYDVQQIDAVQYXJpczEOMAwGA1UEBwwFUGFyaXMxEzARBgNVBAoM
56 | ClByb2Nlc3NPbmUxCzAJBgNVBAsMAklUMRIwEAYDVQQDDAlsb2NhbGhvc3QwHhcN
57 | MTcxMjI5MTExMzA3WhcNNDUwNTE2MTExMzA3WjBjMQswCQYDVQQGEwJGUjEOMAwG
58 | A1UECAwFUGFyaXMxDjAMBgNVBAcMBVBhcmlzMRMwEQYDVQQKDApQcm9jZXNzT25l
59 | MQswCQYDVQQLDAJJVDESMBAGA1UEAwwJbG9jYWxob3N0MIICIjANBgkqhkiG9w0B
60 | AQEFAAOCAg8AMIICCgKCAgEA5M7PkFrLUs8kTVmlgmG8cris6EXxqcQ4ueGDi6Mi
61 | EleLpTFbmJ91M+gCRh9XeKKofyQGlTsdYf23QZ4QGMtuXND+3WLanXKN29UjGSLd
62 | xGMB7IHnU1TamYxtfhMY6lIlPFfK+7RixQYzvzux/c9M12yeyGIVXZ/fYo66PFh3
63 | RKjaZ1h8VUBfyqFXk7xX3KKQ/UAYXLtbr8IjFBuJgjqWG8rJf/TUArDT+E1faUP+
64 | g+o0IyBk87lzu+HBIbYm2i5e3tWjwyMqs4nMEkoJ3ijP8qRvF/VYDPNa9/533ubr
65 | P76yFtLl7x96jrvv2++h1C3WmfDgCLWs8waFDrZfv5GpAjeSfLqCnT+tYcz2Vgi0
66 | /OE+/VkKVjmuHQ4kD7bjjDJadCmQwx/n1t1jBiphfMYhYoJj5m/UmMgFbGR/TrEH
67 | oJUUktXRFdr1cx91qVU62XT0jOrDoWXpfXzlyJH65WV5Rb0B5bb4tI1HnmDPM9Xt
68 | 4hQMyeiFyCrtlG27aOpIRQmU8eBQCaITqFkSYGXDJpxh5STZEQWB+SJkLqS4cEq9
69 | lxDz4YnVubvOzfmTZPZ6f2cpAnCNcYlxX4HJ6woJhFo11FfJ4YIl8peRBQKsjpa7
70 | I3NSyy98pMzWVx8kEhY2mXuRwg8djY8UbHZSn4HC7on1b2mjOVZm+Bshy690dhzU
71 | 3IcCAwEAAaNTMFEwHQYDVR0OBBYEFCTwPSToCR8fTNGz5o2Czlc/BlfqMB8GA1Ud
72 | IwQYMBaAFCTwPSToCR8fTNGz5o2Czlc/BlfqMA8GA1UdEwEB/wQFMAMBAf8wDQYJ
73 | KoZIhvcNAQELBQADggIBADnvcqMt+ESTM12BuX6E+4mA0iR//Lxp8FzQkZEb7YPR
74 | eIor6iPVDX+oRo/uVhEPvjH+SXGb+9FOOexIoxoB4C+1UpBRHBS2PROX0BNmIDb7
75 | abRY6iCkIlyrVkVAtswNZdJHLJX5OMPfV52p6HELd4oYlI+AnQDXkrHA8DD7Y59r
76 | o5MonTJV26L2mq2+ceciqviZzQLA0QJxTOPLaz/pq1a2bauP0Q1EjhB0nYJ9hZxp
77 | CuAWXrVA7veElXg7EKyrQrOt6kcnNqpBj7Pk3R1Zq2xNMlfMMqQlJFt7uKy49EwI
78 | qGgmVj1ScL/Savp967LjRaTz0CnJhSLUlCmLq/4JGPWI/AKEi0Hg14EgRiGbha2B
79 | E+3sQxWmCWDeIMLM6m3001VMyT1JgEoJkbhGruDayxPDQuG4nrpK8lNMrnS1Ji0j
80 | 6VQ6OL66RFlpK+/LRYc8cXsh6+hDUaXLQTPs9v880SpoerbjW5Rh9Z7Dh+fX2SJj
81 | 8x6IbNbppn7SGD4iOaHd6+gq0j6iB1zOcTaU5OnZGb4qWNyqm0m94UWFMMr5zlmn
82 | /MwQAnvgLhfcQ1T5iq3AAIrC1D0jn0b5D2CdCFNW1DmbDZiy8db+Pz5g36G9OceQ
83 | oFdxG1n7Nre84DwOlohVYtFkeYy3D6hd+/sbyNa5YqswuKLdm6fWrp/e3es1auXy
84 | -----END CERTIFICATE-----
85 |
--------------------------------------------------------------------------------
/ecs/config.exs:
--------------------------------------------------------------------------------
1 | import Config
2 |
3 | # This is standard path in the context of ejabberd release
4 | config :ejabberd,
5 | file: "config/ejabberd.yml",
6 | log_path: 'log/ejabberd.log'
7 |
8 | # Customize Mnesia directory:
9 | config :mnesia,
10 | dir: 'database/'
11 |
--------------------------------------------------------------------------------
/ecs/ejabberd-docker-install.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 |
3 | ::
4 | :: ejabberd Docker installer for Windows
5 | :: -------------------------------------
6 | :: v0.3
7 | ::
8 | :: This batch script downloads an ejabberd docker image
9 | :: and setups a docker container to run ejabberd.
10 |
11 | ::
12 | :: 1. Download and install Docker:
13 | ::
14 | :: If you use Windows 10, download Docker Desktop from:
15 | :: https://www.docker.com/
16 | ::
17 | :: If you use Windows 7 or 8, download Docker Toolbox from:
18 | :: https://github.com/docker/toolbox/releases
19 | :: After installation, run Docker Quickstart Installer
20 | ::
21 |
22 | ::
23 | :: 2. Edit those options:
24 |
25 | :: Directory where your ejabberd deployment files will be installed
26 | :: (configuration, database, logs, ...)
27 | ::
28 | :: In Windows 10 you can configure the path:
29 |
30 | set INSTALL_DIR_WINDOWS10=C:\ejabberd
31 |
32 | :: In older Windows, not configurable, it will be installed in:
33 | :: C:\Users\%USERNAME%\ejabberd
34 |
35 | :: Please enter the desired ejabberd domain name.
36 | :: The domain is the visible attribute that is added to the username
37 | :: to form the Jabber Identifier (for example: user@example.net).
38 | :: This computer must be known on the network with this address name.
39 | :: You can later add more in conf/ejabberd.yml
40 |
41 | set HOST=localhost
42 |
43 | :: Please enter the administrator username for the current
44 | :: ejabberd installation. A Jabber account with this username
45 | :: will be created and granted administrative privileges.
46 | :: Don't use blankspaces in the username.
47 |
48 | set USER=admin
49 |
50 | :: Please provide a password for that new administrator account
51 |
52 | set PASSWORD=
53 |
54 | :: By default this downloads 'latest' ejabberd version,
55 | :: but you can set a specific version, for example 21.01
56 |
57 | set VERSION=latest
58 |
59 | :: This tells docker what ports ejabberd will use.
60 | :: You can later configure them in conf/ejabberd.yml
61 |
62 | set PORTS=5180 5222 5269 5443
63 |
64 | ::
65 | :: 3. Now save this script and run it.
66 | ::
67 |
68 | ::
69 | :: 4. When installation is completed:
70 | ::
71 | :: If using Windows 10, open Docker Desktop and you can:
72 | ::
73 | :: - (>) START the ejabberd container
74 | :: - Enter WebAdmin: click the ([->]) OPEN IN BROWSER button
75 | :: - To try ejabberdctl, click the (>_) CLI button, then: bin/ejabberdctl
76 | :: - ([]) STOP the ejabberd container
77 | ::
78 | :: If using an old Windows, open Kitematic and you can:
79 | ::
80 | :: - START the ejabberd container
81 | :: - Open your configuration, logs, ... in Settings > Volumes
82 | :: - Enter WebAdmin in Settings > Hostname/Ports > click on the 5180 port
83 | :: - Try ejabberdctl in EXEC, then: bin/ejabberdctl
84 | :: - STOP the ejabberd container
85 | ::
86 | :: You can delete the container and create it again running this script,
87 | :: the configuration and database are maintained.
88 | ::
89 |
90 | ::===============================================================
91 | :: Check Windows version
92 | ::
93 | ::===============================================================
94 |
95 | set INSTALL_DIR_DOCKER=c/Users/%USERNAME%/ejabberd
96 |
97 | for /f "tokens=4-5 delims=. " %%i in ('ver') do set WVERSION=%%i.%%j
98 | if "%wversion%" == "10.0" (
99 | echo === Preparing paths to install in Windows 10...
100 | set INSTALL_DIR=%INSTALL_DIR_WINDOWS10%
101 | set VC=-v %INSTALL_DIR_WINDOWS10%\conf:/home/ejabberd/conf
102 | set VD=-v %INSTALL_DIR_WINDOWS10%\database:/home/ejabberd/database
103 | set VL=-v %INSTALL_DIR_WINDOWS10%\logs:/home/ejabberd/logs
104 | set VM=-v %INSTALL_DIR_WINDOWS10%\ejabberd-modules:/home/ejabberd/.ejabberd-modules
105 | set DOCKERDOWNLOAD="First download and install Docker Desktop from https://www.docker.com/"
106 | ) else (
107 | echo === Preparing paths to install in Windows older than 10...
108 | set INSTALL_DIR=C:\Users\%USERNAME%\ejabberd
109 | set VC=-v "/%INSTALL_DIR_DOCKER%/conf:/home/ejabberd/conf"
110 | set VD=-v "/%INSTALL_DIR_DOCKER%/database:/home/ejabberd/database"
111 | set VL=-v "/%INSTALL_DIR_DOCKER%/logs:/home/ejabberd/logs"
112 | set VM=-v "/%INSTALL_DIR_DOCKER%/ejabberd-modules:/home/ejabberd/.ejabberd-modules"
113 | set DOCKERDOWNLOAD="First download and install Docker Toolbox from https://github.com/docker/toolbox/releases"
114 | )
115 | set VOLUMES=%VC% %VD% %VL% %VM%
116 |
117 | ::===============================================================
118 | :: Check docker is installed
119 | ::
120 | ::===============================================================
121 |
122 | docker version >NUL
123 | if %ERRORLEVEL% NEQ 0 (
124 | echo.
125 | echo === ERROR: It seems docker is not installed!!!
126 | echo.
127 | echo %DOCKERDOWNLOAD%
128 | echo === Then try to run this script again.
129 | echo.
130 | pause
131 | exit 1
132 | )
133 |
134 | ::===============================================================
135 | :: Check install options are correctly set
136 | ::
137 | ::===============================================================
138 |
139 | if [%PASSWORD%]==[] (
140 | echo.
141 | echo === ERROR: PASSWORD not set!!!
142 | echo.
143 | echo === Please edit this script and set the PASSWORD.
144 | echo === Then try to run this script again.
145 | echo.
146 | pause
147 | exit 1
148 | )
149 |
150 | ::===============================================================
151 | :: Download Docker image
152 | ::
153 | ::===============================================================
154 |
155 | set IMAGE=ejabberd/ecs:%VERSION%
156 |
157 | echo.
158 | echo === Checking if the '%IMAGE%' docker image was already downloaded...
159 | docker image history %IMAGE% >NUL
160 | if %ERRORLEVEL% NEQ 0 (
161 | echo === The '%IMAGE%' docker image was not downloaded yet.
162 | echo.
163 | echo === Downloading the '%IMAGE%' docker image, please wait...
164 | docker pull %IMAGE%
165 | ) else (
166 | echo === The '%IMAGE%' docker image was already downloaded.
167 | )
168 |
169 | ::===============================================================
170 | :: Create preliminary container
171 | ::
172 | ::===============================================================
173 |
174 | echo.
175 | echo === Checking if the 'ejabberd' docker container already exists...
176 | docker container logs ejabberd
177 | if %ERRORLEVEL% EQU 0 (
178 | echo.
179 | echo === The 'ejabberd' docker container already exists.
180 | echo === Nothing to do, so installation finishes now.
181 | echo === You can go to Docker Desktop and start the 'ejabberd' container.
182 | echo.
183 | pause
184 | exit 1
185 | ) else (
186 | echo === The 'ejabberd' docker container doesn't yet exist,
187 | echo === so let's continue the installation process.
188 | )
189 |
190 | echo.
191 | if exist %INSTALL_DIR% (
192 | echo === The INSTALL_DIR %INSTALL_DIR% already exists.
193 | echo === No need to create the preliminary 'ejabberd-pre' image.
194 | ) else (
195 | echo === The INSTALL_DIR %INSTALL_DIR% doesn't exist.
196 | echo === Let's create the preliminary 'ejabberd-pre' image.
197 | CALL :create-ejabberd-pre
198 | )
199 |
200 | ::===============================================================
201 | :: Create final container
202 | ::
203 | ::===============================================================
204 |
205 | echo.
206 | echo === Creating the final 'ejabberd' docker container using %IMAGE% image...
207 |
208 | setlocal EnableDelayedExpansion
209 | set PS=
210 | for %%a in (%PORTS%) do (
211 | set PS=!PS! -p %%a:%%a
212 | )
213 |
214 | docker create --name ejabberd --hostname localhost %PS% %VOLUMES% %IMAGE%
215 |
216 | echo.
217 | echo === Installation completed.
218 | echo.
219 | pause
220 |
221 | EXIT /B %ERRORLEVEL%
222 |
223 | ::===============================================================
224 | :: Function to create preliminary container
225 | ::
226 | ::===============================================================
227 |
228 | :create-ejabberd-pre
229 |
230 | echo.
231 | echo === Creating a preliminary 'ejabberd-pre' docker image using %IMAGE% image...
232 | docker create --name ejabberd-pre --hostname localhost %IMAGE%
233 |
234 | echo.
235 | echo === Now 'ejabberd-pre' will be started.
236 | docker container start ejabberd-pre
237 |
238 | echo.
239 | echo === Waiting ejabberd to be running...
240 | set /A timeout = 10
241 | set status=4
242 | goto :while
243 |
244 | :statusstart
245 | docker exec -it ejabberd-pre bin/ejabberdctl status
246 | goto :statusend
247 |
248 | :while
249 | if %status% GTR 0 (
250 | echo.
251 | timeout /t 1 /nobreak >NUL
252 | set /A timeout = timeout - 1
253 | if %timeout% EQU 0 (
254 | set status=-1
255 | ) else (
256 | goto :statusstart
257 | :statusend
258 | set status=%ERRORLEVEL%
259 | )
260 | goto :while
261 | )
262 |
263 | echo.
264 | echo === Setting a few options...
265 | docker exec -it ejabberd-pre sed -i "s!- localhost!- %HOST%!g" conf/ejabberd.yml
266 | docker exec -it ejabberd-pre sed -i "s!admin@localhost!%USER%@%HOST%!g" conf/ejabberd.yml
267 | docker exec -it ejabberd-pre sed -i "s!5280!5180!g" conf/ejabberd.yml
268 | docker exec -it ejabberd-pre sed -i "s!\"/admin\"!/!g" conf/ejabberd.yml
269 | docker exec -it ejabberd-pre bin/ejabberdctl reload_config
270 |
271 | echo.
272 | echo === Registering the administrator account...
273 | docker exec -it ejabberd-pre bin/ejabberdctl register %USER% %HOST% %PASSWORD%
274 | docker exec -it ejabberd-pre bin/ejabberdctl stop
275 |
276 | echo.
277 | echo === Copying conf, database, logs...
278 | mkdir %INSTALL_DIR%
279 | mkdir %INSTALL_DIR%\conf
280 | mkdir %INSTALL_DIR%\database
281 | mkdir %INSTALL_DIR%\logs
282 | mkdir %INSTALL_DIR%\ejabberd-modules
283 | docker cp ejabberd-pre:/home/ejabberd/conf/ %INSTALL_DIR%
284 | docker cp ejabberd-pre:/home/ejabberd/database/ %INSTALL_DIR%
285 | docker cp ejabberd-pre:/home/ejabberd/logs/ %INSTALL_DIR%
286 |
287 | echo.
288 | echo === Deleting the preliminary 'ejabberd-pre' docker image...
289 | docker stop ejabberd-pre
290 | docker rm ejabberd-pre
291 |
292 | EXIT /B 0
293 |
--------------------------------------------------------------------------------
/ecs/hooks/build:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # See documentation for details:
4 | # https://docs.docker.com/docker-hub/builds/advanced/
5 |
6 | # Use $VERSION build environment variable or the Docker repository tag being built
7 | version=${VERSION:-${DOCKER_TAG}}
8 |
9 | docker build \
10 | --build-arg VERSION=$version \
11 | --build-arg VCS_REF=`git rev-parse --short HEAD` \
12 | --build-arg BUILD_DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"` \
13 | -f $DOCKERFILE_PATH \
14 | -t $IMAGE_NAME .
15 |
--------------------------------------------------------------------------------
/ecs/rel/config.exs:
--------------------------------------------------------------------------------
1 | use Mix.Releases.Config,
2 | # This sets the default release built by `mix release`
3 | default_release: :default,
4 | # This sets the default environment used by `mix release`
5 | default_environment: :dev
6 |
7 | # For a full list of config options for both releases
8 | # and environments, visit https://hexdocs.pm/distillery/configuration.html
9 |
10 |
11 | # You may define one or more environments in this file,
12 | # an environment's settings will override those of a release
13 | # when building in that environment, this combination of release
14 | # and environment configuration is called a profile
15 |
16 | environment :dev do
17 | set dev_mode: true
18 | set include_erts: false
19 | set config: "rel/dev.exs"
20 | set cookie: :"!Vcuwp?y@d{7=`5Ha*2*PLw:i8;i:9B|tq75|K]kt?T]_nap/or,7xBylYJ!N;m{"
21 | end
22 |
23 | environment :prod do
24 | set include_erts: true
25 | set include_src: false
26 | set config: "rel/prod.exs"
27 | set cookie: :"HmewW_sUao={>LXTD8,g;xBu`.i]tq7Dz.m2?ZqO :ejabberd_auth.try_register("test", "localhost", "passw0rd")
50 | {:atomic, :ok}
51 | ```
52 |
53 | You can then connect with user test@localhost (password: passw0rd) on server on localhost port 5222 and use those parameters to connect with an XMPP client.
54 |
55 | ## Get into the container
56 |
57 | If you want to run Erlang command line, you can do so by opening a shell inside the container:
58 |
59 | ```bash
60 | docker run -it -v $(pwd):$(pwd) -w $(pwd) --entrypoint="/bin/sh" ejabberd/mix
61 | ```
62 |
63 | ## Getting Elixir version
64 |
65 | ```bash
66 | docker run -it --rm -v $(pwd):$(pwd) -w $(pwd) ejabberd/mix --version
67 | Erlang/OTP 19 [erts-8.1] [source] [64-bit] [smp:2:2] [async-threads:10] [kernel-poll:false]
68 |
69 | Mix 1.3.4
70 | ```
71 |
72 | ## Build the image
73 |
74 | Building the image is not needed if you simply want to use it. You can simply use the one from [ejabberd Docker Hub](https://hub.docker.com/u/ejabberd/dashboard/).
75 |
76 | ```bash
77 | docker build -t ejabberd/mix .
78 | ```
79 |
80 | ## Troubleshooting
81 |
82 | ### Clock resync
83 |
84 | If you have warning about file timestamp being out of sync (Like 'Clock skew detected'), you may want to force resync your clock before running the build. Docker on MacOS does not force clock resync of Docker after the laptop went to sleep.
85 |
86 | You can force clock resync as follow:
87 |
88 | ```bash
89 | docker run -it --rm --privileged --entrypoint="/sbin/hwclock" ejabberd/mix -s
90 | ```
91 |
92 | You can check if the clock of your laptop is in sync with the one inside Docker with the following command:
93 |
94 | ```bash
95 | docker run --rm --entrypoint="/bin/sh" ejabberd/mix -c date -u && date -u
96 | ```
97 |
98 |
--------------------------------------------------------------------------------