In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article mainly introduces "how to build a PHP development environment based on Docker". In daily operation, I believe many people have doubts about how to build a PHP development environment based on Docker. The editor consulted all kinds of materials and sorted out simple and easy-to-use operation methods. I hope it will be helpful to answer the doubts about "how to build a PHP development environment based on Docker". Next, please follow the editor to study!
What is a good development environment?
First of all, we need to know what a good development environment is. For me, a good development environment needs to have the following characteristics:
Feel free to use it. I must be able to delete and create new environments at will.
Quick start. When I want to work with it, it can be used right away.
Easy to update. In our industry, things are changing so fast that it must make it easy for me to update my development environment to a new software version.
Docker supports these features, and even more. You can destroy and rebuild the container almost immediately, while updating the environment only needs to rebuild the image you are currently using.
What is the PHP development environment
At present, the application of Web is complex, and the PHP development environment needs a lot of things. In order to ensure the simplicity of the environment, we need to do a variety of restrictions.
This time we use Nginx, PHP5-FPM, and MySQL to run the Synmfony project.
Pet and Cattle
Another focus we want to discuss is whether we want to deploy the development environment in multiple containers or in a single container. The two approaches have their own advantages:
A single container is easy to distribute and maintain. Because they are independent, everything runs in the same container, which is like a virtual machine. But it also means that when you upgrade something (such as a new version of PHP), you need to rebuild the entire container.
Multiple containers can provide better modularity when adding components. Because each container contains part of the stack: Web, PHP, MySQL, and so on, each service can be extended or added separately without having to rebuild everything.
Because I am lazy and I need to put something else on my notebook, we will only introduce the method of a single container here.
Initialization project
The first thing to do is to initialize a new Symfony project. The recommended method is to use composer's create-project command. Composer could have been installed on a workstation, but that was too easy. This time we will use it through Docker.
I previously posted an article about the Docker command: make docker commands (well, I lied, I wrote it in this article, and then I thought it would be better to be independent).
Anyway, you can read it. Next, if you don't already have the composer command, you can create your own composer alias.
$alias composer= "docker run-I-t-v\ $PWD:/srv ubermuda/composer"
Now you can initialize the Symfony project:
$composer create-project symfony/framwork-standard-edition SomeProject
Awesome! Let's do some real work.
Container
Building a self-sufficient container that runs a standard Symfony project is fairly easy, just install the commonly used Nginx, PHP5-FPM, and MySQL-Server, throw in the pre-prepared Nginx virtual host configuration file, and copy some configuration files in.
The source code for this container can be found in the ubermuda/docker-symfony repository on GitHub. Dockerfile is the configuration file used to build the image of Docker. Let's take a look at:
FROM debian:wheezyENV DEBIAN_FRONTEND noninteractiveRUN apt-get update-yRUN apt-get install-y nginx php5-fpm php5-mysqlnd php5-cli mysql-server supervisorRUN sed-e's pacing inception daemonize = yes/daemonize = no/'-I / etc/php5/fpm/php-fpm.confRUN sed-e's pacing Listen\ .group / listen.group/'-I / etc/php5/fpm/pool.d/www.confRUN echo "\ ndaemon off;" > > / etc/nginx/nginx.confADD vhost.conf / etc/nginx/sites-available/defaultADD supervisor.conf / etc/supervisor/conf.d/supervisor.confADD init.sh / init.shEXPOSE 80 3306VOLUME ["/ srv"] WORKDIR / srvCMD ["/ usr/bin/supervisord"]
We start by extending the basic image of debian:wheezy, and then configure Nginx and PHP5-FPM through a series of sed commands.
The copy code is as follows:
RUN sed-e's Universe = yes/daemonize = no/'-I / etc/php5/fpm/php-fpm.conf
RUN sed-e's Universe\ .owner / listen.owner/'-I / etc/php5/fpm/pool.d/www.conf
RUN sed-e's Compact [.group / listen.group/'-I / etc/php5/fpm/pool.d/www.conf]
RUN echo "\ ndaemon off;" > > / etc/nginx/nginx.conf
We have two things to do here. First configure PHP5-FPM and Nginx to run them in the foreground so that supervisord can track them.
Then, configure PHP5-FPM to run Web-Server for the specified user and handle the file permissions.
Next, you need to install a set of configuration files, starting with Nginx's virtual host configuration file vhost.conf:
Server {listen 80; server_name _; access_log / var/log/nginx/access.log; error_log / var/log/nginx/error.log; root / srv/web; index app_dev.php; location / {try_files $uri $uri/ / app_dev.php?$query_string;} location ~ [^ /]\ .php (/ | $) {fastcgi_pass unix:/var/run/php5-fpm.sock; include fastcgi_params;}}
Because we don't need a domain name, we set server_name to _ (a bit like the $_ placeholder variable of perl) and configure the document root to / svr/web. We will deploy the application under / srv, and the rest is the standard Mginx + PHP5-FPM configuration.
Because a container can only run one program at a time, we need supervisord (or any other process manager, but I prefer supervisord). Fortunately, this process manager produces all the processes we need! Here is a short supervisord configuration:
[supervisord] nodaemon= true[program: nginx] command=/usr/sbin/ nginx[program: php5-fpm] command=/usr/sbin/php5- fpm[program: mysql] command=/usr/bin/mysqld_ safe[program: init] command=/init.shautorestart=falseredirect_stderr=trueredirect_stdout=/srv/app/logs/init.log
What we need to do here is to define all the services, plus a special program:init process, which is not an actual service, but an original way to run startup scripts.
The problem with this startup script is that it usually needs to start some services first. For example, you may want to initialize some database tables, but only if you run MySQL first. One possible solution is to start MySQL in the startup script, then initialize the table, and then stop MySQL and finally start supervisord in order to prevent process management from affecting supervisord.
Such a script looks like this:
/ etc/init.d/mysql startapp/console doctrine:schema:update-- force/etc/init.d/mysql stopexec / usr/bin/supervisord
Does it look ugly? let's take a different approach and let supervisor run it and never restart it.
The actual init.sh script is as follows:
#! / bin/bashRET=1while [[RET-ne 0]]; do sleep 1; mysql-e 'exit' > / dev/null 2 > & 1; RET=$?doneDB_NAME=$ {DB_NAME:-symfony} mysqladmin-u root create $DB_NAMEif [- n "$INIT"]; then / srv/$INITfi
The script waits for MySQL to start, then creates a DB based on the environment variable DB_NAME, which defaults to symfony, then looks in the INIT environment variable for the script to run and tries to run it. How to use these environment variables is explained at the end of this article.
Build and run the image
Everything is ready except the east wind. We also need to build a Symfony Docker image, using the docker build command:
$cd docker-symfony$ docker build-t symfony.
Now you can use it to run your Symfony project:
$cd SomeProject$ docker run-I-t-P-v $PWD:/srv symfony
Let's take a look at what this series of options are for:
-I activate interactive mode, that is, STDIO (standard input and output) is connected to your current terminal. It is useful when you want to receive logs or send signals to processes.
-t creates a virtual TTY for the container, which is a good friend with-I and is usually used together.
-P tells the Docker daemon to publish all specified ports, in this case port 80.
-v $PWD:/srv mounts the current directory to the container's / srv directory. Mounting a directory makes the contents of the directory available to the target mount point.
Now you remember the DB_NAME and INIT environment variables mentioned earlier, what are they for: to customize your environment. Basically you can set the environment variable in the container through the-e option of docker run, and the startup script will get the environment variable, so if your DB is named some_project_dev, you can run the container like this:
$docker run-I-t-P-v $PWD:/srv-e DB_NAME=some_project_dev symfony
The INIT environment variable is even more powerful, allowing you to run specified scripts at startup. For example, you have a bin/setup script that runs the composer install command and sets up the database schema:
#! / bin/bashcomposer installapp/console doctrine:schema:update-- force
Run it with-e:
$docker run-I-t-P\-v $PWD:/srv\-e DB_NAME=some_project_dev\-e INIT=bin/setup
Note that the-e option can be used many times in docer run and looks pretty cool. In addition, your startup script requires executable permissions (chmod + x).
Now let's send a request to the container via curl to check that everything is working as expected. First, we need to fetch the public port of port 80 that Docker maps to the container, and use the docker port command:
$docker port $(docker ps-aql 1) 800.0.0.0 purl 49153
Docker ps-aql 1 is a good command to easily retrieve the id of the last container. In our example, Docker maps the container's port 80 to port 49153. Let's take a look at curl.
$curl http://localhost:49153You are not allowed to access this file. Check app_dev.php for more information.
When we do not access dev controller from localhost, we get the default error message of Symfony, which is perfectly normal, because we do not send curl requests from inside the container, so these lines can be safely removed from the front-end controller web/app_dev.php.
/ / This check prevents access to debug front controllers that are deployed by accident to production servers.// Feel free to remove this, extend it, or make something more sophisticated.if (isset ($_ SERVER ['HTTP_CLIENT_IP']) | | isset ($_ SERVER [' HTTP_X_FORWARDED_FOR']) | |! (in_array (@ $_ SERVER ['REMOTE_ADDR'], array (' 127.0.0.1), 'fe80::1' ':: 1')) | | php_sapi_name () =' cli-server')) {header ('HTTP/1.0 403 Forbidden') Exit ('You are not allowed to access this file. Check'. Basename (_ _ FILE__). For more information.');}
These lines block access to dev controller from anywhere other than localhost.
Now you can work properly when you curl, or use a browser to access http://localhost:49153/:
At this point, the study on "how to build a Docker-based PHP development environment" is over. I hope to be able to solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.