cytopia / devilbox

A modern Docker LAMP stack and MEAN stack for local development
http://devilbox.org
MIT License
4.38k stars 653 forks source link

How to add subdomains? #142

Closed mrpsiho closed 6 years ago

mrpsiho commented 6 years ago

Hi,

I'm sorry, I'm not sure how can I use devilbox along with WP multisite? To be more precise, I would like to use subdomains. So, maybe this is the main question - how to add subdomains ? Thanks!

cytopia commented 6 years ago

Hi @mrpsiho

As an example. When your TLD_SUFFIX is set to com.

If you create a project directory named my-wordpress/, your site is reachable by the servername: http://my-wordpress.com.

If you create a project directory named www.my-wordpress/, your site is reachable by the servername: http://www.my-wordpress.com.

If you create a project directory named api.my-wordpress/, your site is reachable by the servername: http://api.my-wordpress.com.

Does this answer your question?

mrpsiho commented 6 years ago

No, sorry. Such tactic is pretty good, but it doesn't solve my case. So, the main question was 'How to use WP multisite with type 'subdomains' as the chosen method of adding network sites?'

Sorry, I'm not that good with DevOps stuff. I guess, this is what I need https://codex.wordpress.org/Configuring_Wildcard_Subdomains , but I don't know how/whether it is possible with devilbox. Please, suggest.

cytopia commented 6 years ago

So you want to set up a wildcard Hostname for one project? E.g.: *.my-wordpress.dev

mrpsiho commented 6 years ago

I think so.

cytopia commented 6 years ago

Yes this is possible now, as every web server is base on vhost-gen.

So far I am lacking a bit of documentation, but some has already been documented here: https://github.com/cytopia/devilbox/blob/master/docs/Configure.md#433-customize-the-vhost-configuration.

Basically saying: Each of your vhosts (project dirs) can have a completely custom web server configuration.

Please read the above documentation for how to achieve it. Let me know the parts you don't understand and I will extend the documentation so its bullet proof.

cytopia commented 6 years ago

@mrpsiho I fixed above vhost-gen link.

mrpsiho commented 6 years ago

Ok, thanks!

So, since I use nginx, the only file I need is nginx.yml unde 'devilbox' folder next to htdocs folder of my project, right?

Then, I tried to add the second 'server' section below the original one, this is how it looks like:

server {
        listen       __PORT____DEFAULT_VHOST__;
        server_name ~^(.*)\.__VHOST_NAME__$ ;

        access_log   "__ACCESS_LOG__" combined;
        error_log    "__ERROR_LOG__" warn;

        client_max_body_size 10m;

    __VHOST_DOCROOT__
    __VHOST_RPROXY__
    __PHP_FPM__
    __ALIASES__
    __DENIES__
    __SERVER_STATUS__
        # Custom directives
    __CUSTOM__
    }

But it doesn't work for me. Could you give me a hint what's wrong?

cytopia commented 6 years ago

Your template is invalid. Not correct yaml. You need to use the whole template and just modify the sections.

Copy this file: https://github.com/devilbox/vhost-gen/blob/master/etc/templates/nginx.yml

mrpsiho commented 6 years ago

No, actually I'm already using this whole document. I cited just a part that I added below the first 'server' block.

I thought maybe just editing the first block is enough, so I tried this:

server {
      listen       __PORT____DEFAULT_VHOST__;
      server_name  __VHOST_NAME__ *.__VHOST_NAME__;

      access_log   "__ACCESS_LOG__" combined;
      error_log    "__ERROR_LOG__" warn;

      client_max_body_size 10m;

  __VHOST_DOCROOT__
  __VHOST_RPROXY__
  __PHP_FPM__
  __ALIASES__
  __DENIES__
  __SERVER_STATUS__
      # Custom directives
  __CUSTOM__
  }

But it also doesn't work((

cytopia commented 6 years ago

I am on the go, but will reply back latest by tomorrow with something you can work on.

mrpsiho commented 6 years ago

Thanks! I will wait.

mavimedia commented 6 years ago

Hi Cytopia, great work!

I'm also interested in changing vhost settings of projects. I couldn't get it running, too.

Best regards!

cytopia commented 6 years ago

Hi @mrpsiho @mavimedia

I just double checked it locally and it seems to work fine. The steps I did are as follows:

.env file

HTTPD_TEMPLATE_DIR=.devilbox
TLD_SUFFIX=loc
HOST_PATH_HTTPD_DATADIR=./data/www

/etc/hosts:

127.0.0.1    cytopia.loc
127.0.0.1    t1.cytopia.loc
127.0.0.1    t2.cytopia.loc

Projects:

