ruby-on-rails - docker-compose.yml 不适用于 Rails 应用程序
问题描述
我开发了一个使用 Redis、sidekiq 和 mysql2 的简单 rails 应用程序。我正在尝试使用 docker-compose 运行该应用程序。我写了一个运行良好的 docker-compose.yml。我对无法正常工作的 docker 文件进行了一些更改,当我看到日志时,webapp 容器正在以退出代码 1 退出。
这些是我的文件
Dockerfile
FROM ubuntu:16.04
ENV RUBY_MAJOR="2.6" \
RUBY_VERSION="2.6.3" \
RUBYGEMS_VERSION="3.0.8" \
BUNDLER_VERSION="1.17.3" \
RAILS_VERSION="5.2.1" \
RAILS_ENV="production" \
GEM_HOME="/usr/local/bundle"
ENV BUNDLE_PATH="$GEM_HOME" \
BUNDLE_BIN="$GEM_HOME/bin" \
BUNDLE_SILENCE_ROOT_WARNING=1 \
BUNDLE_APP_CONFIG="$GEM_HOME"
ENV PATH="$BUNDLE_BIN:$GEM_HOME/bin:$GEM_HOME/gems/bin:$PATH"
USER root
RUN apt-get update && \
apt-get -y install sudo
RUN echo "%sudo ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers && \
addgroup --gid 1024 stars && \
useradd -G stars,sudo -d /home/user --shell /bin/bash -m user
RUN mkdir -p /usr/local/etc \
&& echo 'install: --no-document' >> /usr/local/etc/gemrc \
&& echo 'update: --no-document' >> /usr/local/etc/gemrc
USER user
RUN sudo apt-get -y install --no-install-recommends vim make gcc zlib1g-dev autoconf build-essential libssl-dev libsqlite3-dev \
curl htop unzip mc openssh-server openssl bison libgdbm-dev ruby git libmysqlclient-dev tzdata mysql-client
RUN sudo rm -rf /var/lib/apt/lists/* \
&& sudo curl -fSL -o ruby.tar.gz "http://cache.ruby-lang.org/pub/ruby/$RUBY_MAJOR/ruby-$RUBY_VERSION.tar.gz" \
&& sudo mkdir -p /usr/src/ruby \
&& sudo tar -xzf ruby.tar.gz -C /usr/src/ruby --strip-components=1 \
&& sudo rm ruby.tar.gz
USER root
RUN cd /usr/src/ruby \
&& { sudo echo '#define ENABLE_PATH_CHECK 0'; echo; cat file.c; } > file.c.new && mv file.c.new file.c \
&& autoconf \
&& ./configure --disable-install-doc
USER user
RUN cd /usr/src/ruby \
&& sudo make -j"$(nproc)" \
&& sudo make install \
&& sudo gem update --system $RUBYGEMS_VERSION \
&& sudo rm -r /usr/src/ruby
RUN sudo gem install bundler --version "$BUNDLER_VERSION"
RUN sudo mkdir -p "$GEM_HOME" "$BUNDLE_BIN" \
&& sudo chmod 777 "$GEM_HOME" "$BUNDLE_BIN" \
&& sudo gem install rails --version "$RAILS_VERSION"
RUN mkdir -p ~/.ssh && \
chmod 0700 ~/.ssh && \
ssh-keyscan github.com > ~/.ssh/known_hosts
ARG ssh_pub_key
ARG ssh_prv_key
RUN echo "$ssh_pub_key" > ~/.ssh/id_rsa.pub && \
echo "$ssh_prv_key" > ~/.ssh/id_rsa && \
chmod 600 ~/.ssh/id_rsa.pub && \
chmod 600 ~/.ssh/id_rsa
USER root
RUN curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -
RUN apt-get install -y nodejs
USER user
WORKDIR /data
RUN sudo mkdir /data/checklist
WORKDIR /data/checklist
ADD Gemfile Gemfile.lock ./
RUN sudo chown -R user /data/checklist
RUN bundle install
ADD . .
RUN sudo chown -R user /data/checklist
EXPOSE 3001
ENV RAILS_SERVE_STATIC_FILES true
ENV RAILS_LOG_TO_STDOUT true
RUN chmod +x ./config/docker/compile.sh && ./config/docker/compile.sh
CMD ["bundle", "exec", "rails", "s", "-p", "3001"]
编译.sh
bundle exec rake assets:precompile
bundle exec rake db:migrate 2>/dev/null || bundle exec rake db:create db:migrate
echo "Assets Pre-compiled!"
这是我的 docker-compose.yml
version: '3'
services:
db:
image: mysql:5.7
restart: always
environment:
MYSQL_DATABASE: "list"
MYSQL_ROOT_PASSWORD: "Mission2019"
MYSQL_USERNAME: "root"
webapp:
build: .
ports:
- '3001:3001'
volumes:
- '.:/data/checklist'
depends_on:
- db
- redis
command: rails db:migrate
environment:
DB_USERNAME: "root"
DB_PASSWORD: "Mission2019"
DB_DATABASE: "list"
DB_PORT: 3306
DB_HOST: db
RAILS_ENV: production
RAILS_MAX_THREADS: 5
redis:
image: redis:4.0-alpine
command: redis-server
ports:
- '6379:6379'
sidekiq:
build: .
command: bundle exec sidekiq -C config/sidekiq.yml
depends_on:
- "db"
- "redis"
工作 Dockerfile
FROM ubuntu:16.04
ENV RUBY_MAJOR="2.6" \
RUBY_VERSION="2.6.3" \
RUBYGEMS_VERSION="3.0.8" \
BUNDLER_VERSION="1.17.3" \
RAILS_VERSION="5.2.1" \
RAILS_ENV="production" \
GEM_HOME="/usr/local/bundle"
ENV BUNDLE_PATH="$GEM_HOME" \
BUNDLE_BIN="$GEM_HOME/bin" \
BUNDLE_SILENCE_ROOT_WARNING=1 \
BUNDLE_APP_CONFIG="$GEM_HOME"
ENV PATH="$BUNDLE_BIN:$GEM_HOME/bin:$GEM_HOME/gems/bin:$PATH"
USER root
RUN apt-get update && \
apt-get -y install sudo
RUN echo "%sudo ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers && \
addgroup --gid 1024 stars && \
useradd -G stars,sudo -d /home/user --shell /bin/bash -m user
RUN mkdir -p /usr/local/etc \
&& echo 'install: --no-document' >> /usr/local/etc/gemrc \
&& echo 'update: --no-document' >> /usr/local/etc/gemrc
USER user
RUN sudo apt-get -y install --no-install-recommends vim make gcc zlib1g-dev autoconf build-essential libssl-dev libsqlite3-dev \
curl htop unzip mc openssh-server openssl bison libgdbm-dev ruby git libmysqlclient-dev tzdata mysql-client
RUN sudo rm -rf /var/lib/apt/lists/* \
&& sudo curl -fSL -o ruby.tar.gz "http://cache.ruby-lang.org/pub/ruby/$RUBY_MAJOR/ruby-$RUBY_VERSION.tar.gz" \
&& sudo mkdir -p /usr/src/ruby \
&& sudo tar -xzf ruby.tar.gz -C /usr/src/ruby --strip-components=1 \
&& sudo rm ruby.tar.gz
USER root
RUN cd /usr/src/ruby \
&& { sudo echo '#define ENABLE_PATH_CHECK 0'; echo; cat file.c; } > file.c.new && mv file.c.new file.c \
&& autoconf \
&& ./configure --disable-install-doc
USER user
RUN cd /usr/src/ruby \
&& sudo make -j"$(nproc)" \
&& sudo make install \
&& sudo gem update --system $RUBYGEMS_VERSION \
&& sudo rm -r /usr/src/ruby
RUN sudo gem install bundler --version "$BUNDLER_VERSION"
RUN sudo mkdir -p "$GEM_HOME" "$BUNDLE_BIN" \
&& sudo chmod 777 "$GEM_HOME" "$BUNDLE_BIN" \
&& sudo gem install rails --version "$RAILS_VERSION"
RUN mkdir -p ~/.ssh && \
chmod 0700 ~/.ssh && \
ssh-keyscan github.com > ~/.ssh/known_hosts
ARG ssh_pub_key
ARG ssh_prv_key
RUN echo "$ssh_pub_key" > ~/.ssh/id_rsa.pub && \
echo "$ssh_prv_key" > ~/.ssh/id_rsa && \
chmod 600 ~/.ssh/id_rsa.pub && \
chmod 600 ~/.ssh/id_rsa
USER root
RUN curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -
RUN apt-get install -y nodejs
USER user
WORKDIR /data
RUN sudo mkdir /data/checklist
WORKDIR /data/checklist
ADD Gemfile Gemfile.lock ./
RUN sudo chown -R user /data/checklist
RUN bundle install
ADD . .
RUN sudo chown -R user /data/checklist
EXPOSE 3001
ENV RAILS_SERVE_STATIC_FILES true
ENV RAILS_LOG_TO_STDOUT true
ENTRYPOINT ["sh", "./config/docker/startup.sh"]
startup.sh 用于工作的 Dockerfile
kill -9 `cat /data/checklist/tmp/pids/server.pid`
bundle exec rake assets:precompile
bundle exec rake db:migrate 2>/dev/null || bundle exec rake db:create db:migrate
rails s -p 3001 -b 0.0.0.0 -e PRODUCTION
echo "Assets Pre-compiled!"
更改 Dockerfile 的原因是,因为我使用的是 sidekiq,并且我希望 sidekiq 一起在另一个单独的容器中运行。如果我在 docker-compose.yml 中给出命令选项,它不会启动,bundle exec sidekiq -C config/sidekiq.yml
也不会在 sidekiq 容器中运行。
我有同一个应用程序的 kubernetes yaml 文件。那里也面临同样的问题。我无法为 sidekiq pod 覆盖 YAML 中的入口点指令。
如果需要任何其他信息,请告诉我。
解决方案
您也应该CMD
在第二个 Dockerfile 中使用,然后它可以被 Docker Compose 覆盖command:
。
# CMD, not ENTRYPOINT
CMD ["sh", "./config/docker/startup.sh"]
的一个常见用途ENTRYPOINT
是作为一个包装程序,它执行一些环境或其他首次设置,然后执行CMD
作为命令行参数的其余部分传入的那些。然后您可以单独替换命令部分,同时保留设置部分。在 Ruby 环境bundle exec ...
中具有正确的语义,因此您还可以考虑:
# Note: MUST be JSON-array syntax
ENTRYPOINT ["bundle", "exec"]
# Can be either string or JSON-array form
CMD ["./config/docker/startup.sh"]
version: '3.8'
services:
webapp:
build: .
# Use default CMD/ENTRYPOINT from image
sidekiq:
build: .
# Overrides CMD, leaves ENTRYPOINT in place
command: sidekiq -C config/sidekiq.yml
有一个单独的 Composeentrypoint:
覆盖,但您应该很少需要它。
(您的 Dockerfile 可以简单得多。一般情况下,您不需要配置sudo
或用户密码,并且 Dockerfiles 默认以 root 身份运行,除非您明确使用USER
切换当前用户 ID。将 ssh 凭据添加到 Dockerfile 中它们可以很简单docker cp
'd out 也不是最佳实践。还可以考虑使用 Docker Hubruby
映像而不是从源代码构建自己的映像。)
推荐阅读
- php - PHP SSH连接可以被拦截吗?
- c# - 无法转换 lambda 表达式(异步/等待)
- angular - 如何在 Angular 5 中使用图像缩放功能
- php - MPDF - 更改最后一页的背景?
- django - 无法在数字海洋上上传媒体文件 django
- r - 以 AM/PM 格式解析日期时间
- javascript - Chrome 扩展将输入附加到 URL。
- flutter - 通过 ScrollUpdateNotification 找到 Flutter Scrollable
- java - 如何使用dependsOnGroups解决TestNG中的Nullpointer异常
- python - 在 Pandas 中,.where(cond, other) 是否计算 _other_ 而不管 _cond_ 吗?