Nginx – Can nginx run both for gitlab and taiga.io on the same VM

gitlabgunicornnginxunicorn

I having troubles running GitLab and Taiga.io on the same VM (i.e. sharing the same IP). Both use nginx. My VM runs Debian 8.

I have followed the classical Omnibus installation of GitLab for Debian 8, and when I enter the IP of my VM on a browser, gitlab is served correctly, and all goes well.

Then I shut it down (sudo gitlab-ctl stop), and I installed Taiga, following the production environment setup. According to the doc it uses Gunicorn and Circus for taiga-back (which serves REST APIs), and nginx for serving the frontend. Once /etc/nginx/sites-available|enabled/taiga, ~/taiga-back/settings/local.py and ~/taiga-front-dist/dist/conf.json are all setup using the same IP address, and nginx is restarted (sudo service nginx restart) all goes well too.

Now, it is possible to change all the aforementioned Taiga IP addresses with a different port (say 8080), restart nginx, and Taiga is now served from the IP adress:8080. All fine!

When I restart GitLab (sudo gitlab-ctl start), it says that everything starts smoothly. But when I try to access it (on default port 80) I get a 502!

If I switch down Taiga and restart GitLab, hoho, GitLab is available! Basically, I can have them only separately, but not at the same time.

I also tried to keep Taiga on port 80, and move GitLab on port 8080 (by changing the port on the file /etc/gitlab/gitlab.rb and running sudo gitlab-ctlr reconfigure), but I never managed to run it successfully.

I have also tried to configure GitLab to use the system nginx (and not that embedded one), that is, the one used by Taiga. For that I disabled nginx on gitlab.rb following the doc, and using that omnibus (non-ssl) recipe:

## GitLab 8.3+
##
## Lines starting with two hashes (##) are comments with information.
## Lines starting with one hash (#) are configuration parameters that can be uncommented.
##
##################################
##        CONTRIBUTING          ##
##################################
##
## If you change this file in a Merge Request, please also create
## a Merge Request on https://gitlab.com/gitlab-org/omnibus-gitlab/merge_requests
##
###################################
##         configuration         ##
###################################
##
## See installation.md#using-https for additional HTTPS configuration details.

upstream gitlab-workhorse {
  server unix:/var/opt/gitlab/gitlab-workhorse/socket;
}

## Normal HTTP host
server {
  ## Either remove "default_server" from the listen line below,
  ## or delete the /etc/nginx/sites-enabled/default file. This will cause gitlab
  ## to be served if you visit any address that your server responds to, eg.
  ## the ip address of the server (http://x.x.x.x/)n 0.0.0.0:80 default_server;
  listen 80 default_server;
  #listen [::]:80 default_server;
  server_name gitlab.<replaced with company URL> <replace with VM IP address>; ## Replace
  server_tokens off; ## Don't show the nginx version number, a security best practice
  root /opt/gitlab/embedded/service/gitlab-rails/public;

  ## See app/controllers/application_controller.rb for headers set

  ## Individual nginx logs for this GitLab vhost
  access_log  /var/log/nginx/gitlab_access.log;
  error_log   /var/log/nginx/gitlab_error.log;

  location / {
    client_max_body_size 0;
    gzip off;

    ## https://github.com/gitlabhq/gitlabhq/issues/694
    ## Some requests take more than 30 seconds.
    proxy_read_timeout      300;
    proxy_connect_timeout   300;
    proxy_redirect          off;

    proxy_http_version 1.1;

    proxy_set_header    Host                $http_host;
    proxy_set_header    X-Real-IP           $remote_addr;
    proxy_set_header    X-Forwarded-For     $proxy_add_x_forwarded_for;
    proxy_set_header    X-Forwarded-Proto   $scheme;

    proxy_pass http://gitlab-workhorse;
  }
}

along with that for Taiga:

server {
    listen 8080 default_server;
    server_name taiga.<replaced with company URL> <replace with VM IP address>; 

    large_client_header_buffers 4 32k;
    client_max_body_size 50M;
    charset utf-8;

    access_log /opt/taiga/logs/nginx.access.log;
    error_log /opt/taiga/logs/nginx.error.log;

    # Frontend
    location / {
        root /opt/taiga/taiga-front-dist/dist/;
        try_files $uri $uri/ /index.html;
    }

    # Backend
    location /api {
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Scheme $scheme;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://127.0.0.1:8001/api;
        proxy_redirect off;
    }

    # Django admin access (/admin/)
    location /admin {
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Scheme $scheme;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://127.0.0.1:8001$request_uri;
        proxy_redirect off;
    }

    # Static files
    location /static {
        alias /opt/taiga/taiga-back/static;
    }

    # Media files
    location /media {
        alias /opt/taiga/taiga-back/media;
    }
}

With these two configs in /etc/nginx/sites-enabled, after a restart (sudo service nginx restart) my Taiga server is accessible through port 8080, but strangely, the gitlab server isn't accessible anymore. No 502 but a connexion timeout!

Anyone knowing nginx with an idea? Any help would be greatly appreciated!

Best Answer

Thanks to the help of my IT provider, we found a solution, which goes along the starting point of @Alex_hha answer: it was a mistake to bind Taiga to port 8080 (LSNED...)

So finally, I use the Debian installation of nginx in my VM as a reverse proxy, disabled the embedded nginx inside GitLab (by editing the /etc/gitlab/gitlab.rb file) and configured both Taiga and Gitlab with configurations file inside /etc/nginx/sites-available (and symlinks to /etc/nginx/sites-enabled), as the following:

Taiga:

server {
    listen 80 default_server;
    server_name taiga.<company URL> <VM IP address>;

and the remaining unchanged. And for Gitlab:

server {
    listen 80;
    server_name gitlab.<company URL>;

    large_client_header_buffers 4 32k;
    client_max_body_size 50M;
    charset utf-8;

    access_log /opt/gitlab/logs/nginx.access.log;
    error_log /opt/gitlab/logs/nginx.error.log;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host               $host;
        proxy_set_header X-Real-IP          $remote_addr;
        proxy_set_header X-Forwarded-For    $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto  $scheme;
    }
}

So both are accessed through the port 80, but given the URL of the request, the right service is called. Note the absence of default_server in GitLab config.

This combination of config makes all GitLab traffic going to GitLab and anything else (even invalid URL) ending up on Taiga service.