From b9bb1c512e0285d047792c2fe4e5e1d20e1bee63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gw=C3=A9na=C3=ABl=20Rault?= Date: Fri, 18 Jul 2025 12:08:22 +0200 Subject: [PATCH] Reduce production image size --- .../.dockerignore | 0 .devcontainer/devcontainer.json | 6 +- .../production.rb | 16 ++-- .dockerignore | 11 --- Dockerfile | 92 +++++++++++++------ README.md | 5 + docker-compose.yml | 1 + 7 files changed, 81 insertions(+), 50 deletions(-) rename .dockerignore-development => .devcontainer/.dockerignore (100%) rename docker/production.rb.devcontainer => .devcontainer/production.rb (94%) diff --git a/.dockerignore-development b/.devcontainer/.dockerignore similarity index 100% rename from .dockerignore-development rename to .devcontainer/.dockerignore diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 8a7c09485..713593782 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -5,8 +5,8 @@ // Update the 'dockerComposeFile' list if you have more compose files or use different names. // The .devcontainer/docker-compose.yml file contains any overrides you need/want to make. "dockerComposeFile": [ - "../docker-compose.yml", - "../docker-compose-qr-shortener.yml" + "docker-compose.yml", + "docker-compose-qr-shortener.yml" ], // The 'service' property is the name of the service for the container that VS Code should // use. Update this value and .devcontainer/docker-compose.yml to the real service name. @@ -31,7 +31,7 @@ ] } }, - "initializeCommand": "cp ./.dockerignore-development ./.dockerignore && cp ./docker/production.rb.devcontainer config/environments/production.rb" + "initializeCommand": "cp .devcontainer/.dockerignore ../.dockerignore", // Uncomment the next line if you want start specific services in your Docker Compose config. // "runServices": [], // Uncomment the next line if you want to keep your containers running after VS Code shuts down. diff --git a/docker/production.rb.devcontainer b/.devcontainer/production.rb similarity index 94% rename from docker/production.rb.devcontainer rename to .devcontainer/production.rb index 9f051928d..754c307ef 100644 --- a/docker/production.rb.devcontainer +++ b/.devcontainer/production.rb @@ -1,8 +1,6 @@ Rails.application.configure do - config.webpacker.check_yarn_integrity = false # Settings specified here will take precedence over those in config/application.rb. - # Code is not reloaded between requests. - config.cache_classes = false + config.cache_classes = true # Eager load code on boot. This eager loads most of Rails and # your application in memory, allowing both threaded web servers @@ -106,6 +104,8 @@ def cache_factory(namespace, expires_in) ActiveSupport::Cache::RedisStore.new(host: ENV['REDIS_HOST'] || 'localhost', namespace: namespace, expires_in: expires_in, raise_errors: true) end + config.planner_cache = cache_factory('planner', 60*60*12*1) + config.optimizer = OptimizerWrapper.new( cache_factory('optimizer_wrapper', 60*60*24*10), ENV['OPTIMIZER_URL'] || 'http://localhost:1791/0.1', @@ -116,11 +116,12 @@ def cache_factory(namespace, expires_in) config.optimize_minimal_time = 10 config.optimize_max_split_size = 500 config.optimize_cluster_size = 0 - config.optimize_stop_soft_upper_bound = 0.0 - config.optimize_vehicle_soft_upper_bound = 0.0 + config.optimize_stop_soft_upper_bound = 0.3 + config.optimize_vehicle_soft_upper_bound = 0.3 config.optimize_overload_multiplier = 0 config.optimize_cost_waiting_time = 1 config.optimize_force_start = false + config.optimize_cost_fixed = 3.hours.to_i config.geocode_complete = false # Build time setting @@ -184,5 +185,8 @@ def cache_factory(namespace, expires_in) config.validate_during_duplication = false - config.logger_sms = nil + config.logger_sms = Logger.new(STDOUT) + + # config.action_dispatch.cookies_same_site_protection = :none + # config.session_store :cookie_store, key: '_cartoway_session', same_site: :none, secure: true end diff --git a/.dockerignore b/.dockerignore index 729cb6184..77ec3a819 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,13 +1,2 @@ docker -Dockerfile -.git -.github -.env node_modules -log/* -delayed_job_logs -public/api-web/ -public/assets/ -public/javascripts/ -public/packs/ -public/upload/ diff --git a/Dockerfile b/Dockerfile index 193d759c8..cd78574b4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,42 +1,74 @@ -FROM ruby:3.1 -ENTRYPOINT [] -CMD ["/bin/bash"] - -ARG RAILS_ENV -ARG NODE_ENV -ENV REDIS_HOST redis-cache - +# Step 1: Build (assets, gems, node_modules) +FROM ruby:3.1.7-alpine AS builder ENV NODE_OPTIONS=--openssl-legacy-provider -RUN apt update && \ - apt install -y \ - git build-essential lsb-release \ - zlib1g-dev libicu-dev g++ libgeos-dev libgeos++-dev libpq-dev \ - zlib1g libicu72 libgeos3.11.1 libpq5 libjemalloc2 \ - nodejs yarnpkg && \ - ln -s /usr/bin/yarnpkg /usr/bin/yarn - -RUN sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list' && \ -wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - && \ -apt update && \ -apt install -y postgresql-client-15 +# Install build dependencies +RUN apk add --no-cache \ + build-base \ + git \ + postgresql-dev \ + nodejs \ + yarn \ + libxml2-dev \ + libxslt-dev \ + libffi-dev \ + tzdata \ + geos-dev \ + jemalloc-dev \ + icu-dev \ + zlib-dev WORKDIR /srv/app -ADD ./package.json /srv/app/ -RUN yarn install - -ADD ./Gemfile /srv/app/ -ADD ./Gemfile.lock /srv/app/ +COPY Gemfile Gemfile.lock ./ +RUN bundle config set --local no-doc 'true' && \ + bundle install --jobs=4 --retry=3 && \ + rm -rf /usr/local/bundle/cache/*.gem /usr/local/bundle/doc -RUN bundle config git.allow_insecure true && \ - bundle install --full-index +COPY package.json yarn.lock ./ +RUN yarn install --frozen-lockfile && \ + yarn cache clean -ADD . /srv/app/ +COPY . . RUN bundle exec rake i18n:js:export && \ bundle exec rake assets:precompile API_DOC_MODE=true -# Prepare configuration files -ADD ./config/database.yml.docker config/database.yml + +# Step 2: Final image, minimal +FROM ruby:3.1.7-alpine + +RUN apk add --no-cache \ + postgresql-client \ + nodejs \ + yarn \ + tzdata \ + geos \ + jemalloc \ + icu \ + zlib \ + su-exec + +WORKDIR /srv/app + +RUN addgroup -S app && adduser -S app -G app + +COPY --from=builder /usr/local/bundle /usr/local/bundle +COPY --from=builder /srv/app/public /srv/app/public +COPY --from=builder /srv/app/app /srv/app/app +COPY --from=builder /srv/app/config /srv/app/config +COPY --from=builder /srv/app/lib /srv/app/lib +COPY --from=builder /srv/app/bin /srv/app/bin +COPY --from=builder /srv/app/db /srv/app/db +COPY --from=builder /srv/app/vendor /srv/app/vendor + +RUN rm -rf /srv/app/tmp /srv/app/spec /srv/app/test /srv/app/node_modules /srv/app/log /srv/app/coverage + +ENV RAILS_ENV=production +ENV NODE_ENV=production +ENV REDIS_HOST=redis-cache VOLUME /srv/app/public/uploads + +USER app + +CMD ["bundle", "exec", "puma", "-C", "config/puma.rb"] diff --git a/README.md b/README.md index 9365747d9..c52a2df74 100644 --- a/README.md +++ b/README.md @@ -204,6 +204,11 @@ docker compose run --rm web bundle exec rake db:structure:dump ## Dev in Docker through VSCode +Copy and update settings. +``` +cp .env.template .devcontainer/.env +``` + * Install [Visual Studio Code](https://code.visualstudio.com/download) * Install the following extensions : Docker & Dev Containers * Press F1 > Select command "Dev Containers: Open Folder in Container..." diff --git a/docker-compose.yml b/docker-compose.yml index e285b8c75..0005fbcb9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -66,3 +66,4 @@ services: volumes: pg_data: + name: planner-web_pg_data