 Okay. Okay. Hi, everyone. I'm Mike Koen Buy. I'm a software engineer. I have been working with PHP around like nine to ten years already. Actually, I started with learning PHP earlier than that, but I obviously working for companies in around like 2007, 2008. So around eight to ten years. So today I'm going to talk about my experience using PHP with Docker, which is my interest. And a bit about me. I'm a staffed learning LAMP stack in 2004 and official working on citizen and add. I like programming. I like learning new things and I like building things. And I also like photography, playing chess, traveling, tracking and sport. I play football every week. And it's open group. If you want anyone want to join, just let me know. We are very welcome. And also a father of very lovely daughter. Okay. About the Docker. The Docker is help you to build ship and run any app and almost everywhere. They say everywhere, but there are some conflicts. You cannot run, for example, you cannot run the Intel architecture on AM architecture. And Docker is not a virtual machine like what we are talking about comparing to vagrant. And you can see on the screen here, the most important difference is about the guest OS and the hypervisor. So it reduce the load for the host machine and it make Docker is very portable, very lightweight and run very fast. And currently Docker is version 1.12. And it's in AC1. Docker is available in natively in Linux. And in Windows OS, currently the official support is via Tunebox. It's an official virtual machine running on top of VirtualBox. And now on March of this year, they introduce native support for Windows and OS, but until now, they are still in beta. And previously, I think two weeks ago, they still in private beta, but now they are in public beta, so everyone can download and try it on your computer. So today I talk about the pp development. I focus on four things only. First thing is how you run pp project with Docker, how you debug it, how you run test, and how you deploy it. I will do a live coding which is cost me a bit issue, so a bit delay until now. Okay, so here is my project. I will upload the source code of the home project to GitHub and share to everybody. So everybody is very convenient to follow. I use Laravel, which I think is people is very familiar with. I wanted to use symphony, but I think we are more familiar with Laravel than symphony. So eventually I decided to use Laravel. So this is a demo app from Laravel, which is just very simple thing to do list. The first thing is this is Docker container I'm running. And you can see I have two containers now. One is for the source code. One is for database. So that is the idea of Docker. They want us to separate all the components. So everything is loosely coupled to each other. So we can easily scale, easy to upgrade. And this is a website. So as you can see it's very simple thing. Just add and new. So you see it works. So that is how you run the PPP application. So under the line, okay, let me change. Okay, it's easier to everybody. Okay, sorry. Okay, so this is the main thing of the Docker environment where you bootstrap and run on the Docker container. The first thing is like the project. I name it PPSG for PPP Singapore. And I have some mapping. I have some mapping from my source. My source folder here into VAR-WW and I have a customized NGX file for only for this project. So if you have another project, you can have another NGX file to override. So it's very convenient for us. And this line is I mapped the host pod to the local pod. So I will access it in the pod 8,000 as you can see here. And I link this container with my database container here. So here I set up very simple application only. So my database is almost empty. Only have database from the basic app. I will come up to this one later. But the first, okay, I move this one up. So it's easier. So the first, this is a two container. We are in the new version of PPP combos. They call this service. So this is two service we are using now, which is mapping to these two containers. Any question for running PPP application on local for now? This is native. Yes. So I run, you can see here, I run everything directly from my version of scene. Yeah. And this latest version. Yeah. So you can try. It's very cool. I find it's have a bad, a bit impact on the performance for the file system. But I think for development, it's fine for me so far. Okay. So let's go to the debug. The debug is a bit tricky part here because I don't know why the Docker, the Docker native Docker, it doesn't have good support for I don't know if only specific for the communication between the container and the host. But for the, for the debugging PPP, right, we need to run a X debug and we need to run a server to listen to listening to the debug request. But the, the debug request cannot reach to the host machine from inside container. But I found a fix for that. And I'll show you my fix. So basically this is my X debug configuration. So previously the remote host, especially you specify as a local host like one, two, seven, zero, zero, one. But I specify another local IP address here. And in my mark, sorry, window. Okay. In my mark, I add a new alias to the local config here. So it, by adding this alias, it can connect. I don't know how, but it works. So I just want to share what I found for, so anyone want to debug is very easy. Another configuration is quite simple. You can specify the pod and specify the ID key here. And inside your PPP storm, you also specify the same thing. Okay. You have a pod here. Okay. Let's try it. So basically, if I reload this one, for example, usually to try if debug is working, I open the index file. It's here. And I stop at the first line here to see and make sure you enable and disable the debug listening here. Otherwise, you won't get it. So this one is disabled. You have to enable this like this. So it's listening. Okay. Now if I reload this one, okay, boom. It's go here already. So from now, you can see, you can debug everything from here. What is the current variable? And you can go deep inside that. And for example, I know it will go until here. For example, this note is a home page, right? So you can just go here. You stop here. And let's see what happens. You can just skip jump from the first breakpoint to the second one by this button. And here it stops here. And from here, you can even see more from here. Now, as you know, ZIT is a route service provider. And you can even go further. Like, if I want to go inside to this function, you can press F7. If you step to the next function code, you use F8. So I'm going to this function. You see, ZIT is a loader, auto loader from the platform. So you see from here, it started a new eloquence query from here, which is used for this code. So this one, it triggers the code static method, which is the magic code. And from here, it will create a new query for this function. See, it goes to the order by here. So by using, okay, how many people have used using HDBug before? Oh, only one. Okay, so that's also a good thing. So from here, you can see that by using HDBug, you can easily to see all the parameters you don't have to use like VADAM, PRINAR, or DAI, or something with your application. So basically, you will never leave your debug code inside your production code, which is prevent some accident. So try to learn HDBug. It's very cool. And you'll find it will help you a lot. Okay, this time out, because we have spent a lot of time in debugging. So NGINX out to time out after, I think, 20 seconds or 90 seconds. So if I run this one, and you see the frame, if frame is not available, that means the execution already done. So if I refresh this one, if I run it really fast, okay, let's go back here. So that is about debugging PPP application. Now you want to run a test for your application. I haven't created a new test. I still using the default test for the demo application. ZIT is more tricky part. So basically, okay, now I come back to this part. Okay, can you see clearly? Okay, never mind. This part. So now, can you see now? Okay. So basically, this is my image, docker image. I personally view it just now. I can share it with everybody so everybody can use it. So basically, inside this container, I only have on the PPP package enough to run the component, also the PPP unit library to run the PPP unit. And I also map the source file to the VWW. So to make sure that we have a source file to test it. And also, ZIT is command line to run the test. And in order to test it, you can run this simple query. Okay, first thing, in order to run the docker compose, you have to go to the directory where the docker compose file located in. If you go to another directory, you cannot run it. So basically, I will go to to make sure that my docker composer is here. Okay. Docker file is a file you use for building an image. Yeah, let me show you. So ZIT is a docker file to build the PPP unit. So the good thing, also the difference between the docker and another virtual environment like vagrant is like the docker, you can inherit from another image. So from now, I inherit from unpy 3.4 here. So as you can see here. So ZIT is already built image out there, public there on the, yes, it's official image, but you can extend from any image, not only the official. Yeah, and I run some command to add the PPP library here. Yeah, and prepare the environment here. And after I'm using like this, I need to, ZIT is a file to declare the, to instruct the way to build the image. After that, you need to run the command to actually build the image. So the command is similar like this. I think I increased the phone sign here so you can see it's better. Yeah, docker view, that's T is for tag. So when you build an image, you need to tag it or you need to label it somehow so you can easily find it later. So I will label it GIGARY PPP unit. GIGARY is my personal depth team. So I use this only. So not meaning, and not any meaningful here. What's it? That's T, T for tag, T for tagging. It's just a label link. Yeah, so you label it. This is PPP image belong to GIGARY group. And the tag, the version is 5.4.6. Actually, the tag is 5.4.6. What Michael is doing is doing a namespace. So GIGARY is a namespace. And the actual container name that it's creating is for PPP unit. And the colon, for all of the columns after that, it's basically a tag, a version number that you can tag with this one. So usually by default, it tags as colon latest, which gives you the latest version of this name. Good thing about it, what is, okay, tag can be arbitrary string. So it's done that it has added a namespace in front. So it's easy for it to be, can easily push stuff into Docker Hub later on. Docker Hub is like a place where you can download and share Docker images, am I right? Yes, correct. So it's done this way to make it easier for PPP to push stuff and share it. So you know Github, right? So the structure is similar to Github. You have a namespace or user or a group. And then you go to the Jor repo name. This is exactly the same, but except on top of that, we have a tag or label to this commit, for example. Yes. If you don't have anything after this, it's auto tag at latest. Yes. I haven't pushed it, but later I can push it. Yeah, this is in local. Yeah. So if you don't have any tag here, it's automatically at a latest. But the best practice is you need to tag a version, the specific version here. So you won't have any conflict later. Like for example, you use the latest version, but somehow maybe in next one month, your outer upgrade the version to another, a new version. And which is not compatible with your current project. So it may break your project. So you need to specify the version specifically when you use this. Okay. I tag this folder and I point to the Docker file name which is inside Docker and PPP unit. So you can see this Docker PPP unit is a part from here. Docker PPP unit here. You don't have to specify the Docker files which is automatically added. And I run it. I already view it. So it runs very fast. So the thing is like you can see the step three, set step four, step five, one step is one line you define in this Docker file. So if at any step, if already built before, when you rebuild it, it will not even reuse the built version. So it don't have to run over and over. So like for example, if instead of using being here, you want to put it in local. So only the last command will run. Only the red is already built. It will reuse that they call it intermediate containers. Yeah. Caches things like your older packages. Yes. And actually, you can see all the emits by here on everything you see none here which is the none. That means it's failed to build previously. Yeah. So it has no name at all. So by default, it's none. So after that, it will reuse this image to build another image. So it's very convenient. It's very fast for it as well. So yeah. Yes, I can clean later. But if I rebuild it, if I delete everything, if I rebuild it, if Docker says that there's no image built for this version before, then it has to run it again. So if you 100% sure you never need it anymore, then you just delete it. Okay. For everything, like for example, if I know that this version is running five already, and okay, if I test my application running five already, I can just delete every none. So basically, from here, I can just run Docker, remove image, and I copy all the image ID here. Done. It's clean up. I can 100% sure that my image is still running five. So I just clean it up. And that is for Docker five. Docker five is for building image. And Docker compose is for using image. Yeah. So the image I just build is inside here. So when I create a container or create a new service, I need to define the image when I want to use for that image. I have another configuration, like volume. I want to link this image to MySQL because when I run the test, my test is also need a database connection as well. So I need to link it. All those things that happened here can happen in Kamaa MySQL. You can issue to the doctor. Yes. The doctor up and I want these other things. Yeah. Please get as flat as you can in the Kamaa MySQL. But when you're going to compose, Docker compose file, you can declaratively set up the links. And the file studies which that is we go, that is we map into the instances and you can make them all speed up at the same time. Basically, you can speed up the whole group of this Docker images. Yeah. Sorry. Go top. Yeah. Okay. So basically the name here is the service name. You can create an alias for that. So for example, this one, you can create a PHP MySQL here. The naming here or the alias name here will be used inside the PHP SG container. And it will be available. It will be used to connect the PHP SG container to the MySQL container. Okay. So for example, if I don't have this part, this will be the name using the PHP SG container. If I have this part, this will be the name using in PHP SG container. Actually, both this one and this one will be available. But the thing is like, for example, I have a multiple MySQL database or have a multiple PHP application. I want to use, but my default conversion or my NGINX conversion or HSA proceed conversion is point to PHP only. So basically here I can define PHP SG1, PHP SG2, or for example, I can define here MySQL 1, MySQL 2. But from here, I still map it to MySQL. So I don't have to change my configuration. Yeah. Even I can declare even more service. Essentially what this does is it adds an entry in your EC host file inside the container. So internally it refers to it by say PHP. MySQL actually refers to the other container in this list by the name. So every Docker container is, has their own IP address? Yes. Okay. So basically, when you run a Docker, even create a network, by default the network name is D4. And you have have a multiple type of network. You can implement your own network type. But currently have two type of network is bridge and overlay with built-in. And also by default if you don't declare any network, then we use the D4, the D4 network. And all of this will be inside the D4 network. And actually from new version of Docker, I don't need to link here and here because it automatically available within the same network. But for some reason, sometimes it may not work. So to be safe, include it in. Yeah. I haven't, I haven't tested it. Just now I test without this link it failed. So for some, but previously if I remove this one, I still can ping it. So to be safe, just include it in. And yes, when you create a new, create a new container, it will have, each container will have a dynamic IP address. So you cannot predict which IP address is that. And by using the host name like this, it makes the development more convenient. Okay. So Zit is a Docker Composer file. In order to run ppunit, I will use this ppunit service to run which is run the ppunit configuration here. Okay. Before I run this, I want to explain a bit. So Zit is a command line. I want to run ppunit. But after immediately the ppunit service is running and stopped, I will, I want to remove it. So there's no unused container, unused service in my environment. Just to make it clean. Okay. Everything is running fine here. Okay. So just to show you something, I want, I will destroy everything on my environment. And I will show you, it won't work. And then I will bring them up very quickly. Okay. So first thing I want. Okay. You can see, we have two images here. We have two images here. Which is one is PSG, one is MySQL. Now I will delete these two containers. This is my shortcut function to delete it. So basically it will delete two. I run, I list them. I use the same command here, docker ps to list on container. And we don't have anything here. Just to make sure that it works. Actually, the command works. We go to the website. There's nothing here. Now I want to bring them up. Okay. I want to bring everything inside the docker file up and run it at the daemon. So I can run another command. Okay. Now you see it's run. But as you can see previously we have two docker container. Now we have three because I declare the ppunit as well. But ppunit, sorry. Because in the docker file, I define three services. One is MySQL. One is the ppsg. And one is ppunit. So that's why it creating all three services. And after that, because the ppunit is running and assist immediately. So the stated is assist. These two containers is still running here. And now, okay. Do you guess if I go, if I refresh this one, it's working? Not really. Okay. It's showing something work here. Good. But it's not because database is not there. Yeah. That's why I say it's card work, but it's not really working. So that is, I want to show you this one doesn't backup your database. So you need to have another strategy to backup your database and restore the database. One of the techniques is you create a share volume. The share volume will be used for all the database container. So when it up, it use the database, it use that volume. The volume will contain the data previously we use. So the data will be there even we destroy the containers. So it is a bit advanced topic. So I'm not talking about here, but very easily we can just go to the database, create the database. It needs some time to connect. And then, yes, I delete the containers. The data is, okay, there are two concepts in Docker. One is image, one is container. Image is kind of like template and container is the actual run time, which actual file you are using. Yes, everything. Yes. So if I, if inside, if inside this my SQL, I have another volume, which the volume is used somewhere else. So but after delete and bring it back, it's still using that volume. So the data is still there, but because I don't do that for now. So it's a bit advanced things, advanced configuration. So I don't put it here. But you can do a research on that. It's not so difficult. Yeah. It's not like a pool set. It's actually a isolated environment run only my SQL service. Yeah. Okay. I create a pp, I create a database here and then I need to log in to the SQL, yeah, this one. Okay. The SQL command is for ad hoc running, to run ad hoc commands only. So after I assist this one, this one went gone. So I need to scroll to the, you see this is VARW. The VARW is the volume I'm mapping from here, from this, from this source folder. I go here, I will see the, the folder structure exactly like inside here. So it is where you are using volume is where you are communicate between the Docker container and the host machine. And from here, I need to run the migration from Laravel and that will make this work. Okay. So if you, if you configure, if you configure the database properly and you make, you turn it down, bring it up, it's very quickly in just a second compared to like a few minutes with the vagrant, even you have a hundred of Docker container or a hundred of service running on your local, everything is seen up and running in just a less than one minute. Usually it will allow like half a minute only. Okay. Now about deployment and usually I clean, I just clean it, the PPP unique container which is not in use, so it's clear for us now. So now I know that I have PPP, SGS file and service and Maria database service. Now I want to deploy this app so I can use this in depth or in staging or in production. So basically once, okay, give me a second. Okay. So basically I need to copy the source file into VWW folder. The source file after I run in the test, I make sure that my application is running fine as I expected. So I will copy all the source code to the VWW which we use, it's like system D4. It's not the global but we define that as our D4. So we copy the source code there and then we need to remove this volume. Okay. If you don't have this one, this volume, we create an empty folder inside the environment. So if you want to work with the folder, it will not show any error like folder not found or something like that. So now if you add the source file to the folder already, you don't need the volume instruction. Okay. So after you copy everything from source folder from here, you build this image exactly like what I built before. And amazing you have image already like from here. For example, I have everything here already. Now I want to deploy the Vigari PPSG. So there's two places you can deploy. You can just deploy your image file. By default, you can deploy it to Docker Hub. It's similar to GitHub. And from there you can pull from anywhere. Another one is if you don't want to, you can implement general registry. So it's only like for, if you're really concerned about security, you implement the internal, the private registry. So only you can push image to that registry. And all you can use Docker Hub, you need to pay the subscription to use the private image. Let me introduce a bit about the Docker Hub first. So this Docker Hub is exactly like similar to GitHub. This is my user and this is my organization. And you can see inside my organization I already have some Docker image. Let's go need repo. And then now you see from here I don't have any PPSG repo. You can see from here I can go to the second one to make sure that nothing here. Okay. I go back to my local. The first thing in order you push the image into the Docker Hub, you need to log in first. And Docker Hub haven't support the SSS key. So you need to log in by your user and password. But it should be done only once. So I need to give in the user and the password. Okay. Take a bit long. Now I want to push my image to Docker Hub. Okay. For example, from here you can see I have latest tag here. But manually I can just put it like this. So it will push this image, this tag to GitHub. But because latest is a default tag, so I don't have to do that. This one is 50 meg. It should be done in one or few minutes. Yeah. So in the meantime, do you have any questions? So I can answer between what? VirtualBox. Okay. VirtualBox is virtual machine. Docker is not virtual machine. VirtualBox and VMware is virtual machine. It simulates the host machine work. And inside virtual machine you need to install a guest OS. Yes. I'm going back here. Okay. Can you see it? Okay. So Docker is a Docker container. It's just a combination of library and binary file enough to run your job. But for virtual machine you need to have everything need to boot up the OS. Like for example, you want to install Linux or Windows here. You have to put everything inside that. And everything will run without even you don't really need it. So that will be very heavy. See, the guys put here one ton. Cluster management. What do you mean by cluster management? Yes. Actually in Docker world, we have a different type they call it orchestration. Yeah. Previously Docker have a tune called Docker swarm. And you can Docker swarm to orchestration. And another tune is Terraform. Terraform is for you to is similar to Docker compose. Terraform you can declare and you can even create a new machine in AWS in Google App Engine Google Cloud or another provider. Another tune which is very powerful is created and supported by Google is Kubernetes. Yeah. Kubernetes if you really have a lot of containers, Kubernetes is very useful for you to manage everything, all of them. You can monitor it. You can scale it very easily. Sorry? Because in VMware, you have one center and you have one insert and one center and you can see everything. Is it simple or good? Yes. So that is the community you think? Okay. So different tune have different way to manage this. Like for example, for Terraform you have a text file to declare on the instant. And for example, for PPP, for example, you have a NGINX and PPP, right? NGINX is very lightweight. So if you have very high traffic, you want to scale PPP into five instant. You need to declare the scale number inside the Terraform file as well. That is for Terraform. But for Kubernetes, you have a command line to do that. So you can scale up or scale down. But the nice thing about community is they can't, I'm not sure what is the kind of like rolling update. So for example, you have a file running PPP 5.5, right? You want to upgrade to PPP 7. You have a 10 container running PPP 5.5. If you want to upgrade it, you upgrade to, actually you change the image. So it's rolling one by one. It's not destroy everything and launch a new thing. So it's very convenient for you as well. It's almost transparent to user. Any question? Okay. Yes. We can do it very easily. Actually, for WordPress, right, you need to have Nginx. You need to have a PPP, okay, Nginx or Apache. And then you need to have a PPP. And then you need to have MySQL server. Right? Okay. I don't use this. I use command line. But basically, if you want to put everything in one image, it's not a good practice. Yeah. Because like the concept of the Docker, like they want to separate on the component. If the component is not really coupled to another one, then just keep it separated. So for example, MySQL and PPP is not really connected. They can communicate over TCP IP. Yeah. So just keep it separate. So basically what I will do is I create a one container for MySQL, one container for PPP, one container for Apache or Nginx. I usually I use Nginx. So I have three containers and I use the Docker Compose to compile them together. And later, if I want to bring it up, I just run Docker Composer up and that's all. Yeah. Let's see if this one finished. Okay. It's finished already. And now let's go to Docker Hub and check. Okay. Where is PPSG? Okay. The last one. Yeah. You have it here. You will click it. You see we don't have anything at all. My collaborator should be me. And that, yeah, you see we have this tag here. So basically, you see the Vigari PPSG is the repo name and the latest is a tag name. Yeah. So from here, you can define the list or the version. So you can easily to manage this. Sorry. D, right? That's D for daemon or detach. Okay. So like, for example, if you don't have dash D, then after you run the command, you are still inside the command. So you cannot type any other command. It's not set now, but it's just hanged there. If you type dash D, it will push it to the background and it can continue your work. Okay. So it, the question is if you want to continue type more command after that or not, if you don't, it doesn't matter if you have type dash D or not. Yeah. Any more questions? Yeah. Thank you very much.