# One project only (one vhost)
$ ls -lap ./data/www
total 12
drwxr-xr-x 3 cytopia cytopia 4096 Nov 11 15:40 ./
drwxr-xr-x 6 cytopia cytopia 4096 Sep 26 16:38 ../
drwxr-xr-x 4 cytopia cytopia 4096 Nov 11 15:36 cytopia/

# Note the .devilbox folder for configuration
ls -lap ./data/www/cytopia/
total 16
drwxr-xr-x 4 cytopia cytopia 4096 Nov 11 15:36 ./
drwxr-xr-x 3 cytopia cytopia 4096 Nov 11 15:40 ../
drwxr-xr-x 2 cytopia cytopia 4096 Nov 11 15:40 .devilbox/
drwxr-xr-x 2 cytopia cytopia 4096 Nov 11 15:36 htdocs/

Now download the nginx.yml template (in case of using nginx):

cd ./data/www/cytopia/.devilbox
wget https://raw.githubusercontent.com/devilbox/vhost-gen/master/etc/templates/nginx.yml

Note, keep the whole file as it is and do not remove any sections from it.

Now I have simply added a line below server_name, to get multiple server names:

./data/www/cytopia/.devilbox/nginx.yml

This line was added server_name *.__VHOST_NAME__;

---

# Nginx vHost Template defintion for vhost-gen.py
#
# The 'feature' section contains optional features that can be enabled via
# conf.yml and will then be replaced into the main vhost ('structure' section)
# into their corresponding position:
#
#    __XDOMAIN_REQ__
#    __PHP_FPM__
#    __ALIASES__
#    __DENIES__
#    __STATUS__
#
# The features itself also contain variables to be adjusted in conf.yml
# and will then be replaced in their corresponding feature section
# before being replaced into the vhost section (if enabled):
#
# PHP-FPM:
#    __PHP_ADDR__
#    __PHP_PORT__
# XDomain:
#    __REGEX__
# Alias:
#    __REGEX__
#    __PATH__
# Deny:
#    __REGEX__
# Status:
#    __REGEX__
#
# Variables to be replaced directly in the vhost configuration can also be set
# in conf.yml and include:
#    __VHOST_NAME__
#    __DOCUMENT_ROOT__
#    __INDEX__
#    __ACCESS_LOG__
#    __ERROR_LOG__
#    __PHP_ADDR__
#    __PHP_PORT__
#

###
### Basic vHost skeleton
###
vhost: |
  server {
      listen       __PORT____DEFAULT_VHOST__;
      server_name  __VHOST_NAME__;
      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__
  }

###
### vHost Type (normal or reverse proxy)
###
vhost_type:
  # Normal vHost (-p)
  docroot: |
    # Define the vhost to serve files
    root         "__DOCUMENT_ROOT__";
    index        __INDEX__;

  # Reverse Proxy (-r)
  rproxy: |
    # Define the vhost to reverse proxy
    location __LOCATION__ {
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_pass __PROXY_PROTO__://__PROXY_ADDR__:__PROXY_PORT__;
    }

###
### Optional features to be enabled in vHost
###
features:

  # PHP-FPM will not be applied to a reverse proxy!
  php_fpm: |
    # PHP-FPM Definition
    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }
    location ~ \.php?$ {
        try_files $uri = 404;
        include fastcgi_params;

        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_split_path_info ^(.+\.php)(.*)$;

        fastcgi_pass __PHP_ADDR__:__PHP_PORT__;

        fastcgi_index index.php;
        fastcgi_intercept_errors on;
    }

  alias: |
    # Alias Definition
    location ~ __ALIAS__ {
        root  __PATH__;
    __XDOMAIN_REQ__
    }

  deny: |
    # Deny Definition
    location ~ __REGEX__ {
        deny all;
    }

  server_status: |
    # Status Page
    location ~ __REGEX__ {
        stub_status on;
        access_log off;
    }

  xdomain_request: |
    # Allow cross domain request from these hosts
    if ( $http_origin ~* (__REGEX__) ) {
        add_header "Access-Control-Allow-Origin" "$http_origin";
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
        add_header 'Access-Control-Expose-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
        add_header 'Access-Control-Max-Age' 0;
        return 200;
    }

Now in order to apply the changes, you will either have to restart the devilbox, or simply rename the cytopia project directory to something else and then back to cytopia, then the httpd container will re-apply the changes.

Result

Now there is one vhost called http://cytopia.loc as well as unlimited vhosts for all subdomains of http:*.cytopia.loc

As I have already added new DNS entries via /etc/hosts above, I can simply go to http://t1.cytopia.loc which is the same vhost/project as http://cytopia.loc

cytopia commented 6 years ago

