Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 13 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Asterisk Docker Images

Production-ready Docker images for Asterisk PBX with advanced DRY template system, supporting 24 versions from 1.2.40 to 23.4.1 plus git development builds.
Production-ready Docker images for Asterisk PBX with advanced DRY template system, supporting 27 versions from 1.2.40 to 23.5.0 plus git development builds.

## Quick Start

Expand Down Expand Up @@ -53,17 +53,21 @@ All supported Asterisk versions with automatic variant detection. Generated buil
| **git** | `testing,dev` | Trixie | amd64, arm64 |
| **git** | experimental-git | Forky | amd64, arm64 |
| **git** | `testing,dev` | Edge | amd64, arm64 |
| **23.4.1** | 23 | Trixie | amd64, arm64 |
| **23.5.0** | 23 | Trixie | amd64, arm64 |
| **23.5.0** | experimental | Forky | amd64, arm64 |
| **23.4.1** | - | Trixie | amd64, arm64 |
| **23.4.1** | experimental | Forky | amd64, arm64 |
| **23.4.1** | 23 | 3.24 | amd64, arm64, armv7, armhf |
| **23.4.1** | 23 | Edge | amd64, arm64 |
| **22.10.1** | `latest,stable,22` | Trixie | amd64, arm64 |
| **22.10.1** | `latest,stable,22` | 3.24 | amd64, arm64, armv7, armhf |
| **22.10.1** | `latest,stable,22` | Edge | amd64, arm64 |
| **23.4.1** | - | 3.24 | amd64, arm64, armv7, armhf |
| **23.4.1** | - | Edge | amd64, arm64 |
| **22.11.0** | `latest,stable,22` | Trixie | amd64, arm64 |
| **22.10.1** | - | Trixie | amd64, arm64 |
| **22.10.1** | - | 3.24 | amd64, arm64, armv7, armhf |
| **22.10.1** | - | Edge | amd64, arm64 |
| **22.8-cert4** | 22-cert | Trixie | amd64, arm64 |
| **21.12.3** | 21 | Trixie | amd64, arm64 |
| **20.20.1** | 20 | Trixie | amd64, arm64 |
| **20.20.1** | 20 | 3.24 | amd64, arm64 |
| **20.21.0** | 20 | Trixie | amd64, arm64 |
| **20.20.1** | - | Trixie | amd64, arm64 |
| **20.20.1** | - | 3.24 | amd64, arm64 |
| **20.7-cert11** | 20-cert | Trixie | amd64, arm64 |
| **19.8.1** | 19 | Bookworm | amd64 |
| **18.26.4** | 18 | Trixie | amd64 |
Expand Down
177 changes: 177 additions & 0 deletions asterisk/20.21.0-trixie/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
# Multi-stage optimized Asterisk Docker build
# Asterisk 20.21.0 on Debian trixie
# Generated from YAML configuration - DO NOT EDIT MANUALLY

# ==============================================================================
# STAGE 1: Build Environment
# ==============================================================================
FROM debian:trixie AS asterisk-builder

LABEL maintainer="Andrius Kairiukstis <k@andrius.mobi>"
LABEL org.opencontainers.image.title="Asterisk PBX Builder"
LABEL org.opencontainers.image.description="Build stage for Asterisk 20.21.0"
LABEL org.opencontainers.image.version="20.21.0"
LABEL org.opencontainers.image.source="https://github.com/andrius/asterisk"

# Build arguments
ARG ASTERISK_VERSION=20.21.0
ARG JOBS=8
ARG DEBIAN_FRONTEND=noninteractive
ARG TARGETARCH

# Environment variables
ENV ASTERISK_VERSION=${ASTERISK_VERSION}
ENV DEBIAN_FRONTEND=${DEBIAN_FRONTEND}
ENV TMPDIR="/tmp/asterisk_build"

# Create build directories first
RUN mkdir -p \
/usr/src/asterisk \
${TMPDIR} \
&& chmod 777 ${TMPDIR}

