Nginx and Passenger deploy issue - ruby-on-rails

Currently I can only get the default nginx page to come up on my domain name. I am pretty sure the error is either in the /etc/hosts file or the enginx.config file.
my /etc/hosts file is
127.0.0.1 localhost.localdomain localhost
myip server.mydomain.com server
and nginx.config is:
server {
listen 80;
server_name server.mydomain.com;
root /whatever/pulic;
passenger_enabled on;
rails_env production;
I don't get any errors in the log. Incidentally I can run mongrel and on mydomain:3000 see the application there.

In your /etc/hosts, you have
123.45.67.78 server.domain.com servername
So in you nginx.conf you should have the line
server_name servername
as you defined in the third column of your /etc/host. Make sure you don't still have the default nginx server block in your nginx.conf file, too, otherwise it might be taking priority (based on it's relative position).

We just had this issue. The problem turned out to be that Nginx was using a different config file than we thought it was (possibly an issue with how it was compiled on the server?).
We discovered this by doing nginx -t, which lists the config file it's reading and tests the syntax. The one it said it was testing was not the one we expected.

Related

SSL certificate on local Laradock Nginx project

I need your help to set my Laradock (with Docker) using Nginx and SSL "fake" certificate on my local machine.
I have no idea how to setup it. Could you please help me?
Thanks
To enable SSL with the current version of laradock (as of Nov 2019) with a self signed certificate you must enable it in the nginx settings. Inside the folder nginx/sites remove the comments below line 6 "# For https" :
# For https
listen 443 ssl default_server;
listen [::]:443 ssl default_server ipv6only=on;
ssl_certificate /etc/nginx/ssl/default.crt;
ssl_certificate_key /etc/nginx/ssl/default.key;
restart nginx : docker-compose restart nginx
and you're ready.
If google-chrome complains you can enable the flag at chrome://flags/#allow-insecure-localhost to allow even invalid certificates.
The solution given only allows for https://localhost, however you might need to generate your own when using custom domain pointing to localhost, e.g https://testing.dev
I've written a gist to this — https://gist.github.com/r0lodex/0fe03fc8d22241d79cba65107b30868b
Hopefully this will help those who are still searching.

LetsEncrypt in a Docker (docker-compose) app container not working

