Özel Docker imajı oluşturma
FrankenPHP Docker imajları, resmi PHP imajları temel alınarak hazırlanmıştır. Popüler mimariler için Debian ve Alpine Linux varyantları sağlanmıştır. Debian varyantları tavsiye edilir.
PHP 8.2, 8.3, 8.4 ve 8.5 için varyantlar sağlanmıştır.
Etiketler şu deseni takip eder: dunglas/frankenphp:<frankenphp-version>-php<php-version>-<os>
<frankenphp-version>ve<php-version>, sırasıyla FrankenPHP ve PHP’nin ana (örn.1), ikincil (örn.1.2) ve yama sürümlerine (örn.1.2.3) kadar değişen sürüm numaralarıdır.<os>isetrixie(Debian Trixie için),bookworm(Debian Bookworm için) veyaalpine(Alpine’ın en son kararlı sürümü için) olabilir.
İmajlar nasıl kullanılır
Projenizde bir Dockerfile oluşturun:
FROM dunglas/frankenphp
COPY . /app/public
Ardından, Docker imajını oluşturmak ve çalıştırmak için bu komutları çalıştırın:
docker build -t my-php-app .
docker run -it --rm --name my-running-app my-php-app
Yapılandırma nasıl ayarlanır
Kolaylık sağlamak için, faydalı ortam değişkenleri içeren varsayılan bir Caddyfile imajda sağlanmıştır.
Daha fazla PHP eklentisi nasıl kurulur
docker-php-extension-installer betiği temel imajda sağlanmıştır.
Ek PHP eklentileri eklemek basittir:
FROM dunglas/frankenphp
# ek eklentileri buraya ekleyin:
RUN install-php-extensions \
pdo_mysql \
gd \
intl \
zip \
opcache
Daha fazla Caddy modülü nasıl kurulur
FrankenPHP, Caddy’nin üzerine inşa edilmiştir ve tüm Caddy modülleri FrankenPHP ile kullanılabilir.
Özel Caddy modüllerini kurmanın en kolay yolu xcaddy kullanmaktır:
FROM dunglas/frankenphp:builder AS builder
# xcaddy'yi builder imajına kopyalayın
COPY --from=caddy:builder /usr/bin/xcaddy /usr/bin/xcaddy
# CGO, FrankenPHP oluşturmak için etkinleştirilmelidir
RUN CGO_ENABLED=1 \
XCADDY_SETCAP=1 \
XCADDY_GO_BUILD_FLAGS="-ldflags='-w -s' -tags=nobadger,nomysql,nopgx" \
CGO_CFLAGS=$(php-config --includes) \
CGO_LDFLAGS="$(php-config --ldflags) $(php-config --libs)" \
xcaddy build \
--output /usr/local/bin/frankenphp \
--with github.com/dunglas/frankenphp=./ \
--with github.com/dunglas/frankenphp/caddy=./caddy/ \
--with github.com/dunglas/caddy-cbrotli \
# Mercure ve Vulcain resmi derlemeye dahildir, ancak bunları kaldırmaktan çekinmeyin
--with github.com/dunglas/mercure/caddy \
--with github.com/dunglas/vulcain/caddy
# Ek Caddy modüllerini buraya ekleyin
FROM dunglas/frankenphp AS runner
# Resmi binary dosyayı özel modüllerinizi içeren binary dosyayla değiştirin
COPY --from=builder /usr/local/bin/frankenphp /usr/local/bin/frankenphp
FrankenPHP tarafından sağlanan builder imajı libphp’nin derlenmiş bir sürümünü içerir.
Builder imajları hem Debian hem de Alpine için FrankenPHP ve PHP’nin tüm sürümleri için sağlanmıştır.
İpucu
Eğer Alpine Linux ve Symfony kullanıyorsanız, varsayılan yığın boyutunu artırmanız gerekebilir.
Varsayılan olarak worker modunun etkinleştirilmesi
FrankenPHP’yi bir worker betiği ile başlatmak için FRANKENPHP_CONFIG ortam değişkenini ayarlayın:
FROM dunglas/frankenphp
# ...
ENV FRANKENPHP_CONFIG="worker ./public/index.php"
Geliştirme sürecinde volume kullanma
FrankenPHP ile kolayca geliştirme yapmak için, uygulamanın kaynak kodunu içeren dizini ana bilgisayarınızdan Docker konteynerine bir volume olarak bağlayın:
docker run -v $PWD:/app/public -p 80:80 -p 443:443 -p 443:443/udp --tty my-php-app
İpucu
--tty seçeneği JSON günlükleri yerine insan tarafından okunabilir güzel günlüklere sahip olmayı sağlar.
Docker Compose ile:
# compose.yaml
services:
php:
image: dunglas/frankenphp
# özel bir Dockerfile kullanmak istiyorsanız aşağıdaki satırın yorumunu kaldırın
#build: .
# bunu bir üretim ortamında çalıştırmak istiyorsanız aşağıdaki satırın yorumunu kaldırın
# restart: always
ports:
- "80:80" # HTTP
- "443:443" # HTTPS
- "443:443/udp" # HTTP/3
volumes:
- ./:/app/public
- caddy_data:/data
- caddy_config:/config
# üretimde aşağıdaki satırı yorum satırı yapın; geliştirme ortamında ise güzel, insan tarafından okunabilir günlükler sağlar
tty: true
# Caddy sertifikaları ve yapılandırması için gereken volume'ler
volumes:
caddy_data:
caddy_config:
Root olmayan kullanıcı olarak çalıştırma
FrankenPHP, Docker’da root olmayan kullanıcı olarak çalışabilir.
İşte bunu yapan örnek bir Dockerfile:
FROM dunglas/frankenphp
ARG USER=appuser
RUN \
# Alpine tabanlı dağıtımlar için "adduser -D ${USER}" kullanın
useradd ${USER}; \
# 80 ve 443 numaralı bağlantı noktalarına bağlanmak için ek özellik ekleyin
setcap CAP_NET_BIND_SERVICE=+eip /usr/local/bin/frankenphp; \
# /config/caddy ve /data/caddy dosyalarına yazma erişimi verin
chown -R ${USER}:${USER} /config/caddy /data/caddy
USER ${USER}
Yetenek olmadan çalıştırma
FrankenPHP, root yetkisi olmadan çalışırken bile, web sunucusunu ayrıcalıklı bağlantı noktalarında (80 ve 443) bağlamak için CAP_NET_BIND_SERVICE yeteneğine ihtiyaç duyar.
FrankenPHP’yi ayrıcalıklı olmayan bir bağlantı noktasında (1024 ve üzeri) çalıştırırsanız, web sunucusunu root olmayan bir kullanıcı olarak ve herhangi bir yeteneğe ihtiyaç duymadan çalıştırmak mümkündür:
FROM dunglas/frankenphp
ARG USER=appuser
RUN \
# Alpine tabanlı dağıtımlar için "adduser -D ${USER}" kullanın
useradd ${USER}; \
# Varsayılan yeteneği kaldırın
setcap -r /usr/local/bin/frankenphp; \
# /config/caddy ve /data/caddy dosyalarına yazma erişimi verin
chown -R ${USER}:${USER} /config/caddy /data/caddy
USER ${USER}
Ardından, ayrıcalıklı olmayan bir bağlantı noktası kullanmak için SERVER_NAME ortam değişkenini ayarlayın.
Örnek: :8000
Güncellemeler
Docker imajları oluşturulur:
- Yeni bir sürüm etiketlendiğinde
- Her gün UTC ile sabah 4’te, resmi PHP imajlarının yeni sürümleri mevcutsa
İmajları sertleştirme
FrankenPHP Docker imajlarınızın saldırı yüzeyini ve boyutunu daha da azaltmak için, onları Google distroless veya Docker hardened bir imaj üzerine inşa etmek de mümkündür.
Uyarı
Bu minimal temel imajlar, hata ayıklamayı zorlaştıran bir kabuk veya paket yöneticisi içermez. Bu nedenle, güvenlik yüksek öncelikliyse yalnızca üretim için önerilirler.
Ek PHP eklentileri eklerken, bir ara derleme aşamasına ihtiyacınız olacaktır:
FROM dunglas/frankenphp AS builder
# Ek PHP eklentilerini buraya ekleyin
RUN install-php-extensions pdo_mysql pdo_pgsql #...
# frankenphp'nin paylaşılan kütüphanelerini ve kurulu tüm eklentileri geçici bir konuma kopyalayın
# Bu adımı, frankenphp binary'sinin ve her bir eklenti .so dosyasının ldd çıktısını analiz ederek manuel olarak da yapabilirsiniz
RUN apt-get update && apt-get install -y libtree && \
EXT_DIR="$(php -r 'echo ini_get("extension_dir");')" && \
FRANKENPHP_BIN="$(which frankenphp)"; \
LIBS_TMP_DIR="/tmp/libs"; \
mkdir -p "$LIBS_TMP_DIR"; \
for target in "$FRANKENPHP_BIN" $(find "$EXT_DIR" -maxdepth 2 -type f -name "*.so"); do \
libtree -pv "$target" | sed 's/.*── \(.*\) \[.*/\1/' | grep -v "^$target" | while IFS= read -r lib; do \
[ -z "$lib" ] && continue; \
base=$(basename "$lib"); \
destfile="$LIBS_TMP_DIR/$base"; \
if [ ! -f "$destfile" ]; then \
cp "$lib" "$destfile"; \
fi; \
done; \
done
# Distroless debian temel imajı, bunun temel imajla aynı debian sürümü olduğundan emin olun
FROM gcr.io/distroless/base-debian13
# Docker hardened imaj alternatifi
# FROM dhi.io/debian:13
# Uygulamanızın ve Caddyfile'ınızın konteynere kopyalanacak konumu
ARG PATH_TO_APP="."
ARG PATH_TO_CADDYFILE="./Caddyfile"
# Uygulamanızı /app'e kopyalayın
# Daha fazla sertleştirme için, yalnızca yazılabilir yolların nonroot kullanıcısına ait olduğundan emin olun
COPY --chown=nonroot:nonroot "$PATH_TO_APP" /app
COPY "$PATH_TO_CADDYFILE" /etc/caddy/Caddyfile
# frankenphp'yi ve gerekli kütüphaneleri kopyalayın
COPY --from=builder /usr/local/bin/frankenphp /usr/local/bin/frankenphp
COPY --from=builder /usr/local/lib/php/extensions /usr/local/lib/php/extensions
COPY --from=builder /tmp/libs /usr/lib
# php.ini yapılandırma dosyalarını kopyalayın
COPY --from=builder /usr/local/etc/php/conf.d /usr/local/etc/php/conf.d
COPY --from=builder /usr/local/etc/php/php.ini-production /usr/local/etc/php/php.ini
# Caddy veri dizinleri — salt okunur bir kök dosya sisteminde bile nonroot için yazılabilir olmalıdır
ENV XDG_CONFIG_HOME=/config \
XDG_DATA_HOME=/data
COPY --from=builder --chown=nonroot:nonroot /data/caddy /data/caddy
COPY --from=builder --chown=nonroot:nonroot /config/caddy /config/caddy
USER nonroot
WORKDIR /app
# Sağlanan Caddyfile ile frankenphp'yi çalıştırmak için giriş noktası
ENTRYPOINT ["/usr/local/bin/frankenphp", "run", "-c", "/etc/caddy/Caddyfile"]
Geliştirme sürümleri
Geliştirme sürümleri dunglas/frankenphp-dev Docker deposunda mevcuttur.
GitHub deposunun main dalına her commit gönderildiğinde yeni bir derleme tetiklenir.
latest* etiketleri main dalının başına işaret eder.
sha-<git-commit-hash> biçimindeki etiketler de mevcuttur.