{"id":40596,"date":"2020-02-02T10:38:43","date_gmt":"2020-02-02T07:38:43","guid":{"rendered":"https:\/\/prohoster.info\/blog\/blog_prohoster\/razrabotka-prilozhenij-i-blue-green-deployment-opirayas-na-metodologiyu-the-twelve-factor-app-s-primerami-na-php-i-docker"},"modified":"2020-02-02T10:38:43","modified_gmt":"2020-02-02T07:38:43","slug":"razrabotka-prilozhenij-i-blue-green-deployment-opirayas-na-metodologiyu-the-twelve-factor-app-s-primerami-na-php-i-docker","status":"publish","type":"post","link":"https:\/\/prohoster.info\/en\/blog\/razrabotka-prilozhenij-i-blue-green-deployment-opirayas-na-metodologiyu-the-twelve-factor-app-s-primerami-na-php-i-docker","title":{"rendered":"Application development and Blue-Green deployment, based on The Twelve-Factor App methodology with examples in PHP and Docker.","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Application development and Blue-Green deployment, based on The Twelve-Factor App methodology with examples in PHP and Docker.\" src=\"\/wp-content\/uploads\/2020\/02\/c8f98efef30babe012d23dd82a01c13b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h3>First, a bit of theory. What is <noindex><a rel=\"nofollow\" href=\"https:\/\/12factor.net\/ru\/\">The Twelve-Factor App<\/a><\/noindex>?<\/h3>\n<p>\nSimply put, this is a document designed to simplify the development of SaaS applications, helping by informing developers and DevOps engineers about the issues and practices that are most frequently encountered in modern application development. <\/p>\n<p>The document was created by the developers of the Heroku platform.<\/p>\n<p>The Twelve-Factor App methodology can be applied to applications written in any programming language and using any combination of external services (backing services) (databases, message queues, caching, etc.).<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h3>A brief overview of the factors on which this methodology is based:<\/h3>\n<p><\/p>\n<ol>\n<li><b>Codebase<\/b> \u2013 One codebase, tracked in version control, with many deployments <\/li>\n<li><b>Dependencies<\/b> \u2013 Explicitly declare and isolate dependencies<\/li>\n<li><b>Configuration<\/b> \u2013 Store configuration in the environment<\/li>\n<li><b>Backing Services<\/b> \u2013 Treat backing services as attached resources<\/li>\n<li><b>Build, Release, Run<\/b> \u2013 Strictly separate build and run stages<\/li>\n<li><b>Processes<\/b> \u2013 Run the app as one or more stateless processes <\/li>\n<li><b>Port Binding<\/b> \u2013 Export services via port binding <\/li>\n<li><b>Concurrency<\/b> \u2013 Scale out via the process model <\/li>\n<li><b>Disposability<\/b> \u2013 Maximize robustness with fast startup and graceful shutdown <\/li>\n<li><b>Development\/Production Parity<\/b> \u2013 Keep development, staging, and production environments as similar as possible <\/li>\n<li><b>Logs<\/b> \u2013 Treat logs as a stream of events<\/li>\n<li><b>Admin Processes<\/b> \u2013 Run admin\/management tasks as one-off processes <\/li>\n<\/ol>\n<p>\n<b>You can find more information about the 12 factors from the following resources:<\/b><\/p>\n<ul>\n<li> <noindex><a rel=\"nofollow\" href=\"https:\/\/12factor.net\/ru\/\">Official source<\/a><\/noindex> \u2014 a must-read<\/li>\n<li> <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/258739\/\">Article on Habr. The Twelve-Factor App<\/a><\/noindex> \u2014 official translation<\/li>\n<li> <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/460363\/\">Article on Habr. 7 Missing Factors in the 12 Factor App Approach<\/a><\/noindex> \u2014 a fresh perspective on the 12 factors aimed at improving them.<\/li>\n<\/ul>\n<p><\/p>\n<h3>What is Blue-Green deployment?<\/h3>\n<p>\nBlue-Green deployment is a method for delivering an application. <b>production<\/b> in such a way that the end client does not see any changes on their side. In other words, deploying the application with zero <b>downtime<\/b>.<\/p>\n<p>The classic BG Deploy scheme looks as shown in the image below. <\/p>\n<p><img decoding=\"async\" alt=\"Application development and Blue-Green deployment, based on The Twelve-Factor App methodology with examples in PHP and Docker.\" src=\"\/wp-content\/uploads\/2020\/02\/8252356ac93ce40b248ab27982754985.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<ul>\n<li>At the start, there are 2 physical servers with exactly the same code, application, project, and there is a router (load balancer). <\/li>\n<li>The router initially directs all requests to one of the servers (<b>green<\/b>). <\/li>\n<li>At the moment when a release needs to be made again, the entire project is updated on the other server (<b>blue<\/b>), which is currently not processing any requests. <\/li>\n<li>After the code on the <b>blue<\/b> server is fully updated, the router is commanded to switch from the <b>green<\/b> to <b>blue<\/b> server. <\/li>\n<li>Now all clients see the code running on the <b>blue<\/b> Server. <\/li>\n<li> For some time, <b>green<\/b> the server serves as a backup in case of a failed deployment on the <b>blue<\/b> server, and in case of failure and bugs, the router switches the user flow back to the <b>green<\/b> server with the old stable version, while the new code is sent for further work and testing.<\/li>\n<li>And at the end of the process, the <b>green<\/b> server is updated in the same way. After its update, the router switches the flow of requests back to <b>green<\/b> server.<\/li>\n<\/ul>\n<p>\nIt all looks very good and at first glance there shouldn\u2019t be any problems.<br \/>\nBut since we live in the modern world, the physical switching option as outlined in the classic scheme does not suit us. Please note this information, we will return to it later.<\/p>\n<h3>Bad and Good Advice<\/h3>\n<p>\n<i>Disclaimer<\/i>: The examples below include utilities \/ methodologies that I use; you can use absolutely any alternatives with similar functions. <\/p>\n<p>Most examples will in one way or another overlap with web development (surprise), PHP, and Docker.<\/p>\n<p>The points below provide a simple practical description of how to use factors in specific examples; if you want more theory on this topic, refer to the sources above. <\/p>\n<h4>1. Codebase<\/h4>\n<p>\nUse FTP and FileZilla to upload files to the servers one by one, do not store code anywhere except on the production server.<\/p>\n<p>The project should always have a single codebase, meaning all code comes from one source. <b>Git<\/b> repository. The servers (production, staging, test1, test2 ...) use code from branches of a common repository. This way, we achieve code consistency.<\/p>\n<h4>2. Dependencies<\/h4>\n<p>\nDownload all libraries in folders directly to the root of the project. Updates should be made simply by transferring the new code to the folder with the current version of the library. Install all necessary utilities directly on the host server where another 20 services are running.<\/p>\n<p>The project must always have a clearly defined list of dependencies (by dependencies, I also mean the environment). All dependencies must be explicitly defined and isolated. <br \/>\nAs an example, let's take <b>Composer<\/b> and <b>Docker<\/b>.<\/p>\n<p><b>Composer<\/b> \u2014 a package manager that allows you to install libraries in PHP. Composer allows you to specify versions strictly or loosely, and to define them explicitly. There can be 20 different projects on the server, each having its own list of packages and libraries that do not depend on each other.<\/p>\n<p><b>Docker<\/b> \u2014 a utility that allows you to define and isolate the environment in which the application will run. Accordingly, just like with Composer, but in a more thorough manner, we can define what the application works with. Choose a specific PHP version, install only the necessary packages for the project to function, without adding anything extra. Most importantly, without overlapping with the packages and environment of the host machine and other projects. This means all projects on the server running through Docker can use any set of packages and completely different environments.<\/p>\n<h4>3. Configuration<\/h4>\n<p>\nStore configuration constants directly in the code. Separate constants for the test server and separate ones for production. Tie the application's operation to the environment directly in the business logic of the project using if-else statements.<\/p>\n<p><b>Configurations<\/b> \u2014 are the only thing that should differentiate project deployments. Ideally, configurations should be passed through environment variables (env vars). <\/p>\n<p>This means that even if you store several configuration files .config.prod and .config.local and rename them to .config (the main config from which the application reads data) at the time of deployment, it is not the correct approach. In this case, the information from the configurations will be publicly accessible to all developers of the application, and the data from the production server will be compromised. All configurations should be stored directly in the deployment system (CI\/CD) and generated for different environments with different values needed for a specific environment right at the time of deployment.<\/p>\n<h4>4. Backing Services<\/h4>\n<p>\nTightly bind to the environment; use different connections for the same services in specific environments.<\/p>\n<p>In fact, this point overlaps significantly with the one about configurations, as without this point, it would be impossible to create normal configuration data, and the ability to configure would collapse altogether.<\/p>\n<p>All connections to external services, such as queue servers, databases, and caching services, must be the same for both local environments and external\/production environments. In other words, I can at any moment change the connection string from database #1 to database #2 without changing the application code. Or, to anticipate, when scaling the service, you won't have to specify a special way to connect for an additional cache server.<\/p>\n<h4>5. Build, Release, Run<\/h4>\n<p>\nOnly keep the final version of the code on the server, without any chances to roll back the release. There's no need to fill up disk space. Anyone who thinks they can push faulty code to production is a bad programmer!<\/p>\n<p>All stages of deployment should be separated from each other.<\/p>\n<p>Have the option to roll back. Make releases while keeping old copies of the application (already built and ready for action) easily accessible, so that in case of errors you can restore the old version. So, conditionally there is a folder <i>releases<\/i> and a folder <i>current<\/i>, and after a successful deployment and build, the folder <i>current<\/i> is linked by a symbolic link to the new release located within <i>releases<\/i> with a conditional release number name. <\/p>\n<p>This is where we recall Blue-Green deployment, which not only allows switching between code but also switching between all resources and even environments with the ability to roll everything back.<\/p>\n<h4>6. Processes<\/h4>\n<p>\nKeep application state data directly within the application itself. Use in-memory sessions within the application. Utilize as many shared resources between third-party services as possible. Bind to the fact that the application can have only one process and do not allow for scaling.<\/p>\n<p>Regarding sessions, store data only in cache controlled by third-party services (memcached, redis), so that even if you have 20 application processes running, any of them can access the cache to continue working with the client in the same state as the user was when working with the application in another process. With this approach, no matter how many copies of third-party services you use, everything will operate as expected without issues accessing data.<\/p>\n<h4>7. Port Binding<\/h4>\n<p>\nOnly the web server should know how to work with third-party services. Ideally, host third-party services directly inside the web server, for instance as a PHP module in Apache.<br \/>\nAll your services must be accessible to each other via some address and port (localhost:5432, localhost:3000, nginx:80, php-fpm:9000), meaning that from nginx I can access both php-fpm and postgres, while php-fpm can access postgres and nginx, and essentially from each service, I can access another service. Thus, the viability of one service is not dependent on the viability of another service.<\/p>\n<h4>8. Parallelism<\/h4>\n<p>\nWork with one process, otherwise multiple processes might not get along! <\/p>\n<p>Leave room for scaling. Docker swarm is perfect for this. <br \/>\nDocker Swarm is a tool for creating and managing container clusters across different machines as well as multiple containers on a single machine.<\/p>\n<p>Using swarm, I can determine how many resources I will allocate to each process and how many processes of the same service I will start, while the internal load balancer, taking data on a specified port, will automatically proxy it to the processes. Thus, noticing that the server load has increased, I can add more processes, thereby reducing the load on specific processes.<\/p>\n<h4>9. Disposability<\/h4>\n<p>\nDo not use queues for working with processes and data. Killing one process should affect the operation of the entire application. If one service fails, everything fails.<\/p>\n<p>Each process and service can be turned off at any moment and it should not affect other services (this not referring to the service being unavailable to another service, but rather that another service does not get turned off following this one). All processes should terminate gently, ensuring that data is not compromised and that the system will operate correctly upon the next start. This means that even in case of a crash, data should not be harmed (a transaction mechanism would be suitable here, where database requests work only in groups, and if even one request from the group fails or encounters an error, no other request from the group is actually executed).<\/p>\n<h4>10. Application Development\/Work Parity<\/h4>\n<p>\nProduction, staging, and local versions of the application must be different. On production, we have the Yii Lite framework, while locally we use Yii, so it works faster in production!<\/p>\n<p>In reality, all deployments and work with code should be in nearly identical environments (not referring to physical hardware). Also, deploying code to production, when necessary, should be possible for any development employee, not solely a specially trained devops department, which can only bring up the application in production through special means.<\/p>\n<p>Docker also assists us in this. By adhering to the previous points, using Docker will make the process of deploying the environment both in production and on a local machine as simple as entering one or two commands.<\/p>\n<h4>11. Logging<\/h4>\n<p>\nWe write logs to files and databases! We do not clean logs from files and databases. We'll just buy a hard drive with 9000 Petabytes and be fine.<\/p>\n<p>All logs should be considered as a stream of events. The application itself should not handle log processing. Logs should either be output to stdout or sent via a protocol like UDP, so that log handling does not create any issues for the application. Graylog is a good fit for this purpose. By accepting all logs over UDP (which does not require waiting for a response to confirm successful receipt of the packet), Graylog does not interfere with the application in any way and only focuses on structuring and processing logs. The application's logic remains unchanged when working with such approaches.<\/p>\n<h4>12. Administration Tasks<\/h4>\n<p>\nTo update data, the database, etc., use a separately created endpoint in the API. Executing it twice in a row could lead to data duplication. But you are not foolish enough to click it twice; migrations are unnecessary for us.<\/p>\n<p>All administration tasks must be performed in the same environment as the code, at the release level. This means that if we need to change the database structure, we will not do it manually by changing column names and adding new ones through some visual database management tools. For such tasks, we create separate scripts\u2014migrations\u2014that run everywhere and across all environments with a consistent and clear result. Similar methodologies should be applied for other tasks, such as populating the project with data.<\/p>\n<h3>Example implementation in PHP, Laravel, Laradock, Docker-Compose<\/h3>\n<p>\nP.S. All examples were done on MacOS. Most will also apply to Linux. Windows users, I apologize, but I haven't worked with Windows in a long time.<\/p>\n<p>Let's imagine a situation where no version of PHP is installed on our PC and there's nothing at all. <br \/>\nWe will install the latest versions of Docker and Docker-Compose. (This can be found online)<\/p>\n<pre><code class=\"bash\">docker -v &amp;&amp; \ndocker-compose -v\n<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Application development and Blue-Green deployment, based on The Twelve-Factor App methodology with examples in PHP and Docker.\" src=\"\/wp-content\/uploads\/2020\/02\/d9e77c47eef486befb6ebd8118403d13.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n1. Install <noindex><a rel=\"nofollow\" href=\"https:\/\/laradock.io\/\">Laradock<\/a><\/noindex><\/p>\n<pre><code class=\"bash\">git clone https:\/\/github.com\/Laradock\/laradock.git &amp;&amp; \nls\n<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Application development and Blue-Green deployment, based on The Twelve-Factor App methodology with examples in PHP and Docker.\" src=\"\/wp-content\/uploads\/2020\/02\/67b3214d9a5cff4596c4914ea6e199c5.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nRegarding Laradock, I must say that it is a very cool tool, packed with many containers and helpful features. However, I would not recommend using Laradock as is in production due to its redundancy. It's better to create your own containers based on examples from Laradock; that way, there will be room for optimization since no one needs everything there at once.<\/p>\n<p>2. Configure Laradock to work with our application.<\/p>\n<pre><code class=\"bash\">cd laradock &amp;&amp; \ncp env-example .env\n<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Application development and Blue-Green deployment, based on The Twelve-Factor App methodology with examples in PHP and Docker.\" src=\"\/wp-content\/uploads\/2020\/02\/df8107e1be933cc955be8ca5066f22f2.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n2.1. Open the habr directory (parent folder where laradock is cloned) in any editor. (In my case, PHPStorm)<\/p>\n<p>At this stage, we only set the project name.<\/p>\n<p><img decoding=\"async\" alt=\"Application development and Blue-Green deployment, based on The Twelve-Factor App methodology with examples in PHP and Docker.\" src=\"\/wp-content\/uploads\/2020\/02\/f6026fd04130590539e0945db30ec0dd.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n2.2. Start the workspace image. (In your case, the images will take some time to build)<br \/>\nWorkspace is a specially prepared image for framework work on behalf of the developer.<\/p>\n<p>Enter the container using <\/p>\n<pre><code class=\"bash\">docker-compose up -d workspace &amp;&amp; \ndocker-compose exec workspace bash\n<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Application development and Blue-Green deployment, based on The Twelve-Factor App methodology with examples in PHP and Docker.\" src=\"\/wp-content\/uploads\/2020\/02\/e839a5cd055b6c06c02cdd03a5054477.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n2.3. Install Laravel<\/p>\n<pre><code class=\"bash\">composer create-project --prefer-dist laravel\/laravel application<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Application development and Blue-Green deployment, based on The Twelve-Factor App methodology with examples in PHP and Docker.\" src=\"\/wp-content\/uploads\/2020\/02\/b21b3fc30ce1bec63aee43ab5fce53e3.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n2.4. After installation, check if the directory with the project has been created, and stop compose.<\/p>\n<pre><code class=\"bash\">ls\nexit\ndocker-compose down\n<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Application development and Blue-Green deployment, based on The Twelve-Factor App methodology with examples in PHP and Docker.\" src=\"\/wp-content\/uploads\/2020\/02\/e812f383138637656ec96804833cfc53.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n2.5. Go back to PHPStorm and set the correct path to our Laravel application in the .env file.<\/p>\n<p><img decoding=\"async\" alt=\"Application development and Blue-Green deployment, based on The Twelve-Factor App methodology with examples in PHP and Docker.\" src=\"\/wp-content\/uploads\/2020\/02\/abb9a5694d01163960af5375767f331b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n3. Let's add all the code to Git.<\/p>\n<p>To do this, create a repository on GitHub (or anywhere else). Go to the habr directory in the terminal and execute the following code.<\/p>\n<pre><code class=\"bash\">echo \"# habr-12factor\" &gt;&gt; README.md\ngit init\ngit add README.md\ngit commit -m \"first commit\"\ngit remote add origin git@github.com:nzulfigarov\/habr-12factor.git # here will be the link to your repo\ngit push -u origin master\ngit status\n<\/code><\/pre>\n<p>\nCheck if everything is okay. <\/p>\n<p><img decoding=\"async\" alt=\"Application development and Blue-Green deployment, based on The Twelve-Factor App methodology with examples in PHP and Docker.\" src=\"\/wp-content\/uploads\/2020\/02\/cbcb770a95d91655bdaf727be79742ab.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nFor convenience, I recommend using some visual interface for Git, in my case it's <noindex><a rel=\"nofollow\" href=\"https:\/\/www.gitkraken.com\/invite\/qXBXV9Wm\">GitKraken<\/a><\/noindex>. (here is the referral link)<\/p>\n<p>4. Let's start!<\/p>\n<p>Before starting, make sure nothing is running on ports 80 and 443.<\/p>\n<pre><code class=\"bash\">docker-compose up -d nginx php-fpm<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Application development and Blue-Green deployment, based on The Twelve-Factor App methodology with examples in PHP and Docker.\" src=\"\/wp-content\/uploads\/2020\/02\/f0bf0416e67b918e0966100e37c74454.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nThus, our project consists of 3 separate services:<\/p>\n<ul>\n<li>nginx \u2014 web server<\/li>\n<li>php-fpm \u2014 PHP for handling requests from the web server<\/li>\n<li>workspace \u2014 PHP for the developer<\/li>\n<\/ul>\n<p>\nAt this point, we have achieved the creation of an application that meets 4 of the 12 points, namely:<\/p>\n<p>1. <b>Codebase<\/b> \u2014 all code is in a single repository (a small note: it might be correct to put docker inside the laravel project, but this is not essential).<\/p>\n<p>2. <b>Dependencies<\/b> \u2014 All our dependencies are clearly stated in application\/composer.json and in each Dockerfile of each container.<\/p>\n<p>3. <b>Backing Services<\/b> \u2014 Each service (php-fpm, nginx, workspace) lives its own life and is connected from the outside, and while working with one service, the other will not be affected.<\/p>\n<p>4. <b>Processes<\/b> \u2014 each service is one process. Each of the services does not retain internal state.<\/p>\n<p>5.<b> Port Binding<\/b><\/p>\n<pre><code class=\"bash\">docker ps\n<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Application development and Blue-Green deployment, based on The Twelve-Factor App methodology with examples in PHP and Docker.\" src=\"\/wp-content\/uploads\/2020\/02\/e6e3fa4a12a43d1bcd51992c424c1245.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAs we can see, each service is running on its own port and is accessible to all other services.<\/p>\n<p>6.<b> Concurrency <\/b><\/p>\n<p>Docker allows us to spin up multiple processes of the same services with automatic load balancing between them. <\/p>\n<p>We will stop the containers and restart them using the flag <b>\u2014scale<\/b><\/p>\n<pre><code class=\"bash\">docker-compose down &amp;&amp; \ndocker-compose up -d --scale php-fpm=3 nginx php-fpm\n<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Application development and Blue-Green deployment, based on The Twelve-Factor App methodology with examples in PHP and Docker.\" src=\"\/wp-content\/uploads\/2020\/02\/f5d279b8a034512dd20024272c7f03b0.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAs we can see, copies of the php-fpm container have been created. We don't need to change anything in our work with this container. We continue to access it via port 9000, while Docker manages the load between the containers for us.<\/p>\n<p>7. <b>Disposability<\/b> \u2014 each container can be terminated without affecting others. Stopping or restarting a container will not impact the application in subsequent launches. Each container can also be started at any time.<\/p>\n<p>8. <b>Development\/Production Parity<\/b> \u2014 all our environments are identical. Once the system is running on the server in production, you won\u2019t have to change anything in your commands. Everything will be based on Docker exactly the same way.<\/p>\n<p>9. <b>Logs<\/b> \u2014 all logs in these containers are streamed and visible in the Docker console. (In this case, with other custom containers, it may not be the same if you don't take care of that.)<\/p>\n<pre><code class=\"bash\"> docker-compose logs -f<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Application development and Blue-Green deployment, based on The Twelve-Factor App methodology with examples in PHP and Docker.\" src=\"\/wp-content\/uploads\/2020\/02\/67e275042b96f5270534466b426d4fdc.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nHowever, there\u2019s a catch that the default values in PHP and Nginx also write logs to a file. To comply with the 12 factors, it's necessary to <b>disable<\/b> log writing to a file in the configurations of each container separately.<\/p>\n<p>Docker also provides the ability to direct logs not just to stdout, but also to things like graylog, which I mentioned above. Inside graylog, we can manipulate logs however we want, and our application won\u2019t notice this at all.<\/p>\n<p>10. <b>Admin Processes<\/b> \u2014 all administration tasks are handled by Laravel thanks to the artisan tool, just as the creators of the 12-factor app would want.<\/p>\n<p>As an example, I will show how some commands are executed.<br \/>\nLet's enter the container.<\/p>\n<pre><code class=\"bash\"> \ndocker-compose exec workspace bash\nphp artisan list\n<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Application development and Blue-Green deployment, based on The Twelve-Factor App methodology with examples in PHP and Docker.\" src=\"\/wp-content\/uploads\/2020\/02\/3d5fb5bc40b4b8b0cb225116c0f3d625.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNow we can use any command. (Note that we haven't configured the database or cache, so half the commands won't execute correctly, as they are intended to work with the cache and the database.)<\/p>\n<p><img decoding=\"async\" alt=\"Application development and Blue-Green deployment, based on The Twelve-Factor App methodology with examples in PHP and Docker.\" src=\"\/wp-content\/uploads\/2020\/02\/6f84bb2ade2ade654d2c361c585edeae.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n11. <b>Configurations<\/b> and 12. <b>Build, Release, Run<\/b><\/p>\n<p>I wanted to dedicate this part to Blue-Green Deployment, but it turned out to be too elaborate for this article. I will write a separate article about this. <\/p>\n<p>In short, the concept is built on CI\/CD systems like <b>Jenkins<\/b> and <b>Gitlab CI<\/b>. In both, you can set environment variables related to a specific environment. Accordingly, this setup will execute the point regarding <b>Configurations<\/b>.<\/p>\n<p>And the point about <b>Build, Release, Run<\/b> is resolved by functions built into both utilities called <b>Pipeline<\/b>.<\/p>\n<p><b>Pipeline<\/b> allows you to break down the deployment process into several stages, highlighting the build, release, and execution phases. Additionally, in the Pipeline, you can create backups, or really anything else. This tool has limitless potential.<\/p>\n<p>The application code resides on <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/nzulfigarov\/habr-12factor\">Github<\/a><\/noindex>.<br \/>\nDon\u2019t forget to initialize the submodule when cloning this repository.<\/p>\n<p>P.S.: All these approaches can be used with any other tools and programming languages. The main thing is that the essence remains unchanged.<br \/>\n<br \/>Source: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/480020\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0442\u0435\u043e\u0440\u0438\u0438. \u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 The Twelve-Factor App? \u041f\u0440\u043e\u0441\u0442\u044b\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438, \u044d\u0442\u043e \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442 \u043f\u0440\u0438\u0437\u0432\u0430\u043d\u043d\u044b\u0439 \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443 SaaS \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439, \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u0442\u0435\u043c \u0447\u0442\u043e, \u043e\u0441\u0432\u0435\u0434\u043e\u043c\u043b\u044f\u0435\u0442 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u0438 DevOps \u0438\u043d\u0436\u0435\u043d\u0435\u0440\u043e\u0432 \u043e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u0445 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0430\u0445 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0447\u0430\u0449\u0435 \u0432\u0441\u0435\u0433\u043e \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u043b\u0438\u0441\u044c \u0432 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439. \u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442 \u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u043c\u0438 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b Heroku. \u041c\u0435\u0442\u043e\u0434\u043e\u043b\u043e\u0433\u0438\u044f \u0434\u0432\u0435\u043d\u0430\u0434\u0446\u0430\u0442\u0438 \u0444\u0430\u043a\u0442\u043e\u0440\u043e\u0432(The Twelve-Factor App) \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0430 \u0434\u043b\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 \u043b\u044e\u0431\u043e\u043c [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":40597,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-40596","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.2 - aioseo.com -->\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/en\/blog\/razrabotka-prilozhenij-i-blue-green-deployment-opirayas-na-metodologiyu-the-twelve-factor-app-s-primerami-na-php-i-docker\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0438 Blue-Green deployment, \u043e\u043f\u0438\u0440\u0430\u044f\u0441\u044c \u043d\u0430 \u043c\u0435\u0442\u043e\u0434\u043e\u043b\u043e\u0433\u0438\u044e The Twelve-Factor App \u0441 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u043c\u0438 \u043d\u0430 php \u0438 docker | ProHoster\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/en\/blog\/razrabotka-prilozhenij-i-blue-green-deployment-opirayas-na-metodologiyu-the-twelve-factor-app-s-primerami-na-php-i-docker\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-02-02T07:38:43+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-02-02T07:38:43+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Application development and Blue-Green deployment, based on The Twelve-Factor App methodology with examples in php and docker | ProHoster","description":"","canonical_url":"https:\/\/prohoster.info\/en\/blog\/razrabotka-prilozhenij-i-blue-green-deployment-opirayas-na-metodologiyu-the-twelve-factor-app-s-primerami-na-php-i-docker","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"en_US","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0438 Blue-Green deployment, \u043e\u043f\u0438\u0440\u0430\u044f\u0441\u044c \u043d\u0430 \u043c\u0435\u0442\u043e\u0434\u043e\u043b\u043e\u0433\u0438\u044e The Twelve-Factor App \u0441 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u043c\u0438 \u043d\u0430 php \u0438 docker | ProHoster","og:url":"https:\/\/prohoster.info\/en\/blog\/razrabotka-prilozhenij-i-blue-green-deployment-opirayas-na-metodologiyu-the-twelve-factor-app-s-primerami-na-php-i-docker","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-02-02T07:38:43+00:00","article:modified_time":"2020-02-02T07:38:43+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"40596","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 19:20:45","updated":"2022-09-27 22:57:35","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/posts\/40596","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/comments?post=40596"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/posts\/40596\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/media\/40597"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/media?parent=40596"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/categories?post=40596"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/tags?post=40596"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}