简体   繁体   中英

docker-compose.yml not working for rails app

I have developed a simple rails app that uses Redis, sidekiq, and mysql2. I'm trying to run the app using docker-compose. I wrote a docker-compose.yml which is working fine. I've made a few changes to the docker file which isn't working and when I see the logs the webapp container is exiting with exit code 1.

These are my files

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"]

compile.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!"

This is my 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"

Working 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 for the working 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!"

The reason for changing the Dockerfile from the one which works is, since I'm using sidekiq and I want sidekiq to run in another separate container all together. If I give command option in the docker-compose.yml it's not picking up and bundle exec sidekiq -C config/sidekiq.yml is not running in the sidekiq container.

I've kubernetes yaml files for the same app. Facing same problem there as well. I'm not able to overwrite the entrypoint instruction from the YAML for sidekiq pod.

Please let me know if any other info is needed.

You should use CMD in the second Dockerfile too, and then it can be overridden by the Docker Compose command: .

# CMD, not ENTRYPOINT
CMD ["sh", "./config/docker/startup.sh"]

One common use for ENTRYPOINT is to be a wrapper program that does some environment or other first-time setup, then executes the CMD that's passed in as the remainder of the command-line arguments. Then you can separately replace the command part, while keeping the setup part. In a Ruby environment bundle exec ... has the right semantics, so you can also consider:

# 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

There is a separate Compose entrypoint: override, but you should rarely need it.

(Your Dockerfile can be much much simpler. In general you do not need to configure sudo or user passwords, and Dockerfiles run as root by default unless you explicitly use USER to switch the current user IDs. Adding ssh credentials into a Dockerfile where they can be trivially docker cp 'd out is also not a best practice. Also consider using the Docker Hub ruby image over building your own from source.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM