{"id":69,"date":"2022-09-29T20:27:01","date_gmt":"2022-09-29T18:27:01","guid":{"rendered":"https:\/\/blog.douwedevri.es\/?p=69"},"modified":"2025-02-19T01:03:10","modified_gmt":"2025-02-18T23:03:10","slug":"apache-php-website-in-docker-with-git-integration","status":"publish","type":"post","link":"https:\/\/blog.dbdv.nl\/?p=69","title":{"rendered":"Apache\/PHP website in Docker with git integration"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">This tutorial will show you how to set up an <strong>Apache\/PHP<\/strong> website in docker using <strong>docker-compose<\/strong>. It will show you a script to <strong>simplify the update process<\/strong> so Apache and PHP versions are easily updatable (if desired).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Furthermore, it will add <strong>git integration<\/strong>. This will make it possible to push updates to your website from a remote machine. &#8220;Simply push to the master branch and the changes are live.&#8221;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Prerequisites<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">This tutorial works for&nbsp;<strong>Linux&nbsp;<\/strong>systems.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For the next instructions to work, the following packages must be installed:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>docker<\/code><\/li>\n\n\n\n<li><code>docker-compose<\/code><\/li>\n\n\n\n<li><code>git<\/code><\/li>\n\n\n\n<li><code>vim<\/code> (or any other text-editor)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Installing Apache and PHP<\/h3>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"553\" height=\"270\" src=\"https:\/\/blog.douwedevri.es\/wp-content\/uploads\/2022\/09\/30eecf10.png\" alt=\"\" class=\"wp-image-89\" style=\"width:350px;height:170px\" srcset=\"https:\/\/blog.dbdv.nl\/wp-content\/uploads\/2022\/09\/30eecf10.png 553w, https:\/\/blog.dbdv.nl\/wp-content\/uploads\/2022\/09\/30eecf10-300x146.png 300w\" sizes=\"auto, (max-width: 553px) 100vw, 553px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s start by installing the Apache and PHP website. In this case PHP version 7.4.  Visit <a href=\"https:\/\/hub.docker.com\/_\/php?tab=description&amp;name=7.4-apache\">Docker Hub<\/a> for more information about this container and future releases.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"492\" src=\"https:\/\/blog.douwedevri.es\/wp-content\/uploads\/2022\/09\/docker-compose-button-661887138-1024x492.jpeg\" alt=\"\" class=\"wp-image-90\" style=\"width:529px;height:254px\" srcset=\"https:\/\/blog.dbdv.nl\/wp-content\/uploads\/2022\/09\/docker-compose-button-661887138-1024x492.jpeg 1024w, https:\/\/blog.dbdv.nl\/wp-content\/uploads\/2022\/09\/docker-compose-button-661887138-300x144.jpeg 300w, https:\/\/blog.dbdv.nl\/wp-content\/uploads\/2022\/09\/docker-compose-button-661887138-768x369.jpeg 768w, https:\/\/blog.dbdv.nl\/wp-content\/uploads\/2022\/09\/docker-compose-button-661887138-1536x738.jpeg 1536w, https:\/\/blog.dbdv.nl\/wp-content\/uploads\/2022\/09\/docker-compose-button-661887138-1568x753.jpeg 1568w, https:\/\/blog.dbdv.nl\/wp-content\/uploads\/2022\/09\/docker-compose-button-661887138.jpeg 1851w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">For this website we will use docker-compose. Simply create a new file called <code>docker-compose.yml<\/code> and add the following contents.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"\" class=\" line-numbers\">version: '3'\n\nservices:\nphp-apache:\ncontainer_name: website\nimage: php:7.4-apache\nrestart: always\nvolumes:\n- .\/html:\/var\/www\/html<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then to start the website, run:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash line-numbers\">docker-compose up -d<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This will make a <code>html<\/code> folder in the project directory. That is where the actual website (i.e. index.php) is stored.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Adding git repository<\/h3>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"647\" height=\"270\" src=\"https:\/\/blog.douwedevri.es\/wp-content\/uploads\/2022\/09\/d11b358b.png\" alt=\"\" class=\"wp-image-92\" style=\"width:272px;height:114px\" srcset=\"https:\/\/blog.dbdv.nl\/wp-content\/uploads\/2022\/09\/d11b358b.png 647w, https:\/\/blog.dbdv.nl\/wp-content\/uploads\/2022\/09\/d11b358b-300x125.png 300w\" sizes=\"auto, (max-width: 647px) 100vw, 647px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Create a new folder in the project directory (so besides <code>docker-compose.yml<\/code> and <code>html<\/code>) called <code>repo.git<\/code>. Then navigate into this folder.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash line-numbers\">mkdir repo.git\ncd repo.git<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Now, create a <strong>bare<\/strong> git repository from the current working directory by executing.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash line-numbers\">git init --bare<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">To update the html directory every time a new commit is pushed to the git repository, we will add a <strong>post-receive hook<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Inside the <code>repo.git<\/code> directory there is folder called hooks. Create a new file within hooks called <code>post-receive<\/code> (no extension). Copy the below script into this file.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash line-numbers\">#!\/bin\/sh\n\nGIT_WORK_TREE=\/home\/[username]\/path\/to\/html git checkout -f<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">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 <code>pwd<\/code> within that folder.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">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.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash line-numbers\">git init<br>git remote add origin [username]@localhost:path\/to\/repo.git<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Changing html from a remote machine<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">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 <code>[username]<\/code> with your username and <code>[domainname]<\/code> with the domain or IP address of your server.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash line-numbers\">git clone [username]@[domainname]:path\/to\/repo.git<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This will create a copy of your website on the remote machine. For ease of explaining, let&#8217;s change the name of the folder to <code>website<\/code>.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Up the security<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">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.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So open the <code>website<\/code> folder and create a <code>.htaccess<\/code> file with the following lines.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash line-numbers\"># Deny access to the .git folder.\nRedirectMatch 404 \/\\.git<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">When the file is created. Add the changes by executing&#8230;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash line-numbers\">git add .<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Than create a commit&#8230;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash line-numbers\">git commit -m \"Added .htaccess to deny access to git folder\"<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">And finally, upload them to the website&#8230;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash line-numbers\">git push origin master<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The push should trigger the <strong>post-receive hook<\/strong> at the server and update the website contents automatically. To verify this, go to the html directory on the server and check if the <code>.htaccess<\/code> file is added.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Updating Apache and PHP<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">To make updating the website fast and easy, we will create an <code>update.sh<\/code> 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.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash line-numbers\">#!\/bin\/sh\n\ndocker-compose pull\ndocker-compose up -d --remove-orphans\ndocker image prune<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">To make the script executable run the following command. Please note that you may need root privileges to do this.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash line-numbers\">chmod +x update.sh<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then, whenever you want to update the website to the latest docker image, run:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash line-numbers\">.\/update.sh<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>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 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":89,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[10,7,11,12,5,9],"class_list":["post-69","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tech","tag-apache","tag-docker","tag-docker-compose","tag-git","tag-linux","tag-php"],"_links":{"self":[{"href":"https:\/\/blog.dbdv.nl\/index.php?rest_route=\/wp\/v2\/posts\/69","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.dbdv.nl\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.dbdv.nl\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.dbdv.nl\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.dbdv.nl\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=69"}],"version-history":[{"count":24,"href":"https:\/\/blog.dbdv.nl\/index.php?rest_route=\/wp\/v2\/posts\/69\/revisions"}],"predecessor-version":[{"id":238,"href":"https:\/\/blog.dbdv.nl\/index.php?rest_route=\/wp\/v2\/posts\/69\/revisions\/238"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.dbdv.nl\/index.php?rest_route=\/wp\/v2\/media\/89"}],"wp:attachment":[{"href":"https:\/\/blog.dbdv.nl\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=69"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.dbdv.nl\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=69"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.dbdv.nl\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=69"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}