# EOL distribution setup (if needed)
# Update package lists and install ca-certificates first, then build dependencies
RUN apt-get update \
&& apt-get install -y --no-install-recommends ca-certificates \
&& apt-get install -y --no-install-recommends \
build-essential autoconf binutils-dev curl file libcurl4-openssl-dev \
libedit-dev libgsm1-dev libicu-dev libjansson-dev libncurses-dev libogg-dev \
libpopt-dev libpqxx-dev libresample1-dev libspandsp-dev libspeex-dev \
libspeexdsp-dev libsqlite3-dev libssl-dev libtool libvorbis-dev libxml2-dev \
libxslt1-dev make odbcinst patch pkg-config portaudio19-dev procps \
python3-dev unixodbc unixodbc-dev uuid uuid-dev xmlstarlet libsrtp2-dev \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* \
&& mkdir -p ${TMPDIR} && chmod 777 ${TMPDIR}


WORKDIR /usr/src/asterisk

# Download and extract Asterisk source.
# When a sha256 checksum is present (plan 002) verify it before extracting;
# otherwise fall back to the historical unverified pipe (legacy tail /
# versions not yet backfilled). sha256sum ships in coreutils on every
# Debian base, including jessie/stretch - no new build dependency.
RUN curl -fsSL -o /tmp/asterisk-src.tar.gz https://downloads.asterisk.org/pub/telephony/asterisk/releases/asterisk-20.21.0.tar.gz \
&& echo "13fd6e8f1fbb19a3174af82a388dd72c87eb2c92d32fca83c4d51bfab03f686a /tmp/asterisk-src.tar.gz" | sha256sum -c - \
&& tar --strip-components=1 -xzf /tmp/asterisk-src.tar.gz \
&& rm /tmp/asterisk-src.tar.gz

# Configure Asterisk build (skip for very old versions that don't have configure script)
RUN ./configure

# Generate menuselect configuration
RUN make menuselect/menuselect menuselect-tree menuselect.makeopts


# Copy and execute build script
COPY build.sh /usr/src/asterisk/build.sh
RUN chmod +x build.sh && ./build.sh

# ==============================================================================
# STAGE 2: Runtime Environment
# ==============================================================================
FROM debian:trixie AS asterisk-runtime

LABEL maintainer="Andrius Kairiukstis <k@andrius.mobi>"
LABEL org.opencontainers.image.title="Asterisk PBX Runtime"
LABEL org.opencontainers.image.description="Runtime environment for Asterisk 20.21.0"

ARG DEBIAN_FRONTEND=noninteractive
ARG TARGETARCH
ENV DEBIAN_FRONTEND=${DEBIAN_FRONTEND}

# Install only runtime dependencies
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
binutils ca-certificates curl gettext-base libedit2 libgsm1 libjansson4 \
libogg0 libopus0 libpopt0 libresample1 libspandsp2 libspeex1 libspeexdsp1 \
libsqlite3-0 libvorbis0a libxml2 libxslt1.1 odbcinst portaudio19-dev procps \
python3 unixodbc uuid libcurl4t64 libssl3t64 libsrtp2-1 libncurses6 \
libpqxx-7.10 libicu76 \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

# Create asterisk user and required directories
RUN useradd --uid 1000 --system --user-group \
--home-dir /home/asterisk --create-home \
asterisk \
&& mkdir -p \
/var/run/asterisk \
/var/log/asterisk \
/var/spool/asterisk/monitor \
/var/spool/asterisk/outgoing \
/var/spool/asterisk/tmp \
/var/spool/asterisk/voicemail \
/var/spool/asterisk/fax \
/var/lib/asterisk/keys \
/var/lib/asterisk/phoneprov \
/var/lib/asterisk/sounds \
/var/lib/asterisk/docs

# ==============================================================================
# STAGE 3: Final Production Image
# ==============================================================================
FROM asterisk-runtime AS asterisk-production

LABEL maintainer="Andrius Kairiukstis <k@andrius.mobi>"
LABEL org.opencontainers.image.title="Asterisk PBX"
LABEL org.opencontainers.image.description="Production Asterisk PBX 20.21.0"
LABEL org.opencontainers.image.version="20.21.0"
LABEL org.opencontainers.image.source="https://github.com/andrius/asterisk"
LABEL org.opencontainers.image.vendor="Andrius Kairiukstis <k@andrius.mobi>"

