Architecture | Features | Examples] | Environment variables | Volumes
- Serve static files
- Serve PHP files with PHP-FPM
- Serve PHP files with PHP-FPM and sync local permissions
- Serve PHP files with PHP-FPM over HTTPS
- Act as a Reverse Proxy for NodeJS
- Act as a Reverse Proxy for Websocket
- Fully functional LEMP stack with Mass vhosts
- Docker Compose
This example creates the main (default) vhost, which only serves static files.
- Vhost: main (default)
- Backend: none
🛈 With no further configuration, the webserver expects files to be served by the main vhost in:
/var/www/default/htdocs
.
- Create a static page
mkdir -p www/htdocs echo '<h1>It works</h1>' > www/htdocs/index.html
- Start the webserver
docker run -d -it \ -p 9090:80 \ -v $(pwd)/www:/var/www/default \ devilbox/apache-2.4
- Verify
curl http://localhost:9090
This example creates the main (default) vhost, which contacts a remote PHP-FPM host to serve PHP files.
- Vhost: main (default)
- Backend: PHP-FPM
PHP-FPM Reference Images |
---|
🛈 For this to work, the
$(pwd)/www
directory must be mounted into the webserver container as well as into the php-fpm container.
🛈 With no further configuration, the webserver expects files to be served by the main vhost in:/var/www/default/htdocs
.
- Create a helo world page
mkdir -p www/htdocs echo '<?php echo "hello from php";' > www/htdocs/index.php
- Start the PHP-FPM container
docker run -d -it \ --name php \ -v $(pwd)/www:/var/www/default \ devilbox/php-fpm:8.2-base
- Start the webserve, linking it to the PHP-FPM container
docker run -d -it \ -p 9090:80 \ -v $(pwd)/www:/var/www/default \ -e MAIN_VHOST_BACKEND='conf:phpfpm:tcp:php:9000' \ --link php \ devilbox/apache-2.4
- Verify
curl http://localhost:9090
The same as the previous example, but also ensures that you can edit files locally and have file ownerships synced with webserver and PHP-FPM container.
See Syncronize File System Permissions for details
- Vhost: main (default)
- Backend: PHP-FPM
- Feature:
uid
andgid
are synced
🛈 For this to work, the
$(pwd)/www
directory must be mounted into the webserver container as well as into the php-fpm container.
🛈 With no further configuration, the webserver expects files to be served by the main vhost in:/var/www/default/htdocs
.
🛈NEW_UID
andNEW_GID
are set to your local users' value
- Create a helo world page
mkdir -p www/htdocs echo '<?php echo "hello from php";' > www/htdocs/index.php
- Start the PHP-FPM container
docker run -d -it \ --name php \ -v $(pwd)/www:/var/www/default \ -e NEW_UID=$(id -u) \ -e NEW_GID=$(id -g) \ devilbox/php-fpm:8.2-base
- Start the webserve, linking it to the PHP-FPM container
docker run -d -it \ -p 9090:80 \ -v $(pwd)/www:/var/www/default \ -e NEW_UID=$(id -u) \ -e NEW_GID=$(id -g) \ -e MAIN_VHOST_BACKEND='conf:phpfpm:tcp:php:9000' \ --link php \ devilbox/apache-2.4
- Verify
curl http://localhost:9090
- Explanation: Whenever a file is created by the webserver (e.g.: file uploads) or the PHP-FPM process (e.g.: php creates a file on the filesystem), it is done with the same permissions as your local operating system user. This means you can easily edit files in your IDE/editor and do not come accross permission issues.
The same as the previous example, just with the addition of enabling SSL (HTTPS).
This example shows the SSL type redir
, which makes the webserver redirect any HTTP requests to HTTPS.
Additionally we are mounting the ./ca
directory into the container under /ca
. After startup you will find generated Certificate Authority files in there, which you could import into your browser.
- Vhost: main (default)
- Backend: Reverse Proxy
- Features:
uid
andgid
are synced and SSL (redirect)
🛈 For this to work, the
$(pwd)/www
directory must be mounted into the webserver container as well as into the php-fpm container.
🛈 With no further configuration, the webserver expects files to be served by the main vhost in:/var/www/default/htdocs
.
- Create a helo world page
mkdir -p www/htdocs echo '<?php echo "hello from php";' > www/htdocs/index.php
- Start the PHP-FPM container
docker run -d -it \ --name php \ -e NEW_UID=$(id -u) \ -e NEW_GID=$(id -g) \ -v $(pwd)/www:/var/www/default \ devilbox/php-fpm:8.2-base
- Start the webserve, linking it to the PHP-FPM container
docker run -d -it \ -p 80:80 \ -p 443:443 \ -v $(pwd)/www:/var/www/default \ -v $(pwd)/ca:/ca \ -e NEW_UID=$(id -u) \ -e NEW_GID=$(id -g) \ -e MAIN_VHOST_BACKEND='conf:phpfpm:tcp:php:9000' \ -e MAIN_VHOST_SSL_TYPE='redir' \ --link php \ devilbox/apache-2.4
- Verify redirect
curl -I http://localhost
- Verify HTTPS
curl -k https://localhost
The following example proxies all HTTP requests to a NodeJS remote backend. You could also enable SSL on the webserver in order to access NodeJS via HTTPS.
- Vhost: main (default)
- Backend: Reverse Proxy
🛈 No files need to be mounted into the webserver, as content is coming from the NodeJS server.
- Create a NodeJS application
mkdir -p src cat << EOF > src/app.js const http = require('http'); const server = http.createServer((req, res) => { res.statusCode = 200; res.setHeader('Content-Type', 'text/plain'); res.write('[OK]\n'); res.write('NodeJS is running\n'); res.end(); }); server.listen(3000, '0.0.0.0'); EOF
- Start the NodeJS container
docker run -d -it \ --name nodejs \ -v $(pwd)/src:/app \ node:19-alpine node /app/app.js
- Start Reverse Proxy
docker run -d -it \ -p 80:80 \ -e MAIN_VHOST_BACKEND='conf:rproxy:http:nodejs:3000' \ --link nodejs \ devilbox/apache-2.4
- Verify
curl http://localhost
The following example proxies all HTTP requests to a Websocket remote backend. You could also enable SSL on the webserver in order to access the websocket backend via HTTPS.
- Vhost: main (default)
- Backend: Reverse Proxy (with websocket support)
🛈 No files need to be mounted into the webserver, as content is coming from the websocket server.
- Create a websocket server application
# Create source directory mkdir -p src # websocket server application cat << EOF > src/index.js const WebSocket = require("ws"); const wss = new WebSocket.Server({ port: 3000 }); wss.on("connection", (ws) => { ws.send("hello client, you are connected to me"); ws.on("message", (message) => { console.log("New message from client: %s", message); }); }); console.log("WebSocket server ready at localhost:3000"); EOF # package.json cat << EOF > src/package.json { "name": "node-websocket-example", "version": "1.0.0", "main": "index.js", "devDependencies": {}, "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "description": "", "dependencies": { "ws": "^7.5.1" } } EOF # Startup script cat << EOF > src/start.sh #!/bin/sh npm install node index.js EOF
- Start the Websocket server container
docker run -d -it \ --name websocket \ -v $(pwd)/src:/app \ -w /app \ node:19-alpine sh start.sh
- Start Reverse Proxy
docker run -d -it \ -p 80:80 \ -e MAIN_VHOST_BACKEND='conf:rproxy:ws:websocket:3000' \ --link websocket \ devilbox/apache-2.4
- Verify
# On your host system npm install -g wscat wscat --connect localhost Connected (press CTRL+C to quit) < hello client, you are connected to me >
The following example creates a dynamic setup. Each time you create a new project directory below www/
, a new virtual host is being created.
Additionally all projects will have the .com
suffix added to their domain name, which results in <project>.com
as the final domain.
- Vhost: mass (unlimited vhosts)
- Backend: PHP-FPM
🛈 For this to work, the
$(pwd)/www
directory must be mounted into the webserver container as well as into the php-fpm container.
🛈 With no further configuration, the webserver expects files to be served by the mass vhost in:/shared/httpd/<project>/htdocs
, where<project>
is a placeholder for any directory.
- Create the project base directory
mkdir -p www
- Start the MySQL container (only for demonstration purposes)
docker run -d -it \ --name mysql \ -e MYSQL_ROOT_PASSWORD=my-secret-pw \ devilbox/mysql:mariadb-10.10
- Start the PHP-FPM container
docker run -d -it \ --name php \ -v $(pwd)/www:/shared/httpd \ devilbox/php-fpm:8.2-base
- Start the webserver container, linking it to the two above
docker run -d -it \ -p 8080:80 \ -v $(pwd)/www:/shared/httpd \ -e MAIN_VHOST_ENABLE=0 \ -e MASS_VHOST_ENABLE=1 \ -e MASS_VHOST_TLD_SUFFIX=.com \ -e MASS_VHOST_BACKEND='conf:phpfpm:tcp:php:9000' \ --link php \ --link mysql \ devilbox/apache-2.4
- Create
project-1
mkdir -p www/project-1/htdocs echo '<?php echo "hello from project-1";' > www/project-1/htdocs/index.php
- Verify
project-1
curl -H 'Host: project-1.com' http://localhost:8080
- Create
another
mkdir -p www/another/htdocs echo '<?php echo "hello from another";' > www/another/htdocs/index.php
- Verify
another
curl -H 'Host: another.com' http://localhost:8080
- Add more projects as you wish...
Have a look at the examples directory. It is packed with all kinds of Docker Compose
examples:
- SSL
- PHP-FPM remote server
- Python and NodeJS Reverse Proxy
- Mass virtual hosts
- Mass virtual hosts with PHP-FPM, Python and NodeJS as backends