-
Notifications
You must be signed in to change notification settings - Fork 3
/
Dockerfile
190 lines (138 loc) · 5.91 KB
/
Dockerfile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# syntax = docker/dockerfile:1
# Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile
ARG RUBY_VERSION=3.2.2
FROM registry.docker.com/library/ruby:$RUBY_VERSION-slim as base
# Rails app lives here
WORKDIR /arquivo
# Set production environment
ENV RAILS_ENV="production" \
BUNDLE_WITHOUT="development" \
BUNDLE_DEPLOYMENT="1"
ENV ARQUIVO_STORAGE_PATH=/data/storage
RUN mkdir -p /data/storage
# Update gems and bundler
RUN gem update --system --no-document && \
gem install -N bundler
# Install packages needed for deployment
RUN --mount=type=cache,id=dev-apt-cache,sharing=locked,target=/var/cache/apt \
--mount=type=cache,id=dev-apt-lib,sharing=locked,target=/var/lib/apt \
apt-get update -qq && \
apt-get install --no-install-recommends -y curl git openssh-client libsqlite3-0 wget
RUN useradd rails --create-home --shell /bin/bash
USER rails:rails
RUN mkdir -p /home/rails/.ssh/ && \
chmod 0700 /home/rails/.ssh && \
ssh-keyscan github.com > /home/rails/.ssh/known_hosts
USER root
# Throw-away build stages to reduce size of final image
FROM base as prebuild
# Install packages needed to build gems and node modules
RUN --mount=type=cache,id=dev-apt-cache,sharing=locked,target=/var/cache/apt \
--mount=type=cache,id=dev-apt-lib,sharing=locked,target=/var/lib/apt \
apt-get update -qq && \
apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3
FROM prebuild as install-node
# FROM prebuild as node
# Install JavaScript dependencies
ARG NODE_VERSION=18.16.0
ARG YARN_VERSION=1.22.4
ENV PATH=/usr/local/node/bin:$PATH
RUN curl -sL https://github.com/nodenv/node-build/archive/master.tar.gz | tar xz -C /tmp/ && \
/tmp/node-build-master/bin/node-build "${NODE_VERSION}" /usr/local/node && \
npm install -g yarn@$YARN_VERSION && \
rm -rf /tmp/node-build-master
FROM install-node as install-node-modules
# Copy application code
## Contrary to the template, here we copy the app code *before* fetching the gems
## and running yarn install because our repo vendors these dependencies; if we copy
## the app code *after* installing deps we'll then overwrite these folders.
COPY package.json yarn.lock .
COPY node_modules ./node_modules
# Install node modules
RUN --mount=type=cache,id=bld-yarn-cache,target=/root/.yarn \
YARN_CACHE_FOLDER=/root/.yarn yarn install --frozen-lockfile
FROM install-node-modules as install-gems
## Stage commented out to handle the need for npm when precompiling assets
# FROM prebuild as build
# Install application gems
## Contrary to the template, we avoid setting up the run mount cached directory,
## because we already have a `vendor` folder we copied above, when we copied over
## our application code.
COPY Gemfile Gemfile.lock .
COPY vendor ./vendor
RUN bundle config set app_config .bundle && \
bundle config set path vendor && \
bundle install --local && \
bundle clean
# Copy node modules
## if we're in one big build section, we don't need this line:
## I suspect the idea is that in the 7.1 world you aren't using npm to build stuff
## so you can just copy the node modules from the node build stage?
# COPY --from=node /rails/node_modules /rails/node_modules
FROM install-gems as build
COPY --link . .
# In install-gems my expectation is that it only has the vendor & node_modules folders
# typing this out maybe i should mount the folder as cache.
COPY --from=install-gems /arquivo .
# Precompile bootsnap code for faster boot times
RUN bundle exec bootsnap precompile --gemfile
RUN bundle exec bootsnap precompile app/ lib/
# Adjust binfiles to be executable on Linux
RUN chmod +x bin/*
# Precompiling assets for production without requiring secret RAILS_MASTER_KEY
# NODE_OPTIONS is a workaround for https://stackoverflow.com/questions/69394632/webpack-build-failing-with-err-ossl-evp-unsupported/69476335#69476335
ENV NODE_OPTIONS="--openssl-legacy-provider"
RUN SECRET_KEY_BASE=DUMMY ./bin/rails assets:precompile
# ---- END STAGES -----
# BEGIN development stage {
FROM build as development
RUN chown -R rails:rails db log storage tmp public /data
# in development, we don't want half the files to be owned by root, so we copy-chown it:
COPY --from=build --chown=rails:rails /arquivo /arquivo
USER rails:rails
# in development, we want every gem
ENV BUNDLE_WITHOUT=
ENV BUNDLE_DEPLOYMENT=
## install packages needed for development
RUN bundle install --local
# temporary hack to handle git config options during test run
RUN git config --global user.email "you@example.com" && \
git config --global user.name "Your Name"
RUN SECRET_KEY_BASE=DUMMY ./bin/rails assets:precompile RAILS_ENV=test
# Deployment options
ENV DATABASE_URL="sqlite3:///data/database.sqlite3" \
RAILS_LOG_TO_STDOUT="1" \
RAILS_SERVE_STATIC_FILES="true"
# Entrypoint prepares the database.
ENTRYPOINT ["/arquivo/bin/docker-entrypoint"]
# Start the server by default, this can be overwritten at runtime
EXPOSE 3000
VOLUME /data
CMD ["./bin/rails", "server"]
# } END development stage
# { BEGIN test stage
FROM development as test
CMD ["./bin/rails", "test"]
# } END test stage
# ---------------
# Final stage for app image
FROM base as final
# Copy built artifacts: gems, application
COPY --from=build /usr/local/bundle /usr/local/bundle
COPY --from=build /arquivo /arquivo
# Run and own only the runtime files as a non-root user for security
RUN chown -R rails:rails db log storage tmp public /data
USER rails:rails
# Deployment options
ENV DATABASE_URL="sqlite3:///data/production.sqlite3" \
RAILS_LOG_TO_STDOUT="1" \
RAILS_SERVE_STATIC_FILES="true"
# temporary hack to handle git config options during test run
RUN git config --global user.email "you@example.com" && \
git config --global user.name "Your Name"
# Entrypoint prepares the database.
ENTRYPOINT ["/arquivo/bin/docker-entrypoint"]
# Start the server by default, this can be overwritten at runtime
EXPOSE 3000
VOLUME /data
CMD ["./bin/rails", "server"]