Please let me know if it works out for you or at what steps you still have struggle.

mrpsiho commented 6 years ago

Ok, I did the same and whenever I try to reach my subdomain, it shows me the content of localhost (devilbox info page). I'm using Devilbox v0.12 (2017-10-10). Is it the correct version?

cytopia commented 6 years ago

@mrpsiho can you check how the vhost actually looks inside the httpd container:

$ docker-compose exec httpd bash
httpd> /etc/httpd/vhost.d
httpd> cat <vhost-name>.conf

And paste the output here along with your nginx.yml

mrpsiho commented 6 years ago

this is what it actually looks like:

server {
    listen       80;
    server_name  moomoo.loc;

    access_log   "/var/log/nginx-stable/moomoo-access.log" combined;
    error_log    "/var/log/nginx-stable/moomoo-error.log" warn;

    # Define the vhost to serve files
    root         "/shared/httpd/moomoo/htdocs";
    index        index.php;

    # PHP-FPM Definition
    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }
    location ~ \.php?$ {
        try_files $uri = 404;
        include fastcgi_params;

        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_split_path_info ^(.+\.php)(.*)$;

        fastcgi_pass php:9000;

        fastcgi_index index.php;
        fastcgi_intercept_errors on;
    }

    # Alias Definition
    location ~ /devilbox-api/ {
        root  /var/www/default/api;
        # Allow cross domain request from these hosts
        if ( $http_origin ~* (http(s)?://(.*)$) ) {
            add_header "Access-Control-Allow-Origin" "$http_origin";
            add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
            add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
            add_header 'Access-Control-Expose-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
            add_header 'Access-Control-Max-Age' 0;
            return 200;
        }
    }

    # Deny Definition
    location ~ /\.git {
        deny all;
    }

    # Deny Definition
    location ~ /\.ht.* {
        deny all;
    }

    # Custom directives

}

and this is the content of nginx.yml

---

# Nginx vHost Template defintion for vhost-gen.py
#
# The 'feature' section contains optional features that can be enabled via
# conf.yml and will then be replaced into the main vhost ('structure' section)
# into their corresponding position:
#
#    __XDOMAIN_REQ__
#    __PHP_FPM__
#    __ALIASES__
#    __DENIES__
#    __STATUS__
#
# The features itself also contain variables to be adjusted in conf.yml
# and will then be replaced in their corresponding feature section
# before being replaced into the vhost section (if enabled):
#
# PHP-FPM:
#    __PHP_ADDR__
#    __PHP_PORT__
# XDomain:
#    __REGEX__
# Alias:
#    __REGEX__
#    __PATH__
# Deny:
#    __REGEX__
# Status:
#    __REGEX__
#
# Variables to be replaced directly in the vhost configuration can also be set
# in conf.yml and include:
#    __VHOST_NAME__
#    __DOCUMENT_ROOT__
#    __INDEX__
#    __ACCESS_LOG__
#    __ERROR_LOG__
#    __PHP_ADDR__
#    __PHP_PORT__
#

###
### Basic vHost skeleton
###
vhost: |
  server {
      listen       __PORT____DEFAULT_VHOST__;
      server_name  __VHOST_NAME__;
      server_name  *.__VHOST_NAME__;
      server_name  builderius.loc;
      server_name  *.builderius.loc;

      access_log   "__ACCESS_LOG__" combined;
      error_log    "__ERROR_LOG__" warn;

  __VHOST_DOCROOT__
  __VHOST_RPROXY__
  __PHP_FPM__
  __ALIASES__
  __DENIES__
  __SERVER_STATUS__
      # Custom directives
  __CUSTOM__
  }

###
### vHost Type (normal or reverse proxy)
###
vhost_type:
  # Normal vHost (-p)
  docroot: |
    # Define the vhost to serve files
    root         "__DOCUMENT_ROOT__";
    index        __INDEX__;

  # Reverse Proxy (-r)
  rproxy: |
    # Define the vhost to reverse proxy
    location __LOCATION__ {
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_pass __PROXY_PROTO__://__PROXY_ADDR__:__PROXY_PORT__;
    }

