I've followed suit to quite some instructions, tutorials, and also questions in this forum, but I can still not get this working. I've setup a REST API using a PHP Apache Docker container, and need to create a rewrite rule in my apache config to reroute API requests to index.php
(the REST controller). Currently, with what's written below, I'm getting a 404:
File Structure on local machine (listed everything except php source code; not needed here):
php
conf.d
- error_reporting.ini
- xdebug.ini
Dockerfile
index.php
apache
- apache2.conf
docker-compose.yml
The content of the Dockerfile being:
FROM php:8.1-apache
WORKDIR /var/www/html/
RUN pecl install xdebug \
&& docker-php-ext-enable xdebug \
&& a2enmod rewrite
COPY . .
EXPOSE 80
And the content of docker-compose.yml being:
services:
php:
build: ./php
depends_on:
- db
container_name: php-apache
ports:
- 80:80
volumes:
- ./php:/var/www/html
- ./php/conf.d/xdebug.ini:/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
- ./php/conf.d/error_reporting.ini:/usr/local/etc/php/conf.d/error_reporting.ini
- ./apache/apache2.conf:/etc/apache2/apache2.conf
environment:
MARIADB_HOST: localhost
MARIADB_USER: root
MARIADB_PASSWORD: top_very_secret
MARIADB_DB: apidb
adminer:
image: adminer
depends_on:
- db
restart: always
ports:
- 8080:8080
db:
image: mariadb
container_name: db
volumes:
- maria-db-storage:/var/lib/mysql
environment:
MARIADB_ROOT_PASSWORD: top_very_secret
MARIADB_DATABASE: apidb
volumes:
maria-db-storage:
Regarding the contents of apache2.conf
; I've done the following to create it on the local machine:
- Went into the container's virtual filesystem using
docker exec -t -i <container_name> /bin/bash
. - Wandered to
/etc/apache2
- Printed the file contents via
cat apache2.conf
- Copy-pasted the contents into my local
/apache/apache2.conf
file - Added the following directive lines to the end of that local file:
# Custom directives start here
# Set Server's name
ServerName 'localhost'
# Rewrite for routing of all requests through REST controller
RewriteEngine On
# If requested resource is index.php, do nothing
RewriteRule ^index\.php$ - [L]
# If requested resource is a file or directory that does not exist, reroute to REST
# controller index.php
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d
RewriteRule . /index.php [L]
After building the images and running the containers, I've checked within the container's virtual filesystem again via CLI. The /etc/apache2/apache2.conf
successfully holds the contents of my local file, and I've also done a apachectl -M
within the container, and can see rewrite_module (shared)
getting printed.
Again, I'm simply getting a 404; for example if I search for http://localhost/xyz
. Same if I do not omit the port (and search for http://localhost:80/xyz
). Searching for http://localhost
and http://localhost:80
both work; so it seems that my rewrite rules are simply not being applied.
When running apachectl configtest
within the docker container, I also get Syntax OK
.
Just guessing; does this maybe have something with xdebugs outgoing communication from the container's port 9003?
What am I missing?
Apparently serverfault is the intended place for these questions; so I posted it over there (don't know how to migrate): https://serverfault.com/questions/1115336/cant-get-apache-rewrite-to-work-on-docker-php-apache-container
CodePudding user response:
I've actually figured it out. The problem seems to be that, when using docker, you must specify the rewrite rules within the Virtual Host context of the port you've specified. At least I've done what's written above, plus the following steps:
- Within the container, I've migrated (in CLI) to the folder
etc/apache2/sites-enabled
- In there is the file
000-default.conf
, holding the default configs for the sites that are currently enabled on the concerned apache unit. As far as this application is concerned, it's thus fine to modify the default configuration, as the container will exclusively be used for this API. At least that was my thought. - So again I did the same; copy the file contents as they're shipped with an initiated docker container, via
cat 000-default.conf
. - Copy-paste the contents within the local
apache/sites-enabled/000-default.conf
file (that you newly create) - Now you take the following part that was previously in the local
apache2.conf
file (slightly improved):
# Rewrite for routing of all requests through REST controller
RewriteEngine On
RewriteRule ^index\.php$ - [L]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d
RewriteRule ^(.*)$ /index.php [L]
and paste it into the local 000-default.conf
file; before the closing </VirtualHost>
tag. Then you remove the rewrite rules from your apache/apache2.conf
file, but you leave it for the added ServerName
directive.
- You then add the path mapping to the volumes of your php container to load your custom virtual host default configuration file into your container, and you should be good to go; so your docker-compose.yml becomes:
services:
php:
....
volumes:
- ./php:/var/www/html
- ./php/conf.d/xdebug.ini:/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
- ./php/conf.d/error_reporting.ini:/usr/local/etc/php/conf.d/error_reporting.ini
- ./apache/apache2.conf:/etc/apache2/apache2.conf
- ./apache/sites-enabled/000-default.conf:/etc/apache2/sites-enabled/000-default.conf
....
Rewrite is now fully functional!