Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
1fd7092
Symfony docker github url added in README
llegaz Apr 8, 2026
687652d
add some deploying section in README.md
llegaz Apr 8, 2026
de53fda
clearer explanation on README.md
llegaz Apr 8, 2026
e7719c8
Dockerfile prod stage fix
llegaz Apr 8, 2026
b8abbd4
almost done
llegaz Apr 8, 2026
7b475a9
README.md last updates
llegaz Apr 9, 2026
16c0213
back and forth now Ineed to fix CI again
llegaz Apr 10, 2026
d7ea496
GITHUB_TOKEN tweak test
llegaz Apr 10, 2026
bc16ac4
ci test
llegaz Apr 10, 2026
a1df05b
back and forth, zizmor does not like pull_request_target directive
llegaz Apr 10, 2026
6561276
typo
llegaz Apr 10, 2026
917bfa9
remove debug superfluous utilitaries for good
llegaz Apr 10, 2026
c26b456
added new security ci workflow based on docker scout
llegaz Apr 8, 2026
2b213b7
security CI workflow fix
llegaz Apr 8, 2026
70cc32f
report only no build fail
llegaz Apr 8, 2026
62521b6
comment non needed secrets
llegaz Apr 9, 2026
93f384e
security: inject secrets via env instead of direct inputs
llegaz Apr 10, 2026
58aba6b
do not persist credentials
llegaz Apr 10, 2026
ac5ddcd
new environment added for security measure
llegaz Apr 10, 2026
b8a3138
force PR comment for CVEs report
llegaz Apr 10, 2026
7131cf9
add CVEs reports to actions summary
llegaz Apr 10, 2026
5052e01
fix send report to summary cmd
llegaz Apr 10, 2026
7f06f9d
final version
llegaz Apr 10, 2026
c9586f3
gemini frustration
llegaz Apr 10, 2026
f307740
OK done, launch scan on slected branchs only
llegaz Apr 10, 2026
136f5e3
finalize summary report for the CVEs analysis
llegaz Apr 10, 2026
d3174e4
add all commands in a single optimized block
llegaz Apr 10, 2026
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
81 changes: 81 additions & 0 deletions .github/workflows/security.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
---
name: CVE Analysis

on:
push:
branches: [main, dev]
pull_request:
branches: [main, dev]
workflow_dispatch: {}

jobs:
analyze:
name: Upstream Images Scan
runs-on: ubuntu-latest
environment: "open source"

permissions:
contents: read
pull-requests: write

env:
DOCKER_USER: ${{ secrets.DOCKER_USER }}
DOCKER_PAT: ${{ secrets.DOCKER_PAT }}

steps:
- name: Checkout
uses: actions/checkout@v4
with:
persist-credentials: false

- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ env.DOCKER_USER }}
password: ${{ env.DOCKER_PAT }}

- name: Scan FrankenPHP Upstream
uses: docker/scout-action@v1
with:
command: cves
image: dunglas/frankenphp:1-php8.5
only-severities: critical,high
exit-code: false
write-comment: true
github-token: ${{ secrets.GITHUB_TOKEN }}
output: frankenphp-report.md

- name: Scan Debian Base
uses: docker/scout-action@v1
with:
command: cves
image: debian:13-slim
only-severities: critical,high
exit-code: false
write-comment: true
github-token: ${{ secrets.GITHUB_TOKEN }}
output: debian-report.md

- name: Publish Results to Summary
if: always()
run: |
{
echo "# 🛡️ CVE Analysis Summary"
echo "Scan performed on $(date +'%Y-%m-%d %H:%M')"
echo ""
if [ -s frankenphp-report.md ]; then
echo "## 🐘 FrankenPHP Upstream"
echo ""
cat frankenphp-report.md
echo ""
fi
if [ -s debian-report.md ]; then
echo "## 🐧 Debian Base"
echo ""
cat debian-report.md
echo ""
fi
if [ ! -s frankenphp-report.md ] && [ ! -s debian-report.md ]; then
echo "> ✅ Reports were integrated directly by Docker Scout above."
fi
} >> "$GITHUB_STEP_SUMMARY"
35 changes: 19 additions & 16 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ RUN <<-EOF
iptables \
jq \
sudo