I'm using docker-compose for a rails app to have an app and db container. In order to test some app functionality I need SSL...so I'm going with LetsEncrypt vs self-signed.
The app uses nginx, and the server is ubuntu 14.04 lts, with the phusion passenger docker image as a base image (lightweight debian)
Normally with LetsEncrypt, I run the usual ./certbot-auto certonly --webroot -w /path/to/app/public -d www.example.com
My server runs nginx (proxy passing the app to the container), so I've hopped into the container to run the certbot command without issue.
However, when I try to go to https://test-app.example.com it doesn't work. I can't figure out why.
Error on site (Chrome):
This site can’t be reached
The connection was reset.
Curl gives a bit better error:
curl: (35) Unknown SSL protocol error in connection to test-app.example.com
Server nginx app.conf
upstream test_app { server localhost:4200; }
server {
listen 80;
listen 443 default ssl;
server_name test-app.example.com;
# for SSL
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_dhparam /etc/ssl/dhparam.pem;
ssl_prefer_server_ciphers on;
ssl_ciphers 'ECDHE-RSA-blahblahblah-SHA';
location / {
proxy_set_header Host $http_host;
proxy_pass http://test_app;
}
}
Container's nginx app.conf
server {
server_name _;
root /home/app/test/public;
ssl_certificate /etc/letsencrypt/live/test-app.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/test-app.example.com/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_dhparam /etc/ssl/dhparam.pem;
ssl_prefer_server_ciphers on;
ssl_ciphers 'ECDHE-RSA-blahblah-SHA';
passenger_enabled on;
passenger_user app;
passenger_ruby /usr/bin/ruby2.3;
passenger_app_env staging;
location /app_test/assets/ {
passenger_enabled off;
alias /home/app/test/public/assets/;
gzip_static on;
expires +7d;
add_header Cache-Control public;
break;
}
}
In my Dockerfile, I have:
# expose port
EXPOSE 80
EXPOSE 443
In my docker-compose.yml file I have:
test_app_app:
build: "."
env_file: config/test_app-application.env
links:
- test_app_db:postgres
environment:
app_url: https://test-app.example.com
ports:
- 4200:80
And with docker ps it shows up as:
Up About an hour 443/tcp, 0.0.0.0:4200->80/tcp
I am now suspecting it's because the server's nginx - the "front-facing" server - doesn't have the certs, but I can't run the LetsEncrypt command without an app location.
I tried running the manual LetsEncrypt command on the server, but because I presumably have port 80 exposed, I get this: socket.error: [Errno 98] Address already in use Did I miss something here?
What do I do?
Fun one.
I would tend to agree that it's likely due to not getting the certs.
First and foremost read my disclaimer at the end. I would try to use DNS authentication., IMHO it's a better method for something like Docker. A few ideas come to mind. Easiest that answers your question would be a docker entrypoint script that gets the certs first and then starts nginx:
#!/bin/bash
set -ea
#get cert
./certbot-auto certonly --webroot -w /path/to/app/public -d www.example.com
#start nginx
nginx
This is "okay" solution, IMHO, but is not really "automated" (which is part of the lets encrypt goals). It doesn't really address renewing the certificate down the road. If that's not a concern of yours, then there you go.
You could get really involved and create an entrypoint script that detects when the cert expires and then rerun the command to renew it and then reloads nginx.
A much more complicated (but also more scalable solution) would be to create a docker image that's sole purpose in life is to handle lets_encrypt certificates and renewals and then provide a way of distributing those certificates to other containers, eg: nfs (or shared docker volumes if you are really careful).
For anyone in the future reading this: this was written before compose hooks was an available feature, which would be by far the best way of handling something like this.
Please read this disclaimer:
Docker is not really the best solution for this, IMHO. Docker images should be static data. Because lets encrypt certificates expire after 3 months, that means your container should have a shelf-life of three months or less (or, like I said above, account for renewing). "Thats fine!" I hear you say. But that would also mean you are constantly getting a new certificate issued each time you start the container (with the entrypoint method). At the very least, that means that the previous certificate gets revoked every time. I don't know what the ramifications are for doing this with Lets Encrypt. They may only give you so many revokes before they think something fishy is going on.
What I tend to do most often is actually use configuration management and use nginx as the "front" on the host system. Or rely on some other mechanism to handle SSL termination. But that doesn't answer your question of how to get Lets Encrypt to work with docker. :-)
I hope that helps or points you in a better direction. :-)
I knew I was missing one small thing. As stated in the question, since the nginx on the server is the 'front-facing' nginx, with the container's nginx specifically for the app, the server's nginx needed to know about the SSL.
The answer was super simple. Copy the certs over! (Kudos to my client's ops lead)
I cat the fullchain.pem and privkey.pem in the docker container and created the associated files in /etc/ssl on the server.
On the server's /etc/nginx/sites-enabled/app.conf I added:
ssl_certificate /etc/ssl/test-app-fullchain.pem;
ssl_certificate_key /etc/ssl/test-app-privkey.pem;
Checked configuration and restarted nginx. Boom! Worked like a charm. :)

Issue with Nginx redirecting to Rails app

So, I have a domain: coolapp.com Now I want to make it so I can have two subdomains, such as game.coolapp.com and sports.coolapp.com. I have two server configurations in the nginx config as follows:
server {
listen 80;
server_name sports.coolapp.com;
location / {
root /home/deployer/Sports/current/public;
index index.php;
}
passenger_enabled on;
}
server {
listen 80;
server_name game.coolapp.com;
location / {
root /home/deployer/Game/current/public;
index index.php;
}
passenger_enabled on;
}
For some reason, both of these domains are redirecting to the 'sports' app. They SHOULD each by redirecting to their own application, but are interfering with each other.
I am running the Sports app via passenger, with something like 'passenger start --port 80', and I'm running the second app with 'passenger start --port 81'. Should I be running these with different arguments, or what exactly is causing the issue here?
Your problem is not quite clear to me. I am making the following assumptions in my answer.
You are running 3 apps all on Phusion with Nginx.
Nginx configuration is pretty straight forward. Probably you have configured nginx.conf properly because you main app is working.
The next thing you should do is read the phusion passenger doc on how to run Rails on subdomain. Reading https://www.phusionpassenger.com/documentation/Users%20guide%20Nginx.html#deploying_a_rack_app will give you a lot of insight. I recommend you read the entire doc.
I think there is a problem in the way you have configured your nginx.conf and how you are starting you phusion passenger (BTW I think you do not even have to start the phusion passenger explicitly and that NGINX should take care of that)
In your nginx configuration you are listening to port 80 and in your phusion passenger command you are asking it to listen to port 81 and 82. Change you nginx configuration to read like (BTW it is better to use sites-available & site-enabled for this)
server {
listen 80;
server_name sports.coolapp.com;
root /home/deployer/Sports/current/public;
passenger_enabled on;
}
server {
listen 80;
server_name games.coolapp.com;
root /home/deployer/Sports/current/public;
passenger_enabled on;
}
I hope you have configured your subdomains properly. You should double check that as well.
Save changes. Restart Nginx and you should be good to go.

