Hello guys I am trying to make work my rails app with nginx as a reverse proxy the rails app and nginx are in separate docker containers and works thru docker-compose services. I am until now without any success.
Rails environment production.rb => config.force_ssl = true
my docker-compose file is this:
version: '3'
services:
nginx:
image: reverse_nginx:latest
ports:
- '80:80'
depends_on:
- web
web:
image: production_my_app:latest
command: rails s -p 3000 -b '0.0.0.0' -e production
ports:
- '3000:3000'
depends_on:
- postgres
- redis
env_file:
- ...
restart: always
For build reverse_nginx:latest I use Dockerfile-nginx with this:
# Base image: debian strech
FROM nginx:stable
RUN apt-get update -qq \
&& apt-get install -y ca-certificates
COPY ssl/server.crt /etc/ssl/certs/server.crt
COPY ssl/server.key /etc/ssl/private/server.key
RUN cd /etc/ssl/private \
&& chmod 600 server.* \
&& cd /etc/ssl/certs \
&& chmod 600 server.* \
&& update-ca-certificates --fresh
# establish where Nginx should look for files
ENV RAILS_ROOT /var/www/my_app/public
# Set working directory inside the image
WORKDIR $RAILS_ROOT
# create log directory
RUN mkdir log
# copy over static assets
COPY public .
# copy custom general nginx conf
COPY config/nginx.conf /etc/nginx/nginx.conf
# copy custom conf for my_app to sites-available folder
COPY config/my.app.conf /etc/nginx/sites-available/my.app.conf
# create sites-enabled folder and soft link custom conf for my_app
RUN mkdir -p /etc/nginx/sites-enabled/ \
&& cd /etc/nginx/sites-enabled/ \
&& ln -s /etc/nginx/sites-available/my.app.conf . \
&& ls -la \
&& nginx -c /etc/nginx/nginx.conf -t
EXPOSE 80
CMD [ "nginx", "-g", "daemon off;" ]
The /etc/nginx/nginx.conf file:
user nginx;
worker_processes auto;
worker_rlimit_nofile 1024;
events {
multi_accept on;
worker_connections 1024;
}
http {
# load configs
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*.conf;
# MIME
include /etc/nginx/mime.types;
default_type application/octet-stream;
# logging
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log warn;
charset utf-8;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
server_tokens off;
log_not_found off;
types_hash_max_size 2048;
client_max_body_size 16M;
# SSL
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
# modern configuration
ssl_protocols TLSv1.2;
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256;
ssl_prefer_server_ciphers on;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 1.1.1.1 1.0.0.1 8.8.8.8 8.8.4.4 208.67.222.222 208.67.220.220 valid=60s;
# resolver_timeout 2s;
}
The /etc/nginx/sites-available/my_app.conf file:
# HTTPS
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name my.app;
root /var/www/myapp/public;
ssl_certificate /etc/ssl/certs/server.crt;
ssl_certificate_key /etc/ssl/private/server.key;
# index.html fallback
location / {
try_files $uri $uri/ /index.html;
}
# reverse proxy
location /var/www/myapp/public {
# proxy_pass needs to be name of service on docker compose to connect with container?
proxy_pass http://web:3000;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
# HTTP redirect to HTTPS
server {
listen 80;
listen [::]:80;
server_name .my.app;
return 301 https://my.app$request_uri;
}
Scenarios:
$ docker-compose up nginx_1 => message (as expected):
nginx_1 | "ssl_stapling" ignored, issuer certificate not found for certificate "/etc/ssl/certs/server.crt"
scenario 1: visit 0.0.0.0 in browser, url changes to https://my.app browser says: ERR_SSL_PROTOCOL_ERROR
scenario 2: visit 0.0.0.0:80 in browser, url changes to https://my.app browser says: ERR_SSL_PROTOCOL_ERROR
scenario 3: visit 0.0.0.0:3000 in browser, url changes to https://0.0.0.0:3000 rails error log HTTPS parse error malformed invalid HTTP format parsing fails, browser says: ERR_SSL_PROTOCOL_ERROR
scenario 4: visit https://0.0.0.0:80, url stays the same, nginx_1 log throw characters: 192.168.0.1 - - [28/Nov/2018:21:39:22 +0000] "\x16\x03\x01\x00\xB5\x01\x00\x00\xB1\x03\x03\xD3@kn" 400 166 "-" "-"
I think that the problem is in proxy_pass directive in my_app.conf but to be honest I do not know what I am doing right now I am stuck. can you help me to understand what is going on? I had never used nginx