###
### Optional features to be enabled in vHost
###
features:

  # PHP-FPM will not be applied to a reverse proxy!
  php_fpm: |
    # PHP-FPM Definition
    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }
    location ~ \.php?$ {
        try_files $uri = 404;
        include fastcgi_params;

        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_split_path_info ^(.+\.php)(.*)$;

        fastcgi_pass __PHP_ADDR__:__PHP_PORT__;

        fastcgi_index index.php;
        fastcgi_intercept_errors on;
    }

  alias: |
    # Alias Definition
    location ~ __ALIAS__ {
        root  __PATH__;
    __XDOMAIN_REQ__
    }

  deny: |
    # Deny Definition
    location ~ __REGEX__ {
        deny all;
    }

  server_status: |
    # Status Page
    location ~ __REGEX__ {
        stub_status on;
        access_log off;
    }

  xdomain_request: |
    # Allow cross domain request from these hosts
    if ( $http_origin ~* (__REGEX__) ) {
        add_header "Access-Control-Allow-Origin" "$http_origin";
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
        add_header 'Access-Control-Expose-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
        add_header 'Access-Control-Max-Age' 0;
        return 200;
    }

P.S. Yep, I also try to use a different domain for my multisite installation

mrpsiho commented 6 years ago

Omg! I must use '.devilbox' folder name? Not just 'devilbox'? Maybe this is the reason...

cytopia commented 6 years ago

Yes ;-p

cytopia commented 6 years ago

You can however change this by altering: HTTPD_TEMPLATE_DIR=.devilbox to HTTPD_TEMPLATE_DIR=devilbox

mrpsiho commented 6 years ago

Haha, omg. I just wasn't attentive enough(((

Yes, it works. I confirm this! Just in case - WP multisite edition also works! :)

Thanks a lot! Devilbox is must have for developers!))

cytopia commented 6 years ago

Good to hear. I will keep this open until @mavimedia issue has also been resolved and until better documentation has been added.

mavimedia commented 6 years ago

It works for me too. Thanks.

I'm using Apache 2.4. I have made with ServerAlias *.__VHOST_NAME__ directive.

mavimedia commented 6 years ago

Is it possible to override the global vhost templates?

cytopia commented 6 years ago

@mavimedia could you add a new issue for this topic please

cytopia commented 6 years ago

The whole thing is going to be documented with new documentation setup: https://github.com/cytopia/devilbox/issues/157

cytopia commented 6 years ago

@mrpsiho @mavimedia Documentation available here: http://devilbox.readthedocs.io/en/documentation/tutorials/adding-subdomains.html

cytopia commented 6 years ago

Documentation moved here: https://devilbox.readthedocs.io/en/latest/vhost-gen/example-add-subdomains.html#complex-sub-domains-for-one-project

timersys commented 5 years ago

Is this still valid for latest version? I'm following docs but conf file remains the same

cytopia commented 5 years ago

@timersys is still valid and nothing has changed. If it doesn't work for you please create a separate ticket with full steps to reproduce, so we can solve your issue quickly.

axamitdeveloper commented 2 years ago

Hi all. And if, for example, I need to make such a folder structure and a project. The my-project folder contains two folders: front and backend. And I want the front folder to be displayed at the address my-project.lok and the backend folder to be displayed at the address admin.my-project.lok. How to implement this?

cytopia commented 2 years ago

@belvgdeveloper just treat them as two separate projects/services. The Devilbox supports unlimited number of projects/services running at the same time (they can also communicate with each other).

See a directory structure here:

$ tree  data/www/
data/www/
├── admin.my-project/
│   ├── htdocs -> source/
│   └── source/
└── my-project/
    ├── htdocs -> source/
    └── source/

6 directories, 0 files
axamitdeveloper commented 2 years ago

Your option is logical and I know that it works. But I meant a more complicated version

I want both of these apps to have the same root path

$ tree data/www/ data/www/ my-project/ ├── front/ │ ├── htdocs -> source/ │ └── source/ └── backend/ | ├── htdocs -> source/ | └── source/

cytopia commented 2 years ago

This way won't really work, as vhost names are determined by the root directory name.

You could however symlink your my-project/backend/source/ directory out to ./admin.my-project.

axamitdeveloper commented 2 years ago

I'm currently looking at your guide https://devilbox.readthedocs.io/en/latest/vhost-gen/example-add-subdomains.html and I'm trying to do something similar, but there is no option you mentioned. Can you clarify please. I make my project folder, make a symbolic link to htdocs and the site will display the front. And how, from where and where to make a symbolic link to the admin part is unfortunately not clear to me.

Bfaschat commented 1 year ago

@belvgdeveloper A quick solution to this issue can be found on stackoverflow. Here is an except to it..

  1. Create a new file in the root of devilbox project called docker-compose.override.yml
  2. Copy and paste this into the file
# IMPORTANT: The version must match the version of docker-compose.yml
---
version: '2.3'

services:
  php:
    volumes:
      - $HOME:$HOME
  httpd:
    volumes:
      - $HOME:$HOME

Now you are able to create symlinks such as data/www/proj-slug/htdocs -> ~/your-custom-path

Explanation https://stackoverflow.com/a/69457741