# Redirect loop problem with SSL

**URL:** <https://www.ruby-forum.com/t/redirect-loop-problem-with-ssl/223511>\
**Category:** NGINX\
**Created:** [October 8, 2012, 4:31am UTC](https://www.ruby-forum.com/t/redirect-loop-problem-with-ssl/223511 "2012-10-08T04:31:14Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![aris](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/258eb7/32.png) [@aris](https://www.ruby-forum.com/u/aris)\
**Post date:** [October 8, 2012, 4:31am UTC](https://www.ruby-forum.com/t/redirect-loop-problem-with-ssl/223511/1 "2012-10-08T04:31:14Z")

</div>

Hello, I am having a problem understanding exactly how to configure my  
nginx  
server to use SSL with Linode, RoR, Unicorn and spree ecommerce. This  
post  
will be kind of long, but this is just so you can see all the steps I  
have  
taken thus far. The first section will include all the steps I have  
taken  
to set up my linode instance. In this setup, the site displays, but I  
get  
the Redirect Loop when I try to log in. Someone suggested that I needed  
to  
set up separate server blocks for port 80 and port 443. After I did this  
(the nginx.conf for that set up will be at the end), every page gives me  
the  
Redirect loop. So, I clearly do not understand what I am doing and need  
a  
little nudge. Please help me.

— error message —

This webpage has a redirect loop

The webpage at [https://50.116.18.21/login](https://50.116.18.21/login) has resulted in too many  
redirects. Clearing your cookies for this site or allowing third-party  
cookies may fix the problem. If not, it is possibly a server  
configuration  
issue and not a problem with your computer.

— end error message —

— original steps —

1. create server Ubuntu 10.04 LTS (with defaults)

2. boot server

3. ssh [root@50.116.18.21](mailto:root@50.116.18.21)

4. apt-get -y update

5. apt-get -y install curl git-core python-software-properties

6. add-apt-repository ppa:nginx/stable

7. apt-get -y update

8. apt-get -y install nginx  
/\*\*\* Can I do the SSL stuff here??? \*\*\*/  
#. mkdir /srv/ssl/  
#. cd /srv/ssl  
#. openssl req -new -x509 -days 365 -nodes -out /srv/ssl/nginx.pem  
-keyout  
/srv/ssl/nginx.key

9. service nginx start

10. apt-get -y install imagemagick

11. add-apt-repository ppa:pitti/postgresql

12. apt-get -y update

13. apt-get -y install postgresql libpq-dev

14. sudo -u postgres psql

15. \password

16. create user mayorio with password ‘secret’;

17. create database mayorio\_production owner mayorio;

18. \q

19. apt-get -y install telnet postfix

20. add-apt-repository ppa:chris-lea/node.js

21. apt-get -y update

22. apt-get -y install nodejs

23. apt-get -y install libxslt-dev libxml2-dev

24. adduser deployer --ingroup admin

25. su deployer

26. cd

27. curl -L  
[https://raw.github.com/fesplugas/rbenv-installer/master/bin/rbenv-installer](https://raw.github.com/fesplugas/rbenv-installer/master/bin/rbenv-installer)  
| bash

28. vim ~/.bashrc # add rbenv to the top

29. put the following in the top:  
— begin snippet —  
export RBENV\_ROOT=“${HOME}/.rbenv”

if [-d “${RBENV\_ROOT}”]; then  
export PATH=“${RBENV\_ROOT}/bin:${PATH}”  
eval “$(rbenv init -)”  
fi  
— end snippet —  
30. . ~/.bashrc  
31. rbenv bootstrap-ubuntu-10-04  
32. rbenv install 1.9.3-p125  
33. rbenv global 1.9.3-p125  
34. gem install bundler --no-ri --no-rdoc  
35. rbenv rehash  
36. ssh removed\_email\_address@domain.invalid  
37. switch back to local box  
38. rails new mayorio -d postgresql  
39. cd mayorio  
\*\*\* 40 and 41 no longer necessary. they must have fixed it 🙂  
40. edit Gemfile to add “gem ‘cocaine’, :git =\>  
‘git://github.com/thoughtbot/cocaine.git’” (make sure to do to newlines  
after for spree)  
41. bundle install  
\*\*\* see above \*\*\*  
42. sudo -u postgres psql  
43. create user mayorio with password ‘secret’;  
44. create database mayorio\_development owner mayorio;  
45. \q  
46. edit config/database.yml to add password  
47. spree install (accept all defaults)  
48. bundle exec rake assets:precompile:nondigest  
\*\*\* consider adding public/assets to .gitignore \*\*\*  
49. edit .gitignore and add “/config/database.yml”  
50. cp config/database.yml config/database.example.yml  
51. git init  
52. git add .  
53. git commit -m “initial commit”  
54. create github repo “mayorio”  
55. git remote add origin removed\_email\_address@domain.invalid:mlybrand/mayorio.git  
56. git push origin master  
57. edit Gemfile to uncomment unicorn and capistrano lines  
58. bundle  
59. capify .  
60. edit Capfile to uncomment load assets line  
61. edit config/deploy.rb to be the following:  
— begin code snippet —  
require “bundler/capistrano”

server “50.116.18.21”, :web, :app, :db, primary: true

set :application, “mayorio”  
set :user, “deployer”  
set :deploy\_to, “/home/#{user}/apps/#{application}”  
set :deploy\_via, :remote\_cache  
set :use\_sudo, false

set :scm, “git”  
set :repository, “removed\_email\_address@domain.invalid:mlybrand/#{application}.git”  
set :branch, “master”

default\_run\_options[:pty] = true  
ssh\_options[:forward\_agent] = true

after “deploy”, “deploy:cleanup” # keep only the last 5 releases

namespace :deploy do  
%w[start stop restart].each do |command|  
desc “#{command} unicorn server”  
task command, roles: :app, except: {no\_release: true} do  
run “/etc/init.d/unicorn\_#{application} #{command}”  
end  
end

task :setup\_config, roles: :app do  
sudo “ln -nfs #{current\_path}/config/nginx.conf  
/etc/nginx/sites-enabled/#{application}”  
sudo “ln -nfs #{current\_path}/config/unicorn\_init.sh  
/etc/init.d/unicorn\_#{application}”  
run “mkdir -p #{shared\_path}/config”  
put File.read(“config/database.example.yml”),  
“#{shared\_path}/config/database.yml”  
puts “Now edit the config files in #{shared\_path}.”  
end  
after “deploy:setup”, “deploy:setup\_config”

task :symlink\_config, roles: :app do  
run “ln -nfs #{shared\_path}/config/database.yml  
#{release\_path}/config/database.yml”  
end  
after “deploy:finalize\_update”, “deploy:symlink\_config”

desc “Make sure local git is in sync with remote.”  
task :check\_revision, roles: :web do  
unless `git rev-parse HEAD` == `git rev-parse origin/master`  
puts “WARNING: HEAD is not the same as origin/master”  
puts “Run `git push` to sync changes.”  
exit  
end  
end  
before “deploy”, “deploy:check\_revision”  
end  
— end code snippet —  
62. edit config/nginx.conf  
— begin code snippet —  
upstream unicorn {  
server unix:/tmp/unicorn.mayorio.sock fail\_timeout=0;  
}

server {  
listen 80; # default deferred

# server\_name [example.com](http://example.com)

listen 443 ssl;  
ssl\_certificate /srv/ssl/nginx.pem;  
ssl\_certificate\_key /srv/ssl/nginx.key;

# server\_name [example.com](http://example.com);

root /home/deployer/apps/mayorio/current/public;

location ^~ /assets/ {  
gzip\_static on;  
expires max;  
add\_header Cache-Control public;  
}

try\_files $uri/index.html $uri @unicorn;  
location @unicorn {  
proxy\_set\_header X-Forwarded-For $proxy\_add\_x\_forwarded\_for;  
proxy\_set\_header Host $http\_host;  
proxy\_redirect off;  
proxy\_pass [http://unicorn](http://unicorn);  
}

error\_page 500 502 503 504 /500.html;  
client\_max\_body\_size 4G;  
keepalive\_timeout 10;  
}

— end code snippet —  
63. edit config/unicorn.rb  
— begin code snippet —  
root = “/home/deployer/apps/mayorio/current”  
working\_directory root  
pid “#{root}/tmp/pids/unicorn.pid”  
stderr\_path “#{root}/log/unicorn.log”  
stdout\_path “#{root}/log/unicorn.log”

listen “/tmp/unicorn.mayorio.sock”  
worker\_processes 2  
timeout 30  
— end code snippet —  
64. edit config/unicorn\_init.sh  
— begin code snippet —  
#!/bin/sh

### BEGIN INIT INFO

# Provides: unicorn

# Required-Start: $remote\_fs $syslog

# Required-Stop: $remote\_fs $syslog

# Default-Start: 2 3 4 5

# Default-Stop: 0 1 6

# Short-Description: Manage unicorn server

# Description: Start, stop, restart unicorn server for a specific

application.

### END INIT INFO

set -e

# Feel free to change any of the following variables for your app:

TIMEOUT=${TIMEOUT-60}  
APP\_ROOT=/home/deployer/apps/mayorio/current  
PID=$APP\_ROOT/tmp/pids/unicorn.pid  
CMD=“cd $APP\_ROOT; bundle exec unicorn -D -c $APP\_ROOT/config/unicorn.rb  
-E  
production”  
AS\_USER=deployer  
set -u

OLD\_PIN=“$PID.oldbin”

sig () {  
test -s “$PID” && kill -$1 `cat $PID`  
}

oldsig () {  
test -s $OLD\_PIN && kill -$1 `cat $OLD_PIN`  
}

run () {  
if [“$(id -un)” = “$AS\_USER”]; then  
eval $1  
else  
su -c “$1” - $AS\_USER  
fi  
}

case “$1” in  
start)  
sig 0 && echo \>&2 “Already running” && exit 0  
run “$CMD”  
;;  
stop)  
sig QUIT && exit 0  
echo \>&2 “Not running”  
;;  
force-stop)  
sig TERM && exit 0  
echo \>&2 “Not running”  
;;  
restart|reload)  
sig HUP && echo reloaded OK && exit 0  
echo \>&2 “Couldn’t reload, starting ‘$CMD’ instead”  
run “$CMD”  
;;  
upgrade)  
if sig USR2 && sleep 2 && sig 0 && oldsig QUIT  
then  
n=$TIMEOUT  
while test -s $OLD\_PIN && test $n -ge 0  
do  
printf ‘.’ && sleep 1 && n=$(( $n - 1 ))  
done  
echo

