{"id":3145,"date":"2025-05-07T10:35:28","date_gmt":"2025-05-07T15:35:28","guid":{"rendered":"https:\/\/xlinesoft.com\/blog\/?p=3145"},"modified":"2025-05-07T10:35:28","modified_gmt":"2025-05-07T15:35:28","slug":"running-phprunner-application-as-a-docker-container","status":"publish","type":"post","link":"https:\/\/xlinesoft.com\/blog\/2025\/05\/07\/running-phprunner-application-as-a-docker-container\/","title":{"rendered":"Running PHPRunner application as a Docker container"},"content":{"rendered":"<p>What is Docker? Docker is a software platform that allows you to package, distribute, and run applications within self-contained units called containers. These containers include everything the application needs, like code, runtime, and libraries, ensuring consistent execution across different environments. <\/p>\n<p>How this can be useful? There are many possible uses of Docker containers. You can use them for testing for instance. If you have a website that runs on PHP 8.1 and want to make sure that switching to PHP 8.3 doesn&#8217;t break anything, you can create a container based on PHP 8.3 and fully test your app there before making a switch on the main website. Other options include distributing your application to your customers as a container or using containers for web hosting if your web hosting provider supports this option.  <\/p>\n<p>In this article we will explain how you can package your PHPRunner application as a Docker container. <\/p>\n<h3>Docker Desktop installation<\/h3>\n<p>As a first step you need to install Docker Desktop on your local computer. Just download it from the <a href=\"https:\/\/www.docker.com\/products\/docker-desktop\/\">official website<\/a> and install keeping all default settings. <\/p>\n<p>Once Docker Desktop is installed, launch it. Two main sections we are going to work with are <strong>Images<\/strong> and <strong>Containers<\/strong>. <\/p>\n<p>A Docker image is a read-only template that contains everything needed to run an application, including the application&#8217;s code, system tools, and libraries. A Docker container is a running instance of a Docker image Think of an image as a blueprint and a container as the building constructed from that blueprint. <\/p>\n<h3>Project structure<\/h3>\n<p>Create a new folder for our Docker project i.e. C:\\Project\\Docker. Here is how the default Docker project looks like. <strong>src<\/strong> folder needs to be created manually and this is where all our PHP files will be stored. Luckily, we do not need to create the rest of file manually, Docker desktop can help us creating those. <\/p>\n<p><a href=\"https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2025\/04\/project_structure.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2025\/04\/project_structure-600x358.png\" alt=\"\" width=\"600\" height=\"358\" class=\"alignnone size-medium wp-image-3152\" srcset=\"https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2025\/04\/project_structure-600x358.png 600w, https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2025\/04\/project_structure-768x458.png 768w, https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2025\/04\/project_structure.png 965w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/a><\/p>\n<h3>Docker init<\/h3>\n<p>Start by opening a terminal ( click Terminal icon in the bottom right corner ). First, switch to your project folder and then run <strong>docker init<\/strong> command. <\/p>\n<div class=\"my-syntax-highlighter\">\n<pre><textarea id=\"mshighlighter\" class=\"mshighlighter\" language=\"php\" name=\"mshighlighter\" >\r\ncd C:\\Projects\\Docker\r\n\r\ndocker init<\/textarea><\/pre>\n<\/div>\n<p>Docker will ask you a few questions about what you want to create. Select Apache+PHP web application. You can use up and down keyboard keys to change your selection. Press Enter to make a choice.  <\/p>\n<p><a href=\"https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2025\/05\/docker_init.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2025\/05\/docker_init-600x405.png\" alt=\"\" width=\"600\" height=\"405\" class=\"alignnone size-medium wp-image-3171\" srcset=\"https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2025\/05\/docker_init-600x405.png 600w, https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2025\/05\/docker_init-1024x691.png 1024w, https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2025\/05\/docker_init-768x518.png 768w, https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2025\/05\/docker_init.png 1475w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/a><\/p>\n<p>For all other questions leave default options. Docker will create an image for you, based on your selection. On <strong>Images<\/strong> tab you are now going to see a new image. Docker will also tell you that now you need to run <strong>docker compose up &#8211;build<\/strong> command in order to build and launch your container. <\/p>\n<p><a href=\"https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2025\/04\/docker_after_init.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2025\/04\/docker_after_init-600x392.png\" alt=\"\" width=\"600\" height=\"392\" class=\"alignnone size-medium wp-image-3150\" srcset=\"https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2025\/04\/docker_after_init-600x392.png 600w, https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2025\/04\/docker_after_init-1024x669.png 1024w, https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2025\/04\/docker_after_init-768x502.png 768w, https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2025\/04\/docker_after_init.png 1415w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/a><\/p>\n<h3>Dockerfile<\/h3>\n<p>This is how the initial <strong>dockerfile<\/strong> looks. I just removed some extra comments for brevity. Lets try to create a container and run it. <\/p>\n<div class=\"my-syntax-highlighter\">\n<pre><textarea id=\"mshighlighter\" class=\"mshighlighter\" language=\"php\" name=\"mshighlighter\" >\r\n# syntax=docker\/dockerfile:1\r\n\r\n# https:\/\/docs.docker.com\/go\/dockerfile-reference\/\r\n\r\nFROM php:8.2-apache\r\n\r\nRUN mv \"$PHP_INI_DIR\/php.ini-production\" \"$PHP_INI_DIR\/php.ini\"\r\n\r\n# Copy app files from the app directory.\r\nCOPY .\/src \/var\/www\/html\r\n\r\n# Switch to a non-privileged user (defined in the base image) that the app will run under.\r\n# See https:\/\/docs.docker.com\/go\/dockerfile-user-best-practices\/\r\nUSER www-data<\/textarea><\/pre>\n<\/div>\n<h3>Build and first run<\/h3>\n<p>Without making any changes to <strong>dockerfile<\/strong> we go back to the terminal and run the suggested build command:<\/p>\n<div class=\"my-syntax-highlighter\">\n<pre><textarea id=\"mshighlighter\" class=\"mshighlighter\" language=\"php\" name=\"mshighlighter\" >\r\ndocker compose up \u2013build<\/textarea><\/pre>\n<\/div>\n<p>First build will take about a minute and consecutive will be a bit faster. Dcker performs the build and starts our container. You can see container&#8217;s status on Containers tab. You can see that our new container is up and running. <\/p>\n<p><a href=\"https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2025\/04\/container_running.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2025\/04\/container_running-600x402.png\" alt=\"\" width=\"600\" height=\"402\" class=\"alignnone size-medium wp-image-3149\" srcset=\"https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2025\/04\/container_running-600x402.png 600w, https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2025\/04\/container_running-1024x686.png 1024w, https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2025\/04\/container_running-768x515.png 768w, https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2025\/04\/container_running.png 1343w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/a><\/p>\n<p>Which means we can can now open a web browser and type in the following URL: <strong>http:\/\/localhost:9000<\/strong>. This is what you are supposed to see:<\/p>\n<p><a href=\"https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2025\/04\/mysqli_missing.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2025\/04\/mysqli_missing-600x371.png\" alt=\"\" width=\"600\" height=\"371\" class=\"alignnone size-medium wp-image-3151\" srcset=\"https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2025\/04\/mysqli_missing-600x371.png 600w, https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2025\/04\/mysqli_missing-768x474.png 768w, https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2025\/04\/mysqli_missing.png 955w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/a><\/p>\n<p>Good news: our container is in fact running.<br \/>\nBad news: mysqli extension is missing and we cannot connect to MySQL.<\/p>\n<h3>Installing mysqli extension<\/h3>\n<p>Quick Google search for &#8220;docker php install mysqli&#8221; points us to the solution and we modify our <strong>dockerfile<\/strong> in any text editor adding lines 7 and 8. <\/p>\n<div class=\"my-syntax-highlighter\">\n<pre><textarea id=\"mshighlighter\" class=\"mshighlighter\" language=\"php\" name=\"mshighlighter\" >\r\n# syntax=docker\/dockerfile:1\r\n\r\n# https:\/\/docs.docker.com\/go\/dockerfile-reference\/\r\n\r\nFROM php:8.2-apache\r\n\r\n# this is the line we have added manually\r\nRUN docker-php-ext-install mysqli\r\n\r\nRUN mv \"$PHP_INI_DIR\/php.ini-production\" \"$PHP_INI_DIR\/php.ini\"\r\n\r\n# Copy app files from the app directory.\r\nCOPY .\/src \/var\/www\/html\r\n\r\n# Switch to a non-privileged user (defined in the base image) that the app will run under.\r\n# See https:\/\/docs.docker.com\/go\/dockerfile-user-best-practices\/\r\nUSER www-data<\/textarea><\/pre>\n<\/div>\n<p>Now we stop the container, run the build command again and once finished we refresh our browser window. This takes us one step further but we are not quite there yet. <\/p>\n<p><a href=\"https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2025\/05\/docker_mysql_connection_error.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2025\/05\/docker_mysql_connection_error-600x342.png\" alt=\"\" width=\"600\" height=\"342\" class=\"alignnone size-medium wp-image-3181\" srcset=\"https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2025\/05\/docker_mysql_connection_error-600x342.png 600w, https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2025\/05\/docker_mysql_connection_error-1024x584.png 1024w, https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2025\/05\/docker_mysql_connection_error-768x438.png 768w, https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2025\/05\/docker_mysql_connection_error-900x515.png 900w, https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2025\/05\/docker_mysql_connection_error.png 1135w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/a><\/p>\n<p>While this error is not very descriptive we can guess that our application is not able to connect to MySQL. We use &#8220;localhost&#8221; as MySQL server address which in case of the container refers to container itself. We need to find a way to connect to MySQL on the host which is our local computer running Docker desktop. Another quick Google search for &#8220;docker connect to host from container&#8221; points us to <strong>host.docker.internal<\/strong> which we need to use instead of <strong>localhost<\/strong> while connecting to MySQL. <\/p>\n<p>We proceed to PHPRunner, create a new Server Database Connection on the &#8216;Output Directory&#8217; screen and change the address of MySQL server as follows:<\/p>\n<div class=\"my-syntax-highlighter\">\n<pre><textarea id=\"mshighlighter\" class=\"mshighlighter\" language=\"php\" name=\"mshighlighter\" >\r\n$host = 'host.docker.internal';\r\n$user = 'root';\r\n$pwd = '';\r\n$port = 3306;\r\n$sys_dbname = 'cars';<\/textarea><\/pre>\n<\/div>\n<h3>And one more try<\/h3>\n<p>1. Stop the container<br \/>\n2. Build PHPRunner project ( make sure that new connection is selected )<br \/>\n3. Copy all files from PHPRunner&#8217;s output folder to C:\\Projects\\Docker\\src<br \/>\n4. Execute <strong>docker compose up &#8211;build<\/strong> command one more time.<br \/>\n5. Refresh browser&#8217;s window<\/p>\n<p>It runs!<\/p>\n<p><a href=\"https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2025\/05\/docker_runs.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2025\/05\/docker_runs-600x314.png\" alt=\"\" width=\"600\" height=\"314\" class=\"alignnone size-medium wp-image-3184\" srcset=\"https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2025\/05\/docker_runs-600x314.png 600w, https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2025\/05\/docker_runs-1024x536.png 1024w, https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2025\/05\/docker_runs-768x402.png 768w, https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2025\/05\/docker_runs.png 1394w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/a><\/p>\n<p>Additional notes. You can make your container connect to any database. It can be a database that is a part of the same container ( though it is not recommended ), or a database running in another container or any external database server. All you need to do is to point the database connection to your database of choice. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>What is Docker? Docker is a software platform that allows you to package, distribute, and run applications within self-contained units called containers. These containers include everything the application needs, like code, runtime, and libraries, ensuring consistent execution across different environments. How this can be useful? There are many possible uses of Docker containers. You can use them for testing for instance. If you have a website that runs on PHP 8.1 and want to make sure that switching to PHP 8.3 doesn&#8217;t break anything, you&#8230;<span class=\"clearfix clearfix-post\"><\/span><a href=\"https:\/\/xlinesoft.com\/blog\/2025\/05\/07\/running-phprunner-application-as-a-docker-container\/\" class=\"more-link\">Continue Reading <span class=\"screen-reader-text\">&#8220;Running PHPRunner application as a Docker container&#8221;<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10,1,4,8],"tags":[],"class_list":["post-3145","post","type-post","status-publish","format-standard","hentry","category-news","category-php-category","category-php-code-generator","category-tutorials"],"_links":{"self":[{"href":"https:\/\/xlinesoft.com\/blog\/wp-json\/wp\/v2\/posts\/3145","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/xlinesoft.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/xlinesoft.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/xlinesoft.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/xlinesoft.com\/blog\/wp-json\/wp\/v2\/comments?post=3145"}],"version-history":[{"count":25,"href":"https:\/\/xlinesoft.com\/blog\/wp-json\/wp\/v2\/posts\/3145\/revisions"}],"predecessor-version":[{"id":3186,"href":"https:\/\/xlinesoft.com\/blog\/wp-json\/wp\/v2\/posts\/3145\/revisions\/3186"}],"wp:attachment":[{"href":"https:\/\/xlinesoft.com\/blog\/wp-json\/wp\/v2\/media?parent=3145"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/xlinesoft.com\/blog\/wp-json\/wp\/v2\/categories?post=3145"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/xlinesoft.com\/blog\/wp-json\/wp\/v2\/tags?post=3145"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}