I have created an infrastructure (application) using AWS, Docker (docker-compose), and Rails.
After launching the container in EC2 and starting the rails server, I get "ERR_CONNECTION_REFUSED" when I access the public IP address.
I would like to know how to display the application screen.
My directory structure looks like:
kthr01/
docker-compose.yml
Dockerfile
start.sh
src/
app/
bin/
....
Dockerfile
FROM ruby:2.7
ENV RAILS_ENV=production
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
&& echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list \
&& apt-get update -qq \
&& apt-get install -y nodejs yarn \
&& apt-get install -y vim
WORKDIR /app
COPY ./src /app
RUN bundle config --local set path 'vendor/bundle' \
&& bundle install
COPY start.sh /start.sh
RUN chmod 744 /start.sh
CMD ["sh", "/start.sh"]
docker-compose.yml
version: '3'
services:
db:
image: mysql:8.0
command: --default-authentication-plugin=mysql_native_password
volumes:
- ./src/db/mysql_data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: password
web:
build: .
command: bundle exec rails s -p 3000 -b '0.0.0.0'
volumes:
- ./src:/app
ports:
- "3000:3000"
depends_on:
- db
start.sh
#!/bin/sh
if [ "${RAILS_ENV}" = "production" ]
then
bundle exec rails assets:precompile
fi
bundle exec rails s -p ${PORT:-3000} -b 0.0.0.0
I have a screen shot of the AWS console showing the EC2 security group setup:
To run this:
Verify that the container is created in the local environment and appears correctly on localhost:3000
↓
Connect to EC2 via ssh
↓
git clone
↓
docker-compose build
↓
docker-compose up
...
web_1 | => Booting Puma
web_1 | => Rails 6.1.4.4 application starting in production
web_1 | => Run `bin/rails server --help` for more startup options
web_1 | Puma starting in single mode...
web_1 | * Puma version: 5.6.1 (ruby 2.7.5-p203) ("Birdie's Version")
web_1 | * Min threads: 5
web_1 | * Max threads: 5
web_1 | * Environment: production
web_1 | * PID: 1
web_1 | * Listening on http://0.0.0.0:3000
web_1 | Use Ctrl-C to stop
↓
Access the public IP address of EC2
↓
ERR_CONNECTION_REFUSED is displayed
Based on the comments.
The issue was blocked port 3000 in a security group. The solution was to allow that port.
Related
dockerfile
FROM node:10
RUN mkdir /app
WORKDIR /app
COPY . /app
RUN npm install
EXPOSE 3000
CMD ["npm","start"]
docker-compose.yaml
version: "3.9"
networks:
app-tier:
driver: bridge
services:
db:
platform: linux/x86_64
image: mysql
networks:
- app-tier
container_name: mysql_container
restart: always
ports:
- "3306:3306"
# environment:
# - MYSQL_ROOT_PASSWORD: abc
# - MYSQL_DATABASE: mydb
volumes:
- ./:/usr/src/app
web:
depends_on:
- db
environment:
- MYSQL_HOST=mysql
- MYSQL_USER=me
- MYSQL_PASSWORD=1234
- MYSQL_DATABASE=mydb
build: .
docker-entrypoint.sh
dockerize -wait tcp://mysql:3306 -timeout 20s
echo "Start server"
npm run start
result: app and mysql starts up but I am assuming db should start up first in order app to connect to the database
web_1 |
web_1 | > xxxx#0.0.0 start /app
web_1 | > export NODE_ENV=production || set NODE_ENV=production && node ./bin/www
web_1 |
web_1 | production
web_1 | process.env.NODE_ENV production
web_1 | { SequelizeConnectionRefusedError: connect ECONNREFUSED 127.0.0.1:3306
web_1 | at ConnectionManager.connect (/app/node_modules/sequelize/lib/dialects/mysql/connection-manager.js:116:17)
web_1 | at process._tickCallback (internal/process/next_tick.js:68:7)
web_1 | name: 'SequelizeConnectionRefusedError',
web_1 | parent:
web_1 | { Error: connect ECONNREFUSED 127.0.0.1:3306
web_1 | at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1107:14)
web_1 | errno: 'ECONNREFUSED',
web_1 | code: 'ECONNREFUSED',
web_1 | syscall: 'connect',
web_1 | address: '127.0.0.1',
......
I don't know if docker-compose file is not reading .sh file or not nor do I know somethings wrong on docker-compose file.
can anybody help me with the configuration.
You have a connection issue as your web service cannot connect with your database.
Keep in mind that the hostname of your database equals the service name. So instead of connecting with 127.0.0.1:3306 connect with http://db:3306 instead.
I figured it out
I didn't define RUN ["chmod", "+x", "docker-entrypoint.sh"] ENTRYPOINT ["sh", "docker-entrypoint.sh"]
in my dockerfile
FROM node:10
ENV DOCKERIZE_VERSION v0.2.0
RUN wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz \
&& tar -C /usr/local/bin -xzvf dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz
# Create app directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
# Install dependencies
COPY package.json .
RUN npm install
# Bundle app source
COPY . .
RUN ["chmod", "+x", "docker-entrypoint.sh"]
ENTRYPOINT ["sh", "docker-entrypoint.sh"]
# Exports
EXPOSE 3000
I didn't configure db related configutation as same as my docker-compose file in my .env file
DB_USERNAME=user1
DB_PASSWORD=password1
DB_NAME=user1
DB_HOSTNAME=mysql
JWT_SECRETKEY=123
I'm currently having an issue with my docker-compose that have these services.
Rails app and Postgres. These are my configurations:
docker-compose.yml
version: '3'
services:
db:
image: postgres:alpine
restart: always
volumes:
- ./tmp/db:/var/lib/postgresql/data
ports:
- "5432:5432"
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
app:
build: .
restart: always
command: bash -c "rm -f tmp/pids/server.pid && rails s -p 3000 -b '0.0.0.0'"
volumes:
- .:/myapp
- bundle_path:/bundle
ports:
- "3000:3000"
depends_on:
- db
volumes:
bundle_path:
Dockerfile
FROM ruby:2.5.3-slim
# install rails dependencies
RUN apt-get update -qq \
&& apt-get install -y \
# Needed for certain gems
build-essential \
# Needed for postgres gem
libpq-dev \
# Others
nodejs \
vim-tiny \
# The following are used to trim down the size of the image by removing unneeded data
&& apt-get clean autoclean \
&& apt-get autoremove -y \
&& rm -rf \
/var/lib/apt \
/var/lib/dpkg \
/var/lib/cache \
/var/lib/log
# Changes localtime to Singapore
RUN cp /usr/share/zoneinfo/Asia/Singapore /etc/localtime
# create a folder /myapp in the docker container and go into that folder
RUN mkdir /myapp
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
# Run bundle install to install gems inside the gemfile
RUN bundle install
ADD . /myapp
CMD bash -c "rm -f tmp/pids/server.pid && rails s -p 3000 -b '0.0.0.0'"
database.yml
default: &default
adapter: postgresql
encoding: unicode
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
development:
<<: *default
database: myapp_development
host: db
username: postgres
password: postgres
port: 5432
I can build the app using docker-compose build but whenever I docker-compose up the service db exited but my rails app is running.
This is the logs I'm getting when I run docker-compose up
db_1 | The files belonging to this database system will be owned by user "postgres".
db_1 | This user must also own the server process.
db_1 |
db_1 | The database cluster will be initialized with locale "en_US.utf8".
db_1 | The default database encoding has accordingly been set to "UTF8".
db_1 | The default text search configuration will be set to "english".
db_1 |
db_1 | Data page checksums are disabled.
db_1 |
db_1 | initdb: error: directory "/var/lib/postgresql/data" exists but is not empty
db_1 | If you want to create a new database system, either remove or empty
db_1 | the directory "/var/lib/postgresql/data" or run initdb
db_1 | with an argument other than "/var/lib/postgresql/data".
The error I'm getting when I access http://localhost:3000 is
could not connect to server: No route to host Is the server running on host "db" (172.18.0.2) and accepting TCP/IP connections on port 5432?
I think you should use volume for Postgres too.
services:
db:
image: postgres:alpine
restart: always
volumes:
- postgres_volume:/var/lib/postgresql/data
volumes:
postgres_volume:
I had similar issue and fixed it with that. Try also to restart Docker.
I'm new to docker, and trying to workout why my Docker setup is hanging and not connecting like I expect it to.
I'm running
Docker version 18.09.2, build 6247962
docker-compose version 1.23.2, build 1110ad01
OSX 10.14.5
My setup is based on this Gist that I found.
I've reduced it somewhat, to better demonstrate the issue.
Dockerfile
FROM ruby:2.4
ARG DEBIAN_FRONTEND=noninteractive
RUN echo "deb http://apt.postgresql.org/pub/repos/apt/ xenial-pgdg main" >> /etc/apt/sources.list.d/postgeresql.list \
&& wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - \
&& apt-get update \
&& apt-get update \
&& apt-get install -y --no-install-recommends apt-utils \
&& apt-get install -y build-essential \
&& apt-get install -y nodejs \
&& apt-get install -y --no-install-recommends \
postgresql-client-9.6 pv ack-grep ccze unp htop vim \
&& apt-get install -y libxml2-dev libxslt1-dev \
&& rm -rf /var/lib/apt/lists/* \
&& apt-get purge -y --auto-remove
# Set environment
ENV APP_HOME /usr/src/app
ENV BUNDLER_VERSION 2.0.2
# Setup bundler
RUN gem install bundler -v $BUNDLER_VERSION
WORKDIR $APP_HOME
EXPOSE 7051
CMD ["bundle", "exec", "puma", "-p", "7051", "-C", "config/puma.rb"]
docker_compose.yml
version: '3.1'
services:
app: &app_base
build: .
working_dir: /usr/src/app
volumes:
- .:/usr/src/app
# to be able to forward ssh-agent to github through capistrano (bundle on server)
- "~/.ssh/id_rsa:/root/.ssh/id_rsa"
- $SSH_AUTH_SOCK:$SSH_AUTH_SOCK
environment: &app_environment
# to keep bundle effect between container restarts (without rebuild):
BUNDLE_PATH: /usr/src/app/.bundle
BUNDLE_APP_CONFIG: /usr/src/app/.bundle
DATABASE_HOST: db
SSH_AUTH_SOCK: # this left empty copies from outside env
env_file: '.env'
ports:
- "7051:7051"
depends_on:
- db
db:
image: postgres:9.5.17
ports:
- "5432:5432"
environment:
POSTGRES_DB: my_project_development
POSTGRES_USER: root
POSTGRES_PASSWORD: root
config/database.yml
development:
adapter: postgresql
encoding: unicode
pool: 5
database: my_project_development
username: root
password: root
host: db
config/puma.rb
threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }.to_i
threads threads_count, threads_count
# Specifies the `port` that Puma will listen on to receive requests, default is 3000.
#
port ENV.fetch("PORT") { 7051 }
# Specifies the `environment` that Puma will run in.
#
environment ENV.fetch("RAILS_ENV") { "development" }
# Allow puma to be restarted by `rails restart` command.
plugin :tmp_restart
So what I'm doing is:
Running docker-compose build to first build the images & containers
Running docker-compose run --rm app bundle install to install the gems
Running docker-compose run --rm app bundle exec rake db:create db:migrate db:seed to create/migrate/seed the database
Step 3. is the step I am stuck on. It just hangs there with no feedback:
docker-compose run --rm app bundle exec rake db:create db:migrate db:seed
Starting my_project_db_1 ... done
I know the database is running, as I can connect to it locally.
I can also log into the app container, and connect via psql, so I know that the app container can talk to the db container:
docker exec -it f6d6edadaed4 /bin/bash (52s 699ms)
root#f6d6edadaed4:/usr/src/app# psql "postgresql://root:root#db:5432/my_project_development"
psql (9.6.14, server 9.5.17)
Type "help" for help.
my_project_development=# \dt
No relations found.
If I try to boot the app with docker-compose up, then it also just hangs:
app_1 | Puma starting in single mode...
app_1 | * Version 3.11.4 (ruby 2.4.6-p354), codename: Love Song
app_1 | * Min threads: 5, max threads: 5
app_1 | * Environment: ci
I.e. puma would normally show a 'listening' message once connected:
* Listening on tcp://0.0.0.0:7051
Use Ctrl-C to stop
But it's not getting to that point, it just hangs.
What could be going on? Why can't my Rails container just connect to the PostgreSQL container and have puma boot normally?
MORE INFORMATION:
I've learn't now, if I wait 10+ minutes, it does eventually boot!
During that 10 mins, my CPU fans are spinning like crazy, so it's really thinking about something.
But when it finishes, the CPU fans shut off, and puma has booted and I can access it locally at http://127.0.0.1:7051 like I would expect.
Why would it be so slow to startup? My machine is otherwise pretty fast.
I think Docker on OSX is just extremely slow. I've since read about some performance issues here
Adding a cached option to the volume seems to have reduced the boot time to ~2mins
version: '3.1'
services:
app: &app_base
build: .
working_dir: /usr/src/app
volumes:
- .:/usr/src/app:cached
...
Still not very acceptable in my opinion. Would love to know if there's anything else that can be done?
I found an actual working answer to this, which I also posted here: https://stackoverflow.com/a/58603025/172973
Basically, see the article here to see how to properly setup Dockerfile and docker-compose.yml, so that it performs well on OSX.
The main thing to understand:
To make Docker fast enough on MacOS follow these two rules: use :cached to mount source files and use volumes for generated content (assets, bundle, etc.).
So if anyone else comes across this, just follow the article or see my other answer.
I have my project set with docker-compose. Was working fine until today when I rebuilt the web container. Now whenever I want to start it using docker-compose up it just exits without an Error message:
web_1 | => Booting Unicorn
web_1 | => Rails 3.2.22.5 application starting in development on http://0.0.0.0:3000
web_1 | => Call with -d to detach
web_1 | => Ctrl-C to shutdown server
web_1 | Exiting
If I run it with --verbose, docker-compose --verbose up, the following lines show after 'Exiting':
compose.cli.verbose_proxy.proxy_callable: docker wait <- (u'a03b58f2116698d670f86155cd68605a148143b83ee3351a5e5a4808d682afc9')
compose.cli.verbose_proxy.proxy_callable: docker inspect_container <- (u'a03b58f2116698d670f86155cd68605a148143b83ee3351a5e5a4808d682afc9')
urllib3.connectionpool._make_request: http://localhost:None "POST /v1.25/containers/a03b58f2116698d670f86155cd68605a148143b83ee3351a5e5a4808d682afc9/wait HTTP/1.1" 200 30
compose.cli.verbose_proxy.proxy_callable: docker wait -> 1
urllib3.connectionpool._make_request: http://localhost:None "GET /v1.25/containers/a03b58f2116698d670f86155cd68605a148143b83ee3351a5e5a4808d682afc9/json HTTP/1.1" 200 None
compose.cli.verbose_proxy.proxy_callable: docker inspect_container -> {u'AppArmorProfile': u'docker-default',
u'Args': [u'redis:6379',
u'--',
u'./wait-for-it.sh',
u'postgres:5432',
u'--',
u'bundle',
u'exec',
u'rails',
u's',
This is my docker-compose.yml:
version: '3'
services:
memcached:
image: memcached:1.5.2-alpine
restart: always
ports:
- "11211:11211"
postgres:
image: postgres:9.4-alpine
restart: always
volumes:
- ~/.myapp-data/postgres:/var/lib/postgresql/data
ports:
- "5432:5432"
environment:
- POSTGRES_DB=myapp_development
- POSTGRES_USER=default
- POSTGRES_PASSWORD=secret
redis:
image: redis:3.2.0-alpine
restart: always
volumes:
- ~/.myapp-data/redis:/data
ports:
- "6379:6379"
web:
build:
context: .
dockerfile: "Dockerfile-dev"
stdin_open: true
tty: true
command: ./wait-for-it.sh redis:6379 -- ./wait-for-it.sh postgres:5432 -- bundle exec rails s -p 3000 -b '0.0.0.0'
volumes:
- .:/opt/apps/myapp
depends_on:
- memcached
- redis
- postgres
ports:
- "80:3000"
env_file:
- .env
extra_hosts:
- "api.myapp:127.0.0.1"
- "api.getmyapp:127.0.0.1"
- "my.app:127.0.0.1"
EDIT:
Here are the contents of Dockerfile-dev, required on the comments:
FROM ruby:2.3.7-slim
RUN apt-get update
RUN apt-get -y install software-properties-common libpq-dev build-essential \
python-dev python-pip wget curl git-core \
--fix-missing --no-install-recommends --allow-unauthenticated
# Set install path for reference later.
ENV INSTALL_PATH /opt/apps/engine
RUN mkdir -p $INSTALL_PATH
RUN gem install bundler
WORKDIR $INSTALL_PATH
ADD Gemfile $INSTALL_PATH
ADD Gemfile.lock $INSTALL_PATH
RUN bundle install
RUN find /tmp -type f -atime +10 -delete
ADD . $INSTALL_PATH
RUN cp config/database.docker-dev.yml config/database.yml
CMD [ "bundle", "exec", "rails", "s", "-p", "3000", "-b" "0.0.0.0" ]
Docker containers exit as soon as the commands run inside them are finished. From the logs you have posted, it seems like the container has 'nothing else' to do after starting up the server. You need to run the process in the foreground or have some sort of sleep to keep the container alive.
I'm trying to dockerize a Rails application. It uses Sphinx for search, and I can't make it run through docker.
This is what happens when I run docker-compose up and try to perform search:
web_1 | [1fd79fbf-2e77-4af5-90ad-ae3637ada807] Sphinx Query (1.9ms) SELECT * FROM `field_core` WHERE MATCH('soccer') AND `sphinx_deleted` = 0 ORDER BY `name` ASC LIMIT 0, 10000
web_1 | [1fd79fbf-2e77-4af5-90ad-ae3637ada807] Completed 500 Internal Server Error in 27ms (ActiveRecord: 3.0ms)
web_1 | [1fd79fbf-2e77-4af5-90ad-ae3637ada807]
web_1 | ThinkingSphinx::ConnectionError (Error connecting to Sphinx via the MySQL protocol. Can't connect to MySQL server on '127.0.0.1' (111)):
web_1 | app/controllers/fields_controller.rb:7:in `search'
This is result of docker-compose run sphinx rake ts:index:
sh: 1: searchd: not found
The Sphinx start command failed:
Command: searchd --pidfile --config "/app/config/development.sphinx.conf"
Status: 127
Output: See above
There may be more information about the failure in /app/log/development.searchd.log.
docker-compose.yml:
version: '3'
services:
db:
image: circleci/mysql:5.7
restart: always
volumes:
- mysql_data:/var/lib/mysql
ports:
- "3309:3309"
expose:
- '3309'
web:
build: .
command: rails server -p 3000 -b '0.0.0.0'
ports:
- "3000:3000"
expose:
- '3000'
depends_on:
- db
- sphinx
volumes:
- app:/app
sphinx:
container_name: sociaball_sphinx
image: stefobark/sphinxdocker
restart: always
links:
- db
volumes:
- /app/config/sphinxy.conf:/etc/sphinxsearch/sphinxy.conf
- /app/sphinx:/var/lib/sphinx
volumes:
mysql_data:
app:
Dockerfile:
FROM ruby:2.4.1
RUN apt-get update && apt-get install -qq -y build-essential nodejs --fix-missing --no-install-recommends
RUN curl -s \
http://sphinxsearch.com/files/sphinxsearch_2.3.2-beta-1~wheezy_amd64.deb \
-o /tmp/sphinxsearch.deb \
&& dpkg -i /tmp/sphinxsearch.deb \
&& rm /tmp/sphinxsearch.deb \&& mkdir -p /var/log/sphinxsearch
WORKDIR /app
COPY Gemfile Gemfile.lock ./
RUN gem install bundler && bundle install --jobs 20 --retry 5
COPY . ./
EXPOSE 3000
CMD ["bundle", "exec", "rails", "server", "-b", "0.0.0.0"]
thinking_sphinx.yml:
development: &common
min_infix_len: 1
charset_table: "0..9, english, U+0021..U+002F"
port: 9306
address: sociaball_mysql_1
production:
<<: *common
So, rake isn't available in sphinx container, and sphinx scripts aren't available in app's container. What am I doing wrong?
Thinking Sphinx expects a copy of the Rails app when running the rake tasks, so you'll need to have a copy of your app within your Sphinx container. This will ensure (once you've bundled the gems) that rake exists in the Sphinx container, where the Sphinx binaries are also present.
So.
Instead of running rake task, I just did what it does directly in sphinx container. Like this:
docker-compose run --rm sphinx indexer \
--config "/etc/sphinxsearch/sphinxy.conf" --all --rotate
Regarding 500 error. It was caused by incorrect configuration in thinking_sphinx.yml. It should have pointed to remote host with sphinx instead of db:
development: &common
# ...
address: sociaball_sphinx_1