https://github.com/dazz/s6-nginx-php-fpm
Run nginx and php-fpm in one container supervised by s6-overlay
https://github.com/dazz/s6-nginx-php-fpm
docker nginx php-fpm s6-overlay
Last synced: 8 months ago
JSON representation
Run nginx and php-fpm in one container supervised by s6-overlay
- Host: GitHub
- URL: https://github.com/dazz/s6-nginx-php-fpm
- Owner: dazz
- Created: 2023-11-15T09:45:03.000Z (about 2 years ago)
- Default Branch: main
- Last Pushed: 2024-09-22T07:15:41.000Z (over 1 year ago)
- Last Synced: 2025-05-07T06:10:04.722Z (8 months ago)
- Topics: docker, nginx, php-fpm, s6-overlay
- Language: Shell
- Homepage:
- Size: 26.4 KB
- Stars: 14
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# S6 nginx/php-fpm container
## usage
This is a simple container with nginx and php-fpm based on alpine linux.
To install all the dependencies and build the container run:
```bash
make up
```
## What is this about
We often have the case that we need to deploy our PHP application to `$server`, but since PHP does not come with its own
webserver we always run a second container which passes the requests to our PHP process.
We looked into many options and decided against them for different reasons.
- **Kubernetes:** Overkill for a PHP-Application
- **Docker Compose:** Not recommended in production, not well documented
- **FrankenPHP:** Not stable enough (at the time), written in go, compiles PHP
- **SupervisorD:** Not recommended for running as PID 1 in a dockerized environment
- **SystemD:** Not available for alpine (package requires gclib)
- **s6-overlay:** Works like a charm in ubuntu (glibc) and alpine (musl) and is made for running as PID 1 in container
## What are the components
We installed just an index file in the `app` directory to showcase a running php application.
- Alpine
- s6-overlay
- nginx
- php-fpm
We use preconfigured user `www-data` and install the app in `var/www/html`.
## s6-overlay
- starts PID 1 with `ENTRYPOINT ["/init"]`
- starts all services and scripts that are defined in `/etc/s6-overlay/s6-rc.d/user/contents.d`
## Recipes
Use cases and how they can be solved using s6
### Feature Flags
Sometimes you need to enable or disable services.
> s6-rc wasn't made for dynamic service sets; it was made for reliability and predictability of the machine state,
> which runtime changes are bad for - and you're going against its design by attempting to conditionally start services.
> The way to achieve what you want is by making sure that only the services you want to activate are in s6-rc's user
> bundle, which contains everything that will be started. For that purpose, you have the S6_STAGE2_HOOK environment variable:
> in it, put the path to a script, and that script will be run before s6-rc analyzes its service set.
> That script should be the one to read your environment variables, and adjust the files of /etc/s6-overlay/s6-rc.d/user/contents accordingly.
```yaml
# docker-compose.yml
services:
app:
environment:
S6_STAGE2_HOOK: /etc/s6-hook/feature-toggle
FEATURE_MIGRATIONS_ENABLED: "false"
```
#### /etc/s6-hook/feature-toggle
```shell
#!/command/with-contenv sh
# Read environment variable and default to "false" if not set
INIT_MIGRATIONS="${FEATURE_MIGRATIONS_ENABLED:-false}"
# Define a space-separated list of feature toggles (since arrays are not supported in sh)
# the feature name is the upper SNAKE_CASE version of the feature directory name in lower kebab-case
features="INIT_MIGRATIONS"
# Iterate through each feature toggle
for feature in $features; do
# Get the value of the environment variable, default to "false" if not set
is_enabled=$(eval echo \${$feature:-false})
# Convert the feature name to lowercase and replace underscores with hyphens
feature_file=$(echo "$feature" | tr 'A-Z' 'a-z' | tr '_' '-')
# Check if the feature is enabled
if [ "$is_enabled" = "true" ]; then
touch "/etc/s6-overlay/s6-rc.d/user/contents.d/$feature_file"
else
rm -f "/etc/s6-overlay/s6-rc.d/user/contents.d/$feature_file"
fi
done
exit 0
```
### Doctrine Migrations
```shell []
/etc/s6-overlay/s6-rc.d
├── init-migrations
│ ├── dependencies.d
│ │ └── svc-php-fpm
│ ├── type
│ └── up
└── scripts
└── init-migrations
```
```shell []
#!/command/with-contenv sh
s6-setuidgid www-data
php /var/www/html/bin/console doctrine:migrations:migrate --env=`printcontenv APP_ENV` --no-interaction
php /var/www/html/bin/console doctrine:migrations:status --env=`printcontenv APP_ENV`
```
### CronJobs with Symfony Scheduler Component
```shell []
/etc/s6-overlay/s6-rc.d
├── svc-scheduler
│ ├── dependencies.d
│ │ └── svc-php-fpm
│ ├── type
│ └── up
└── scripts
└── svc-scheduler
```
```shell []
#!/command/with-contenv sh
s6-setuidgid www-data
php /var/www/html/bin/console messenger:consume scheduler_default \
--time-limit=300 \
--limit=10 \
--env=`printcontenv APP_ENV` --quiet
```
### check requirements in dev
```shell []
/etc/s6-overlay/s6-rc.d
├── init-dependencies
│ ├── dependencies.d
│ │ ├── base
│ │ └── svc-php-fpm
│ ├── type
│ └── up
└── scripts
└── init-dependencies
```
```shell []
#!/command/with-contenv sh
# Check if the composer binary exists
if command -v composer >/dev/null 2>&1; then
# Composer is installed, run composer install
echo "init-dependencies: info: Composer found. Checking dependencies."
composer -d /var/www/html check-platform-reqs
exit 0
fi
echo "init-dependencies: info: Composer not found. Please install Composer before running this script."
exit 0
```