如何优化Ruby on Rails多阶段Docker镜像体积(当前632MB)
优化Ruby on Rails Docker镜像体积的方案
以下是针对你的Dockerfile的具体优化措施,能有效降低镜像体积:
替换运行时不必要的开发依赖包
base阶段中,libpq-dev是编译PostgreSQL相关Gem所需的开发依赖,运行时只需要libpq即可。将base阶段的libpq-dev替换为libpq,减少冗余的编译类库文件。安装Gem时跳过文档生成
在bundle install命令中添加--no-document参数,避免安装Gem的文档、手册、示例等非必需内容,这能大幅缩减Gem目录的占用空间。合并RUN命令减少镜像层数
Docker每条RUN命令都会生成独立镜像层,合并用户创建、目录权限设置这类关联命令,能减少层数,间接降低镜像体积。用.dockerignore排除冗余文件
创建.dockerignore文件,排除项目中无需复制到镜像的内容,比如版本控制目录、日志、临时文件等,避免无用文件占用镜像空间。深度清理Gem目录冗余内容
在dependencies阶段,除了已有的清理步骤,额外删除Gem中的测试、示例目录,进一步压缩Gem体积。
修改后的Dockerfile
# Dockerfile for local development. # Default Ruby version for this project. ARG RUBY_VERSION=3.1.0 # Base image FROM ruby:$RUBY_VERSION-alpine AS base # Set environment variables for the username, # app directory, and the language. ENV USER app ENV APP_DIR /app # Set env variables for dev ENV BUNDLER_VERSION 2.3.3 ENV GEM_HOME=/usr/local/bundle ENV BUNDLE_PATH=$GEM_HOME ENV BUNDLE_APP_CONFIG=$BUNDLE_PATH ENV BUNDLE_JOBS 4 ENV BUNDLE_RETRY 3 ENV RAILS_ENV development ENV RACK_ENV development ENV PATH=$APP_DIR/bin:$PATH ENV LANG C.UTF-8 # 替换为运行时依赖libpq,移除开发依赖libpq-dev RUN apk add --no-cache --update \ libpq \ tzdata \ git \ && rm -rf /var/cache/apk/* # Start building a new image called "dependencies" # from the "base" image. FROM base AS dependencies # Add libraries required for installing gems. RUN apk add --no-cache --update \ build-base \ libpq-dev \ && rm -rf /var/cache/apk/* # Copy the Gemfile and Gemfile.lock # files to the current directory. COPY Gemfile Gemfile.lock ./ # Install bundler with specified version. RUN gem install bundler -v $BUNDLER_VERSION # "frozen" option means that the exact versions of gems # specified in the Gemfile.lock file will be used, # and any updates to those gems will be ignored. # # Install gems with --no-document跳过文档,同时进一步清理冗余文件 RUN bundle config --global frozen 1 && \ bundle install --no-document && \ rm -rf $BUNDLE_PATH/cache/*.gem && \ rm -rf $BUNDLE_PATH/ruby/*/cache && \ find $BUNDLE_PATH/gems/ -name "*.c" -delete && \ find $BUNDLE_PATH/gems/ -name "*.o" -delete && \ find $BUNDLE_PATH/gems/ -name "test" -o -name "spec" -o -name "examples" | xargs rm -rf # Start building a new image from the "base" image. FROM base # Copy entrypoint, make it executable. COPY entrypoint.sh /usr/bin/ RUN chmod +x /usr/bin/entrypoint.sh ENTRYPOINT ["entrypoint.sh"] # 合并用户创建和目录权限设置命令,减少镜像层数 RUN adduser -D $USER && \ mkdir -p $APP_DIR && \ chown $USER $APP_DIR # Set the working directory to the app directory. WORKDIR $APP_DIR # Switch from root to specified user. USER $USER # Copy the bundle directory from the "dependencies" # image and copy all files to the current directory, # setting the ownership to the specified user. COPY --from=dependencies $BUNDLE_PATH $BUNDLE_PATH COPY --chown=$USER . ./ # Expose port 3000 for the application. EXPOSE 3000 # Run the command to start the Rails server. CMD ["rails", "s", "-b", "0.0.0.0"]
配套的.dockerignore文件
.git/ log/ tmp/ node_modules/ .gitignore .DS_Store *.log
内容的提问来源于stack exchange,提问作者etranz
相关产品推荐
相关产品推荐

