How to Develop and Debug PHP Applications in Kubernetes

If you are building a cloud-based application at scale, running it in Kubernetes is a no-brainer: It's been adopted by the industry at an incredible rate, it has a wonderful community, and every single cloud vendor offers it as a service.
But the development experience available when building Kubernetes applications is less than ideal: write your code, build a Docker image, push it to the registry, redeploy, validate your changes and repeat. This flow is not only slow and full of friction but it prevents us from benefiting from PHP's rich toolkit ecosystem. Think about this for a second. When was the last time that you debug with an actual debugger, instead of adding echo
s everywhere in your code?
Okteto was created to solve this problem. On this blog post, we will show you how Okteto improves the developer experience in Kubernetes for PHP developers. You will be able to take full advantage of the entire PHP toolkit (debuggers, dependency managers, test frameworks, etc...) while developing your application directly in your cluster.
Step 1: Deploy the PHP Sample App
For this post, we'll be using a very simple PHP sample application. Run the command below to get a local clone of it:
$ git clone https://github.com/okteto/php-getting-started
$ cd php-getting-started
The k8s.yml
file contains the Kubernetes manifests to deploy the application. Run the application by executing:
You can deploy to your own Kubernetes cluster or give Okteto Cloud a try. Okteto Cloud is a development platform for Kubernetes applications. Sign up today to get a free developer account with 4 CPUs and 8GB of RAM.
$ kubectl apply -f k8s.yml
deployment.apps "hello-world" created
service "hello-world" created
One command and we have the application up and running. Pretty cool no 😎?
Step 2: Install the Okteto CLI
The Okteto CLI is an open-source project that lets you develop your applications directly in Kubernetes while taking advantage of well-known local tooling. We will use it to speed up our development cycle instead of using the typical development workflow based on building docker images and redeploying containers.
Install the Okteto CLI (>= 1.12.13):
MacOS / Linux
$ curl https://get.okteto.com -sSfL | sh
Windows
Download https://downloads.okteto.com/cli/okteto.exe and add it to your $PATH
.
Step 3: Create your okteto manifest
To start developing on the PHP Sample App you first need to create an okteto manifest. With the PHP Sample App deployed, run the following command to create your okteto manifest:
$ okteto init
This command walks you through creating an okteto manifest.
It only covers the most common items, and tries to guess sensible defaults.
See https://okteto.com/docs/reference/manifest for the official documentation about the okteto manifest.
Use the arrow keys to navigate: ↓ ↑ → ←
Select the deployment you want to develop:
▸ hello-world
Use default values
The okteto init
command will scan the available deployments in your Kubernetes namespace and ask you to pick one.
Select the hello-world
deployment. It's the one we deployed on the previous step.
✓ hello-world
✓ Deployment 'hello-world' successfully analyzed
✓ okteto manifest (okteto.yml) created
i Run 'okteto up' to activate your development container
The okteto init
command creates the following okteto.yml
file:
name: hello-world
command: bash
volumes:
- /root/.composer/cache
sync:
- .:/app
forward:
- 8080:8080
reverse:
- 9000:9000
This file defines how to activate a development container for the PHP Sample App:
name
: the name of the Kubernetes deployment you want to put on development mode.command
: the start command of the development container.volumes
: a list of paths in your development container to be mounted as persistent volumes. For example, this is useful to persist the Composer cache.sync
: the folders that will be synchronized between your local machine and the development container.forward
: a list of ports to forward from your development container.reverse
: a list of ports to reverse forward from your development container to your local machine
Also, the okteto init
command creates a .stignore
file to indicate which files shouldn't be synchronized to your development container.
This is useful to avoid synchronizing binaries, build artifacts, or git metadata.
Step 4: Activate your development container
Next, execute the following command to activate your development container:
$ okteto up
✓ Persistent volume successfully attached
✓ Images successfully pulled
✓ Files synchronized
Namespace: cindy
Name: hello-world
Name: hello-world
Forward: 8080 -> 8080
Reverse: 9000 <- 9000
Welcome to your development container. Happy coding!
default:hello-world app>
Working in your development container is the same as working on your local machine. Start the application by running the following command:
default:hello-world app> php -S 0.0.0.0:8080
[Tue Jan 7 01:54:59 2020] PHP 7.4.1 Development Server (http://0.0.0.0:8080) started
Okteto automatically forwards port 8080
from your local computer to the development container, making it accessible via localhost
. Test it by running the command below in a local shell:
$ curl localhost:8080
Hello world!
Step 5: Develop directly in Kubernetes
Open the index.php
file in your favorite local IDE and modify the response message on line 2 to be Hello world from the cluster!
. Save your changes.
<?php
$message = "Hello world from the cluster!";
echo($message);
Okteto will synchronize your changes to your development container and PHP's webserver will automatically reload them.
Call your application from a local shell to test the changes:
$ curl localhost:8080
Hello world from the cluster!
Cool! Your changes were instantly applied to your application running in Kubernetes. No commit, build or push required 😎!
Step 6: Debug directly in Kubernetes
Okteto enables you to debug your applications directly from your favorite IDE. Let’s take a look at how that works with PHPStorm, one of the most popular IDEs for PHP development.
If you haven’t already, fire up PHP Storm and load the sample application code there. Once the project is loaded, open index.php
and set a breakpoint in line 2
. Click on the Start Listen PHP Debug Connections
button on the PhpStorm toolbar.
Go back to your local shell and call the application:
$ curl localhost:8080
If this is the first time you debug this application, the IDE will ask you to confirm the source mapping configuration. Verify the values and click ok to continue.
The execution will halt at your breakpoint. At this point, you are able to inspect the request object, the current values of everything, the contents of $_SERVER
variable, etc… Just as you would do if you were debugging locally.
How does it works?
The development container we are using already has PHP7 and XDebug installed. We pre-configured XDebug so that it accepts remote debugging requests on 127.0.0.1:9000
. Finally, we configured the Okteto manifest to start a reverse tunnel on port 9000.
This configuration allows you to take advantage of PHPStorm’s Zero Configuration Debugging to make debugging extremely simple. And the coolest thing is that since all of this is described in your Okteto manifest, everyone collaborating in your project will get the exact same configuration by simply running okteto up
🤖.
Conclusions
Kubernetes has the potential to be a great development platform, providing replicable, resource-efficient and production-like development environments. We have shown you how to use Okteto to create a development workflow that also lets you take advantage of features like hot reloaders or debuggers while developing your application directly in Kubernetes.
Accelerate your development and start developing directly in Kubernetes today. Let us know what you think about it on Twitter, or in our #okteto channel in the Kubernetes community Slack.