# Copy Asterisk binaries and configurations from builder
COPY --from=asterisk-builder /usr/sbin/asterisk /usr/sbin/asterisk
COPY --from=asterisk-builder /usr/lib/asterisk /usr/lib/asterisk
COPY --from=asterisk-builder /var/lib/asterisk /var/lib/asterisk
COPY --from=asterisk-builder /etc/asterisk /etc/asterisk

# Copy Asterisk shared libraries
COPY --from=asterisk-builder /usr/lib/libasterisk*.so* /usr/lib/

# Copy healthcheck script
COPY healthcheck.sh /usr/local/bin/healthcheck.sh
RUN chmod +x /usr/local/bin/healthcheck.sh

# Copy entrypoint script (PUID/PGID volume permission handling)
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh

# Set proper ownership and permissions
RUN chown -R asterisk:asterisk \
/etc/asterisk \
/home/asterisk \
/var/*/asterisk \
/usr/lib*/asterisk 2>/dev/null || true \
&& chmod -R 750 /var/spool/asterisk

# Runtime verification
RUN asterisk -V || (echo "Error: Unable to run asterisk -V" && exit 1)

# Configure networking
# EXPOSE 5060/udp
# EXPOSE 5060/tcp
# EXPOSE 5061/tcp
# EXPOSE 10000-10099/udp

# Define volumes for persistent data
VOLUME ["/var/lib/asterisk/sounds", "/var/lib/asterisk/keys", "/var/lib/asterisk/phoneprov", "/var/spool/asterisk", "/var/log/asterisk", "/etc/asterisk"]

# Add health check
HEALTHCHECK --interval=30s \
--timeout=10s \
--start-period=30s \
--retries=3 \
CMD /usr/local/bin/healthcheck.sh

# Entrypoint runs as root, adapts asterisk uid/gid to PUID/PGID, then execs CMD.
# Asterisk drops privileges itself via `-U asterisk -p` in the CMD below.
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]

# Set working directory
WORKDIR /home/asterisk

# Default command with production settings
CMD ["/usr/sbin/asterisk", "-vvvdddf", "-T", "-W", "-U", "asterisk", "-p"]
145 changes: 145 additions & 0 deletions asterisk/20.21.0-trixie/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
#!/bin/bash
# Asterisk build script
# Generated from template for 20.21.0
# Contains menuselect configuration and build commands

set -euo pipefail

# Color output for better readability
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m' # No Color

log() {
echo -e "${GREEN}[BUILD]${NC} $1"
}

warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}

error() {
echo -e "${RED}[ERROR]${NC} $1"
}

log "Starting Asterisk 20.21.0 build process..."

# Set build parallelization (use Docker ARG or default)
NPROC=$(nproc)
JOBS=${JOBS:-8}
log "Using $JOBS parallel jobs for compilation (detected $NPROC CPUs)"

# Configure Asterisk
log "Configuring Asterisk with options..."
./configure --with-pjproject-bundled --with-ssl=ssl --with-crypto

# Workaround: Asterisk 18.x ships makeopts with a literal '\n' in DOWNLOAD
# that dash echo interprets as a real newline, mangling
# get_sourceable_makeopts output and breaking make_xml_documentation. Flatten
# the line to a plain curl invocation. No-op on versions without the bug.
if [ -f makeopts ]; then
sed -i 's|^DOWNLOAD=.*|DOWNLOAD=/usr/bin/curl -L -O --progress-bar|' makeopts
fi

# Build menuselect tool
log "Building menuselect tool..."
make menuselect

# Configure Asterisk modules using menuselect
log "Configuring Asterisk modules..."

# Disable BUILD_NATIVE optimization for container builds
menuselect/menuselect --disable BUILD_NATIVE menuselect.makeopts

# Enable better backtraces for debugging
menuselect/menuselect --enable BETTER_BACKTRACES menuselect.makeopts

# Disable sound packages to reduce image size
menuselect/menuselect --disable-category MENUSELECT_CORE_SOUNDS menuselect.makeopts
menuselect/menuselect --disable-category MENUSELECT_MOH menuselect.makeopts
menuselect/menuselect --disable-category MENUSELECT_EXTRA_SOUNDS menuselect.makeopts

