ruby-on-railsdockernginxamazon-ec2dev-to-production

AWS EC2 instance not showing Rails app production


Quick newbie question. I have a simple Rails app that I want to put into production. I would like to deploy it in a AWS EC2 server. The app works perfectly fine locally on the port 3000.

I tried running the container and although it says that is listening on the port 3000, when I try to go to: 13.241.213.464:3000 on the browser it keeps loading without showing anything.

I read around the internet that you need to change your CMD on the Dockerfile to make it run so I changed it from this:

CMD ["rails", "server", "-b", "0.0.0.0"]

to this:

CMD ["bundle",  "exec", "rails", "server", "-e", "production"]

So now my Dockerfile looks like this:

# Start from the official ruby image, then update and install JS & DB
FROM ruby:2.6.6
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client

# Create a directory for the application and use it
RUN mkdir /myapp
WORKDIR /myapp

# Gemfile and lock file need to be present, they'll be overwritten immediately
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock

# Install gem dependencies
RUN gem install bundler:2.2.32
RUN bundle install
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
RUN apt-get update -qq && apt-get install -y yarn  && apt-get install -y npm
RUN yarn install
RUN yarn add bootstrap jquery popper.js
COPY . /myapp

# This script runs every time the container is created, necessary for rails
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

# Start rails
CMD ["bundle",  "exec", "rails", "server", "-e", "production"]

My docker-compose.yml is:

version: "3"

services:
  db:
    image: postgres
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
      POSTGRES_HOST: db

And the entrypoint.sh is:

#!/bin/bash

# Rails-specific issue, deletes a pre-existing server, if it exists

set -e

rm -f /myapp/tmp/pids/server.pid

exec "$@"

To run the container for production I run the docker-compose.override.yml :

version: "3"

services:
  db:
    image: postgres
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
  web:
    image: "dockerhub_user/repo:${WEB_TAG:-latest}"
    ports:
      - "3000:3000"
    depends_on:
      - db
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
      POSTGRES_HOST: db

I run it like this: docker-compose -f docker-compose.override.yml up

It still keeps loading without showing anything.

I also read about some projects that have nginx but I am not sure if it is needed or not to make it work. I kind of understood the nginx help to proxy the requests between users and the Rails app, is it correct? Then, do I need nginx to make it work in production?

Any kind of enlightment is welcome. Thank you!


Solution

  • So I ended up building nginx but even then it was not working. Then I realized it might be the Inbound and outbound rules in the Security of the AWS EC2 instance.

    So, right now, my app is listening on port 80 (because of nginx). What I did was to create a couple of Inbound rules:

    80  TCP 0.0.0.0/0
    80  TCP ::/0
    

    With this, it is now showing the app once I go into the public ip of the instance:80.

    Hope this helps someone in need in the future