使rails和sidekiq从不同的Docker容器一起工作(但不能使用docker-compose)

问题描述 投票:0回答:2

我正在将一个 Rails 应用程序从 Heroku 移动到 Linux 服务器并使用 Caprover 进行部署。这是一个非常依赖后台作业的应用程序,我使用 sidekiq 运行它。

我成功地通过在 Dockerfile 的 CMD 中启动的脚本运行 Rails 服务器 (

bundle exec rails server -b 0.0.0.0 -p80 &
) 和 sidekiq (
bundle exec sidekiq &
),使其正常工作。

但我想如果 Rails 服务器位于一个 Docker 容器中而 sidekiq 位于另一个容器中,情况会好得多(关注点分离)。但我不知道如何连接它们。如何告诉我的 Rails 应用 sidekiq 位于另一个容器中?

因为我使用 Caprover,所以我只能使用 Dockerfiles 来部署我的映像,所以 我无法使用 docker-compose

有没有办法告诉rails它应该使用在某个Docker容器中找到的某个sidekiq?如果有任何帮助,Caprover 使用 Docker swarm

我是否以错误的方式思考这个问题?

目前我的设置如下:

  • 1 个带有 Rails 服务器 + sidekiq 的 Docker 容器
  • 1 个带有 postgres DB 的 Docker 容器
  • 1 个带有 Redis DB 的 Docker 容器

我想要的设置是:

  • 1 个带有 Rails 服务器的 Docker 容器
  • 1 个带有 sidekiq 的 Docker 容器
  • 1 个带有 postgres DB 的 Docker 容器
  • 1 个带有 Redis DB 的 Docker 容器

以我目前的限制,这可能吗?

我的rails + sidekiq Dockerfile如下:

FROM ruby:2.6.4-alpine
#
RUN apk update && apk add nodejs yarn postgresql-client postgresql-dev tzdata build-base ffmpeg
RUN apk add --no-cache --upgrade bash
RUN mkdir /myapp
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install --deployment --without development test
COPY . /myapp
RUN yarn 
RUN bundle exec rake yarn:install
# Set production environment
ENV RAILS_ENV production
ENV RAILS_SERVE_STATIC_FILES true
# Assets, to fix missing secret key issue during building
RUN SECRET_KEY_BASE=dumb bundle exec rails assets:precompile
# Add a script to be executed every time the container starts.
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 80
COPY start_rails_and_sidekiq.sh /myapp/start_rails_and_sidekiq.sh
RUN chmod +x /myapp/start_rails_and_sidekiq.sh
# Start the main process.
WORKDIR /myapp
CMD ./start_rails_and_sidekiq.sh

start_rails_and_sidekiq.sh
看起来像这样:

#!/bin/bash

# Start the first process
bundle exec rails server -b 0.0.0.0 -p80 &
status=$?
if [ $status -ne 0 ]; then
  echo "Failed to start Rails server: $status"
  exit $status
fi

# Start the second process
bundle exec sidekiq &
status=$?
if [ $status -ne 0 ]; then
  echo "Failed to start Sidekiq: $status"
  exit $status
fi

# Naive check runs checks once a minute to see if either of the processes exited.
# This illustrates part of the heavy lifting you need to do if you want to run
# more than one service in a container. The container exits with an error
# if it detects that either of the processes has exited.
# Otherwise it loops forever, waking up every 60 seconds

while sleep 60; do
  ps aux |grep puma |grep -q -v grep
  PROCESS_1_STATUS=$?
  ps aux |grep sidekiq |grep -q -v grep
  PROCESS_2_STATUS=$?
  # If the greps above find anything, they exit with 0 status
  # If they are not both 0, then something is wrong
  if [ $PROCESS_1_STATUS -ne 0 -o $PROCESS_2_STATUS -ne 0 ]; then
    echo "One of the processes has already exited."
    exit 1
  fi
done

我彻底迷路了! 预先感谢!

ruby-on-rails docker dockerfile docker-swarm
2个回答
0
投票

方法1

根据CapRover docs,似乎可以在CapRover上运行Docker Compose,但我自己还没有尝试过。

方法2

尽管此 CapRover 示例适用于不同的 Web 应用程序,但内部访问原理是相同的:

如果您想从其他容器访问它,只需在容器名称中添加 srv-captain-- 前缀即可。

但是,这个方法不是告诉 Rails Web 应用程序在哪里找到 PostgreSQL DB 容器的吗?还是通过外部子域名访问?


0
投票

这篇文章已经有 3 年历史了,但没有答案,我在railway.app 上运行应用程序时遇到了同样的问题,其中不支持 Docker Compose。我没有创建另一个容器,而是在 foreman gem 的帮助下使用 Procfile 来启动这两个服务:

在您的 Dockerfile 中: 添加

RUN gem install foreman
最后将CMD更改为
CMD ["foreman", "start"]

在项目根目录添加Procfile:

web: bin/rails server -b 0.0.0.0 -p 80
worker: bundle exec sidekiq

这将同时启动,并且还会为您提供漂亮且有用的日志文件。

© www.soinside.com 2019 - 2024. All rights reserved.