This tutorial will show you how to set up an Apache/PHP website in docker using docker-compose. It will show you a script to simplify the update process so Apache and PHP versions are easily updatable (if desired).
Furthermore, it will add git integration. This will make it possible to push updates to your website from a remote machine. “Simply push to the master branch and the changes are live.”
Prerequisites
This tutorial works for Linux systems.
For the next instructions to work, the following packages must be installed:
dockerdocker-composegitvim(or any other text-editor)
Installing Apache and PHP

Let’s start by installing the Apache and PHP website. In this case PHP version 7.4. Visit Docker Hub for more information about this container and future releases.

For this website we will use docker-compose. Simply create a new file called docker-compose.yml and add the following contents.
version: '3'
services:
php-apache:
container_name: website
image: php:7.4-apache
restart: always
volumes:
- ./html:/var/www/html
Then to start the website, run:
docker-compose up -d
This will make a html folder in the project directory. That is where the actual website (i.e. index.php) is stored.
Adding git repository

Create a new folder in the project directory (so besides docker-compose.yml and html) called repo.git. Then navigate into this folder.
mkdir repo.git
cd repo.git
Now, create a bare git repository from the current working directory by executing.
git init --bare
To update the html directory every time a new commit is pushed to the git repository, we will add a post-receive hook.
Inside the repo.git directory there is folder called hooks. Create a new file within hooks called post-receive (no extension). Copy the below script into this file.
#!/bin/sh
GIT_WORK_TREE=/home/[username]/path/to/html git checkout -f
The GIT_WORK_TREE path should lead to the html folder created by docker-compose earlier. If you are not sure what the path is, use pwd within that folder.
To connect our html folder to repository, navigate to the html folder and initialise it. Than add an origin. This will be repo.git that we just created.
git init
git remote add origin [username]@localhost:path/to/repo.git
Changing html from a remote machine
It is now possible to connect with the website from a remote machine (other than the server). To do this, make a folder and execute the following command. Replace [username] with your username and [domainname] with the domain or IP address of your server.
git clone [username]@[domainname]:path/to/repo.git
This will create a copy of your website on the remote machine. For ease of explaining, let’s change the name of the folder to website.
Up the security
All the actual website files (like index.php) will go into the html folder, and will thus be available to the internet. However, sinds this folder is now a git repository, it is good practice to deny access to the .git directory. This can be done on the remote machine.
So open the website folder and create a .htaccess file with the following lines.
# Deny access to the .git folder.
RedirectMatch 404 /\.git
When the file is created. Add the changes by executing…
git add .
Than create a commit…
git commit -m "Added .htaccess to deny access to git folder"
And finally, upload them to the website…
git push origin master
The push should trigger the post-receive hook at the server and update the website contents automatically. To verify this, go to the html directory on the server and check if the .htaccess file is added.
Updating Apache and PHP
To make updating the website fast and easy, we will create an update.sh script. This script will download the latest image, restart the website with this new image, and remove the old one. The actual website contents (the html folder) will not be touched and thus remain unchanged.
#!/bin/sh
docker-compose pull
docker-compose up -d --remove-orphans
docker image prune
To make the script executable run the following command. Please note that you may need root privileges to do this.
chmod +x update.sh
Then, whenever you want to update the website to the latest docker image, run:
./update.sh