Ctrl K
ComunidadGuías…

Dockerfile

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# ==========================================================================
# Flarum 2.0 — self-contained image (nginx + php-fpm under supervisor).
#
# Everything is baked at build time: system packages, PHP extensions, Composer,
# and the boot/entrypoint scripts. There is NO runtime fetch of a setup script
# from the network — the image is fully self-describing and reproducible.
# ==========================================================================
FROM php:8.3-fpm

# Ride over transient apt mirror/network blips during the build. Applies to
# every apt-get below, including the ones install-php-extensions spawns to pull
# gd/intl build deps.
RUN printf 'Acquire::Retries "8";\nAcquire::http::Timeout "30";\nAcquire::https::Timeout "30";\n' \
        > /etc/apt/apt.conf.d/80-retries

# System packages baked at build time — no apt at container start.
RUN apt-get update \
    && apt-get install -y --no-install-recommends \
        git unzip zip curl ca-certificates supervisor \
        netcat-openbsd mariadb-client postgresql-client nginx cron libgmp-dev \
    && update-ca-certificates \
    && rm -rf /var/lib/apt/lists/*

# install-php-extensions pinned to a release tag (not /latest) so a compromised
# release can't slip into a build without a git diff.
#
# redis is pinned too. Everything else here is compiled from the PHP source
# already in the base image, but redis is fetched from pecl.php.net at build
# time — which is why v1.0.0 needed three attempts while PECL returned 504s.
# A pin does not make PECL more reliable, but it does mean a retry produces the
# SAME extension rather than whatever is newest by then.
ARG PECL_REDIS_VERSION=6.3.0
RUN curl -sSLf --retry 5 --retry-delay 2 --retry-connrefused \
        -o /usr/local/bin/install-php-extensions \
        https://github.com/mlocati/docker-php-extension-installer/releases/download/2.11.1/install-php-extensions \
    && chmod +x /usr/local/bin/install-php-extensions \
    && install-php-extensions \
        bcmath ctype curl dom exif fileinfo filter gd gmp hash intl json \
        mbstring openssl pcre pdo session sodium tokenizer xml \
        pdo_mysql pdo_pgsql pgsql opcache "redis-${PECL_REDIS_VERSION}" pcntl sockets zip

# Composer pinned, and the installer's signature checked before it is run.
#
# This used to pipe whatever getcomposer.org served straight into php,
# unverified and unversioned: a bad day upstream became a bad image, and two
# builds of the same commit could ship different Composer versions. The
# signature check is the one the Composer project publishes for exactly this.
ARG COMPOSER_VERSION=2.10.2
RUN set -eux; \
    curl -sSLf --retry 5 --retry-delay 2 --retry-connrefused \
        -o /tmp/composer-setup.php https://getcomposer.org/installer; \
    expected="$(curl -sSLf --retry 5 https://composer.github.io/installer.sig)"; \
    actual="$(php -r 'echo hash_file("sha384", "/tmp/composer-setup.php");')"; \
    if [ "$expected" != "$actual" ]; then \
        echo "composer installer signature mismatch" >&2; exit 1; \
    fi; \
    php /tmp/composer-setup.php --install-dir=/usr/local/bin --filename=composer \
        --version="${COMPOSER_VERSION}"; \
    rm -f /tmp/composer-setup.php; \
    composer --version

# ── The pinned Flarum skeleton ───────────────────────────────────────────────
# Flarum itself, resolved at BUILD time from the committed lock rather than
# from Packagist when a container first starts. Build-time network is fine and
# reproducible — the lock decides what gets installed. Runtime network is not:
# it made the same image tag produce different forums a week apart and left no
# offline install path at all. See issue #2 and skeleton/README.md.
#
# create-project supplies the skeleton's OWN files (index.php, the flarum CLI,
# public/, storage/) which are part of the flarum/flarum package and never
# appear in vendor/. --no-install skips dependency resolution, because the
# committed lock replaces its composer.json immediately below and decides that.
ARG FLARUM_VERSION=2.0.0-rc.5
ENV FLARUM_SKELETON=/opt/flarum-skeleton
ENV FLARUM_SKELETON_VERSION=${FLARUM_VERSION}

RUN COMPOSER_HOME=/tmp/composer composer create-project \
        "flarum/flarum:${FLARUM_VERSION}" "$FLARUM_SKELETON" \
        --stability=beta --no-install --no-interaction --no-progress

COPY skeleton/composer.json skeleton/composer.lock ${FLARUM_SKELETON}/

# Fail the build rather than ship a skeleton whose files and lock disagree: the
# ARG picks the package that supplies the root files, the lock picks everything
# else, and nothing else would notice them drifting apart.
RUN set -eu; \
    locked="$(php -r '$l = json_decode(file_get_contents(getenv("FLARUM_SKELETON")."/composer.lock"), true); foreach ($l["packages"] as $p) { if ($p["name"] === "flarum/core") { echo ltrim($p["version"], "v"); exit; } } exit(1);')"; \
    if [ "$locked" != "${FLARUM_VERSION}" ]; then \
        echo "FLARUM_VERSION=${FLARUM_VERSION} but skeleton/composer.lock pins flarum/core $locked" >&2; \
        exit 1; \
    fi; \
    cd "$FLARUM_SKELETON"; \
    COMPOSER_HOME=/tmp/composer composer install \
        --no-dev --no-interaction --no-progress --optimize-autoloader; \
    rm -rf /tmp/composer

# Baked config + boot scripts (no runtime download).
COPY nginx.conf       /etc/nginx/conf.d/flarum.conf
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
COPY entrypoint.sh    /usr/local/bin/entrypoint.sh
COPY lr-db.php        /usr/local/bin/lr-db.php
COPY backup.sh        /usr/local/bin/backup.sh
RUN chmod +x /usr/local/bin/entrypoint.sh /usr/local/bin/backup.sh \
    && rm -f /etc/nginx/sites-enabled/default /etc/nginx/conf.d/default.conf 2>/dev/null || true

WORKDIR /var/www/html

EXPOSE 80 6001

# docker-compose.yml declares the same check, but a compose-level healthcheck
# does not travel with the image — anyone running `docker run`, or pulling this
# into their own orchestrator, gets nothing. Declaring it here makes the image
# self-describing; compose's copy simply overrides it with identical values.
#
# The long start period covers first boot: composer create-project, migrations
# and extension installs take 1-2 minutes on a cold volume, and the container
# must not be declared unhealthy while that is still legitimately running.
HEALTHCHECK --interval=30s --timeout=5s --start-period=240s --retries=5 \
    CMD curl -fsS -o /dev/null http://127.0.0.1/ || exit 1

ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]