Skip to content

Commit 8dc8e16

Browse files
JulianPasqualePerezIgnaciosmerloguillermoapaxelpontetto
authored
Dockerfile setup improvements (#732)
Co-authored-by: Ignacio Perez <ignacio.perez@rootstrap.com> Co-authored-by: smerlo <s.merlo75@gmail.com> Co-authored-by: Guillermo Aguirre <guillermoaguirre1@gmail.com> Co-authored-by: Axel Pontetto Wasik <axelpontetto@hotmail.com>
1 parent 8a0a2dd commit 8dc8e16

18 files changed

+378
-87
lines changed

.dockerignore

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,46 @@
11
# See https://docs.docker.com/engine/reference/builder/#dockerignore-file for more about ignoring files.
22

3+
.git
4+
.gitignore
5+
.github
6+
37
# Ignore bundler config.
4-
/.bundle
8+
.bundle
59

610
# Ignore all default key files
711
config/master.key
812
config/credentials/*.key
913

1014
# Ignore all logfiles and tempfiles.
11-
/log/*
12-
/tmp/*
13-
!/log/.keep
14-
!/tmp/.keep
15+
log/*
16+
tmp/*
17+
!log/.keep
18+
!tmp/.keep
1519

1620
# Ignore pidfiles, but keep the directory.
17-
/tmp/pids/*
18-
!/tmp/pids/
19-
!/tmp/pids/.keep
21+
tmp/pids/*
22+
!tmp/pids/
23+
!tmp/pids/.keep
2024

2125
# Ignore storage (uploaded files in development and any SQLite databases).
22-
/storage/*
23-
!/storage/.keep
24-
/tmp/storage/*
25-
!/tmp/storage/
26-
!/tmp/storage/.keep
26+
storage/*
27+
!storage/.keep
28+
tmp/storage/*
29+
!tmp/storage/
30+
!tmp/storage/.keep
31+
32+
public/assets
2733

28-
/public/assets
34+
coverage
2935

3036
# Ignore node_modules
31-
/node_modules
37+
node_modules
3238

3339
# Ignore .env files
34-
!.env.test
3540
.env*
41+
!.env.test
42+
43+
.DS_Store
44+
.byebug_history
45+
46+
vendor/bundle

.github/workflows/ci.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ jobs:
2626
steps:
2727
- name: Checkout code
2828
uses: actions/checkout@v4
29+
- name: Setup Node
30+
uses: actions/setup-node@v4
31+
with:
32+
node-version-file: '.nvmrc'
33+
cache: 'yarn'
2934
- name: Setup Ruby
3035
uses: ruby/setup-ruby@v1
3136
with:
@@ -85,6 +90,11 @@ jobs:
8590
if [ $(git diff ${{ github.event.before }} ${{ github.event.after }} --name-only | grep 'spec/requests/api' | wc -l) -gt 0 ]; then
8691
echo "OPENAPI=true" >> $GITHUB_ENV
8792
fi
93+
- name: Setup Node
94+
uses: actions/setup-node@v4
95+
with:
96+
node-version-file: '.nvmrc'
97+
cache: 'yarn'
8898
- name: Setup Ruby
8999
uses: ruby/setup-ruby@v1
90100
with:
@@ -173,6 +183,11 @@ jobs:
173183
run: |
174184
./cc-test-reporter sum-coverage coverage/**/*.json
175185
./cc-test-reporter upload-coverage
186+
- name: Setup Node
187+
uses: actions/setup-node@v4
188+
with:
189+
node-version-file: '.nvmrc'
190+
cache: 'yarn'
176191
- name: Setup Ruby
177192
if: ${{ env.OPENAPI }}
178193
uses: ruby/setup-ruby@v1

.nvmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
20.10.0

Dockerfile

Lines changed: 71 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,88 @@
1-
FROM ruby:3.3.1
1+
ARG RUBY_VERSION=3.3.1
2+
ARG NODE_VERSION=20.10.0
3+
ARG YARN_VERSION=1.22.19
24

3-
RUN apt-get update -qq && \
4-
apt-get install -y build-essential libssl-dev libpq-dev less vim nano libsasl2-dev
5-
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
6-
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
7-
8-
RUN mkdir -p /etc/apt/keyrings
9-
RUN curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
10-
11-
ENV NODE_MAJOR=18
12-
RUN echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list
5+
# Use Node image so we can pull the binaries from here.
6+
FROM node:$NODE_VERSION as node
137

14-
RUN apt update && apt install -y yarn nodejs
8+
# Ruby build image.
9+
FROM ruby:${RUBY_VERSION}-slim as base
1510

11+
# Setup environment variables.
1612
ENV WORK_ROOT /src
17-
ENV APP_HOME $WORK_ROOT/myapp/
13+
ENV APP_HOME $WORK_ROOT/app
1814
ENV LANG C.UTF-8
19-
ENV GEM_HOME $WORK_ROOT/bundle
20-
ENV BUNDLE_BIN $GEM_HOME/gems/bin
21-
ENV PATH $GEM_HOME/bin:$BUNDLE_BIN:$PATH
15+
ENV BUNDLE_PATH $APP_HOME/vendor/bundle
16+
17+
# Set prod environment to avoid installing dev dependencies
18+
ENV BUNDLE_WITHOUT development:test
19+
ENV BUNDLE_DEPLOYMENT 1
20+
ENV RAILS_ENV production
21+
ENV NODE_ENV production
22+
23+
# Throw-away build stage to reduce size of final image
24+
FROM base as builder
2225

23-
RUN gem install bundler
26+
RUN apt-get update -qq && \
27+
apt-get install -y build-essential libssl-dev libpq-dev git libsasl2-dev && \
28+
rm -rf /var/lib/apt/lists/*
29+
30+
# Copy node binaries from node image.
31+
COPY --from=node /usr/local /usr/local
32+
COPY --from=node /opt /opt
2433

34+
# Create app directory.
2535
RUN mkdir -p $APP_HOME
2636

27-
RUN bundle config --path=$GEM_HOME
37+
# Setup work directory.
38+
WORKDIR $APP_HOME
39+
40+
# Copy dependencies files and install libraries.
41+
COPY --link Gemfile Gemfile.lock package.json yarn.lock ./
42+
43+
RUN gem install bundler && bundle install -j 4 && yarn install --frozen-lockfile && \
44+
bundle exec bootsnap precompile --gemfile && \
45+
rm -rf ~/.bundle/ $BUNDLE_PATH/ruby/*/cache $BUNDLE_PATH/ruby/*/bundler/gems/*/.git
2846

47+
# Copy application code
48+
COPY --link . .
49+
50+
# Precompile bootsnap code for faster boot times
51+
RUN bundle exec bootsnap precompile app/ lib/
52+
53+
# Precompiling assets for production without requiring secret RAILS_MASTER_KEY
54+
RUN SECRET_KEY_BASE=DUMMY ./bin/rails assets:precompile
55+
56+
# Build runtime image.
57+
FROM base
58+
59+
# Install packages needed for deployment
60+
RUN apt-get update -qq && \
61+
apt-get install --no-install-recommends -y curl libpq-dev libvips libjemalloc2 && \
62+
apt-get clean
63+
64+
# Create app directory.
65+
RUN mkdir -p $APP_HOME
66+
67+
# Setup work directory.
2968
WORKDIR $APP_HOME
3069

31-
ADD Gemfile ./
32-
ADD Gemfile.lock ./
33-
RUN bundle update --bundler
34-
RUN bundle install
70+
# Copy everything from the builder image
71+
COPY --link . .
72+
COPY --from=builder $APP_HOME/public/ $APP_HOME/public/
73+
COPY --from=builder $APP_HOME/tmp/ $APP_HOME/tmp/
74+
COPY --from=builder $APP_HOME/vendor/ $APP_HOME/vendor/
3575

36-
ADD package.json ./
37-
ADD yarn.lock ./
76+
RUN ln -s /usr/lib/*-linux-gnu/libjemalloc.so.2 /usr/lib/libjemalloc.so.2
3877

39-
RUN yarn install
78+
# Deployment options
79+
ENV RAILS_LOG_TO_STDOUT true
80+
ENV RAILS_SERVE_STATIC_FILES true
81+
ENV LD_PRELOAD=/usr/lib/libjemalloc.so.2
4082

41-
ADD . $APP_HOME
83+
# Entrypoint prepares the database.
84+
ENTRYPOINT ["./bin/docker-entrypoint"]
4285

86+
# Start the server by default, this can be overwritten at runtime
4387
EXPOSE 3000
44-
45-
ENTRYPOINT bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -b 0.0.0.0 -p 3000"
88+
CMD ["./bin/rails", "server"]

Dockerfile.dev

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
ARG RUBY_VERSION=3.3.1
2+
ARG NODE_VERSION=20.10.0
3+
ARG YARN_VERSION=1.22.19
4+
5+
# Use Node image so we can pull the binaries from here.
6+
FROM node:$NODE_VERSION as node
7+
8+
# Ruby build image.
9+
FROM ruby:${RUBY_VERSION}-slim
10+
11+
RUN apt-get update -qq && \
12+
apt-get install -y build-essential libssl-dev libpq-dev vim git libsasl2-dev && \
13+
rm -rf /var/lib/apt/lists/*
14+
15+
# Copy node binaries from node image.
16+
COPY --from=node /usr/local /usr/local
17+
COPY --from=node /opt /opt
18+
19+
# Setup environment variables.
20+
ENV WORK_ROOT /src
21+
ENV APP_HOME $WORK_ROOT/app/
22+
ENV LANG C.UTF-8
23+
ENV BUNDLE_PATH $WORK_ROOT/bundle
24+
25+
# Create app directory.
26+
RUN mkdir -p $APP_HOME
27+
28+
# Setup work directory.
29+
WORKDIR $APP_HOME
30+
31+
RUN gem install foreman bundler
32+
33+
# Copy dependencies files and install libraries.
34+
COPY --link package.json yarn.lock ./
35+
RUN yarn install --frozen-lockfile
36+
37+
COPY --link Gemfile Gemfile.lock ./
38+
RUN bundle install -j 4
39+
40+
COPY --link . .
41+
42+
# Entrypoint prepares the database.
43+
ENTRYPOINT ["./bin/docker-entrypoint"]
44+
45+
# Start the server by default, this can be overwritten at runtime
46+
EXPOSE 3000
47+
CMD ["./bin/dev"]

Gemfile.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -669,7 +669,7 @@ DEPENDENCIES
669669
yaaf (~> 2.2)
670670

671671
RUBY VERSION
672-
ruby 3.3.1p55
672+
ruby 3.3.1p55
673673

674674
BUNDLED WITH
675-
2.5.10
675+
2.5.10

Procfile.dev

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
web: bin/rails server -p3000
1+
web: ./bin/rails server -p 3000 -b 0.0.0.0
22
js: yarn build --watch

bin/docker-entrypoint

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#!/bin/bash -e
2+
3+
# If running the rails server then create or migrate existing database
4+
if ([ "${1}" == "./bin/rails" ] && [ "${2}" == "server" ]) || [ "${1}" == "./bin/dev" ]; then
5+
./bin/rails db:prepare
6+
fi
7+
8+
if [ "${1}" == "./bin/rspec" ]; then
9+
./bin/rails db:test:prepare
10+
fi
11+
12+
exec "${@}"

bin/helpers.rb

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,9 @@
77
end
88

99
def running_with_docker?
10-
ENV['DOCKER_ENABLED'] == 'true' && docker_compose_installed? && web_service_running?
10+
ENV['DOCKER_ENABLED'] == 'true' && docker_compose_installed?
1111
end
1212

1313
def docker_compose_installed?
1414
system('which docker-compose > /dev/null 2>&1')
1515
end
16-
17-
def web_service_running?
18-
docker_compose_installed? && !web_service.empty?
19-
end
20-
21-
def web_service
22-
abort("\n** ABORTED: docker-compose not installed **") unless docker_compose_installed?
23-
out, = Open3.capture2("docker-compose ps --services --filter 'status=running' | grep web")
24-
out.strip
25-
end

bin/rails

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ require 'shellwords'
44
require_relative 'helpers'
55

66
if running_with_docker?
7-
exec "bin/web 'bin/rails #{Shellwords.join(ARGV)}'"
7+
exec "bin/web './bin/rails #{Shellwords.join(ARGV)}'"
88
else
99
APP_PATH = File.expand_path('../config/application', __dir__)
1010
require_relative '../config/boot'

0 commit comments

Comments
 (0)