mirror of
https://github.com/dunglas/frankenphp
synced 2024-11-22 07:40:16 +00:00
feat: create a static build of FrankenPHP (#198)
* ci: create a static build of FrankenPHP
* try to use alpine
* path mapping
* cache and fixes
* fix
* fix include path
* fix include path
* fix include path
* switch to Docker
* fix github token
* cleanup
* various improvements
* macOS instructions
* fix GHA
* docs
* feat: mac static builds
* minor fix
* fix wd
* Apple silicon build
* Revert "Apple silicon build"
This reverts commit 7a2997e092
.
* add opcache
* update builder
* upgrade to PHP 8.2
* switch to upstream static-php-cli, add intl
This commit is contained in:
parent
a6603b58cc
commit
1f3007337d
4
.github/workflows/docker.yml
vendored
4
.github/workflows/docker.yml
vendored
@ -20,7 +20,7 @@ jobs:
|
||||
platforms: ${{ steps.matrix.outputs.platforms }}
|
||||
metadata: ${{ steps.matrix.outputs.metadata }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
@ -57,7 +57,7 @@ jobs:
|
||||
- platform: linux/386
|
||||
qemu: false
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up QEMU
|
||||
if: matrix.qemu
|
||||
|
97
.github/workflows/static.yml
vendored
Normal file
97
.github/workflows/static.yml
vendored
Normal file
@ -0,0 +1,97 @@
|
||||
name: Build binary releases
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
tags:
|
||||
- v*
|
||||
workflow_dispatch:
|
||||
inputs: {}
|
||||
jobs:
|
||||
build-linux:
|
||||
name: Build Linux x86_64 binary
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
with:
|
||||
version: latest
|
||||
|
||||
- name: Build
|
||||
id: build
|
||||
uses: docker/bake-action@v3
|
||||
with:
|
||||
pull: true
|
||||
load: true
|
||||
targets: static-builder
|
||||
set: |
|
||||
*.cache-from=type=gha,scope=${{github.ref}}-static-builder
|
||||
*.cache-from=type=gha,scope=refs/heads/main-static-builder
|
||||
*.cache-to=type=gha,scope=${{github.ref}}-static-builder
|
||||
env:
|
||||
VERSION: ${{github.ref_name}}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Copy binary
|
||||
run: docker cp $(docker create --name static-builder dunglas/frankenphp:static-builder):/go/src/app/caddy/frankenphp/frankenphp frankenphp ; docker rm static-builder
|
||||
|
||||
- name: Upload binary
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: frankenphp-linux-x86_64-dev
|
||||
path: frankenphp
|
||||
|
||||
build-mac:
|
||||
name: Build macOS binaries
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
repository: crazywhalecc/static-php-cli
|
||||
path: static-php-cli
|
||||
|
||||
- uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: '1.21'
|
||||
|
||||
- name: Install static-php-cli dependencies
|
||||
working-directory: static-php-cli/
|
||||
run: composer install --no-dev -a
|
||||
|
||||
- name: Install missing system dependencies
|
||||
run: ./bin/spc doctor --auto-fix
|
||||
working-directory: static-php-cli/
|
||||
|
||||
- name: Fetch libraries sources
|
||||
working-directory: static-php-cli/
|
||||
run: ./bin/spc fetch --with-php=8.2 -A
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build static libphp
|
||||
working-directory: static-php-cli/
|
||||
run: ./bin/spc build --enable-zts --build-embed --debug "bcmath,calendar,ctype,curl,dba,dom,exif,filter,fileinfo,gd,iconv,intl,mbstring,mbregex,mysqli,mysqlnd,opcache,openssl,pcntl,pdo,pdo_mysql,pdo_pgsql,pdo_sqlite,pgsql,phar,posix,readline,redis,session,simplexml,sockets,sqlite3,tokenizer,xml,xmlreader,xmlwriter,zip,zlib,apcu"
|
||||
|
||||
- name: Set CGO flags
|
||||
working-directory: static-php-cli/
|
||||
run: |
|
||||
echo "CGO_CFLAGS=$(./buildroot/bin/php-config --includes | sed s#-I/#-I$PWD/buildroot/#g)" >> "$GITHUB_ENV"
|
||||
echo "CGO_LDFLAGS=-framework CoreFoundation -framework SystemConfiguration $(./buildroot/bin/php-config --ldflags) $(./buildroot/bin/php-config --libs)" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Build FrankenPHP
|
||||
working-directory: caddy/frankenphp/
|
||||
run: go build -buildmode=pie -tags "cgo netgo osusergo static_build" -ldflags "-linkmode=external -extldflags -static-pie -w -s"
|
||||
|
||||
- name: Upload binary
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: frankenphp-mac-x86_64-dev
|
||||
path: caddy/frankenphp/frankenphp
|
2
.github/workflows/tests.yml
vendored
2
.github/workflows/tests.yml
vendored
@ -7,7 +7,7 @@ jobs:
|
||||
matrix:
|
||||
php-versions: ['8.2', '8.3']
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/setup-go@v4
|
||||
with:
|
||||
|
@ -6,6 +6,10 @@ variable "VERSION" {
|
||||
default = "dev"
|
||||
}
|
||||
|
||||
variable "GO_VERSION" {
|
||||
default = "1.21"
|
||||
}
|
||||
|
||||
variable "SHA" {}
|
||||
|
||||
variable "LATEST" {
|
||||
@ -59,7 +63,7 @@ target "default" {
|
||||
}
|
||||
contexts = {
|
||||
php-base = "docker-image://php:${php-version}-zts-${os}"
|
||||
golang-base = "docker-image://golang:1.21-${os}"
|
||||
golang-base = "docker-image://golang:${GO_VERSION}-${os}"
|
||||
}
|
||||
dockerfile = os == "alpine" ? "alpine.Dockerfile" : "Dockerfile"
|
||||
context = "./"
|
||||
@ -91,3 +95,16 @@ target "default" {
|
||||
FRANKENPHP_VERSION = VERSION
|
||||
}
|
||||
}
|
||||
|
||||
target "static-builder" {
|
||||
contexts = {
|
||||
golang-base = "docker-image://golang:${GO_VERSION}-alpine"
|
||||
}
|
||||
dockerfile = "static-builder.Dockerfile"
|
||||
context = "./"
|
||||
tags = ["${IMAGE_NAME}:static-builder"]
|
||||
args = {
|
||||
FRANKENPHP_VERSION = VERSION
|
||||
}
|
||||
secret = ["id=github-token,env=GITHUB_TOKEN"]
|
||||
}
|
||||
|
@ -1,5 +1,10 @@
|
||||
# Compile From Sources
|
||||
|
||||
This document explain how to create a FrankenPHP build that will load PHP as a dymanic library.
|
||||
This is the recommended method.
|
||||
|
||||
Alternatively, [creating static builds](static.md) is also possible.
|
||||
|
||||
## Install PHP
|
||||
|
||||
FrankenPHP is compatible with the PHP 8.2 and superior.
|
||||
|
64
docs/static.md
Normal file
64
docs/static.md
Normal file
@ -0,0 +1,64 @@
|
||||
# Create a Static Build
|
||||
|
||||
Instead of using a local installation of the PHP library,
|
||||
it's possible to create a static build of FrankenPHP thanks to the great [static-php-cli project](https://github.com/crazywhalecc/static-php-cli) (despite its name, this project support all SAPIs, not only CLI).
|
||||
|
||||
With this method, a single, portable, binary will contain the PHP interpreter, the Caddy web server and FrankenPHP!
|
||||
|
||||
## Linux
|
||||
|
||||
We provide a Docker image to build a Linux static binary:
|
||||
|
||||
```console
|
||||
docker buildx bake --load static-builder
|
||||
docker cp $(docker create --name static-builder dunglas/frankenphp:static-builder):/go/src/app/caddy/frankenphp/frankenphp frankenphp ; docker rm static-builder
|
||||
```
|
||||
|
||||
The resulting static binary is named `frankenphp` and is available in the current directory.
|
||||
|
||||
If you want to build the static binary without Docker, take a look to the `static-builder.Dockerfile` file.
|
||||
|
||||
### Custom Extensions
|
||||
|
||||
By default, most popular PHP extensions are compiled.
|
||||
|
||||
To reduce the size of the binary and to reduce the attack surface, you can choose the list of extensions to build using the `PHP_EXTENSIONS` Docker ARG.
|
||||
|
||||
For instance, run the following command to only build the `opcache` extension:
|
||||
|
||||
```console
|
||||
docker buildx bake --load --set static-builder.args.PHP_EXTENSIONS=opcache,pdo_sqlite static-builder
|
||||
# ...
|
||||
```
|
||||
|
||||
See [the list of supported extensions](https://static-php-cli.zhamao.me/en/guide/extensions.html).
|
||||
|
||||
### GitHub Token
|
||||
|
||||
If you hit the GitHub API rate limit, set a GitHub Personal Access Token in an environment variable named `GITHUB_TOKEN`:
|
||||
|
||||
```console
|
||||
GITHUB_TOKEN="xxx" docker --load buildx bake static-builder
|
||||
# ...
|
||||
```
|
||||
|
||||
## macOS
|
||||
|
||||
Run the following command to create a static binary for macOS:
|
||||
|
||||
```console
|
||||
git clone --depth=1 https://github.com/crazywhalecc/static-php-cli.git
|
||||
cd static-php-cli
|
||||
composer install --no-dev -a
|
||||
./bin/spc doctor --auto-fix
|
||||
./bin/spc fetch --with-php=8.2 -A
|
||||
./bin/spc build --enable-zts --build-embed --debug "bcmath,calendar,ctype,curl,dba,dom,exif,filter,fileinfo,gd,iconv,intl,mbstring,mbregex,mysqli,mysqlnd,opcache,openssl,pcntl,pdo,pdo_mysql,pdo_pgsql,pdo_sqlite,pgsql,phar,posix,readline,redis,session,simplexml,sockets,sqlite3,tokenizer,xml,xmlreader,xmlwriter,zip,zlib,apcu"
|
||||
export CGO_CFLAGS="$(./buildroot/bin/php-config --includes | sed s#-I/#-I$PWD/buildroot/#g)"
|
||||
export CGO_LDFLAGS="-framework CoreFoundation -framework SystemConfiguration $(./buildroot/bin/php-config --ldflags) $(./buildroot/bin/php-config --libs)"
|
||||
|
||||
git clone --depth=1 https://github.com/dunglas/frankenphp.git
|
||||
cd frankenphp/caddy/frankenphp
|
||||
go build -buildmode=pie -tags "cgo netgo osusergo static_build" -ldflags "-linkmode=external -extldflags -static-pie"
|
||||
```
|
||||
|
||||
See [the list of supported extensions](https://static-php-cli.zhamao.me/en/guide/extensions.html).
|
@ -12,13 +12,18 @@ package frankenphp
|
||||
// Use PHP includes corresponding to your PHP installation by running:
|
||||
//
|
||||
// export CGO_CFLAGS=$(php-config --includes)
|
||||
// export CGO_LDFLAGS=$(php-config --ldflags --libs)
|
||||
//
|
||||
// We also set these flags for hardening: https://github.com/docker-library/php/blob/master/8.2/bookworm/zts/Dockerfile#L57-L59
|
||||
|
||||
// #cgo pkg-config: libxml-2.0 sqlite3
|
||||
// #cgo CFLAGS: -Wall -Werror
|
||||
// #cgo darwin pkg-config: libxml-2.0 sqlite3
|
||||
// #cgo CFLAGS: -Wall -Werror -fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
|
||||
// #cgo CFLAGS: -I/usr/local/include/php -I/usr/local/include/php/main -I/usr/local/include/php/TSRM -I/usr/local/include/php/Zend -I/usr/local/include/php/ext -I/usr/local/include/php/ext/date/lib
|
||||
// #cgo linux CFLAGS: -D_GNU_SOURCE
|
||||
// #cgo CPPFLAGS: -fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
|
||||
// #cgo darwin LDFLAGS: -L/opt/homebrew/opt/libiconv/lib -liconv
|
||||
// #cgo LDFLAGS: -L/usr/local/lib -L/usr/lib -lphp -lresolv -ldl -lm -lutil
|
||||
// #cgo linux LDFLAGS: -Wl,-O1
|
||||
// #cgo LDFLAGS: -pie -L/usr/local/lib -L/usr/lib -lphp -lresolv -ldl -lm -lutil
|
||||
// #include <stdlib.h>
|
||||
// #include <stdint.h>
|
||||
// #include <php_variables.h>
|
||||
|
79
static-builder.Dockerfile
Normal file
79
static-builder.Dockerfile
Normal file
@ -0,0 +1,79 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
FROM golang-base
|
||||
|
||||
ARG FRANKENPHP_VERSION='dev'
|
||||
ARG PHP_VERSION='8.2'
|
||||
ARG PHP_EXTENSIONS='bcmath,calendar,ctype,curl,dba,dom,exif,filter,fileinfo,gd,iconv,intl,mbstring,mbregex,mysqli,mysqlnd,opcache,openssl,pcntl,pdo,pdo_mysql,pdo_pgsql,pdo_sqlite,pgsql,phar,posix,readline,redis,session,simplexml,sockets,sqlite3,tokenizer,xml,xmlreader,xmlwriter,zip,zlib,apcu'
|
||||
|
||||
RUN apk update; \
|
||||
apk add --no-cache \
|
||||
autoconf \
|
||||
automake \
|
||||
bash \
|
||||
binutils \
|
||||
bison \
|
||||
build-base \
|
||||
cmake \
|
||||
curl \
|
||||
file \
|
||||
flex \
|
||||
g++ \
|
||||
gcc \
|
||||
git \
|
||||
jq \
|
||||
libgcc \
|
||||
libstdc++ \
|
||||
linux-headers \
|
||||
m4 \
|
||||
make \
|
||||
php82 \
|
||||
php82-common \
|
||||
php82-dom \
|
||||
php82-mbstring \
|
||||
php82-openssl \
|
||||
php82-pcntl \
|
||||
php82-phar \
|
||||
php82-posix \
|
||||
php82-tokenizer \
|
||||
php82-xml \
|
||||
php82-xmlwriter \
|
||||
pkgconfig \
|
||||
wget \
|
||||
xz ; \
|
||||
ln -sf /usr/bin/php82 /usr/bin/php
|
||||
|
||||
# https://getcomposer.org/doc/03-cli.md#composer-allow-superuser
|
||||
ENV COMPOSER_ALLOW_SUPERUSER=1
|
||||
ENV PATH="${PATH}:/root/.composer/vendor/bin"
|
||||
|
||||
COPY --from=composer/composer:2-bin --link /composer /usr/bin/composer
|
||||
|
||||
WORKDIR /static-php-cli
|
||||
|
||||
RUN git clone --depth=1 https://github.com/crazywhalecc/static-php-cli . && \
|
||||
composer install --no-cache --no-dev --classmap-authoritative
|
||||
|
||||
RUN --mount=type=secret,id=github-token GITHUB_TOKEN=$(cat /run/secrets/github-token) ./bin/spc download --with-php=$PHP_VERSION --all
|
||||
|
||||
RUN ./bin/spc build --build-embed --enable-zts --debug "$PHP_EXTENSIONS"
|
||||
|
||||
ENV PATH="/static-php-cli/buildroot/bin:/static-php-cli/buildroot/usr/bin:$PATH"
|
||||
|
||||
WORKDIR /go/src/app
|
||||
|
||||
COPY go.mod go.sum ./
|
||||
RUN go mod graph | awk '{if ($1 !~ "@") print $2}' | xargs go get
|
||||
|
||||
RUN mkdir caddy && cd caddy
|
||||
COPY caddy/go.mod caddy/go.sum ./caddy/
|
||||
|
||||
RUN cd caddy && go mod graph | awk '{if ($1 !~ "@") print $2}' | xargs go get
|
||||
|
||||
COPY *.* ./
|
||||
COPY caddy caddy
|
||||
COPY C-Thread-Pool C-Thread-Pool
|
||||
|
||||
RUN cd caddy/frankenphp && \
|
||||
CGO_CFLAGS="$(/static-php-cli/buildroot/bin/php-config --includes | sed s#-I/#-I/static-php-cli/buildroot/#g)" \
|
||||
CGO_LDFLAGS="$(/static-php-cli/buildroot/bin/php-config --ldflags) $(/static-php-cli/buildroot/bin/php-config --libs | sed -e 's/-lgcc_s//g')" \
|
||||
go build -buildmode=pie -tags "cgo netgo osusergo static_build" -ldflags "-linkmode=external -extldflags -static-pie -s -w -X 'github.com/caddyserver/caddy/v2.CustomVersion=FrankenPHP $FRANKENPHP_VERSION Caddy'"
|
Loading…
Reference in New Issue
Block a user