Skip to content

Commit b2e8153

Browse files
committed
add non-root user documentation
1 parent dab1308 commit b2e8153

File tree

2 files changed

+162
-8
lines changed

2 files changed

+162
-8
lines changed

README.md

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,15 @@ with [FrankenPHP](https://frankenphp.dev) and [Caddy](https://caddyserver.com/)
3333
1. [Options available](docs/options.md)
3434
2. [Using Symfony Docker with an existing project](docs/existing-project.md)
3535
3. [Support for extra services](docs/extra-services.md)
36-
4. [Deploying in production](docs/production.md)
37-
5. [Debugging with Xdebug](docs/xdebug.md)
38-
6. [TLS Certificates](docs/tls.md)
39-
7. [Using MySQL instead of PostgreSQL](docs/mysql.md)
40-
8. [Using Alpine Linux instead of Debian](docs/alpine.md)
41-
9. [Using a Makefile](docs/makefile.md)
42-
10. [Updating the template](docs/updating.md)
43-
11. [Troubleshooting](docs/troubleshooting.md)
36+
4. [Run as non-root](docs/non-root-user.md)
37+
5. [Deploying in production](docs/production.md)
38+
6. [Debugging with Xdebug](docs/xdebug.md)
39+
7. [TLS Certificates](docs/tls.md)
40+
8. [Using MySQL instead of PostgreSQL](docs/mysql.md)
41+
9. [Using Alpine Linux instead of Debian](docs/alpine.md)
42+
10. [Using a Makefile](docs/makefile.md)
43+
11. [Updating the template](docs/updating.md)
44+
12. [Troubleshooting](docs/troubleshooting.md)
4445

4546
## License
4647

docs/non-root-user.md

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
# Non-root user
2+
3+
Following [Docker best practices](https://docs.docker.com/build/building/best-practices/#user), it is recommended to run your services as non-root user whenever possible.
4+
5+
## Apply changes
6+
7+
You can apply the following patches to your `Dockerfile`, `compose.override.yaml` and `compose.prod.yaml` to run the FrankenPHP container as non-root for development and production usage.
8+
9+
`Dockerfile`
10+
11+
```diff
12+
+ARG PUID=${PUID:-1000}
13+
+ARG PGID=${PGID:-1000}
14+
+ARG USER=${USER:-frankenphp}
15+
+ARG GROUP=${GROUP:-frankenphp}
16+
17+
# Versions
18+
FROM dunglas/frankenphp:1-php8.4 AS frankenphp_upstream
19+
20+
# Base FrankenPHP image
21+
FROM frankenphp_upstream AS frankenphp_base
22+
23+
+ARG PUID
24+
+ARG PGID
25+
+ARG USER
26+
+ARG GROUP
27+
+
28+
WORKDIR /app
29+
30+
-VOLUME /app/var/
31+
32+
# ...
33+
34+
+RUN set -eux; \
35+
+ groupadd -g $PGID $GROUP; \
36+
+ useradd -u $PUID -g $PGID --no-create-home $USER; \
37+
+ mkdir -p var/cache var/log; \
38+
+ chown -R $PUID:$PGID /data/ /config/ var/
39+
+
40+
ENTRYPOINT ["docker-entrypoint"]
41+
42+
# ...
43+
44+
# Dev FrankenPHP image
45+
FROM frankenphp_base AS frankenphp_dev
46+
47+
+ARG USER
48+
+
49+
ENV APP_ENV=dev
50+
ENV XDEBUG_MODE=off
51+
ENV FRANKENPHP_WORKER_CONFIG=watch
52+
53+
COPY --link frankenphp/conf.d/20-app.dev.ini $PHP_INI_DIR/app.conf.d/
54+
55+
+USER $USER
56+
+
57+
CMD [ "frankenphp", "run", "--config", "/etc/frankenphp/Caddyfile", "--watch" ]
58+
59+
# Prod FrankenPHP image
60+
FROM frankenphp_base AS frankenphp_prod
61+
62+
+ARG PUID
63+
+ARG PGID
64+
+ARG USER
65+
+
66+
ENV APP_ENV=prod
67+
68+
# ...
69+
70+
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
71+
composer dump-autoload --classmap-authoritative --no-dev; \
72+
composer dump-env prod; \
73+
composer run-script --no-dev post-install-cmd; \
74+
- chmod +x bin/console; sync;
75+
+ chmod +x bin/console; \
76+
+ chown -R $PUID:$PGID var/; sync
77+
+
78+
+USER $USER
79+
```
80+
81+
`compose.override.yaml`
82+
83+
```yaml
84+
services:
85+
php:
86+
build:
87+
context: .
88+
target: frankenphp_dev
89+
+ args:
90+
+ PUID: ${PUID:-1000}
91+
+ PGID: ${PGID:-1000}
92+
+ user: "${PUID:-1000}:${PGID:-1000}"
93+
```
94+
95+
`compose.prod.yaml`
96+
97+
```yaml
98+
services:
99+
php:
100+
build:
101+
context: .
102+
target: frankenphp_prod
103+
+ args:
104+
+ PUID: ${PUID:-1000}
105+
+ PGID: ${PGID:-1000}
106+
+ user: "${PUID:-1000}:${PGID:-1000}"
107+
```
108+
109+
## Usage
110+
111+
After applying the previous changes, you have to pass the `PUID` and `PGID` as environment variables to the Dockerfile.
112+
113+
You can do this in a myriad of different ways:
114+
115+
- Export your `PUID` and `PGID` to your current shell before running `docker compose`.
116+
117+
```console
118+
export PUID=$(id -u); export PGID=$(id -g); docker compose ...
119+
```
120+
121+
- Pass `PUID` and `PGID` directly to `docker compose`.
122+
123+
```console
124+
PUID=$(id -u) PGID=$(id -g) docker compose ...
125+
```
126+
127+
- Add `PUID` and `PGID` to your dotenv (`.env`) file.
128+
129+
```dotenv
130+
PUID=1000
131+
PGID=1000
132+
```
133+
134+
> [!CAUTION]
135+
> This method is not recommended as it can cause issues in CI environment where the runner has a different UID/GID.
136+
137+
- Use third-party tools, like [`Task`](https://taskfile.dev/), to do the heavy lifting for you.
138+
139+
```yaml
140+
version: "3"
141+
142+
env:
143+
PUID:
144+
sh: id -u
145+
PGID:
146+
sh: id -g
147+
148+
tasks:
149+
up:
150+
desc: Up stack
151+
cmds:
152+
- docker compose ...
153+
```

0 commit comments

Comments
 (0)