# Enable core applications
menuselect/menuselect --enable app_voicemail menuselect.makeopts || warn "Module not found: $(echo 'menuselect/menuselect --enable app_voicemail menuselect.makeopts' | grep -o '[a-z_]*' | tail -1)"
menuselect/menuselect --enable app_queue menuselect.makeopts || warn "Module not found: $(echo 'menuselect/menuselect --enable app_queue menuselect.makeopts' | grep -o '[a-z_]*' | tail -1)"
menuselect/menuselect --enable app_confbridge menuselect.makeopts || warn "Module not found: $(echo 'menuselect/menuselect --enable app_confbridge menuselect.makeopts' | grep -o '[a-z_]*' | tail -1)"
menuselect/menuselect --enable app_directory menuselect.makeopts || warn "Module not found: $(echo 'menuselect/menuselect --enable app_directory menuselect.makeopts' | grep -o '[a-z_]*' | tail -1)"
menuselect/menuselect --enable app_dial menuselect.makeopts || warn "Module not found: $(echo 'menuselect/menuselect --enable app_dial menuselect.makeopts' | grep -o '[a-z_]*' | tail -1)"
menuselect/menuselect --enable app_playback menuselect.makeopts || warn "Module not found: $(echo 'menuselect/menuselect --enable app_playback menuselect.makeopts' | grep -o '[a-z_]*' | tail -1)"
menuselect/menuselect --enable app_record menuselect.makeopts || warn "Module not found: $(echo 'menuselect/menuselect --enable app_record menuselect.makeopts' | grep -o '[a-z_]*' | tail -1)"
menuselect/menuselect --enable app_echo menuselect.makeopts || warn "Module not found: $(echo 'menuselect/menuselect --enable app_echo menuselect.makeopts' | grep -o '[a-z_]*' | tail -1)"
menuselect/menuselect --enable app_mixmonitor menuselect.makeopts || warn "Module not found: $(echo 'menuselect/menuselect --enable app_mixmonitor menuselect.makeopts' | grep -o '[a-z_]*' | tail -1)"

# Enable CDR and CEL modules

# Enable channel drivers
menuselect/menuselect --enable chan_pjsip menuselect.makeopts || warn "Module not found: $(echo 'menuselect/menuselect --enable chan_pjsip menuselect.makeopts' | grep -o '[a-z_]*' | tail -1)"
menuselect/menuselect --enable chan_iax2 menuselect.makeopts || warn "Module not found: $(echo 'menuselect/menuselect --enable chan_iax2 menuselect.makeopts' | grep -o '[a-z_]*' | tail -1)"
menuselect/menuselect --enable chan_local menuselect.makeopts || warn "Module not found: $(echo 'menuselect/menuselect --enable chan_local menuselect.makeopts' | grep -o '[a-z_]*' | tail -1)"
menuselect/menuselect --enable chan_bridge_media menuselect.makeopts || warn "Module not found: $(echo 'menuselect/menuselect --enable chan_bridge_media menuselect.makeopts' | grep -o '[a-z_]*' | tail -1)"

# Enable resource modules
menuselect/menuselect --enable res_musiconhold menuselect.makeopts || warn "Module not found: $(echo 'menuselect/menuselect --enable res_musiconhold menuselect.makeopts' | grep -o '[a-z_]*' | tail -1)"
menuselect/menuselect --enable res_pjsip menuselect.makeopts || warn "Module not found: $(echo 'menuselect/menuselect --enable res_pjsip menuselect.makeopts' | grep -o '[a-z_]*' | tail -1)"
menuselect/menuselect --enable res_pjsip_session menuselect.makeopts || warn "Module not found: $(echo 'menuselect/menuselect --enable res_pjsip_session menuselect.makeopts' | grep -o '[a-z_]*' | tail -1)"
menuselect/menuselect --enable res_pjsip_outbound_registration menuselect.makeopts || warn "Module not found: $(echo 'menuselect/menuselect --enable res_pjsip_outbound_registration menuselect.makeopts' | grep -o '[a-z_]*' | tail -1)"
menuselect/menuselect --enable res_pjsip_registrar menuselect.makeopts || warn "Module not found: $(echo 'menuselect/menuselect --enable res_pjsip_registrar menuselect.makeopts' | grep -o '[a-z_]*' | tail -1)"
menuselect/menuselect --enable res_rtp_asterisk menuselect.makeopts || warn "Module not found: $(echo 'menuselect/menuselect --enable res_rtp_asterisk menuselect.makeopts' | grep -o '[a-z_]*' | tail -1)"
menuselect/menuselect --enable res_timing_timerfd menuselect.makeopts || warn "Module not found: $(echo 'menuselect/menuselect --enable res_timing_timerfd menuselect.makeopts' | grep -o '[a-z_]*' | tail -1)"
menuselect/menuselect --enable res_crypto menuselect.makeopts || warn "Module not found: $(echo 'menuselect/menuselect --enable res_crypto menuselect.makeopts' | grep -o '[a-z_]*' | tail -1)"

