.. include:: /_includes/all.rst .. _vhost_gen_example_add_sub_domains: ************************ Example: add sub domains ************************ This tutorial gives you a brief overview how to serve your project under one subdomain via the project directory name as well as how to serve one project with multiple subdomains with a customized virtual host config via ``vhost-gen``. **Table of Contents** .. contents:: :local: Simple sub domains for one project ================================== When you just want to serve your project under different sub domains, you simply name your project directory by the name of it. See the following examples how you build up your project URL. +----------------+----------------+---------------------------------+ | Project dir | ``TLD_SUFFIX`` | Project URL | +================+================+=================================+ | my-test | ``loc`` | ``http://my-test.loc`` | +----------------+----------------+---------------------------------+ | www.my-test | ``loc`` | ``http://www.my-test.loc`` | +----------------+----------------+---------------------------------+ | t1.www.my-test | ``loc`` | ``http://t1.www.my-test.loc`` | +----------------+----------------+---------------------------------+ | my-test | ``local`` | ``http://my-test.local`` | +----------------+----------------+---------------------------------+ | www.my-test | ``local`` | ``http://www.my-test.local`` | +----------------+----------------+---------------------------------+ | t2.www.my-test | ``local`` | ``http://t2.www.my-test.local`` | +----------------+----------------+---------------------------------+ Whatever name you want to have in front of the ``TLD_SUFFIX`` is actually just the directory you create. Generically, it looks like this: +----------------+----------------+-------------------------------+ | Project dir | ``TLD_SUFFIX`` | Project URL | +================+================+===============================+ | | ```` | ``http://.`` | +----------------+----------------+-------------------------------+ .. important:: The project directories must be real directories and not symlinks! See example below for how to set it up. Example ------- Prerequisite ^^^^^^^^^^^^ Let's assume the following settings. +-------------------------------+--------------------------------------+ | Variable | Value | +===============================+======================================+ | :ref:`env_tld_suffix` | ``loc`` | +-------------------------------+--------------------------------------+ | :ref:`env_httpd_docroot_dir` | ``htdocs`` | +-------------------------------+--------------------------------------+ | Project name / directory | ``my-test`` | +-------------------------------+--------------------------------------+ | Sub domain 1 / directory | ``api.my-test`` | +-------------------------------+--------------------------------------+ | Sub domain 2 / directory | ``www.my-test`` | +-------------------------------+--------------------------------------+ * Project which holds the data is ``my-test`` * Web root of ``my-test`` is in ``my-test/FRAMEWORK/public`` * Same project should be available under ``api.my-test`` and ``www.my-test`` Directory structure ^^^^^^^^^^^^^^^^^^^ .. code-block:: bash host> tree -L 2 . ├── my-test │   ├── FRAMEWORK │   └── htdocs -> FRAMEWORK/public ├── api.my-test │   └── htdocs -> ../my-test/FRAMEWORK/public └── www.my-test └── htdocs -> ../my-test/FRAMEWORK/public * ``my-test``, ``api.my-test`` and ``www.my-test`` must be **normal directories** (not symlinks). * The *framework data* resided in ``my-test``. * Each projects ``htdocs`` directory is a symlink pointing to the web root of the *framework* in ``my-test`` With this structure you will have three domains available pointing to the same project: * http://my-test.loc * http://api.my-test.loc * http://www.my-test.loc Complex sub domains for one project =================================== When you want to have more complex sub domains for one project (such as in the case of Wordpress multi-sites), you will need to customize your virtual host config for this project and make the web server allow to serve your files by different server names. Each web server virtual host is auto-generated by a tool called |ext_lnk_project_vhost_gen|. ``vhost-gen`` allows you to overwrite its default generation process via templates. Those templates can be added to each project, giving you the option to customize the virtual host of this specific project. .. note:: :ref:`customize_all_virtual_hosts_globally` and :ref:`customize_specific_virtual_host` .. note:: :ref:`vhost_gen_virtual_host_templates` Ensure you have read and understand how to customize virtual hosts globally with ``vhost-gen``. :ref:`vhost_gen_customize_all_virtual_hosts_globally` Ensure you have read and understand how to customize virtual hosts globally with ``vhost-gen``. :ref:`vhost_gen_customize_specific_virtual_host` Ensure you have read and understand how to customize your virtual host with ``vhost-gen``. :ref:`env_httpd_template_dir` Ensure you know what this variable does inside your ``.env`` file. .. important:: When adjusting vhost-gen templates for a project you have to do **one** of the following: * Restart the devilbox * Or rename your project directory to some other name and then rename it back to its original name. More information here: :ref:`custom_vhost_apply_vhost_gen_changes` .. warning:: Pay close attention that you do not use TAB (``\t``) characters for indenting the vhost-gen yaml files. Some editors might automatically indent using TABs, so ensure they are replaced with spaces. If TAB characters are present, those files become invalid and won't work. https://github.com/cytopia/devilbox/issues/142 You can use the bundled ``yamllint`` binary inside the container to validate your config. **See also:** * :ref:`work_inside_the_php_container` * :ref:`available_tools` Prerequisite ------------ Let's assume the following settings. +-------------------------------+--------------------------------------+ | Variable | Value | +===============================+======================================+ | Devilbox path | ``/home/user/devilbox`` | +-------------------------------+--------------------------------------+ | :ref:`env_httpd_template_dir` | ``.devilbox`` | +-------------------------------+--------------------------------------+ | :ref:`env_httpd_datadir` | ``./data/www`` | +-------------------------------+--------------------------------------+ | :ref:`env_tld_suffix` | ``loc`` | +-------------------------------+--------------------------------------+ | Project name/directory | ``project-1`` (Ensure it exist) | +-------------------------------+--------------------------------------+ Ensure that the default ``vhost-gen`` templates have been copied to your projects template directory: .. code-block:: bash # Navigate to the Devilbox directory host> cd ./home/user/devilbox # Create template directory in your project host> mkdir ./data/www/project-1/.devilbox # Copy vhost-gen templates host> cp cfg/vhost-gen/*.yml ./data/www/project-1/.devilbox By having done all prerequisite, your project should be available under http://my-project-1.loc Now you are all set and we can dive into the actual configuration. .. _tutorial_adding_sub_domains_apache_22: Apache 2.2 ---------- Adding ``www`` sub domain ^^^^^^^^^^^^^^^^^^^^^^^^^ Let's also make this project available under http://www.my-project-1.loc Step 1: Add DNS entry """"""""""""""""""""" The first step would be to add an additional DNS entry for ``www.my-project-1.loc``. See here how to do that for Linux, MacOS or Windows: :ref:`getting_started_create_your_first_project_dns_entry` DNS is in place, however when you visit http://www.my-project-1.loc, you will end up seeing the Devilbox intranet, because this is the default host when no match has been found. Step 2: Adjust apache22.yml """"""""""""""""""""""""""" Next you will have to adjust the Apache 2.2 vhost configuration template. The current default template looks similar to the one shown below (**Note:** Only the ``vhost:`` sub section is shown here). .. code-block:: yaml :caption: /home/user/devilbox/data/www/project-1/.devilbox/apache22.yml :emphasize-lines: 3 vhost: | ServerName __VHOST_NAME__ CustomLog "__ACCESS_LOG__" combined ErrorLog "__ERROR_LOG__" __VHOST_DOCROOT__ __VHOST_RPROXY__ __PHP_FPM__ __ALIASES__ __DENIES__ __SERVER_STATUS__ # Custom directives __CUSTOM__ All you will have to do, is to add another ``ServerName`` directive: .. code-block:: yaml :caption: /home/user/devilbox/data/www/project-1/.devilbox/apache22.yml :emphasize-lines: 3,4 vhost: | ServerName __VHOST_NAME__ ServerName www.__VHOST_NAME__ CustomLog "__ACCESS_LOG__" combined ErrorLog "__ERROR_LOG__" __VHOST_DOCROOT__ __VHOST_RPROXY__ __PHP_FPM__ __ALIASES__ __DENIES__ __SERVER_STATUS__ # Custom directives __CUSTOM__ Step 3: Apply new changes """"""""""""""""""""""""" The **last step** is to actually to apply those changes. This is equal for all web servers. Go to :ref:`tutorial_adding_sub_domains_apply_changes` and follow the steps. Afterwards you can go and visit http://www.my-project-1.loc and you should see the same page as if you visit http://my-project-1.loc Adding catch-all sub domain ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Let's also make this project available under any sub domain. Step 1: Add DNS entry """"""""""""""""""""" The first step would be to add DNS entries for all sub domains you require. See here how to do that for Linux, MacOS or Windows: :ref:`getting_started_create_your_first_project_dns_entry` This however is not really convenient. If you have basically infinite sub domains (via catch-all), you should consider using Auto-DNS instead: :ref:`setup_auto_dns`. Step 2: Adjust apache22.yml """"""""""""""""""""""""""" Next you will have to adjust the Apache 2.2 vhost configuration template. The current default template looks similar to the one shown below (**Note:** Only the ``vhost:`` sub section is shown here). .. code-block:: yaml :caption: /home/user/devilbox/data/www/project-1/.devilbox/apache22.yml :emphasize-lines: 3 vhost: | ServerName __VHOST_NAME__ CustomLog "__ACCESS_LOG__" combined ErrorLog "__ERROR_LOG__" __VHOST_DOCROOT__ __VHOST_RPROXY__ __PHP_FPM__ __ALIASES__ __DENIES__ __SERVER_STATUS__ # Custom directives __CUSTOM__ All you will have to do, is to add another ``ServerName`` directive which does catch-all: .. code-block:: yaml :caption: /home/user/devilbox/data/www/project-1/.devilbox/apache22.yml :emphasize-lines: 3,4 vhost: | ServerName __VHOST_NAME__ ServerName *.__VHOST_NAME__ CustomLog "__ACCESS_LOG__" combined ErrorLog "__ERROR_LOG__" __VHOST_DOCROOT__ __VHOST_RPROXY__ __PHP_FPM__ __ALIASES__ __DENIES__ __SERVER_STATUS__ # Custom directives __CUSTOM__ Step 3: Apply new changes """"""""""""""""""""""""" The **last step** is to actually to apply those changes. This is equal for all web servers. Go to :ref:`tutorial_adding_sub_domains_apply_changes` and follow the steps. Apache 2.4 ---------- The procedure for Apache 2.4 is exactly the same as for Apache 2.2, even the syntax is identical. The only difference is that you need to adjust ``apache24.yml`` instead of ``apache22.yml``. Just go up one section: :ref:`tutorial_adding_sub_domains_apache_22` Nginx ----- The procedure for Nginx is also exactly the same as for Apache 2.4, however the syntax of its ``nginx.yml`` file is slightly different, that's why the whole tutorial will be repeated here fitted for Nginx. Adding ``www`` sub domain ^^^^^^^^^^^^^^^^^^^^^^^^^ Let's also make this project available under http://www.my-project-1.loc Step 1: Add DNS entry """"""""""""""""""""" The first step would be to add an additional DNS entry for ``www.my-project-1.loc``. See here how to do that for Linux, MacOS or Windows: :ref:`getting_started_create_your_first_project_dns_entry` DNS is in place, however when you visit http://www.my-project-1.loc, you will end up seeing the Devilbox intranet, because this is the default host when no match has been found. Step 2: Adjust nginx.yml """"""""""""""""""""""""""" Next you will have to adjust the Nginx vhost configuration template. The current default template looks similar to the one shown below (**Note:** Only the ``vhost:`` sub section is shown here). .. code-block:: yaml :caption: /home/user/devilbox/data/www/project-1/.devilbox/nginx.yml :emphasize-lines: 4 vhost: | server { listen __PORT____DEFAULT_VHOST__; server_name __VHOST_NAME__; access_log "__ACCESS_LOG__" combined; error_log "__ERROR_LOG__" warn; __VHOST_DOCROOT__ __VHOST_RPROXY__ __PHP_FPM__ __ALIASES__ __DENIES__ __SERVER_STATUS__ # Custom directives __CUSTOM__ } All you will have to do, is to extend the ``server_name`` directive: .. code-block:: yaml :caption: /home/user/devilbox/data/www/project-1/.devilbox/nginx.yml :emphasize-lines: 4 vhost: | server { listen __PORT____DEFAULT_VHOST__; server_name __VHOST_NAME__ www.__VHOST_NAME__; access_log "__ACCESS_LOG__" combined; error_log "__ERROR_LOG__" warn; __VHOST_DOCROOT__ __VHOST_RPROXY__ __PHP_FPM__ __ALIASES__ __DENIES__ __SERVER_STATUS__ # Custom directives __CUSTOM__ } Step 3: Apply new changes """"""""""""""""""""""""" The **last step** is to actually to apply those changes. This is equal for all web servers. Go to :ref:`tutorial_adding_sub_domains_apply_changes` and follow the steps. Afterwards you can go and visit http://www.my-project-1.loc and you should see the same page as if you visit http://my-project-1.loc Adding catch-all sub domain ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Let's also make this project available under any sub domain. Step 1: Add DNS entry """"""""""""""""""""" The first step would be to add DNS entries for all sub domains you require. See here how to do that for Linux, MacOS or Windows: :ref:`getting_started_create_your_first_project_dns_entry` This however is not really convenient. If you have basically infinite sub domains (via catch-all), you should consider using Auto-DNS instead: :ref:`setup_auto_dns`. Step 2: Adjust nginx.yml """"""""""""""""""""""""""" Next you will have to adjust the Nginx vhost configuration template. The current default template looks similar to the one shown below (**Note:** Only the ``vhost:`` sub section is shown here). .. code-block:: yaml :caption: /home/user/devilbox/data/www/project-1/.devilbox/nginx.yml :emphasize-lines: 4 vhost: | server { listen __PORT____DEFAULT_VHOST__; server_name __VHOST_NAME__; access_log "__ACCESS_LOG__" combined; error_log "__ERROR_LOG__" warn; __VHOST_DOCROOT__ __VHOST_RPROXY__ __PHP_FPM__ __ALIASES__ __DENIES__ __SERVER_STATUS__ # Custom directives __CUSTOM__ } All you will have to do, is to extend the ``server_name`` directive with a catch-all: .. code-block:: yaml :caption: /home/user/devilbox/data/www/project-1/.devilbox/nginx.yml :emphasize-lines: 4 vhost: | server { listen __PORT____DEFAULT_VHOST__; server_name __VHOST_NAME__ *.__VHOST_NAME__; access_log "__ACCESS_LOG__" combined; error_log "__ERROR_LOG__" warn; __VHOST_DOCROOT__ __VHOST_RPROXY__ __PHP_FPM__ __ALIASES__ __DENIES__ __SERVER_STATUS__ # Custom directives __CUSTOM__ } Step 3: Apply new changes """"""""""""""""""""""""" The **last step** is to actually to apply those changes. This is equal for all web servers. Go to :ref:`tutorial_adding_sub_domains_apply_changes` and follow the steps. .. _tutorial_adding_sub_domains_apply_changes: Apply changes ------------- After having edited your vhost-gen template files, you still need to apply these changes. This can be achieved in two ways: 1. Restart the Devilbox 2. Rename your project directory back and forth Let's cover the second step .. code-block:: bash # Navigate to the data directory host> /home/user/devilbox/data/www # Rename your project to something else host> mv project-1 project-1.tmp # Rename your project to its original name host> mv project-1.tmp project-1 If you want to understand what is going on right now, check the docker logs for the web server. .. code-block:: bash # Navigate to the devilbox directory host> /home/user/devilbox # Check docker logs host> docker-compose logs httpd httpd_1 | vhostgen: [2018-03-18 11:46:52] Adding: project-1.tmp.loc httpd_1 | watcherd: [2018-03-18 11:46:52] [OK] ADD: succeeded: /shared/httpd/project-1.tmp httpd_1 | watcherd: [2018-03-18 11:46:52] [OK] DEL: succeeded: /shared/httpd/project-1 httpd_1 | watcherd: [2018-03-18 11:46:52] [OK] TRIGGER succeeded: /usr/local/apache2/bin/httpd -k restart httpd_1 | vhostgen: [2018-03-18 11:46:52] Adding: project-1loc httpd_1 | watcherd: [2018-03-18 11:46:52] [OK] ADD: succeeded: /shared/httpd/project-1 httpd_1 | watcherd: [2018-03-18 11:46:52] [OK] DEL: succeeded: /shared/httpd/project-1.tmp httpd_1 | watcherd: [2018-03-18 11:46:52] [OK] TRIGGER succeeded: /usr/local/apache2/bin/httpd -k restart **What happened?** The directory changes have been noticed and a new virtual host has been created. This time however your new vhost-gen template has been read and the changes have applied. Checklist --------- 1. Template files are copied from ``cfg/vhost-gen/*`` to your project template dir (as specified in ``.env`` via ``HTTPD_TEMPLATE_DIR``) 2. Ensure the vhost-gen yaml files are valid (No tab characters) 3. When templates are edited, the Devilbox is either restarted or the project directory is renamed to something else and then renamed back to its original name