Ready to rock PHP 7.3 Docker LAMP Stack

I have built a full LAMP stack that comes with the following:

  • Apache
  • PHP 7.3.3
  • Mariadb
  • MailHog
  • XDebug
  • HTTPS Virtualhost with holding page

Here’s how you get a full LAMP stack up and running in no time at all, which will be identical on any platform.

Firstly, install Docker and Virtualbox if you don’t have them. Then create a default base VM.

https://www.docker.com/community-edition

https://www.virtualbox.org/

docker-machine create --driver virtualbox default

OK. So, first thing you need to do is start your VM:

docker-machine start
docker-machine env
eval $(docker-machine env)

You should run eval $(docker-machine env) in any other terminal tabs you open too, this sets up environment vars for setting up docker. Take a note of that IP address, and edit your /etc/hosts file

192.168.99.100 awesome.scot

Ok, lets clone the LAMP stack:

git clone https://github.com/delboy1978uk/lamp
cd lamp

This is another one off, build the image.

docker-compose build

That’s it! Now start your docker image like this

docker-compose up

and you can finally open your browser to

https://awesome.scot

Setting up a multi user XDebug proxy

I absolutely love XDebug, it’s a tool that no PHP developer should go without! I constantly find myself in contracts where the workplace aren’t using it, and I end up installing and configuring it for them. However, using XDebug alone will only allow one connection at a time. This is fine when we are are developing in an isolated environment, but in many offices an entire team of developers could be working on a server at once! The solution to this is to add an XDebug proxy!

I will assume for this tutorial that you already have XDebug working and can connect with one user.

The first step is to download the debugger proxy itself to the machine running PHP. This can be found here http://code.activestate.com/komodo/remotedebugging/

Now, before you click on the PHP download, DON’T. You actually want the Python one. Download the package for your OS. If you use Linux or Mac, you’ll need python installed too. Windows comes with a binary .exe so Python isn’t required.

Depending whether you are using PHP-FPM or not will determine which port XDebug is currently listening on. PHP-FPM itself runs on port 9000, so if you are using that, your XDebug port will probably be 9001. If you are using PHP as an apache module or whatever, XDebug will probably be listening on port 9000. For the purposes of this article I will assume XDebug is listening on port 9000.

To start the proxy on Windows:

.\pydbgpproxy.exe -d 127.0.0.1:9000 -i 100.200.30.40:9001

To start the proxy on Linux:

export PYTHONPATH=<_Komodo install directory_>/lib/support/dbgp/pythonlib;$PYTHONPATH
cd <_Komodo install directory_>/lib/support/dbgp/bin
python pydbgpproxy -d 127.0.0.1:9000 -i 100.200.30.40:9001

To start the proxy on OS X:

export PYTHONPATH=<_Komodo install directory_>/Contents/SharedSupport/dbgp/pythonlib;$PYTHONPATH
cd <_Komodo install directory_>/Contents/SharedSupport/dbgp/bin
python pydbgpproxy -d 127.0.0.1:9000 -i 100.200.30.40:9001

The options;

-d is the debugger itself, listening on port 9000 on the same machine

-i is the IDE listener port. The IP itself is actually the external IP of this same machine.

If it’s running, you should see something like this:

proxy> .\pydbgpproxy.exe -d 127.0.0.1:9000 -i 10.227.148.40:9001
INFO: dbgp.proxy: starting proxy listeners. appid: 8080
INFO: dbgp.proxy: dbgp listener on 127.0.0.1:9000
INFO: dbgp.proxy: IDE listener on 10.227.148.40:9001

Now back in PHPStorm (or some inferior product) Goto the DBGp Proxy settings in the tools menu, and select configure. Put your name in the IDE key box, the IP of the PHP server, and port 9001.

Again in the tool DBGp proxy, and click Register IDE. If successful, you should be able to see lines like this:

INFO: dbgp.proxy: Server:onConnect ('10.227.148.38', 60748) [proxyinit -p 9000 -k DEREK -m 1 ]
INFO: dbgp.proxy: Server:onConnect ('10.227.148.38', 60996) [proxyinit -p 9000 -k KPATIL -m 1 ]

And that’s it! Now two or more developers can simultaneously use XDebug at the same time. Have fun!

Debugging a Twig View

Just a quick note here to save future hunting.

Ever seen this crap error message?

An exception has been thrown during the rendering of a templat

It totally sucks, right? And then you try debugging with XDebug, only to find you can’t most of the time, since Twig uses eval().

Anyway, to save you looking, if you set a breakpoint where that message is thrown you can get to see your own Exception:

vendor/twig/twig/lib/Twig/Template.php

Look at line 401 (this may have changed in later versions):

} catch (Exception $e) {
    throw new Twig_Error_Runtime(sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, $this->getTemplateName(), $e);
}

You can now see your Exception!

A more verbose var_dump()

Have you ever noticed how when you do a var_dump() that it always goes so far into the tree then displays three dots … ?

Have you ever wanted to see beyond those three dots? The answer is your xdebug PHP ini settings!

; with sane limits
xdebug.var_display_max_depth = 10
xdebug.var_display_max_children = 256
xdebug.var_display_max_data = 1024 


; with no limits
; (maximum nesting is 1023)
xdebug.var_display_max_depth = -1 
xdebug.var_display_max_children = -1
xdebug.var_display_max_data = -1 

You can set this stuff on your script with  ini_set() :

ini_set('xdebug.var_display_max_depth', 10);
ini_set('xdebug.var_display_max_children', 256);
ini_set('xdebug.var_display_max_data', 1024);

Much better!

Tidy looking var_dump

I only just noticed that my work computer wasn’t outputting var_dumps nicely like my laptop did, and I knew XDebug took care of that, so I looked into it in more detail! Basically there are TWO settings. Make sure both are on:

 xdebug.overload_var_dump
html_errors

And voila! You can now read your var_dumps a lot more easily! However it looks disgusting and orange, so lets fix that too:

.xdebug-error {
 width: 97%;
 margin: 10px auto;
 border-collapse: collapse;
 border-right: 1px #5b5440 solid;
 border-left: 1px #5b5440 solid;
 border-bottom: 1px #5b5440 solid;
 }
.xdebug-error th,
 .xdebug-error td {
 padding: 4px 6px 3px 5px;
 border-left: none;
 border-right: none;
 }
.xdebug-error th:first-child {
 padding-top: 0;
 }
.xdebug-error th {
 background-color: #515151;
 color: #EEEEEE;
 }
.xdebug-error td {
 background-color: #EEEEEE;
 border-top: 1px #5b5440 solid;
 border-bottom: #DFBA69;
 }
.xdebug-error span {
 background-color: inherit !important;
 color: #FFFF00 !important;
 }

debug   Much nicer! 😀

XDebug your Remote Server

I love IRC. My friend just doesn’t get it however. But he isn’t looking in the right places.

For instance, we are having a hellish time with our server migration in work today. Our site was transferred to a bigger better CentOS cPanel server, only to act very strangely and mess up. Checking logs only tells us so much, so I tried to get XDebug installed on the server. I was having issues, and so went into freenode and joined the ##php channel, where I was redirected to #xdebug, where I received direct help from XDebugs main contributor, Derick Rethans! You couldn’t ask for better assistance!

Anyway, lets get it installed. Log in to your server as root, and download the xdebug source code. Then run the following from within the source folder:

phpize
./configure
make
make install

Then edit your php.ini, with the following:

zend_extension=xdebug.so
xdebug.remote_enable=On
xdebug.remote_port=9000
xdebug.remote_handler="dbgp"
xdebug.remote_autostart=0
xdebug.remote_connect_back=0
xdebug.idekey = PHPSTORM
xdebug.max_nesting_level = 250
xdebug.remote_log = "/home/allagent/xdebuglog"
xdebug.remote_host = 127.0.0.1

Now there are a couple of settings to be aware of. As I am in work and behind a router, connect_back = 1 wouldn’t work. If you can set up port forwarding on your router, then do so! And remove the remote host 127.0.0.1 line. If not, we set it as 0, and set up an SSH tunnel. Derick sent me his blog link explaining how this is done so check it out here:

http://derickrethans.nl/debugging-with-xdebug-and-firewalls.html

In PHPStorm (you are using storm, right?), goto your run/debug configurations and add a PHP Web Application. I called mine LiveDebug, but you can call it whatever you like. In the server drop down, add your server, tick use path mappings,  find your index.php, and stick in the absolute path for the same file on the remote server (something like /home/username/public_html/index.php). You should do the same with the document root, which means it shopuld find all the rest without having to manually set each page/file.

Now for the good bit! Set a breakpoint in your code by clicking to the left of the code but to the right of the line numbers. A red spot should appear to signify you wish to pause the code at that point for inspection. Click the Run menu, and click debug. Then select LiveDebug, or whatever you called it. a browser window should open, and in Storm the debug frame will pop out. Click the variables tab. You can see every variable as it is set at that line of code. To the right of the tabs you have buttons for skipping over code, and stepping into functions etc! Have fun!

Now hopefully I can figure out why this new server is acting up!