install-php-extensions xdebug
rm -rf /var/lib/apt/lists/*
useradd -m -s /bin/bash nonroot
Expand All @@ -91,22 +92,28 @@ RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
COPY --link frankenphp/conf.d/20-app.prod.ini $PHP_INI_DIR/app.conf.d/

# prevent the reinstallation of vendors at every changes in the source code
COPY --link composer.* symfony.* ./
RUN composer install --no-cache --prefer-dist --no-dev --no-autoloader --no-scripts --no-progress

# copy sources
COPY --link --exclude=frankenphp/ . ./

RUN <<-EOF
mkdir -p var/cache var/log var/share
composer dump-autoload --classmap-authoritative --no-dev
EOF
COPY --link src/composer.* /app/src/
RUN composer install \
--working-dir=/app/src \
--no-cache \
--prefer-dist \
--no-dev \
--no-autoloader \
--no-scripts \
--no-progress

COPY --link src/ /app/src/

RUN composer dump-autoload \
--working-dir=/app/src \
--classmap-authoritative \
--no-dev

# Collect shared libraries needed by FrankenPHP and PHP extensions
# hadolint ignore=DL3008,SC3054,DL4006
RUN <<-'EOF'
apt-get update
apt-get install -y --no-install-recommends libtree pstree procps net-
apt-get install -y --no-install-recommends libtree
mkdir -p /tmp/libs
BINARIES=(frankenphp php file)
touch my_log.txt
Expand Down Expand Up @@ -141,11 +148,7 @@ COPY --from=frankenphp_prod_builder /usr/local/etc/php/php.ini /usr/local/etc/ph
COPY --from=frankenphp_prod_builder /usr/local/etc/php/app.conf.d /usr/local/etc/php/app.conf.d

COPY --from=frankenphp_prod_builder /etc/frankenphp/Caddyfile /etc/frankenphp/Caddyfile

# CA certificates for TLS, file/libmagic for Symfony MIME type detection
COPY --from=frankenphp_prod_builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
COPY --from=frankenphp_prod_builder /usr/bin/file /usr/bin/file
COPY --from=frankenphp_prod_builder /usr/lib/file/magic.mgc /usr/lib/file/magic.mgc

ENV XDG_CONFIG_HOME=/config XDG_DATA_HOME=/data

Expand All @@ -156,7 +159,7 @@ RUN <<-EOF
find / -perm /6000 -type f -exec chmod a-s {} + 2>/dev/null || true
EOF

COPY --link --exclude=var --from=frankenphp_prod_builder /app /app
COPY --link --from=frankenphp_prod_builder /app /app
COPY --chown=www-data:www-data --from=frankenphp_prod_builder /app/src/logs /app/src/logs

COPY --link --chmod=755 frankenphp/docker-entrypoint.sh /usr/local/bin/docker-entrypoint
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2017-2025 Laurent LEGAZ
Copyright (c) 2026 Laurent LEGAZ

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
84 changes: 80 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[![CI](https://github.com/llegaz/frankenphp-slim/actions/workflows/ci.yaml/badge.svg)](https://github.com/llegaz/frankenphp-slim/actions/workflows/ci.yaml)

This project is largely inspired from [Kévin Dunglas](https://dunglas.dev)'s project Symfony Docker. it aims to provide a ready to use install for a slim project using frankenPHP server and vulcain / mercure technologies for SSE as well.
This project is largely inspired from [Kévin Dunglas](https://dunglas.dev)'s project [Symfony Docker](https://github.com/dunglas/symfony-docker), it aims to provide a ready to use install for a slim project using frankenPHP server and vulcain / mercure technologies for SSE and hot reloading.

## Getting Started

Expand All @@ -19,7 +19,7 @@ This project is largely inspired from [Kévin Dunglas](https://dunglas.dev)'s pr
4. Open `https://localhost` in your favorite web browser
5. Run `docker compose down --remove-orphans` to stop the Docker containers.

## Set the freshly generated Caddy certificate into your local browser
## Add the authority to the trust store of the host
```bash
docker cp <container_name>:/data/caddy/pki/authorities/local/root.crt ./caddy-root.crt
```
Expand Down Expand Up @@ -50,15 +50,91 @@ sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keyc
- [Vulcain](https://vulcain.rocks) support
- [Hot Reloading](https://frankenphp.dev/docs/hot-reload/)
- Rootless, slim production image
- This project should have a native [XDebug](docs/xdebug.md) integration (but I did not test it yet)
- This project should have a native [XDebug](docs/xdebug.md) integration (sole point that I did not test here yet)

**Enjoy!**

## Deploying

Copy your project on the server using `git clone`, `scp`, or any other tool
that may fit your need.
If you use GitHub, you may want to use [a deploy key](https://docs.github.com/en/free-pro-team@latest/developers/overview/managing-deploy-keys#deploy-keys).
Deploy keys are also [supported by GitLab](https://docs.gitlab.com/user/project/deploy_keys/).

Example with Git:

```console
git clone git@github.com:<username>/<project-name>.git
```

Go into the directory containing your project (`<project-name>`),
and start the app in production mode:

```console
# Build fresh production image
docker compose -f compose.yaml -f compose.prod.yaml build --pull --no-cache

# Start container
SERVER_NAME=your-domain-name.example.com \
APP_SECRET=ChangeMe \
CADDY_MERCURE_JWT_SECRET=ChangeThisMercureHubJWTSecretKey \
docker compose -f compose.yaml -f compose.prod.yaml up --wait
```

Be sure to replace `your-domain-name.example.com` with your actual domain name
and to set the values of `APP_SECRET`, `CADDY_MERCURE_JWT_SECRET`
to cryptographically secure random values.

Your server is up and running, and a HTTPS certificate has been automatically
generated for you.
Go to `https://your-domain-name.example.com` and **enjoy!**

> [!CAUTION]
>
> Docker can have a cache layer, make sure you have the right build
> for each deployment or rebuild your project with `--no-cache` option
> to avoid cache issues.

## Disabling HTTPS

Alternatively, if you don't want to expose an HTTPS server but only an HTTP one,
run the following command:

```console
SERVER_NAME=:80 \
APP_SECRET=ChangeMe \
CADDY_MERCURE_JWT_SECRET=Key \
docker compose -f compose.yaml -f compose.prod.yaml up --wait
```

## Deploying on Multiple Nodes

If you want to deploy your app on a cluster of machines, you can use [Docker Swarm](https://docs.docker.com/engine/swarm/stack-deploy/),
which is compatible with the provided Compose files.
To deploy on Kubernetes, take a look
at [the Helm chart provided with API Platform](https://api-platform.com/docs/deployment/kubernetes/),
which can be easily adapted for use with Symfony Docker.

## Passing local environment variables to containers

By default, `.env.local` and `.env.*.local` files are excluded from production images.
If you want to pass them to your containers, you can use the [`env_file` attribute](https://docs.docker.com/compose/how-tos/environment-variables/set-environment-variables/#use-the-env_file-attribute):

```yaml
# compose.prod.yaml

services:
php:
env_file:
- .env.prod.local
# ...
```

## License

frankenphp-slim is available under the MIT License.

## Credits

By [Laurent Legaz](http://laurent.legaz.eu), largely inspired from [Kévin Dunglas](https://dunglas.dev)'s project Symfony Docker.
By [Laurent Legaz](http://laurent.legaz.eu), largely inspired from [Kévin Dunglas](https://dunglas.dev)'s project [Symfony Docker](https://github.com/dunglas/symfony-docker).

Loading