# Disable unwanted modules
menuselect/menuselect --disable chan_dahdi menuselect.makeopts || warn "Module not found: $(echo 'menuselect/menuselect --disable chan_dahdi menuselect.makeopts' | grep -o '[a-z_]*' | tail -1)"
menuselect/menuselect --disable chan_misdn menuselect.makeopts || warn "Module not found: $(echo 'menuselect/menuselect --disable chan_misdn menuselect.makeopts' | grep -o '[a-z_]*' | tail -1)"
menuselect/menuselect --disable app_festival menuselect.makeopts || warn "Module not found: $(echo 'menuselect/menuselect --disable app_festival menuselect.makeopts' | grep -o '[a-z_]*' | tail -1)"


log "Module configuration completed"


# Pre-build third-party (pjproject) sequentially with verbose output.
# This surfaces real compiler errors that would otherwise be hidden by parallel make.
# Skipped on Asterisk < 13: the 'third-party' target was added with bundled
# pjproject support and does not exist in older trees.
log "Building third-party dependencies (pjproject) with verbose output..."
TMPDIR=${TMPDIR} make NOISY_BUILD=yes -j 1 third-party

# Build Asterisk
log "Building Asterisk core (this may take several minutes)..."
TMPDIR=${TMPDIR} make -j $JOBS all
log "Installing Asterisk..."
TMPDIR=${TMPDIR} make install
log "Installing sample configurations..."
TMPDIR=${TMPDIR} make samples

# Download and install Digium Opus codec binary (x86-64 only)
ARCH=$(dpkg --print-architecture 2>/dev/null || echo "unknown")
if [ "$ARCH" = "amd64" ]; then
OPUS_MAJOR="20"
OPUS_URL="https://downloads.digium.com/pub/telephony/codec_opus/asterisk-${OPUS_MAJOR}.0/x86-64/codec_opus-${OPUS_MAJOR}.0-current-x86_64.tar.gz"
log "Downloading Digium Opus codec (Asterisk ${OPUS_MAJOR}.0)..."
OPUS_TMP="/tmp/codec_opus"
mkdir -p "$OPUS_TMP"
if curl -fsSL "$OPUS_URL" | tar -xz -C "$OPUS_TMP"; then
find "$OPUS_TMP" -name "codec_opus*.so" -exec cp -v {} /usr/lib/asterisk/modules/ \;
find "$OPUS_TMP" -name "format_ogg_opus*.so" -exec cp -v {} /usr/lib/asterisk/modules/ \;
mkdir -p /var/lib/asterisk/documentation
find "$OPUS_TMP" -name "codec_opus_config-en_US.xml" -exec cp -v {} /var/lib/asterisk/documentation/ \;
rm -rf "$OPUS_TMP"
log "Opus codec installed successfully"
else
warn "Failed to download Opus codec from $OPUS_URL - Opus transcoding will not be available"
rm -rf "$OPUS_TMP"
fi
else
log "Skipping Digium Opus codec (x86-64 only, detected: $ARCH)"
fi


# Strip binaries to reduce size
log "Stripping binaries to reduce image size..."
find /usr/sbin /usr/lib/asterisk -type f -executable \
-exec strip --strip-unneeded {} + 2>/dev/null || true

log "Asterisk 20.21.0 build completed successfully!"
Loading
Loading