Docker托管Rails应用找不到Gemfile,容器创建后秒退求助
Docker容器启动后因Gemfile未找到退出的问题解决
问题描述
GitLab流水线运行成功,但Docker容器创建后几秒就退出。在托管服务器上执行docker container logs eops_staging,输出Gemfile未找到的错误:
$ docker container logs eops_staging /usr/local/bundle/gems/bundler-1.10.6/lib/bundler/definition.rb:23:in `build': /usr/src/app/Gemfile not found (Bundler::GemfileNotFound) from /usr/local/bundle/gems/bundler-1.10.6/lib/bundler.rb:155:in `definition' from /usr/local/bundle/gems/bundler-1.10.6/lib/bundler.rb:123:in `setup' from /usr/local/bundle/gems/bundler-1.10.6/lib/bundler/setup.rb:18:in `<top (required)>' from /usr/local/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_require.rb:128:in `require' from /usr/local/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_require.rb:128:in `rescue in require' from /usr/local/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_require.rb:39:in `require' from /usr/local/bundle/bin/rails:14:in `<main>'
本地开发机使用以下命令可正常启动容器:
$ docker --context dockerapps compose -f docker-compose.staging.yml up -d
解决后的关键文件
Dockerfile.staging
FROM ruby:2.1.6 RUN apt-get update -y && apt-get --force-yes install -y --no-install-recommends \ build-essential \ curl \ git \ libaio-dev # 解决bundle install时git clone超时问题 RUN git config --global url."https://".insteadOf git:// # 复制Oracle依赖文件 ADD vendor/oracle /usr/lib/oracle/ ENV LD_LIBRARY_PATH='/usr/lib/oracle/instantclient_21_8' # 设置Oracle字符集环境变量,避免警告 ENV NLS_LANG='AMERICAN_AMERICA.WE8ISO8859P15' RUN echo "The ENV variable value is $NLS_LANG" ARG APP_HOME=/usr/src/app # 创建应用目录并设置为工作目录 RUN mkdir -p /usr/src/app WORKDIR /usr/src/app # 先复制Gemfile相关文件,利用Docker缓存优化构建速度 COPY Gemfile* /usr/src/app/ # 指定bundler的gem安装目录 ENV BUNDLE_PATH /gems # 安装指定版本的bundler并执行bundle install ENV BUNDLER_VERSION='1.9.6' RUN gem install bundler --no-document -v '1.9.6' RUN bundle install # 复制整个应用代码到容器 ADD . /usr/src/app # 调试用:查看当前目录文件 RUN ls -la . # 设置容器启动命令 CMD ["rails", "s", "-b", "0.0.0.0"]
docker-compose.staging.yml
version: '3' services: app: # 指定构建上下文和Dockerfile build: context: . dockerfile: Dockerfile.staging image: eops_app:staging container_name: eops_staging # todo restart: always environment: RAILS_ENV: staging PIDFILE: /tmp/pids/server.pid tmpfs: # 临时挂载/tmp/pids目录,容器停止后自动清理 - /tmp/pids/ env_file: - .env/app ports: - "3001:3000"
gitlab-ci.yml
stages: - publish - deploy publish-to-staging: image: docker:latest stage: publish rules: - if: $CI_COMMIT_BRANCH == 'docker_dev' services: - docker:dind script: - docker image build -f Dockerfile.staging -t registry.example.com/cals-it-acs/hr-eops/docker_app/eops_app:staging . - echo $CI_REGISTRY_PASSW | docker login -u $CI_REGISTRY_USER registry.example.com --password-stdin - docker push registry.example.com/cals-it-acs/hr-eops/docker_app/eops_app:staging deploy-to-staging: stage: deploy rules: - if: $CI_COMMIT_BRANCH == 'docker_dev' script: # 修复SSH私钥权限 - chmod og= $ID_ECDSA # 在托管服务器登录镜像仓库并拉取最新镜像 - ssh -i $ID_ECDSA -o StrictHostKeyChecking=no deploy@dock.cals.wisc.edu "docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSW registry.example.com" - ssh -i $ID_ECDSA -o StrictHostKeyChecking=no deploy@dock.cals.wisc.edu "docker pull registry.example.com/cals-it-acs/hr-eops/docker_app/eops_app:staging" # 删除旧容器(如果存在) - ssh -i $ID_ECDSA -o StrictHostKeyChecking=no deploy@dock.cals.wisc.edu "docker container rm -f eops_staging || true" # 调试命令:查看运行中的容器和网络 - ssh -i $ID_ECDSA -o StrictHostKeyChecking=no deploy@dock.cals.wisc.edu "docker ps" - ssh -i $ID_ECDSA -o StrictHostKeyChecking=no deploy@dock.cals.wisc.edu "docker network list" # 复制环境变量文件 - cp $EOPS_ENV .env/app # 启动容器 - docker --context dockerapps compose -f docker-compose.staging.yml up -d deploy-to-production: stage: deploy when: manual rules: - if: $CI_COMMIT_BRANCH == 'docker_main' script: - echo "deploying to production . . ."
关键修复说明
Dockerfile路径与顺序优化:
- 明确设置
WORKDIR /usr/src/app,确保后续所有文件操作都基于正确的应用目录 - 先复制
Gemfile*到容器,再执行bundle install,保证bundler能找到Gemfile文件,同时利用Docker缓存减少重复构建时间 - 最后复制整个应用代码,确保Gemfile和应用文件都存在于容器的指定路径中
- 明确设置
CI/CD部署流程修正:
- 确保在部署阶段先拉取GitCI构建好的镜像,避免在托管服务器上重新构建(若服务器本地无代码会导致构建失败)
- 修复SSH私钥权限,保证能正常连接托管服务器
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