```
if test $n -lt 0 && test -s $OLD_PIN
then
  echo >&2 "$OLD_PIN still exists after $TIMEOUT seconds"
  exit 1
fi
exit 0

```

fi  
echo \>&2 “Couldn’t upgrade, starting ‘$CMD’ instead”  
run “$CMD”  
;;  
reopen-logs)  
sig USR1  
;;  
\*)  
echo \>&2 “Usage: $0  
\<start|stop|restart|upgrade|force-stop|reopen-logs\>”  
exit 1  
;;  
esac  
— end code snippet —  
65. chmod +x config/unicorn\_init.sh  
66. git add .  
67. git commit -m “deployment configs”  
68. git push  
69. cap deploy:setup  
70. ssh [deployer@50.116.18.21](mailto:deployer@50.116.18.21)  
71. cd apps/mayorio/shared/config  
72. vim database.yml  
73. remove everything except production  
74. add password for production  
75. add “host: localhost”  
76. exit  
77. cap deploy:cold  
78. ssh [deployer@50.116.18.21](mailto:deployer@50.116.18.21)  
79. sudo rm /etc/nginx/sites-enabled/default  
80. sudo service nginx restart  
81. sudo update-rc.d unicorn\_mayorio defaults

— end original steps —

— final nginx.conf used —

