diff --git a/.dockerignore b/.dockerignore index 7451c5a..8125ff6 100644 --- a/.dockerignore +++ b/.dockerignore @@ -2,7 +2,6 @@ !docker/coturn/alpine/ !docker/coturn/debian/ -!docker/coturn/rootfs/ !cmake/ !CMakeLists.txt diff --git a/.gitignore b/.gitignore index afd7bd3..e97aac6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -Makefile +/Makefile /bin/ build include @@ -32,7 +32,7 @@ tags .DS_Store .directory *.debug -Makefile* +/Makefile* *.prl *.app moc_*.cpp diff --git a/docker/coturn/.gitignore b/docker/coturn/.gitignore new file mode 100644 index 0000000..7f90abb --- /dev/null +++ b/docker/coturn/.gitignore @@ -0,0 +1,4 @@ +/node_modules/ +/package-lock.json +/yarn.lock +/yarn-error.log diff --git a/docker/coturn/Makefile b/docker/coturn/Makefile new file mode 100644 index 0000000..45b12d8 --- /dev/null +++ b/docker/coturn/Makefile @@ -0,0 +1,52 @@ +#################### +# Testing commands # +#################### + +# Run Bats tests for Docker image. +# +# Documentation of Bats: +# https://github.com/bats-core/bats-core +# +# Usage: +# make test.docker [tag=($(VERSION)|)] + +test.docker: +ifeq ($(wildcard node_modules/.bin/bats),) + @make npm.install +endif + DOCKERFILE=$(DOCKERFILE) \ + IMAGE=coturn-debian \ + node_modules/.bin/bats \ + --timing $(if $(call eq,$(CI),),--pretty,--formatter tap) \ + tests/main.bats + + + + +################ +# NPM commands # +################ + +# Resolve project NPM dependencies. +# +# Usage: +# make npm.install [dockerized=(no|yes)] + +npm.install: +ifeq ($(dockerized),yes) + docker run --rm --network=host -v "$(PWD)":/app/ -w /app/ \ + node \ + make npm.install dockerized=no +else + npm install +endif + + + + +################## +# .PHONY section # +################## + +.PHONY: npm.install \ + test.docker \ No newline at end of file diff --git a/docker/coturn/alpine/Dockerfile b/docker/coturn/alpine/Dockerfile index f570a20..5ccbc82 100644 --- a/docker/coturn/alpine/Dockerfile +++ b/docker/coturn/alpine/Dockerfile @@ -3,7 +3,6 @@ # ARG alpine_ver=3.13 -ARG coturn_git_ref=- @@ -15,13 +14,15 @@ ARG coturn_git_ref=- # https://hub.docker.com/_/alpine FROM alpine:${alpine_ver} AS dist-coturn +ARG coturn_git_ref=HEAD + # Install tools for building. RUN apk update \ - && apk add --no-cache --virtual .tool-deps \ + && apk add --no-cache \ autoconf coreutils g++ git libtool make # Install Coturn build dependencies. -RUN apk add --no-cache --virtual .build-deps \ +RUN apk add --no-cache \ linux-headers \ libevent-dev \ openssl-dev \ @@ -46,7 +47,7 @@ COPY turndb/ /app/turndb/ WORKDIR /app/ # Use Coturn sources from Git if `coturn_git_ref` is specified. -RUN if [ ! "${coturn_git_ref}" = '-' ]; then true \ +RUN if [ "${coturn_git_ref}" != 'HEAD' ]; then true \ && rm -rf /app/* \ && git init \ && git remote add origin https://github.com/coturn/coturn \ @@ -77,11 +78,12 @@ RUN mkdir -p /out/ \ && rm -f /out/etc/coturn/turnserver.conf.default # Install helper tools of Docker image. -COPY docker/coturn/rootfs/ /out/ +COPY docker/coturn/alpine/rootfs/ /out/ RUN chmod +x /out/usr/local/bin/docker-entrypoint.sh \ - /out/usr/local/bin/detect-external-ip.sh \ - && ln -s /usr/local/bin/detect-external-ip.sh \ + /out/usr/local/bin/detect-external-ip.sh +RUN ln -s /usr/local/bin/detect-external-ip.sh \ /out/usr/local/bin/detect-external-ip +RUN chown -R nobody:nogroup /out/var/lib/coturn/ @@ -93,6 +95,8 @@ RUN chmod +x /out/usr/local/bin/docker-entrypoint.sh \ # https://hub.docker.com/_/alpine FROM alpine:${alpine_ver} AS runtime +LABEL org.opencontainers.image.source="https://github.com/coturn/coturn" + # Update system packages. RUN apk update \ && apk upgrade \ @@ -115,8 +119,11 @@ COPY --from=dist-coturn /out/ / RUN apk add --no-cache libcap \ && setcap CAP_NET_BIND_SERVICE=+ep /usr/bin/turnserver \ # Cleanup unnecessary stuff. + && apk del libcap \ && rm -rf /var/cache/apk/* +USER nobody:nogroup + EXPOSE 3478 3478/udp VOLUME ["/var/lib/coturn"] diff --git a/docker/coturn/rootfs/usr/local/bin/detect-external-ip.sh b/docker/coturn/alpine/rootfs/usr/local/bin/detect-external-ip.sh similarity index 100% rename from docker/coturn/rootfs/usr/local/bin/detect-external-ip.sh rename to docker/coturn/alpine/rootfs/usr/local/bin/detect-external-ip.sh diff --git a/docker/coturn/rootfs/usr/local/bin/docker-entrypoint.sh b/docker/coturn/alpine/rootfs/usr/local/bin/docker-entrypoint.sh similarity index 100% rename from docker/coturn/rootfs/usr/local/bin/docker-entrypoint.sh rename to docker/coturn/alpine/rootfs/usr/local/bin/docker-entrypoint.sh diff --git a/docker/coturn/debian/Dockerfile b/docker/coturn/debian/Dockerfile new file mode 100644 index 0000000..4841160 --- /dev/null +++ b/docker/coturn/debian/Dockerfile @@ -0,0 +1,138 @@ +# +# Dockerfile of coturn/coturn:debian Docker image. +# + +ARG debian_ver=buster + + + + +# +# Stage 'dist-coturn' creates Coturn distribution. +# + +# https://hub.docker.com/_/debian +FROM debian:${debian_ver}-slim AS dist-coturn + +ARG coturn_git_ref=HEAD + +# Install tools for building. +RUN apt-get update \ + && apt-get install -y --no-install-recommends --no-install-suggests \ + autoconf coreutils g++ git libtool make pkg-config + +# Install Coturn build dependencies. +RUN apt-get install -y --no-install-recommends --no-install-suggests \ + libevent-dev \ + libssl-dev \ + libpq-dev libmariadb-dev libsqlite3-dev \ + libhiredis-dev \ + libmongoc-dev + +# Prepare local Coturn sources for building. +COPY CMakeLists.txt \ + configure \ + INSTALL \ + LICENSE LICENSE.OpenSSL \ + make-man.sh Makefile.in \ + postinstall.txt \ + README.turn* \ + /app/ +COPY cmake/ /app/cmake/ +COPY examples/ /app/examples/ +COPY man/ /app/man/ +COPY src/ /app/src/ +COPY turndb/ /app/turndb/ +WORKDIR /app/ + +# Use Coturn sources from Git if `coturn_git_ref` is specified. +RUN if [ "${coturn_git_ref}" != 'HEAD' ]; then true \ + && rm -rf /app/* \ + && git init \ + && git remote add origin https://github.com/coturn/coturn \ + && git pull origin "${coturn_git_ref}" \ + && true; fi + + +# Build Coturn from sources. +RUN ./configure --prefix=/usr \ + --turndbdir=/var/lib/coturn \ + --disable-rpath \ + --sysconfdir=/etc/coturn \ + # No documentation included to keep image size smaller. + --mandir=/tmp/coturn/man \ + --docsdir=/tmp/coturn/docs \ + --examplesdir=/tmp/coturn/examples \ + && make + +# Install and configure Coturn. +RUN mkdir -p /out/ \ + && DESTDIR=/out make install \ + # Remove redundant files. + && rm -rf /out/tmp/ \ + # Preserve license file. + && mkdir -p /out/usr/share/licenses/coturn/ \ + && cp LICENSE /out/usr/share/licenses/coturn/ \ + # Remove default config file. + && rm -f /out/etc/coturn/turnserver.conf.default + +# Install helper tools of Docker image. +COPY docker/coturn/debian/rootfs/ /out/ +RUN chmod +x /out/usr/local/bin/docker-entrypoint.sh \ + /out/usr/local/bin/detect-external-ip.sh +RUN ln -s /usr/local/bin/detect-external-ip.sh \ + /out/usr/local/bin/detect-external-ip +RUN chown -R nobody:nogroup /out/var/lib/coturn/ + + + + +# +# Stage 'runtime' creates final Docker image to use in runtime. +# + +# https://hub.docker.com/_/debian +FROM debian:${debian_ver}-slim AS runtime + +LABEL org.opencontainers.image.source="https://github.com/coturn/coturn" + +# Update system packages. +RUN apt-get update \ + && apt-get upgrade -y \ + && apt-get install -y --no-install-recommends --no-install-suggests \ + ca-certificates \ + && update-ca-certificates \ + # Install Coturn dependencies. + && apt-get install -y --no-install-recommends --no-install-suggests \ + libevent-2.1-6 libevent-core-2.1-6 libevent-extra-2.1-6 \ + libevent-openssl-2.1-6 libevent-pthreads-2.1-6 \ + libssl1.1 \ + libpq5 libmariadb3 libsqlite3-0 \ + libhiredis0.14 \ + libmongoc-1.0-0 \ + # Cleanup unnecessary stuff. + && rm -rf /var/lib/apt/lists/* + +# Install Coturn distribution. +COPY --from=dist-coturn /out/ / + +# Allow non-root using privileged ports. +RUN apt-get update \ + && apt-get install -y --no-install-recommends --no-install-suggests \ + libcap2-bin \ + && setcap CAP_NET_BIND_SERVICE=+ep /usr/bin/turnserver \ + # Cleanup unnecessary stuff. + && apt-get purge -y --auto-remove \ + -o APT::AutoRemove::RecommendsImportant=false \ + libcap2-bin \ + && rm -rf /var/lib/apt/lists/* + +USER nobody:nogroup + +EXPOSE 3478 3478/udp + +VOLUME ["/var/lib/coturn"] + +ENTRYPOINT ["docker-entrypoint.sh"] + +CMD ["--log-file=stdout", "--external-ip=$(detect-external-ip)"] diff --git a/docker/coturn/debian/rootfs/usr/local/bin/detect-external-ip.sh b/docker/coturn/debian/rootfs/usr/local/bin/detect-external-ip.sh new file mode 100644 index 0000000..b4e4c57 --- /dev/null +++ b/docker/coturn/debian/rootfs/usr/local/bin/detect-external-ip.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +if [ -z "$REAL_EXTERNAL_IP" ]; then + export REAL_EXTERNAL_IP="$(curl -4 https://icanhazip.com 2>/dev/null)" +fi + +exec echo "$REAL_EXTERNAL_IP" diff --git a/docker/coturn/debian/rootfs/usr/local/bin/docker-entrypoint.sh b/docker/coturn/debian/rootfs/usr/local/bin/docker-entrypoint.sh new file mode 100644 index 0000000..27d6086 --- /dev/null +++ b/docker/coturn/debian/rootfs/usr/local/bin/docker-entrypoint.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +# If command starts with an option, prepend it with a `turnserver` binary. +if [ "${1:0:1}" == '-' ]; then + set -- turnserver "$@" +fi + +exec $(eval "echo $@") diff --git a/docker/coturn/old.Dockerfile b/docker/coturn/old.Dockerfile deleted file mode 100644 index adac700..0000000 --- a/docker/coturn/old.Dockerfile +++ /dev/null @@ -1,154 +0,0 @@ -### 1. stage: create mongoc image -FROM debian:stable-slim AS mongoc-build - -ENV MONGO_LIB_VERSION 1.17.4 - -# Install build dependencies -RUN export DEBIAN_FRONTEND=noninteractive && \ - apt-get update && \ - apt-get install -y build-essential git python cmake -RUN apt-get install -y libssl-dev -RUN git clone https://github.com/mongodb/mongo-c-driver.git && \ - cd mongo-c-driver && \ - git checkout ${MONGO_LIB_VERSION} && \ - python build/calc_release_version.py > VERSION_CURRENT && \ - mkdir -p cmake-build/install && \ - cd cmake-build && \ - cmake -DENABLE_AUTOMATIC_INIT_AND_CLEANUP=OFF -DCMAKE_BUILD_TYPE=Release .. && \ - DESTDIR=/mongo-c-driver/cmake-build/install cmake --build . --target install - -RUN cd /mongo-c-driver/cmake-build/install && tar -cf /mongoc.tar . - -### 2. stage: create build image -FROM debian:stable-slim AS coturn-build - -ENV BUILD_PREFIX /usr/local/src - -# Install build dependencies -RUN export DEBIAN_FRONTEND=noninteractive && \ - apt-get update && \ - apt-get install -y build-essential git debhelper dpkg-dev pkg-config libssl-dev libevent-dev sqlite3 libsqlite3-dev postgresql-client libpq-dev default-mysql-client default-libmysqlclient-dev libhiredis-dev libsystemd-dev - -COPY --from=mongoc-build /mongoc.tar /tmp -RUN tar -xf /tmp/mongoc.tar -C / - -# Clone Coturn -WORKDIR ${BUILD_PREFIX} -RUN git clone https://github.com/coturn/coturn.git - -# Build Coturn -WORKDIR ${BUILD_PREFIX}/coturn -RUN ./configure -RUN make - -### 3. stage: create production image - -FROM debian:stable-slim AS production - -ENV INSTALL_PREFIX /usr/local -ENV BUILD_PREFIX /usr/local/src -ENV TURNSERVER_GROUP turnserver -ENV TURNSERVER_USER turnserver - -COPY --from=coturn-build ${BUILD_PREFIX}/coturn/bin/ ${INSTALL_PREFIX}/bin/ -COPY --from=coturn-build ${BUILD_PREFIX}/coturn/man/ ${INSTALL_PREFIX}/man/ -#COPY turnserver.conf ${INSTALL_PREFIX}/etc -COPY --from=coturn-build ${BUILD_PREFIX}/coturn/sqlite/turndb ${INSTALL_PREFIX}/var/db/turndb -COPY --from=coturn-build ${BUILD_PREFIX}/coturn/turndb ${INSTALL_PREFIX}/turndb - -COPY --from=mongoc-build /mongoc.tar /tmp -RUN tar -xf /tmp/mongoc.tar -C / && rm /tmp/mongoc.tar - -# Install lib dependencies -RUN export DEBIAN_FRONTEND=noninteractive && \ - apt-get update && \ - apt-get install -y libc6 libsasl2-2 libevent-2.1 libevent-core-2.1-6 libevent-extra-2.1-6 libevent-openssl-2.1-6 libevent-pthreads-2.1-6 libhiredis0.14 libmariadbclient-dev libpq5 libsqlite3-0 libssl1.1 && \ - apt-get clean && rm -f /var/lib/apt/lists/*_* - -RUN if ! getent group "$TURNSERVER_GROUP" >/dev/null; then \ - addgroup --system "$TURNSERVER_GROUP" || exit 1 ;\ - fi \ - && \ - if ! getent passwd "$TURNSERVER_USER" >/dev/null; then \ - adduser --system \ - --home / \ - --shell /bin/false \ - --no-create-home \ - --ingroup "$TURNSERVER_GROUP" \ - --disabled-password \ - --disabled-login \ - --gecos "turnserver daemon" \ - "$TURNSERVER_USER" || exit 1; \ - fi - -WORKDIR ${INSTALL_PREFIX} -CMD ${INSTALL_PREFIX}/bin/turnserver - - -### 4. stage: create testing - -FROM debian:stable-slim as coturn - -ENV INSTALL_PREFIX /usr/local -ENV BUILD_PREFIX /usr/local/src -ENV TURNSERVER_GROUP turnserver -ENV TURNSERVER_USER turnserver - -COPY --from=coturn-build ${BUILD_PREFIX}/coturn/bin/ ${INSTALL_PREFIX}/bin/ -COPY --from=coturn-build ${BUILD_PREFIX}/coturn/man/ ${INSTALL_PREFIX}/man/ -#COPY turnserver.conf ${INSTALL_PREFIX}/etc -COPY --from=coturn-build ${BUILD_PREFIX}/coturn/sqlite/turndb ${INSTALL_PREFIX}/var/db/turndb -COPY --from=coturn-build ${BUILD_PREFIX}/coturn/turndb ${INSTALL_PREFIX}/turndb - -COPY --from=mongoc-build /mongoc.tar /tmp -RUN tar -xf /tmp/mongoc.tar -C / && rm /tmp/mongoc.tar - -# Install lib dependencies -RUN export DEBIAN_FRONTEND=noninteractive && \ - apt-get update && \ - apt-get install -y libc6 libsasl2-2 libevent-2.1 libevent-core-2.1-6 libevent-extra-2.1-6 libevent-openssl-2.1-6 libevent-pthreads-2.1-6 libhiredis0.14 libmariadbclient-dev libpq5 libsqlite3-0 libssl1.1 -RUN apt-get install -y default-mysql-client postgresql-client redis-tools - -# Workaround for MongoDB -RUN ln -s /bin/echo /bin/systemctl - -# Install MongoDB -RUN apt-get update && \ - apt-get install -y wget gnupg && \ - wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | apt-key add - && \ - echo "deb http://repo.mongodb.org/apt/debian stretch/mongodb-org/4.4 main" | tee /etc/apt/sources.list.d/mongodb-org-4.4.list && \ - echo "deb http://deb.debian.org/debian/ stretch main" | tee /etc/apt/sources.list.d/debian-stretch.list && \ - apt-get update && \ - apt-get install -y libcurl3 mongodb-org mongodb-org-server mongodb-org - -RUN if ! getent group "$TURNSERVER_GROUP" >/dev/null; then \ - addgroup --system "$TURNSERVER_GROUP" || exit 1 ;\ - fi \ - && \ - if ! getent passwd "$TURNSERVER_USER" >/dev/null; then \ - adduser --system \ - --home / \ - --shell /bin/false \ - --no-create-home \ - --ingroup "$TURNSERVER_GROUP" \ - --disabled-password \ - --disabled-login \ - --gecos "turnserver daemon" \ - "$TURNSERVER_USER" || exit 1; \ - fi - - -# set startup parameters -# SUTN/TURN PORTS -EXPOSE 3478 3479 3478/udp 3479/udp 80 80/udp -EXPOSE 5349 5350 5349/udp 5350/udp 443 443/udp -# CLI -EXPOSE 5766 -# Relay Ports -EXPOSE 49152-65535 49152-65535/udp - -#COPY ./docker-entrypoint.sh / -#ENTRYPOINT ["/docker-entrypoint.sh"] - -WORKDIR ${INSTALL_PREFIX} -CMD ${INSTALL_PREFIX}/bin/turnserver \ No newline at end of file diff --git a/docker/coturn/package.json b/docker/coturn/package.json new file mode 100644 index 0000000..84e240a --- /dev/null +++ b/docker/coturn/package.json @@ -0,0 +1,5 @@ +{ + "devDependencies": { + "bats": "^1.1" + } +} diff --git a/docker/coturn/tests/main.bats b/docker/coturn/tests/main.bats index e2836b0..682c6a6 100644 --- a/docker/coturn/tests/main.bats +++ b/docker/coturn/tests/main.bats @@ -11,54 +11,38 @@ [ "$status" -eq 0 ] } -@test "Coturn has correct version" { - run sh -c "grep 'ARG coturn_ver=' Dockerfile | cut -d '=' -f2" - [ "$status" -eq 0 ] - [ ! "$output" = '' ] - expected="$output" - - run docker run --rm --entrypoint sh $IMAGE -c \ - "turnserver -o | grep 'Version Coturn' | cut -d ' ' -f2 \ - | cut -d '-' -f2" - [ "$status" -eq 0 ] - [ ! "$output" = '' ] - actual="$output" - - [ "$actual" = "$expected" ] -} - @test "TLS supported" { run docker run --rm --entrypoint sh $IMAGE -c \ - "turnserver -o | grep 'TLS supported'" + "turnserver -o --log-file=stdout | grep 'TLS supported'" [ "$status" -eq 0 ] [ ! "$output" = '' ] } @test "DTLS supported" { run docker run --rm --entrypoint sh $IMAGE -c \ - "turnserver -o | grep 'DTLS supported'" + "turnserver -o --log-file=stdout | grep 'DTLS supported'" [ "$status" -eq 0 ] [ ! "$output" = '' ] } @test "DTLS 1.2 supported" { run docker run --rm --entrypoint sh $IMAGE -c \ - "turnserver -o | grep 'DTLS 1.2 supported'" + "turnserver -o --log-file=stdout | grep 'DTLS 1.2 supported'" [ "$status" -eq 0 ] [ ! "$output" = '' ] } @test "TURN/STUN ALPN supported" { run docker run --rm --entrypoint sh $IMAGE -c \ - "turnserver -o | grep 'TURN/STUN ALPN supported'" + "turnserver -o --log-file=stdout | grep 'TURN/STUN ALPN supported'" [ "$status" -eq 0 ] [ ! "$output" = '' ] } @test "oAuth supported" { run docker run --rm --entrypoint sh $IMAGE -c \ - "turnserver -o | grep '(oAuth) supported'" + "turnserver -o --log-file=stdout | grep '(oAuth) supported'" [ "$status" -eq 0 ] [ ! "$output" = '' ] } @@ -66,35 +50,35 @@ @test "SQLite supported" { run docker run --rm --entrypoint sh $IMAGE -c \ - "turnserver -o | grep 'SQLite supported'" + "turnserver -o --log-file=stdout | grep 'SQLite supported'" [ "$status" -eq 0 ] [ ! "$output" = '' ] } @test "Redis supported" { run docker run --rm --entrypoint sh $IMAGE -c \ - "turnserver -o | grep 'Redis supported'" + "turnserver -o --log-file=stdout | grep 'Redis supported'" [ "$status" -eq 0 ] [ ! "$output" = '' ] } @test "PostgreSQL supported" { run docker run --rm --entrypoint sh $IMAGE -c \ - "turnserver -o | grep 'PostgreSQL supported'" + "turnserver -o --log-file=stdout | grep 'PostgreSQL supported'" [ "$status" -eq 0 ] [ ! "$output" = '' ] } @test "MySQL supported" { run docker run --rm --entrypoint sh $IMAGE -c \ - "turnserver -o | grep 'MySQL supported'" + "turnserver -o --log-file=stdout | grep 'MySQL supported'" [ "$status" -eq 0 ] [ ! "$output" = '' ] } @test "MongoDB supported" { run docker run --rm --entrypoint sh $IMAGE -c \ - "turnserver -o | grep 'MongoDB supported'" + "turnserver -o --log-file=stdout | grep 'MongoDB supported'" [ "$status" -eq 0 ] [ ! "$output" = '' ] }