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!
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