Friday, April 24, 2020

PHP Cloud Native Buildpack Updates

It's been a little while since I've posted an update on the PHP Cloud Native Buildpacks. The good news is that lots of progress has been made. We've basically achieved feature parity with the old PHP buildpack and I believe the PHP CNB's should be working for most apps now!

Add a file to the root called buildpack.yml. In that file, add the following:---php: webdirectory: public

This will tell the buildpack the location of the files that we want it to serve.

Create the folder .php.ini.d and in it put the file symfony.ini. Inside that file, add the line: variables_order = "EGPCS". This tells PHP that we want the $_ENV superglobal. I'm not a Symfony expert, but it seems to be required for Symfony to configure itself from actual environment variables, which we'll be doing.

Now, from the root of our application directory we just run pack build -b paketo-buildpacks/php -e APP_ENV=prod symfony-5-demo to build an image.

Breaking it down:

pack build is the command to build an image from Cloud Native Buildpacks

the -b flag indicates which Cloud Native Buildpacks to use. In this case, we point it to the meta buildpack for PHP. Meta buildpacks are collections of Cloud Native Buildpacks.

the -e flag set an environment variable picked up by Symfony during build. It tells it that we're doing a production build.

the last bit is the image name we want to create

Lastly, we can run our image with docker run -e PORT=8080 -p 8080:8080 -e APP_ENV=prod symfony-5-demo.

Breaking it down:

docker run will run your image

-e sets the PORT environment variable which tells the buildpack what port it should have the app listen to.

-p tells Docker that we want to expose port 8080. This needs to match the value of PORT so that the port on which the app is listening matches the port on which docker is allowing traffic.

the second -e again tells Symfony that we're running in production mode

the last bit is the image name to run, this should match the image name we used with pack build.

At this point, you can go to http://localhost:8080/ in your browser and access the Symfony Demo App that's been built with Cloud Native Buildpacks and is running inside your Docker container.

Some final notes:

By default, it's going to run with PHP's built-in web server. That's not very "production", so we can add Nginx or Apache Web Server by adding the line webserver: httpd or webserver: nginx to buildpack.yml (add it under the php: block). That's it. No server configuration files required. The PHP Cloud Native Buildpacks handle it all for you.

The first time you run pack build, it will be slow. It needs to download resources like the build & run images, plus of course it needs to download PHP itself. After the first time, things will speed up dramatically. The images will exist locally and PHP downloads are smartly cached. With downloads cached, a full build takes about 10 seconds on my laptop.

That's it. Hope you all enjoy. Feel free to raise any feedback on Github.