Hello! Today I would like to talk about how there are ways to arrange brunches for each task and how we did it in Alawar. Here is a simple technique with apache2, which allows you to get excellent results and can be useful both for web developers and system administrators. It is worth noting that similar solutions have already been covered in Habré (for example,
here ), but often they are written for too narrow an audience and do not give answers to all the questions and, most importantly, often complicate the task. The purpose of this particular article is to show how simple everything really is.
So, let's begin.
A few years ago, we had a problem, which was that it was sufficiently time-consuming to prepare a separate test platform on the server for each task. At that time, one branch (trunk) was used in the repository for all developers and one test server. For large tasks, of course, separate instances were manually prepared, but this was a forced measure rather than a normal solution. All this periodically led to conflicts in the code in the course of development, and the saddest thing - to unexpected failures of one task, because of the work done in the framework of another task.
')
A little about the features of the project
This is one of our major projects (alawar.ru, alawar.com, etc.), the essence of which is to provide different content from different domains in different languages. Within the framework of one project, about hundreds of domains and subdomains are involved.
Any change in the code is accompanied by a corresponding ticket in the bugtracker. Tickets of various sizes are performed several dozen per week. Test each ticket separately.
The repository, when solving this problem is not critical, you can use any where it is possible to conduct development in a separate branch, so I will not specifically focus on this issue.
What were our options
1. Create a server configuration manually
In fact, we did this for a long time, but not for all tasks, since it took really a lot of time. Therefore, they created only what is needed and, if possible, only the necessary minimum.
2. Set up 1-2 test stands per developer
This approach allows the developer to show one task and do the second, but the rest of the tasks with this configuration will not look. And there is confusion when the developer switches the test bench to another task.
3. On the test server, change the rules for forming and processing URLs
For example, to make all the links in a project according to this principle:
http: // test.local / (task-number) / (host) / (uri) .
There was such an option, but it required a very large refactoring, so common sense did not allow us to go this way. But this does not mean that this method is not suitable for others.
4. Virtuals for each task
The idea is that the hosts and the paths are always the same, the code from the desired task, the database and other services are their own. In terms of testing, this is probably the ideal option.
In our case, one full instance code, along with the database, along with the statics, etc. - This is tens of gigabytes of data. Just raising such an instance from scratch would take us quite a long time. In addition, more than one terabyte of data would be required for all current tasks. But most importantly, in this case it would not be enough for us to simply give a link to the realized task in order to show the result to the customer. It would be necessary to launch it in advance, and this option did not seem convenient to us.
5. Use virtual hosts
In apache2 there are parameters UseCanonicalName and VirtualDocumentRoot (
Link to documentation ). They allow you to use host subdomains as part of the path to the doc. project root and all this without restarting apache2. Thanks to these parameters, we can actually specify the path to the + uri instance on the host in order to get the answer we need.
Our choice
As a result, we chose the option with virtual hosts and defined the following address format:
http: // (task-number). (site-identifier). test.local / (uri) .
Where (site-identifier) ​​can take values ​​of the form:
• ru - in this case, we understand that you need to show the main site in the .ru zone
• com - the main site in the zone. Com
• test.ru - test subdomain of the main site in the .ru zone
• data.export.com - the data.export subdomain of the main site in the .com zone
For projects where there is no concept of the main site, the following rules apply:
• example.com - in this case, we understand that we need to show the site example.com
• test. example.com is a subdomain test. example.com
• data.export. example.com is a subdomain of data.export. example.com
• etc.
As a result, typing the address in the browser:
http: //task-1234.example.com.test.local/some/page/? SomeParams = value we definitely know that the server will give the answer from the task-task branch of task-1234, the site handler example.com/some/page/?someParams=value.
In order for everything to work as we planned it, it was necessary to fix the ways to the doc.rut as follows:
/data/projects/projectName/branches/(task-number)/application/public
And train the project to determine the host name, according to our rules.
Of the features, I can note that for systems where file paths are important, (task-number) and (site-identifier) ​​must be in lower case.
Apache2 test platform configuration example:
<VirtualHost *:80> UseCanonicalName Off VirtualDocumentRoot /data/projects/projectName/branches/%1/application/public ServerName test.local ServerAlias *.test.local Options -Indexes CustomLog /dev/null combined </VirtualHost>
Automatic Deploy
Ultimately, scripts were written for automated deployments that create the necessary code branch in the repository, unpack and set up a local instance on a test server in a couple of minutes, but this is already a separate topic, here I will tell about it in general terms.
Deploy automation can be done by various means (script on bash, phing, ant, etc.).
This method consists in prescribing a sequence of commands that must be executed to raise the instance of your project. For most web projects, it will look something like this:
1. Ask for a task-number (or get the name of a branch as a parameter);
2. Create a brunch in the repository, if it is not;
3. Create a folder for the brunch (if not);
4. Make a checkout (s) of the code;
5. Set the rights to write to the necessary folders / files;
6. Configure the project configuration;
7. Put down the necessary symlinks;
8. (perform other specific project actions);
9. Run the initialization scripts of the project;
10. If you want to run tests to make sure everything is ok.
So,
on projects that can use apache2 as a server, you can easily use the method described in this article to identify the correct version of the site through virtual hosts.
If you know other ways of preparing test sites for each branch that are not described in this article, write about them in the comments, I think it will be very useful to all readers.