Nginx reverse proxy not connecting to rails web container through docker-compose and Puma/SSL

I setup a simple docker-compose for reviewing a prod build with the inclusion of installing an existing SSL cert. The build process completes successfully and the containers do run. I’m trying to figure out how to setup my localhost env to utilize the SSL cert through nginx for Rails/Puma. I believe the trouble is coming from the nginx.conf but I set it up like I was advised to set it up…Please assist me with my setup below. Take note the goal is to use ssl nginx and puma for my rails application (locally) for now.

I receive the error:
<Puma::HttpParserError: Invalid HTTP format, parsing fails. Are you trying to open an SSL connection to a non-SSL Puma?>

docker-compose.yml

services:
    web_prod:
         container_name: web_prod
         command: sh -c "bundle exec foreman start -f Procfile.prod"
         build:
             context: .
             dockerfile: prod.Dockerfile
         volumes:
             - .:/rails
         networks:
             - priv_network
         environment_file:
             - .env
         restart: unless-stopped
         ports:
             - '3000:3000'
      nginx_prod:
          build:
              context: .
              dockerfile: docker/nginx/nginx.Dockerfile
         ports:
             - '80:80'
             - '443:443'
          volumes:
              - ./tmp/sockets:/tmp/sockets
              - ./log:/web_prod/log

          networks:
              - priv_network
          links:
            - web_prod
          restart: unless-stopped
          depends_on:
              - web_prod
 networks:
     internal_network:

nginx docker. file

FROM nginx
RUN apt-get update --qq && apt-get -y install apache2-utils
COPY /docker/nginx/nginx.conf /etc/nginx/conf.d/default.conf
COPY /docker/nginx/certs/server.crt /etc/nginx/certs/server.crt
COPY /docker/nginx/certs/server.key /etc/nginx/certs/server.key
EXPOSE 80 443
CMD ["nginx", "-g", "daemon off;"]

prod.Dockerfile

ARG RUBY_VERSION=3.4.4
FROM docker.io/library/ruby:$RUBY_VERSION-slim AS base
ENV HTTP_PROXY='http://co-proxy:8080'
ENV HTTPS_PROXY='https://co-proxy:8080'

WORKDIR /rails
RUN mkdir -p /etc/pki/tls/certs
COPY /docker/stuff/ca-bundle.crt /etc/pki/tls/certs/

RUN apt-get update -qq && \
         apt-get ....

ENV RAILS_ENV="production" \
        BUNDLE_DEPLOYMENT="1" \
        BUNDLE_PATH="/usr/local/bundle" \
        BUNDLE_WITHOUT="development" \
        RACK_ENV="production"


FROM base AS build

COPY Gemfile Gemfile.lock ./
RUN bundle config ssl_verify_mode 0 && echo ":ssl_verify_Mode: 0" > ~/.gemrc
RUN bundle install

COPY . .

RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile

FROM base 
FROM apt-get update -qq && apt-get install -y libmariadb-dev

COPY --from=build "${BUNDLE_PATH}" "${BUNDLE_PATH}"
COPY --from=build /rails /rails

RUN groupadd --system --gid 1000 rails && \
        useradd --uid 1000 --gid 1000 --create-home --shell /bin/bash && \
        chown -R rails:rails db log storage tmp
USER 1000:1000

ENTRYPOINT ["sh", "docker-entrypoint"]

HEALTHCHECK --intervals=15s --timeout=3s --start-period=0s --start-interval=5s --retries=3 \
  CMD curl -f https://localhost:3000/up || exit 1

CMD ["bundle", "exec", "puma", "-C", "config/puma.rb"]

EXPOSE 3000

nginx.conf

upstream rails_app {
 server 0.0.0.0:3000;
}


server {
 listen 443 ssl;
 server_name 127.0.0.1;
 ssl_certificate /etc/nginx/certs/server.crt;
 ssl_certificate_key /etc/nginx/certs/server.key;
 ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
 ssl_ciphers HIGH:!aNULL:!MD5;
 keepalive_timeout 70;
 root /public;
 access_log /var/log/nginx/access.log;
 error_log /var/log/nginx/error.log;
 
location ~/\. {
  deny all;
}

location ~* ^.+\.(rb|log)$ {
  deny all;
}

location ~ ^/(assets|images|javascripts|stylesheets|swfs|system)/ {
 try_files $uri @rails;

access_log on;
gzip_static_on;
expires max;
add_header Cache-Control public;
add_header Last-Modified "";
add_header ETag "";
break;
}

location / {
 try_files $uri @rails;
}

location @rails {
  proxy_pass http://rails_app;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header Host $http_host;
  proxy_redirect off;
  proxy_read_timeout 900;
  }
}

Can you share what your intention is with this?

How is the nginx container supposed to know how to access a port in the web_prod container?
You need to use the service name of the target container as upstream server.

But I wouldn’t recommend configuring it that way either, as it will not work reliably because of dns resolution caching. Here is a post about how to bypass that. NGINX swarm redeploy timeouts - #5 by meyay.

1 Like

I may have changed it - due to exhaustion…I tried a few combinations before signing off…I’m just reciting that your recommendation is the one in your other post? Do I need any other changes to my nginx.conf in your opinion? I’ll attempt to reconfigure my nginx.conf to look like that one

Could you add your references here for future viewers of this posts?

I know ppl have tried with http, but given that I’m using an actual ssl cert locally. It could benefit all to know how it should be configured.

upstream rails_app {
 server 0.0.0.0:3000;
}


server {
 listen 443 ssl;
 server_name 127.0.0.1;
 ssl_certificate /etc/nginx/certs/server.crt;
 ssl_certificate_key /etc/nginx/certs/server.key;
 ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
 ssl_ciphers HIGH:!aNULL:!MD5;
 keepalive_timeout 70;
 root /public;
 access_log /var/log/nginx/access.log;
 error_log /var/log/nginx/error.log;
 
location ~/\. {
  deny all;
}

location ~* ^.+\.(rb|log)$ {
  deny all;
}

location ~ ^/(assets|images|javascripts|stylesheets|swfs|system)/ {
 try_files $uri @rails;

access_log on;
gzip_static_on;
expires max;
add_header Cache-Control public;
add_header Last-Modified "";
add_header ETag "";
break;
}

location / {
 try_files $uri @rails;
}

location @rails {
  proxy_pass http://rails_app;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header Host $http_host;
  proxy_redirect off;
  proxy_read_timeout 900;
  }
}

Looks like you accidentally posted the same content again.

I though, you wanted to incorporate the changes and share the result.

I’ll return on Monday morning with my insights.

I updated the link I shared two posts ago. The link was pointing to the wrong post. Now it’s fixed.

I am sure you still got the gist, while reading through the other topic.