Multiple rack apps on nginx + passenger, one as root, the other not...config help - ruby

So I've got two apps I want to run on a server. One app I would like to be the "default" app--that is, all URLs should be sent this app by default, except for a certain path, lets call it /foo:
http://mydomain.com/ -> app1
http://mydomain.com/apples -> app1
http://mydomain.com/foo -> app2
My two rack apps are installed like so:
/var
/www
/apps
/app1
app.rb
config.ru
/public
/app2
app.rb
config.ru
/public
app1 -> apps/app1/public
app2 -> apps/app2/public
(app1 and app2 are symlinks to their respective apps' public directories). This is the Passenger setup for sub URIs described here: http://www.modrails.com/documentation/Users%20guide%20Nginx.html#deploying_rack_to_sub_uri
With the following config I've got /foo going to app2:
server {
listen 80;
server_name mydomain.com;
root /var/www;
passenger_enabled on;
passenger_base_uri /app1;
passenger_base_uri /app2;
location /foo {
rewrite ^.*$ /app2 last;
}
}
Now, how do I get app1 to pick up everything else? I've tried the following (placed after the location /foo directive), but I get a 500 with an infinite internal redirect:
location / {
rewrite ^(.*)$ /app1$1 last;
}
I hoped that the last directive would prevent that infinite redirect, but I guess not. My /foo rewrite still works. And I can still go to http://mydomain.com/app1.
Any ideas? Thanks!

One way is to create a new config.ru file that dispatches the request to the correct app.
# /var/www/apps/config.ru
require './app1/app1'
require './app2/app2'
map ('/') { run App1 }
map ('/foo') { run App2 }
Of course, this means your apps have to be made in a way that they can live on the same execution space.

Related

Nginx proxy return 404 with Laravel and Vue

i have a problem with nginx and laravel/vue app, hope yours help
I have two web app call Admin and System.
Admin use Vuejs call api to System using Nginx proxy (image bellow)
server {
listen 80;
server_name admin.abc.com;
location / {
root /usr/share/nginx/html/onestudy-vuejs/dist;
index index.html;
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass https://system.abc.com;
}
location ~ /\.ht {
deny all;
}
}
After some day not access to web, i have error such as when access api from admin domain (example: https://admin.abc.com/api/user_info)
{"error":{"name":"Error","status":404,"message":"There is no method to handle ","statusCode":404}}
every request 3 times, 2 times ok and 1 time i see this error
but if access direct from system admin, everything will be still ok
After this, i just restart nginx, i don't see this error??? :( don't understand, don't know exactly what the cause is ##
Note: My project has two env, staging and prod, but only prod has error (same config nginx between two env)
Some info of project
Tech stack: Laravel, Vue
Webserver: Nginx
Cloud: AWS (EC2 + ALB)
I see this topic nginx proxy_pass 404 error, don't understand why but it's not for my problem
Glad for your support.
If u need info of system for anwser, please request bellow. Tks u

Nginx configuration setup for windows

I am trying to run my vue applications trough nginx on windows and i was using the following tutorials, one to run nginx with AlwaysUp and the other one to configure it.
https://www.coretechnologies.com/products/AlwaysUp/Apps/RunNginxAsAService.html
https://graspingtech.com/nginx-virtual-hosts-ubuntu-16-04/
I also stumbled upon the following stack overflow question which is basically the problem i have but it didnt work:
nginx Windows: setting up sites-available configs
The service is running and recognizes the two domains i am trying to set up but for whatever reason it always sends me back to the NGINX Welcome page and i am not sure what i am doing wrong.
I followed the steps on the second tutorial and did a few changes, such ass adding "server_names_hash_bucket_size 64;" to my nginx.config file. I also created the symlink between the "sites-available" and "sites-enabled directories" using windows mklink.
Here are my files.
Nginx.config
worker_processes 1;
events {
worker_connections 1024;
}
http {
server_names_hash_bucket_size 64;
include mime.types;
default_type application/octet-stream;
include "C:/nginx/nginx/sites-available/*.conf";
sendfile on;
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
My app config file in sites-available which also contains a symlink in sites-enabled:
server {
listen 80;
listen [::]:80;
server_name myapp.nginx.br;
root "C:/Users/Documents/git-repository/my-app/dist";
index index.html;
location / {
try_files $uri $uri/ #rewrites;
}
location #rewrites {
rewrite ^(.+)$ /index.html last;
}
location ~* \.(?:ico|css|js|gif|jpe?g|png)$ {
expires max;
add_header Pragma public;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
}
}
I also faced the issue how to kill the nginx process. I stumbled a while until I came up with the following command which works:
taskkill /F /FI "IMAGENAME eq nginx.exe"
Well, after many hours i actually found out what was happening.
Everything in my files, from the nginx.conf file to every other .conf files were ok.
However i discovered that when restarting or stop/starting my nginx service with either the AlwaysUp program or the windows service options the service would still be active somehow and wouldnt apply my changes, therefore it would always show me the "welcome to nginx" page.
So i just restarted my computer because i wasnt able to kill the service with conventional means and it worked just fine for every single app i have.
I am sure there is a better way to kill the service and restart it but restarting my computer so the changes to my files would actually be applied solved it.
EDIT: I also discovered that windows takes a little while to stop the nginx service, so if you are using always up try stopping the service there, if it fails try stopping the service trough windows services menu. Also don't forget to set it to manual so you wont accidentally access you nginx app instead of your actual deployed app.

Deploy Grape API with Nginx/Passenger

I have Nginx and Passenger installed on my server. Trying to run a Grape (Rack) API off it.
When I deploy Rails applications I have this server block in Nginx conf;
server {
listen 80;
server_name yourserver.com;
# Tell Nginx and Passenger where your app's 'public' directory is
root /path-to-app/public;
# Turn on Passenger
passenger_enabled on;
passenger_ruby /path-to-ruby;
}
The instructions on Passenger's tutorial are;
The server block's root must point to your application's public
subdirectory.
What would this root be in case of my Grape API?
In case of grape, you need to create an empty public folder and point to this folder in the sever block.

nginx config files redirecting to subfolder

I'm currently trying to deploy a website in two directories. Despite the lot of documentations on it, I was not able to obtain the behavior that I wish. This is the architecture of the websites :
The main website page is stored in /opt/www/mainsite/index.html
The second webiste (working with CodeIgniter) is stored in /opt/www/apps/myapp/index.php
I wish configure nginx to obtain this behavior :
All requests in http must be redirect to https
www.mydomain.com must point to /opt/www/mainsite/index.html
www.mydomain.com/myapp must point to /opt/www/apps/myapp/index.php
currently, my config file contains :
# redirect http to https
server {
listen 80;
rewrite ^(.*) https://$host$1 permanent;
}
# main webiste
server {
listen 443;
# ssl elements...
root /opt/www/mainsite;
index index.html;
server_name www.mydomain.com;
location / {
try_files $uri $uri/ /index.html;
}
}
On this page I found all the informations to set the config file for CodeIgniter. But I don't know how to create the rules to point mydomain.com/myapp on the CodeIgniter folder and how to configure CodeIgniter in order to set the right configuration.
Is anybody can help me?
thanks in advance
You need http://wiki.nginx.org/HttpFastcgiModule to setup CodeIgniter.
Using 2 server blocks is better than using if block for redirect. See IF is Evil.
Don't use $host because that variable value is obtained from the request's HOST header, and can be easily faked. Always set a server_name directive and use that name instead.
Using "return 301" directive is better than a rewrite. Saving cpu time (regex is slow) and easy to follow. Note that a 302 redirect (rewrite...redirect) has side effect because 302 will turn all POST requests to GET requests, which is not good in your case.
You don't need try_files in the main site because the main site just serves static files. But you can use 'expires' directive to allow browser to cache the static files.
server {
listen 80;
server_name www.mydomain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443;
server_name www.mydomain.com;
# ssl elements...
location / {
root /opt/www/mainsite;
index index.html;
expires max;
}
location /myapp {
root /opt/www/apps/myapp;
# fastcgi module goes here...
}
}
server {
listen 80;
listen 443 ssl;
…
if ($scheme != "https") {
rewrite ^ https://$server_name$request_uri? redirect;
}
root /opt/www/mainsite/;
location /myapp {
root /opt/www/apps/myapp/;
}
}
You'd put whatever configuration that is necessary for your myapp within the location for myapp.
BTW, it is generally a bad idea to host multiple independent apps within a single Host, because of XSS concerns.

How do I create multiple locations with Nginx, Passenger, Sinatra

I have a server section that looks like:
server {
listen 80;
server_name arch;
root /data/apps/production/fentonGem2/current/public;
passenger_enabled on;
}
which works fine. However, I'd like to deploy two or more apps to the same server_name and listen port. So presumably I'd use something like the following:
server {
listen 80;
server_name arch;
location /app1 {
root /data/apps/production/fentonGem2/current/public;
passenger_enabled on;
}
location /app2 {
root /data/apps/production/fentonGem3/current/public;
passenger_enabled on
}
}
But that doesn't work. Does anyone know how I can deploy two separate apps, and reach them by:
http://domain.com/app1/
and:
http://domain.com/app2/
The setup uses Nginx, Phusion Passenger, Rack, and Sinatra.
UPDATE:
Thanks for the responses, but I found them and the approach not helpful, though maybe I'm not understanding it well. It kind of seems like I have to deploy one application inside another, which seems very unclean. What I finally resorted to was having separate server sections, and then updating my /etc/hosts file to have server aliases for the same IP address. So now I have:
http://app1/
and:
http://app2/
and server sections that look like:
server {
listen 80;
server_name app1;
root /data/apps/production/app1/current/public;
passenger_enabled on;
}
server {
listen 80;
server_name app2;
root /data/apps/production/app2/current/public;
passenger_enabled on;
}
and in /etc/hosts:
192.168.1.30 app1 app2
The following worked:
First made symlinks named app1 and app2 pointing to the "public" directory as follows:
ln -s /data/apps/production/fentonGem2/current/public /data/apps/production/fentonGem2/current/app1
ln -s /data/apps/production/fentonGem2/current/public /data/apps/production/fentonGem2/current/app2
Modify nginx.conf to have rails_base_uri, which should look something like the following:
...
server {
listen 80;
server_name arch;
location ^~ /app1 {
root /data/apps/production/fentonGem2/current;
rails_env production;
passenger_enabled on;
passenger_base_uri /app1;
}
location ^~ /app2 {
root /data/apps/production/fentonGem2/current;
rails_env production;
passenger_enabled on;
passenger_base_uri /app2;
}
}
...
Hope this helps.
Not sure, but you might need passenger_base_uri /app1;
More about Passenger and Nginx conf:
http://www.modrails.com/documentation/Users%20guide%20Nginx.html#PassengerBaseURI
EDIT:
"It is allowed to specify this option multiple times. Do this to deploy multiple applications in different sub-URIs under the same virtual host."

Resources