Reputation: 71
I used Podman and Podman-Compose to create Nginx and PHP-FPM with openSUSE Tumbleweed images.
The Containerfile for that Nginx container-file and the PHP-FPM container-file is shown below.
# Start with PHP 8 FPM (FastCGI Process Manager)
FROM registry.opensuse.org/opensuse/bci/php-fpm:latest
# Install PHP extensions
RUN zypper -n install \
curl \
wget \
nano \
iputils \
netcat-openbsd \
net-tools \
git \
php8 \
php8-devel \
php8-curl \
php8-zip \
php8-mbstring \
php8-fileinfo \
php8-gd \
php8-mysql \
php8-fpm \
php8-xdebug
# Add PHP config
COPY ./php-fpm/www.conf /etc/php8/fpm/php-fpm.d/www.conf
COPY ./php-fpm/php-fpm.conf /etc/php8/fpm/php-fpm.conf
COPY ./php-fpm/php.ini /etc/php8/fpm/php.ini
# Create nginx user, group
RUN groupadd -g 101 nginx && \
useradd -u 1001 -g nginx -s /sbin/nologin -M nginx
# Set permissions after adding files
RUN mkdir -p /srv/www/htdocs && \
chmod -R 755 /srv/www/htdocs && \
chmod 1777 /tmp # sticky bit for /tmp
# Set working directory.
WORKDIR /srv/www/htdocs
# Set volumes.
ADD ["htdocs", "/srv/www/htdocs"]
# What command to run
CMD ["php-fpm", "-F"]
# Document that we use port 9000, 9003
EXPOSE 9000 9003
## Set master image.
FROM registry.opensuse.org/opensuse/nginx:latest
# Install NginX.
RUN zypper -n install \
curl \
wget \
nano \
iputils \
netcat-openbsd \
net-tools \
nginx
# Add nginx user and group if they don't exist
RUN getent group nginx || groupadd -r nginx && \
getent passwd nginx || useradd -r -g nginx nginx
# Add NginX config
COPY ./nginx/nginx.conf /etc/nginx/nginx.conf
# Create directories
RUN mkdir -p /srv/www/htdocs && \
chmod -R 755 /srv/www/htdocs
# Set working directory.
WORKDIR /srv/www/htdocs
# Set volumes.
ADD ["htdocs", "/srv/www/htdocs"]
# Expose port 80, 443.
EXPOSE 80 443
# Start NginX through bash terminal.
CMD ["/bin/bash", "-c", "nginx -g 'daemon off;'"]
Also, run these Containerfile with the podman-compose command.
podman-compose -f ./podman-compose.yml up -d
version: '3.8'
services:
# PHP-FPM Service
php:
build:
context: . # Build context is current directory
dockerfile: Containerfile_PHP-FPM
image: tw-phpfpm:latest # Image name
container_name: phpfpm # Name our container
ports:
- "9003:9003" # Map port 8080 on our PC to 80 in container
volumes:
- ./htdocs:/srv/www/htdocs:Z # Mount document root
- ./php-fpm/www.conf:/etc/php8/fpm/php-fpm.d/www.conf:Z
- ./php-fpm/php-fpm.conf:/etc/php8/fpm/php-fpm.conf:Z
- ./php-fpm/php.ini:/etc/php8/fpm/php.ini:Z
privileged: true
networks:
- web_network # Connect to our network
#environment:
# PHP_IDE_CONFIG: serverName=Podman # For Xdebug
restart: unless-stopped # Make container restart unless stopped manually
security_opt:
- apparmor=unconfined
# Nginx Service
nginx:
build:
context: . # Build context is current directory
dockerfile: Containerfile_NginX
image: tw-nginx:latest # Image name
container_name: nginx
ports:
- "8080:80" # Map port 8080 on our PC to 80 in container
volumes:
- ./htdocs:/srv/www/htdocs:Z # Mount same source code
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:Z
depends_on:
- php # Wait for PHP container
links:
- php
privileged: true
networks:
- web_network
restart: unless-stopped
security_opt:
- apparmor=unconfined
networks:
web_network:
driver: bridge # Standard Podman network type
The nginx.conf file used is shown below.
# nginx.conf
events {
worker_connections 1024;
use epoll;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
sendfile on;
keepalive_timeout 65;
client_max_body_size 10M;
gzip on;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
include conf.d/*.conf;
server {
listen 80;
server_name localhost;
root /srv/www/htdocs;
index index.php;
# Basic security headers
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
location / {
root /srv/www/htdocs/;
index index.php;
try_files $uri $uri/ /index.php?$query_string;
}
error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /srv/www/htdocs/;
}
# PHP-FPM configuration
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PHP_ADMIN_VALUE "open_basedir=$document_root:/tmp/:/proc/";
fastcgi_param PHP_VALUE "upload_max_filesize=10M \n post_max_size=10M";
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
# Deny access to .htaccess files
location ~ /\.ht {
deny all;
}
}
include vhosts.d/*.conf;
}
The www.conf file used by PHP-FPM is shown below.
# www.conf
[www]
user = wwwrun
group = www
listen = php:9000
php_value[session.save_path] = /var/lib/php8/sessions
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
catch_workers_output = yes
decorate_workers_output = no
When accessing "http://localhost:8080/index.php", the web page displays "Access Denied.".
However, "http://localhost:8080/index.html" is displayed normally.
At this time, if you check the logs of the Nginx container and PHP-FPM container, you will see the following error.
$ podman logs phpfpm
[26-Nov-2024 02:58:24] NOTICE: fpm is running, pid 1
[26-Nov-2024 02:58:24] NOTICE: ready to handle connections
[26-Nov-2024 02:58:24] NOTICE: systemd monitor interval set to 10000ms
NOTICE: PHP message: PHP Warning: PHP Request Startup: Failed to open stream: Permission denied in Unknown on line 0
ERROR: Unable to open primary script: /srv/www/htdocs/index.php (Permission denied)
10.89.4.23 - 26/Nov/2024:02:58:35 +0000 "GET /index.php" 403
$ podman logs nginx
2024/11/26 03:00:54 [error] 7#7: *1 FastCGI sent in stderr: "PHP message: PHP Warning: PHP Request Startup: Failed to open stream: Permission denied
in Unknown on line 0; Unable to open primary script: /srv/www/htdocs/index.php (Permission denied)" while reading response header from upstream, clien
t: 10.89.4.27, server: localhost, request: "GET / HTTP/1.1", upstream: "fastcgi://10.89.4.26:9000", host: "localhost:8080"
10.89.4.27 - - [26/Nov/2024:03:00:54 +0000] "GET / HTTP/1.1" 403 46 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:132.0) Gecko/20100101 Firefox/132.0"
10.89.4.27 - - [26/Nov/2024:03:00:54 +0000] "GET /favicon.ico HTTP/1.1" 200 318 "http://localhost:8080/" "Mozilla/5.0 (X11; Linux x86_64; rv:132.0) Gecko/20100101 Firefox/132.0"
What is causing this error?
And how can it be made to work properly using openSUSE container?
Note that this container is openSUSE Tumbleweed, so it does not contain SELinux, etc.
Apparmor is installed on the host.
The following settings were added or edited.
user nginx;
user = nginx
group = nginx
listen = php:9000
Added nginx user and nginx group to PHP-FPM container.
$ podman exec phpfpm cat /etc/shadow
root:*:20050::::::
nobody:!:19986::::::
wwwrun:!:20050::::::
nginx:!:20053:0:99999:7:::
$ podman exec phpfpm cat /etc/group
root:x:0:
shadow:x:15:
trusted:x:42:
users:x:100:
nogroup:x:65533:
nobody:x:65534:
www:x:499:wwwrun
wwwrun:!:498:
nginx:x:101:
$ podman exec nginx cat /etc/shadow
root:*:20050::::::
nobody:!:19986::::::
nginx:!:20050::::::
$ podman exec nginx cat /etc/group
root:x:0:
shadow:x:15:
trusted:x:42:
users:x:100:
nogroup:x:65533:
nobody:x:65534:
nginx:!:499:
When I access the .php file, I still get "Access Denied".
$ podman logs phpfpm
[26-Nov-2024 02:58:24] NOTICE: fpm is running, pid 1
[26-Nov-2024 02:58:24] NOTICE: ready to handle connections
[26-Nov-2024 02:58:24] NOTICE: systemd monitor interval set to 10000ms
NOTICE: PHP message: PHP Warning: PHP Request Startup: Failed to open stream: Permission denied in Unknown on line 0
ERROR: Unable to open primary script: /srv/www/htdocs/index.php (Permission denied)
10.89.4.23 - 26/Nov/2024:02:58:35 +0000 "GET /index.php" 403
$ podman logs nginx
2024/11/26 03:00:54 [error] 7#7: *1 FastCGI sent in stderr: "PHP message: PHP Warning: PHP Request Startup: Failed to open stream: Permission denied
in Unknown on line 0; Unable to open primary script: /srv/www/htdocs/index.php (Permission denied)" while reading response header from upstream, clien
t: 10.89.4.27, server: localhost, request: "GET / HTTP/1.1", upstream: "fastcgi://10.89.4.26:9000", host: "localhost:8080"
10.89.4.27 - - [26/Nov/2024:03:00:54 +0000] "GET / HTTP/1.1" 403 46 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:132.0) Gecko/20100101 Firefox/132.0"
10.89.4.27 - - [26/Nov/2024:03:00:54 +0000] "GET /favicon.ico HTTP/1.1" 200 318 "http://localhost:8080/" "Mozilla/5.0 (X11; Linux x86_64; rv:132.0) Gecko/20100101 Firefox/132.0"
Upvotes: 0
Views: 128
Reputation: 431
In your php-fpm configuration, you have the wwwrun/www
set as user and group. That is likely the reason the NGINX process does not share similar group permissions to execute PHP scripts.
You may be able to resolve your NGINX configuration simply by adding user nginx;
to have the web server run as a Nginx user. The question is whether that Nginx user could read and write to php-fpm sockets at a /var
location.
A group permission could resolve this.
Upvotes: 0