build_phar.sh
· 4.2 KiB · Bash
Raw
#!/bin/bash
set -e
PROJECT_DIR="$(basename "$(pwd)")"
echo "Building $PROJECT_DIR PHAR..."
IMAGE_NAME="phar-builder-universal"
# ---- Read box.json ----
if [ ! -f "box.json" ]; then
echo "Error: box.json not found"
exit 1
fi
BOX_MAIN=$(php -r "echo json_decode(file_get_contents('box.json'), true)['main'] ?? 'index.php';")
BOX_OUTPUT=$(php -r "echo json_decode(file_get_contents('box.json'), true)['output'] ?? 'output.phar';")
VERSION_DIR=$(dirname "$BOX_MAIN")
echo " Main script: $BOX_MAIN"
echo " Output PHAR: $BOX_OUTPUT"
# ---- Rebuild image if requested ----
if [ "$1" = "--rebuild" ]; then
echo "Removing existing image $IMAGE_NAME for rebuild..."
docker rmi "$IMAGE_NAME" 2>/dev/null || true
fi
# ---- Build image only once ----
if ! docker image inspect "$IMAGE_NAME" >/dev/null 2>&1; then
echo "Image $IMAGE_NAME not found, building..."
TMP_DOCKERFILE="/tmp/grasp_phar_builder.Dockerfile"
trap 'rm -f "$TMP_DOCKERFILE"' EXIT
if [ -f "box.phar" ]; then
echo "Found local box.phar, will COPY it into image"
BOX_INSTALL="COPY box.phar /usr/local/bin/box
RUN chmod +x /usr/local/bin/box"
else
echo "box.phar not found locally, will download from GitHub"
BOX_INSTALL="RUN curl -LSs https://github.com/box-project/box/releases/download/4.5.0/box.phar -o /usr/local/bin/box && chmod +x /usr/local/bin/box"
fi
cat > "$TMP_DOCKERFILE" << DOCKERFILE
FROM php:8.3-cli
RUN apt-get update && apt-get install -y \
git unzip curl \
libbz2-dev liblz4-dev libzstd-dev libzip-dev \
libwebp-dev libjpeg-dev libpng-dev libfreetype-dev \
libmagickwand-dev \
libsodium-dev libssl-dev \
libpq-dev libsqlite3-dev unixodbc-dev libldap-dev \
libxml2-dev libxslt1-dev \
libicu-dev libgmp-dev libonig-dev \
libedit-dev libkrb5-dev libsnmp-dev libtidy-dev libmemcached-dev \
&& rm -rf /var/lib/apt/lists/*
RUN docker-php-ext-configure gd --with-freetype --with-jpeg --with-webp \
&& docker-php-ext-install -j\$(nproc) \
bcmath bz2 calendar dom exif fileinfo ftp \
gd gettext gmp iconv intl ldap mbstring mysqli \
opcache pcntl pdo pdo_mysql pdo_pgsql pdo_sqlite pgsql phar \
posix simplexml snmp soap sockets \
sodium sqlite3 tidy xml \
xmlreader xmlwriter xsl zip \
|| echo "Some core extensions failed (non-fatal)"
RUN pecl install imagick redis apcu xmlrpc || echo "Some PECL extensions failed (non-fatal)"
RUN pecl install memcached lz4 zstd rar || echo "Some PECL extensions failed (non-fatal)"
RUN docker-php-ext-enable imagick redis apcu xmlrpc memcached lz4 zstd rar || true
COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer
${BOX_INSTALL}
WORKDIR /app
DOCKERFILE
docker build -f "$TMP_DOCKERFILE" -t "$IMAGE_NAME" .
echo "Image $IMAGE_NAME built"
else
echo "Using existing image $IMAGE_NAME (pass --rebuild to rebuild)"
fi
CURRENT_UID=$(id -u)
CURRENT_GID=$(id -g)
echo "Running build..."
docker run --rm \
-v "$(pwd)":/app \
-e HOST_UID=$CURRENT_UID \
-e HOST_GID=$CURRENT_GID \
"$IMAGE_NAME" sh -c "
echo ' Installing dependencies...' && \
composer install --no-dev --optimize-autoloader --classmap-authoritative --no-interaction --ignore-platform-req=ext-redis && \
echo ' Generating version file...' && \
if git rev-parse --git-dir > /dev/null 2>&1; then \
mkdir -p $VERSION_DIR && \
git rev-parse --short HEAD > $VERSION_DIR/_version && \
git log --oneline --format=%B -n 1 HEAD | head -n 1 >> $VERSION_DIR/_version && \
git log --oneline --format=\"%at\" -n 1 HEAD | xargs -I{} date -d @{} +%Y-%m-%d >> $VERSION_DIR/_version && \
echo ' Version file written to $VERSION_DIR/_version'; \
else \
echo ' Not a git repository, skipping _version'; \
fi && \
echo ' Compiling PHAR...' && \
box compile && \
echo ' Fixing permissions...' && \
chown \${HOST_UID}:\${HOST_GID} /app/$BOX_OUTPUT && \
echo 'Done!'
"
if [ -f "$BOX_OUTPUT" ]; then
echo "PHAR ready:"
ls -lh "$BOX_OUTPUT"
else
echo "Error: $BOX_OUTPUT was not created."
exit 1
fi
| 1 | #!/bin/bash |
| 2 | set -e |
| 3 | |
| 4 | PROJECT_DIR="$(basename "$(pwd)")" |
| 5 | echo "Building $PROJECT_DIR PHAR..." |
| 6 | |
| 7 | IMAGE_NAME="phar-builder-universal" |
| 8 | |
| 9 | # ---- Read box.json ---- |
| 10 | if [ ! -f "box.json" ]; then |
| 11 | echo "Error: box.json not found" |
| 12 | exit 1 |
| 13 | fi |
| 14 | |
| 15 | BOX_MAIN=$(php -r "echo json_decode(file_get_contents('box.json'), true)['main'] ?? 'index.php';") |
| 16 | BOX_OUTPUT=$(php -r "echo json_decode(file_get_contents('box.json'), true)['output'] ?? 'output.phar';") |
| 17 | VERSION_DIR=$(dirname "$BOX_MAIN") |
| 18 | |
| 19 | echo " Main script: $BOX_MAIN" |
| 20 | echo " Output PHAR: $BOX_OUTPUT" |
| 21 | |
| 22 | # ---- Rebuild image if requested ---- |
| 23 | if [ "$1" = "--rebuild" ]; then |
| 24 | echo "Removing existing image $IMAGE_NAME for rebuild..." |
| 25 | docker rmi "$IMAGE_NAME" 2>/dev/null || true |
| 26 | fi |
| 27 | |
| 28 | # ---- Build image only once ---- |
| 29 | if ! docker image inspect "$IMAGE_NAME" >/dev/null 2>&1; then |
| 30 | echo "Image $IMAGE_NAME not found, building..." |
| 31 | |
| 32 | TMP_DOCKERFILE="/tmp/grasp_phar_builder.Dockerfile" |
| 33 | trap 'rm -f "$TMP_DOCKERFILE"' EXIT |
| 34 | |
| 35 | if [ -f "box.phar" ]; then |
| 36 | echo "Found local box.phar, will COPY it into image" |
| 37 | BOX_INSTALL="COPY box.phar /usr/local/bin/box |
| 38 | RUN chmod +x /usr/local/bin/box" |
| 39 | else |
| 40 | echo "box.phar not found locally, will download from GitHub" |
| 41 | BOX_INSTALL="RUN curl -LSs https://github.com/box-project/box/releases/download/4.5.0/box.phar -o /usr/local/bin/box && chmod +x /usr/local/bin/box" |
| 42 | fi |
| 43 | |
| 44 | cat > "$TMP_DOCKERFILE" << DOCKERFILE |
| 45 | FROM php:8.3-cli |
| 46 | |
| 47 | RUN apt-get update && apt-get install -y \ |
| 48 | git unzip curl \ |
| 49 | libbz2-dev liblz4-dev libzstd-dev libzip-dev \ |
| 50 | libwebp-dev libjpeg-dev libpng-dev libfreetype-dev \ |
| 51 | libmagickwand-dev \ |
| 52 | libsodium-dev libssl-dev \ |
| 53 | libpq-dev libsqlite3-dev unixodbc-dev libldap-dev \ |
| 54 | libxml2-dev libxslt1-dev \ |
| 55 | libicu-dev libgmp-dev libonig-dev \ |
| 56 | libedit-dev libkrb5-dev libsnmp-dev libtidy-dev libmemcached-dev \ |
| 57 | && rm -rf /var/lib/apt/lists/* |
| 58 | |
| 59 | RUN docker-php-ext-configure gd --with-freetype --with-jpeg --with-webp \ |
| 60 | && docker-php-ext-install -j\$(nproc) \ |
| 61 | bcmath bz2 calendar dom exif fileinfo ftp \ |
| 62 | gd gettext gmp iconv intl ldap mbstring mysqli \ |
| 63 | opcache pcntl pdo pdo_mysql pdo_pgsql pdo_sqlite pgsql phar \ |
| 64 | posix simplexml snmp soap sockets \ |
| 65 | sodium sqlite3 tidy xml \ |
| 66 | xmlreader xmlwriter xsl zip \ |
| 67 | || echo "Some core extensions failed (non-fatal)" |
| 68 | |
| 69 | RUN pecl install imagick redis apcu xmlrpc || echo "Some PECL extensions failed (non-fatal)" |
| 70 | RUN pecl install memcached lz4 zstd rar || echo "Some PECL extensions failed (non-fatal)" |
| 71 | RUN docker-php-ext-enable imagick redis apcu xmlrpc memcached lz4 zstd rar || true |
| 72 | |
| 73 | COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer |
| 74 | |
| 75 | ${BOX_INSTALL} |
| 76 | |
| 77 | WORKDIR /app |
| 78 | DOCKERFILE |
| 79 | |
| 80 | docker build -f "$TMP_DOCKERFILE" -t "$IMAGE_NAME" . |
| 81 | echo "Image $IMAGE_NAME built" |
| 82 | else |
| 83 | echo "Using existing image $IMAGE_NAME (pass --rebuild to rebuild)" |
| 84 | fi |
| 85 | |
| 86 | CURRENT_UID=$(id -u) |
| 87 | CURRENT_GID=$(id -g) |
| 88 | |
| 89 | echo "Running build..." |
| 90 | docker run --rm \ |
| 91 | -v "$(pwd)":/app \ |
| 92 | -e HOST_UID=$CURRENT_UID \ |
| 93 | -e HOST_GID=$CURRENT_GID \ |
| 94 | "$IMAGE_NAME" sh -c " |
| 95 | echo ' Installing dependencies...' && \ |
| 96 | composer install --no-dev --optimize-autoloader --classmap-authoritative --no-interaction --ignore-platform-req=ext-redis && \ |
| 97 | echo ' Generating version file...' && \ |
| 98 | if git rev-parse --git-dir > /dev/null 2>&1; then \ |
| 99 | mkdir -p $VERSION_DIR && \ |
| 100 | git rev-parse --short HEAD > $VERSION_DIR/_version && \ |
| 101 | git log --oneline --format=%B -n 1 HEAD | head -n 1 >> $VERSION_DIR/_version && \ |
| 102 | git log --oneline --format=\"%at\" -n 1 HEAD | xargs -I{} date -d @{} +%Y-%m-%d >> $VERSION_DIR/_version && \ |
| 103 | echo ' Version file written to $VERSION_DIR/_version'; \ |
| 104 | else \ |
| 105 | echo ' Not a git repository, skipping _version'; \ |
| 106 | fi && \ |
| 107 | echo ' Compiling PHAR...' && \ |
| 108 | box compile && \ |
| 109 | echo ' Fixing permissions...' && \ |
| 110 | chown \${HOST_UID}:\${HOST_GID} /app/$BOX_OUTPUT && \ |
| 111 | echo 'Done!' |
| 112 | " |
| 113 | |
| 114 | if [ -f "$BOX_OUTPUT" ]; then |
| 115 | echo "PHAR ready:" |
| 116 | ls -lh "$BOX_OUTPUT" |
| 117 | else |
| 118 | echo "Error: $BOX_OUTPUT was not created." |
| 119 | exit 1 |
| 120 | fi |
| 121 |
example_box.json
· 988 B · JSON
Raw
{
"chmod": "0755",
"compactors": [
"KevinGH\\Box\\Compactor\\Php",
"KevinGH\\Box\\Compactor\\Json"
],
"compression": "GZ",
"main": "test_send.php",
"output": "mailer.phar",
"finder": [
{
"name": ["*.php", "*.json", "*.h", "*.so", "*.dll"],
"in": "vendor",
"exclude": [
".github",
".editorconfig",
"infection.json.dist",
".php-cs-fixer.dist.php",
".valgrindc",
"*.exe",
"*.md",
"LICENSE",
"psalm.xml",
"test",
"tests",
"Tests",
"examples",
".gitignore",
".hhconfig",
".travis*",
"phpunit*",
"docs",
"doc"
]
}
],
"dump-autoload": true,
"check-requirements": false
}
| 1 | { |
| 2 | "chmod": "0755", |
| 3 | "compactors": [ |
| 4 | "KevinGH\\Box\\Compactor\\Php", |
| 5 | "KevinGH\\Box\\Compactor\\Json" |
| 6 | ], |
| 7 | "compression": "GZ", |
| 8 | "main": "test_send.php", |
| 9 | "output": "mailer.phar", |
| 10 | "finder": [ |
| 11 | { |
| 12 | "name": ["*.php", "*.json", "*.h", "*.so", "*.dll"], |
| 13 | "in": "vendor", |
| 14 | "exclude": [ |
| 15 | ".github", |
| 16 | ".editorconfig", |
| 17 | "infection.json.dist", |
| 18 | ".php-cs-fixer.dist.php", |
| 19 | ".valgrindc", |
| 20 | "*.exe", |
| 21 | "*.md", |
| 22 | "LICENSE", |
| 23 | "psalm.xml", |
| 24 | "test", |
| 25 | "tests", |
| 26 | "Tests", |
| 27 | "examples", |
| 28 | ".gitignore", |
| 29 | ".hhconfig", |
| 30 | ".travis*", |
| 31 | "phpunit*", |
| 32 | "docs", |
| 33 | "doc" |
| 34 | ] |
| 35 | } |
| 36 | ], |
| 37 | "dump-autoload": true, |
| 38 | "check-requirements": false |
| 39 | } |
| 40 |