How to configure nginx with passenger with rails application

I have followed this tutorial https://www.digitalocean.com/community/articles/how-to-install-rails-and-nginx-with-passenger-on-ubuntu
I have installed passenger with nginx on my virtual machine and trying to access the site.
In the root I have specified path as root /var/rails_apps/public/; which give me Welcome to Nginx page,
server{
listen 80;
server_name localhost;
root /var/rails_apps/public/;
passenger_enabled on;
}
As my root page of my site is in the /var/rails_apps/app/views/home/index.html.erb
so I changed the path to root /var/rails_apps/app/views/home/;
server{
listen 80;
server_name localhost;
root /var/rails_apps/app/views/home/;
passenger_enabled on;
}
but still for both root I am getting Welcome to Nginx page.
My request URL is like this -> /#{IpAddressOfVirtualMachine}:80/
When I specified different port for listening eg 1027 then it gives me error Unable to connect
Please explain how I can get my site running using nginx and passenger, is there any other setting required?
I am able run my site just did following changes.
Install nginx init script
nginx init script by Jason Giedymin helps us to administer web server easily.
$ cd
$ git clone git://github.com/jnstq/rails-nginx-passenger-ubuntu.git
$ sudo mv rails-nginx-passenger-ubuntu/nginx/nginx /etc/init.d/nginx
$ sudo chown root:root /etc/init.d/nginx
After that rails g controller pages home
And point root to public folder root /var/rails_apps/helloworld/public;
then access my virtual machine through http #{IpAddressOfVirtualMachine}:1027/pages/home
port 80 was busy so I used different which is port 1027
And it works !!!
you can refer this blog for more information
http://ershadk.com/blog/2012/04/05/set-up-rails-3-2-2-with-passenger-rvm-and-ngnix/
Change the root back to public folder, and open the URL without the port number
You need to change the server name in the nginx config to the same IP you are connecting to, and yes keep the root in the public folder, that's how rails work.
server_name 123.456.789.000; # replace with your IP
Instead of localhost, then restart nginx.

nginx rewrite not working (with passenger on Mac OS X)

I have nginx with rewriting working correctly on my server in production.
But when I tried to set the same rule on my local development machine (mac) the rewrite doesn't seem to be working.
I want "universitytutor.local" to redirect to "www.universitytutor.local"
Here is the relevant part of my nginx.conf
server{
listen 80;
server_name universitytutor.local;
rewrite ^/(.*) http://www.universitytutor.local/$1 permanent;
}
server {
listen 80;
server_name www.universitytutor.local *.universitytutor.local;
root /Users/barmstrong/NetBeansProjects/universitytutor/public; # <--- be sure to point to 'public'!
passenger_enabled on;
rails_env development;
}
The page loads correctly whether I type "universitytutor.local" or "www.universitytutor.local" and it does not redirect.
I have the *.universitytutor.local in there because I use subdomains for different cities so I need this, but I want a blank subdomain to redirect to "www".
Any ideas?
Found the solution for this. I was not restarting Nginx correctly so it was not picking up the changes. Doh!
You can restart like this
sudo kill `cat /opt/nginx/logs/nginx.pid `
sudo /opt/nginx/sbin/nginx
or add this to your .bashrc for easier use
alias nginx_restart='nginx_stop; nginx_start'
alias nginx_start='sudo /opt/nginx/sbin/nginx'
alias nginx_stop='sudo kill `cat /opt/nginx/logs/nginx.pid `'

Resources