upstream unicorn {  
server unix:/tmp/unicorn.mayorio.sock fail\_timeout=0;  
}

server {  
listen 80; # default deferred

# server\_name [example.com](http://example.com)

rewrite ^(.\*) https://$host$1 permanent;

location ~ .(php|html)$ {  
deny all;  
}

access\_log /dev/null;  
error\_log /dev/null;  
}

server {  
ssl on;

# server\_name [example.com](http://example.com)

listen 443 ssl;  
ssl\_certificate /srv/ssl/nginx.pem;  
ssl\_certificate\_key /srv/ssl/nginx.key;

# server\_name [example.com](http://example.com);

root /home/deployer/apps/mayorio/current/public;

location ^~ /assets/ {  
gzip\_static on;  
expires max;  
add\_header Cache-Control public;  
}

try\_files $uri/index.html $uri @unicorn;  
location @unicorn {  
proxy\_set\_header X-Forwarded-For $proxy\_add\_x\_forwarded\_for;  
proxy\_set\_header X-Forwarded-Proto $scheme;  
proxy\_set\_header Host $http\_host;  
proxy\_redirect off;  
proxy\_pass [http://unicorn](http://unicorn);  
}

error\_page 500 502 503 504 /500.html;  
client\_max\_body\_size 4G;  
keepalive\_timeout 10;  
}

— end final nginx.conf —

Posted at Nginx Forum:

> **[Redirect loop problem with SSL](https://forum.nginx.org/read.php?2,231461,231461#msg-231461)**
>
> Hello, I am having a problem understanding exactly how to configure my nginx server to use SSL with Linode, RoR, Unicorn and spree ecommerce. This post will be kind of long, but this is just so you can see all the steps I have taken thus far. The...

---

<div class="post-metadata">

**Author:** ![mlybrand](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e9a140/32.png) [@mlybrand](https://www.ruby-forum.com/u/mlybrand)\
**Post date:** [October 8, 2012, 6:29pm UTC](https://www.ruby-forum.com/t/redirect-loop-problem-with-ssl/223511/2 "2012-10-08T18:29:42Z")

</div>

hey mlybrand,

You can check the redirecting behaviour with CURL. Use,  
$ curl -I -k [http://example.org](http://example.org) # to get only the respond header and  
dont  
validate the ssl cert

Also, maybe try “return 301 https://$host$request\_uri;” over “rewrite  
^(.\*) https://$host$1 permanent;”, and check the with curl, again.

Good luck and have a nice week!  
~ed
