diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..8e27876 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,39 @@ +dist: trusty +sudo: required + +services: docker + +language: bash + +branches: + only: + - master + +before_script: + - env | sort + - dir="${VARIANT}/" + +script: + - cd "$dir" + - travis_wait docker build --build-arg VERSION=${VERSION} -t ejabberd/ecs:travis-${VERSION} . + - docker images + - travis_retry docker run --name ejabberd -d -p 5222:5222 ejabberd/ecs && sleep 60 + - docker ps + - docker logs ejabberd + - docker logs ejabberd | grep "Start accepting TCP connections" || exit 1 + +notifications: + email: false + +matrix: + allow_failures: + - env: VERSION=latest VARIANT=ecs + - env: VERSION=latest VARIANT=mix + +env: # Environments + - VERSION=latest VARIANT=ecs + - VERSION=latest VARIANT=mix + - VERSION=19.05 VARIANT=ecs + - VERSION=19.05 VARIANT=mix + - VERSION=19.02 VARIANT=ecs + - VERSION=19.02 VARIANT=mix diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..b242799 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,17 @@ +# Version 19.07 + +- Update default configuration +- Add sqlite libs +- Fix sample Let's Encrypt configuration +- Add badges and links docker README +- Allow mapping of upload dir as volume +- Fix INET_DIST_INTERFACE +- Add travis support +- Add STUN/TURN & SIP support +- Add libgd for image manupilation +- Upgrade alpine to 3.10 +- Keep SQL init scripts in database volume + +# Version 19.05 + +- Update default configuration diff --git a/README.md b/README.md index e25b826..b9d0b63 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ + +[![Build Status](https://travis-ci.org/processone/docker-ejabberd.svg)](https://travis-ci.org/processone/docker-ejabberd) + # docker-ejabberd This repository contains a set of Docker images for ejabberd. diff --git a/ecs/Dockerfile b/ecs/Dockerfile index 010da57..cec1bac 100644 --- a/ecs/Dockerfile +++ b/ecs/Dockerfile @@ -24,11 +24,14 @@ RUN mkdir runtime \ && echo 'beam_lib:strip_files(filelib:wildcard("lib/*/ebin/*beam")), init:stop().' | erts*/bin/erl -boot start_clean >/dev/null \ && mv erts*/bin/* bin \ && rm -rf releases erts* bin/*src bin/dialyzer bin/typer \ - && rm bin/ejabberd bin/ejabberd.bat + && rm bin/ejabberd bin/ejabberd.bat \ + && cp -r /ejabberd/sql lib/ejabberd-*/priv # Runtime container -FROM alpine:3.9 +FROM alpine:3.10 ARG VERSION +ARG VCS_REF +ARG BUILD_DATE ENV TERM=xterm \ LC_ALL=C.UTF-8 \ LANG=en_US.UTF-8 \ @@ -38,12 +41,21 @@ ENV TERM=xterm \ VERSION=${VERSION:-latest} LABEL maintainer="ProcessOne " \ product="Ejabberd Community Server" \ - version=$VERSION + version=$VERSION \ + org.label-schema.vcs-ref=$VCS_REF \ + org.label-schema.vcs-url="https://github.com/processone/docker-ejabberd" \ + org.label-schema.build-date=$BUILD_DATE \ + org.label-schema.name="Ejabberd Community Server" \ + org.label-schema.description="Robust, Scalable and Extensible Realtime Server using XMPP, MQTT and SIP" \ + org.label-schema.url="https://www.ejabberd.im/" \ + org.label-schema.vendor="ProcessOne" \ + org.label-schema.version=$VERSION \ + org.label-schema.schema-version="1.0" # Create directory structure and user for ejabberd RUN addgroup ejabberd -g 9000 \ && adduser -s /bin/sh -D -G ejabberd ejabberd -u 9000 \ - && mkdir -p /home/ejabberd/conf /home/ejabberd/database /home/ejabberd/logs \ + && mkdir -p /home/ejabberd/conf /home/ejabberd/database /home/ejabberd/logs /home/ejabberd/upload \ && chown -R ejabberd:ejabberd /home/ejabberd # Install required dependencies @@ -52,6 +64,7 @@ RUN apk upgrade --update musl \ expat \ gd \ jpeg \ + libgd \ libpng \ libstdc++ \ libwebp \ @@ -74,7 +87,7 @@ ADD --chown=ejabberd:ejabberd https://download.process-one.net/cacert.pem conf/c # Setup runtime environment USER ejabberd -VOLUME ["$HOME/database","$HOME/conf","$HOME/logs"] +VOLUME ["$HOME/database","$HOME/conf","$HOME/logs","$HOME/upload"] EXPOSE 1883 4369-4399 5222 5269 5280 5443 ENTRYPOINT ["/home/ejabberd/bin/ejabberdctl"] diff --git a/ecs/README.md b/ecs/README.md index 5bf4d8b..a089b9e 100644 --- a/ecs/README.md +++ b/ecs/README.md @@ -112,6 +112,7 @@ Here are the volume you may want to map: - /home/ejabberd/logs/: Directory containing log files - /home/ejabberd/database/: Directory containing Mnesia database. You should back up or export the content of the directory to persistent storage (host storage, local storage, any storage plugin) - /home/ejabberd/conf/: Directory containing configuration and certificates +- /home/ejabberd/upload/: Directory containing uploaded files. This should also be backed up. All these files are owned by ejabberd user inside the container. Corresponding UID:GID is 9000:9000. If you prefer bind mounts instead of docker volumes, then diff --git a/ecs/bin/ejabberdctl b/ecs/bin/ejabberdctl index 32ab08b..cb9a24f 100755 --- a/ecs/bin/ejabberdctl +++ b/ecs/bin/ejabberdctl @@ -83,7 +83,7 @@ if [ -n "$FIREWALL_WINDOW" ] ; then ERLANG_OPTS="$ERLANG_OPTS -kernel inet_dist_listen_min ${FIREWALL_WINDOW%-*} inet_dist_listen_max ${FIREWALL_WINDOW#*-}" fi if [ -n "$INET_DIST_INTERFACE" ] ; then - INET_DIST_INTERFACE2=$("$ERL" -noshell -eval 'case inet:parse_address("'$INET_DIST_INTERFACE'") of {ok,IP} -> io:format("~p",[IP]); _ -> ok end.' -s erlang halt) + 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) if [ -n "$INET_DIST_INTERFACE2" ] ; then ERLANG_OPTS="$ERLANG_OPTS -kernel inet_dist_use_interface $INET_DIST_INTERFACE2" fi @@ -222,6 +222,7 @@ stop_epmd() # make sure node not already running and node name unregistered # if all ok, ensure runtime directory exists and make it current directory +# then (docker case) make .sql files available on database volume check_start() { "$EPMD" -names 2>/dev/null | grep -q " ${ERLANG_NODE%@*} " && { @@ -237,6 +238,7 @@ check_start() } "$EPMD" -kill >/dev/null } + cp "$HOME_DIR/lib/ejabberd-*/priv/sql/*" "$HOME_DIR/database/" } # allow sync calls diff --git a/ecs/build.sh b/ecs/build.sh index 5f4f548..89a8b52 100755 --- a/ecs/build.sh +++ b/ecs/build.sh @@ -3,5 +3,10 @@ current=$(date +%y.%m) version=${1:-$current} -docker build --build-arg VERSION=$version -t ejabberd/ecs:$version . +docker build \ + --build-arg VERSION=$version \ + --build-arg VCS_REF=`git rev-parse --short HEAD` \ + --build-arg BUILD_DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"` \ + -t ejabberd/ecs:$version . + [ "$version" = "latest" ] || docker tag ejabberd/ecs:$version ejabberd/ecs:latest diff --git a/ecs/conf/ejabberd.yml b/ecs/conf/ejabberd.yml index 068e7ec..109d4ec 100644 --- a/ecs/conf/ejabberd.yml +++ b/ecs/conf/ejabberd.yml @@ -12,23 +12,10 @@ ### ******* MAKE SURE YOU INDENT SECTIONS CORRECTLY ******* ### ******************************************************* ### Refer to http://en.wikipedia.org/wiki/YAML for the brief description. -### However, ejabberd treats different literals as different types: -### -### - unquoted or single-quoted strings. They are called "atoms". -### Example: dog, 'Jupiter', '3.14159', YELLOW -### -### - numeric literals. Example: 3, -45.0, .0 -### -### - quoted or folded strings. -### Examples of quoted string: "Lizzard", "orange". -### Example of folded string: -### > Art thou not Romeo, -### and a Montague? ### -language: "en" hosts: - - "localhost" + - localhost loglevel: 4 log_rotate_size: 10485760 @@ -37,14 +24,14 @@ log_rotate_count: 1 log_rate_limit: 100 certfiles: - - "/home/ejabberd/conf/server.pem" + - /home/ejabberd/conf/server.pem ca_file: "/home/ejabberd/conf/cacert.pem" -# When using let's encrypt to generate certificates +## When using let's encrypt to generate certificates ##certfiles: -## - "/etc/letsencrypt/live/localhost/cert.pem" -## - "/etc/letsencrypt/live/localhost/privkey.pem" +## - /etc/letsencrypt/live/localhost/fullchain.pem +## - /etc/letsencrypt/live/localhost/privkey.pem ## ##ca_file: "/etc/letsencrypt/live/localhost/fullchain.pem" @@ -86,6 +73,55 @@ listen: ip: "::" module: mod_mqtt backlog: 1000 + ## + ## https://docs.ejabberd.im/admin/configuration/#stun-and-turn + ## ejabberd_stun: Handles STUN Binding requests + ## + ##- + ## port: 3478 + ## ip: "0.0.0.0" + ## transport: udp + ## module: ejabberd_stun + ## use_turn: true + ## turn_ip: "{{ IP }}" + ## auth_type: user + ## auth_realm: "example.com" + ##- + ## port: 3478 + ## ip: "0.0.0.0" + ## module: ejabberd_stun + ## use_turn: true + ## turn_ip: "{{ IP }}" + ## auth_type: user + ## auth_realm: "example.com" + ##- + ## port: 5349 + ## ip: "0.0.0.0" + ## module: ejabberd_stun + ## certfile: "/home/ejabberd/conf/server.pem" + ## tls: true + ## use_turn: true + ## turn_ip: "{{ IP }}" + ## auth_type: user + ## auth_realm: "example.com" + ## + ## https://docs.ejabberd.im/admin/configuration/#sip + ## To handle SIP (VOIP) requests: + ## + ##- + ## port: 5060 + ## ip: "0.0.0.0" + ## transport: udp + ## module: ejabberd_sip + ##- + ## port: 5060 + ## ip: "0.0.0.0" + ## module: ejabberd_sip + ##- + ## port: 5061 + ## ip: "0.0.0.0" + ## module: ejabberd_sip + ## tls: true s2s_use_starttls: optional @@ -94,31 +130,29 @@ acl: user_regexp: "" loopback: ip: - - "127.0.0.0/8" - - "::1/128" - - "::FFFF:127.0.0.1/128" + - 127.0.0.0/8 + - ::1/128 + - ::FFFF:127.0.0.1/128 admin: user: - "admin@localhost" access_rules: local: - - allow: local + allow: local c2s: - - deny: blocked - - allow + deny: blocked + allow: all announce: - - allow: admin + allow: admin configure: - - allow: admin + allow: admin muc_create: - - allow: local + allow: local pubsub_createnode: - - allow: local - register: - - allow + allow: local trusted_network: - - allow: loopback + allow: loopback api_permissions: "console commands": @@ -128,26 +162,26 @@ api_permissions: what: "*" "admin access": who: - - access: - - allow: - - acl: loopback - - acl: admin - - oauth: - - scope: "ejabberd:admin" - - access: - - allow: - - acl: loopback - - acl: admin + access: + allow: + acl: loopback + acl: admin + oauth: + scope: "ejabberd:admin" + access: + allow: + acl: loopback + acl: admin what: - "*" - "!stop" - "!start" "public commands": who: - - ip: "127.0.0.1/8" + ip: 127.0.0.1/8 what: - - "status" - - "connected_users_number" + - status + - connected_users_number shaper: normal: 1000 @@ -156,11 +190,11 @@ shaper: shaper_rules: max_user_sessions: 10 max_user_offline_messages: - - 5000: admin - - 100 + 5000: admin + 100: all c2s_shaper: - - none: admin - - normal + none: admin + normal: all s2s_shaper: fast max_fsm_queue: 10000 @@ -185,15 +219,15 @@ modules: mod_fail2ban: {} mod_http_api: {} mod_http_upload: - put_url: "https://@HOST@:5443/upload" + put_url: https://@HOST@:5443/upload mod_last: {} - ## mod_mam: + mod_mam: ## Mnesia is limited to 2GB, better to use an SQL backend ## For small servers SQLite is a good fit and is very easy ## to configure. Uncomment this when you have SQL configured: ## db_type: sql - ## assume_mam_usage: true - ## default: always + assume_mam_usage: true + default: never mod_mqtt: {} mod_muc: access: @@ -202,9 +236,11 @@ modules: - allow: admin access_create: muc_create access_persistent: muc_create + access_mam: + - allow default_room_options: allow_subscription: true # enable MucSub - ## mam: true + mam: false mod_muc_admin: {} mod_offline: access_max_user_messages: max_user_offline_messages @@ -217,11 +253,11 @@ modules: mod_pubsub: access_createnode: pubsub_createnode plugins: - - "flat" - - "pep" + - flat + - pep force_node_config: ## Avoid buggy clients to make their bookmarks public - "storage:bookmarks": + storage:bookmarks: access_model: whitelist mod_push: {} mod_push_keepalive: {} @@ -234,6 +270,7 @@ modules: ip_access: trusted_network mod_roster: versioning: true + mod_sip: {} mod_s2s_dialback: {} mod_shared_roster: {} mod_stream_mgmt: diff --git a/ecs/vars.config b/ecs/vars.config index 6cdb206..4b7809f 100644 --- a/ecs/vars.config +++ b/ecs/vars.config @@ -6,3 +6,5 @@ {zlib, true}. {elixir, true}. {iconv, true}. +{stun, true}. +{sip, true}. diff --git a/mix/Dockerfile b/mix/Dockerfile index 716aff6..c47746a 100644 --- a/mix/Dockerfile +++ b/mix/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.9 +FROM alpine:3.10 LABEL maintainer="ProcessOne " \ product="Ejabberd mix development environment"