-
Notifications
You must be signed in to change notification settings - Fork 0
/
Dockerfile
137 lines (104 loc) · 3.93 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
# syntax = docker/dockerfile:1
# Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile
# renovate: datasource=ruby-version depName=ruby
ARG RUBY_VERSION=3.3.6
FROM ruby:$RUBY_VERSION-slim as base
# Rails app lives here
WORKDIR /rails
# Set production environment
ENV BUNDLE_DEPLOYMENT="1" \
BUNDLE_PATH="/usr/local/bundle" \
BUNDLE_WITHOUT="development:test" \
RAILS_ENV="production"
# Update gems and bundler
RUN gem update --system --no-document && \
gem install -N bundler
# Throw-away build stages to reduce size of final image
FROM base as prebuild
# Install packages needed to build gems and node modules
RUN apt-get update -qq && \
apt-get install --no-install-recommends -y build-essential curl libpq-dev node-gyp pkg-config python-is-python3
FROM prebuild as node
# Install JavaScript dependencies
# renovate: datasource=node-version depName=node
ARG NODE_VERSION=22.11.0
# renovate: datasource=npm depName=yarn versioning=npm
ARG YARN_VERSION=1.22.22
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
# Install node modules
COPY --link package.json yarn.lock ./
RUN yarn install --frozen-lockfile
FROM prebuild as build
# Install application gems
COPY --link Gemfile Gemfile.lock ./
RUN bundle install && \
bundle exec bootsnap precompile --gemfile && \
rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git
# Copy node modules
COPY --from=node /rails/node_modules /rails/node_modules
COPY --from=node /usr/local/node /usr/local/node
ENV PATH=/usr/local/node/bin:$PATH
# Copy application code
COPY --link . .
# Precompile bootsnap code for faster boot times
RUN bundle exec bootsnap precompile app/ lib/
# Precompiling assets for production without requiring secret RAILS_MASTER_KEY
RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile
# Final stage for app image
FROM base
# Install packages needed for deployment
RUN apt-get update -qq && \
apt-get install --no-install-recommends -y curl nginx postgresql-client ruby-foreman && \
rm -rf /var/lib/apt/lists /var/cache/apt/archives
# configure nginx
RUN gem install foreman && \
sed -i 's|pid /run|pid /rails/tmp/pids|' /etc/nginx/nginx.conf && \
sed -i 's/access_log\s.*;/access_log \/dev\/stdout;/' /etc/nginx/nginx.conf && \
sed -i 's/error_log\s.*;/error_log \/dev\/stderr info;/' /etc/nginx/nginx.conf
COPY <<-"EOF" /etc/nginx/sites-available/default
server {
listen 3000 default_server;
listen [::]:3000 default_server;
access_log /dev/stdout;
root /rails/public;
location /cable {
proxy_pass http://localhost:8082/cable;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
}
location / {
try_files $uri @backend;
}
location @backend {
proxy_pass http://localhost:3001;
proxy_set_header Host $http_host;
}
}
EOF
# Copy built artifacts: gems, application
COPY --from=build "${BUNDLE_PATH}" "${BUNDLE_PATH}"
COPY --from=build /rails /rails
# Run and own only the runtime files as a non-root user for security
RUN groupadd --system --gid 1000 rails && \
useradd rails --uid 1000 --gid 1000 --create-home --shell /bin/bash && \
chown 1000:1000 /var/lib/nginx /var/log/nginx/* && \
chown -R 1000:1000 db log storage tmp
USER 1000:1000
# Deployment options
ENV PORT="3001"
# Entrypoint prepares the database.
ENTRYPOINT ["/rails/bin/docker-entrypoint"]
# Build a Procfile for production use
COPY <<-"EOF" /rails/Procfile.prod
nginx: /usr/sbin/nginx -g "daemon off;"
rails: ./bin/rails server -p 3001
EOF
# Start the server by default, this can be overwritten at runtime
EXPOSE 3000
CMD ["foreman", "start", "--procfile=Procfile.prod"]