-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathDockerfile
More file actions
160 lines (130 loc) · 6.83 KB
/
Dockerfile
File metadata and controls
160 lines (130 loc) · 6.83 KB
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
# syntax=docker/dockerfile:1
# check=error=true;skip=SecretsUsedInArgOrEnv
# This Dockerfile is designed for production, not development. Use with Kamal or build'n'run by hand:
# docker build -t fallout .
# docker run -d -p 80:80 -e RAILS_MASTER_KEY=<value from config/master.key> --name fallout fallout
# For a containerized dev environment, see Dev Containers: https://guides.rubyonrails.org/getting_started_with_devcontainer.html
# Make sure RUBY_VERSION matches the Ruby version in .ruby-version
ARG RUBY_VERSION=3.4.4
FROM docker.io/library/ruby:$RUBY_VERSION-slim AS base
# Rails app lives here
WORKDIR /rails
# Install base packages — pinned to current Debian 12 (bookworm) stable versions to
# block unreviewed upgrades; update deliberately when Debian rolls a point release.
ARG CURL_VERSION=7.88.1-10+deb12u14
ARG LIBJEMALLOC2_VERSION=5.3.0-1
ARG LIBVIPS42_VERSION=8.14.1-3+deb12u2
# Enables PDF rendering through libvips (built with --enable-poppler upstream;
# the lib is dlopened at runtime so we install it explicitly). Used by
# ShipChecks::UnifiedScreenshotProcessor when the YSWS Unified upload's source
# file is a PDF (common for hackathon zines).
ARG LIBPOPPLER_GLIB8_VERSION=22.12.0-2+deb12u1
ARG SQLITE3_VERSION=3.40.1-2+deb12u2
RUN apt-get update -qq && \
apt-get install --no-install-recommends -y \
curl="${CURL_VERSION}" \
libjemalloc2="${LIBJEMALLOC2_VERSION}" \
libvips42="${LIBVIPS42_VERSION}" \
libpoppler-glib8="${LIBPOPPLER_GLIB8_VERSION}" \
sqlite3="${SQLITE3_VERSION}" \
wget && \
rm -rf /var/lib/apt/lists /var/cache/apt/archives
# Set production environment
ENV RAILS_ENV="production" \
BUNDLE_DEPLOYMENT="1" \
BUNDLE_PATH="/usr/local/bundle" \
BUNDLE_WITHOUT="development"
# Throw-away build stage to reduce size of final image
FROM base AS build
# Install packages needed to build gems and node modules
RUN apt-get update -qq && \
apt-get install --no-install-recommends -y build-essential curl git libyaml-dev pkg-config && \
rm -rf /var/lib/apt/lists /var/cache/apt/archives
# Install Node.js
ARG NODE_VERSION=22
RUN curl -fsSL https://deb.nodesource.com/setup_${NODE_VERSION}.x | bash - && \
apt-get install --no-install-recommends -y nodejs && \
rm -rf /var/lib/apt/lists /var/cache/apt/archives
# Download s6-overlay (process supervisor for running Meilisearch alongside Rails)
# TARGETARCH is set automatically by Docker buildx (amd64 or arm64).
ARG S6_VERSION=3.2.2.0
RUN ARCH=$([ "$(uname -m)" = "aarch64" ] && echo "aarch64" || echo "x86_64") && \
curl -fsSL "https://github.com/just-containers/s6-overlay/releases/download/v${S6_VERSION}/s6-overlay-noarch.tar.xz" \
-o /tmp/s6-noarch.tar.xz && \
curl -fsSL "https://github.com/just-containers/s6-overlay/releases/download/v${S6_VERSION}/s6-overlay-${ARCH}.tar.xz" \
-o /tmp/s6-arch.tar.xz
# Download Meilisearch binary
ARG MEILISEARCH_VERSION=1.42.1
RUN ARCH=$([ "$(uname -m)" = "aarch64" ] && echo "aarch64" || echo "amd64") && \
curl -fsSL "https://github.com/meilisearch/meilisearch/releases/download/v${MEILISEARCH_VERSION}/meilisearch-linux-${ARCH}" \
-o /usr/local/bin/meilisearch && \
chmod +x /usr/local/bin/meilisearch
# Install application gems
COPY Gemfile Gemfile.lock ./
RUN bundle install && \
rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git && \
bundle exec bootsnap precompile --gemfile
# Install node modules
COPY package.json package-lock.json ./
RUN npm ci
# Copy application code
COPY . .
# Precompile bootsnap code for faster boot times
RUN bundle exec bootsnap precompile app/ lib/
# Sentry release tag for source map upload + event tagging.
# Pass with: docker build --build-arg SENTRY_RELEASE=$(git rev-parse HEAD) ...
# Empty by default — vite plugin/sentry init silently fall back to no release.
ARG SENTRY_RELEASE=""
ENV SENTRY_RELEASE=${SENTRY_RELEASE}
# 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
# Re-declare and re-export so the Ruby Sentry SDK can read it at runtime
ARG SENTRY_RELEASE=""
ENV SENTRY_RELEASE=${SENTRY_RELEASE}
# Install s6-overlay into the final image (xz-utils required for -J flag on slim base)
COPY --from=build /tmp/s6-noarch.tar.xz /tmp/s6-noarch.tar.xz
COPY --from=build /tmp/s6-arch.tar.xz /tmp/s6-arch.tar.xz
RUN apt-get update -qq && \
apt-get install --no-install-recommends -y xz-utils && \
rm -rf /var/lib/apt/lists /var/cache/apt/archives && \
tar -C / -Jxpf /tmp/s6-noarch.tar.xz && \
tar -C / -Jxpf /tmp/s6-arch.tar.xz && \
rm /tmp/s6-noarch.tar.xz /tmp/s6-arch.tar.xz
# Copy Meilisearch binary
COPY --from=build /usr/local/bin/meilisearch /usr/local/bin/meilisearch
# Copy built artifacts: gems, application
COPY --from=build "${BUNDLE_PATH}" "${BUNDLE_PATH}"
COPY --from=build /rails /rails
# s6 service: Meilisearch
RUN mkdir -p /etc/s6-overlay/s6-rc.d/meilisearch && \
printf '#!/bin/sh\nexec /usr/local/bin/meilisearch --db-path /rails/storage/meilisearch --http-addr 127.0.0.1:7700 --no-analytics\n' \
> /etc/s6-overlay/s6-rc.d/meilisearch/run && \
chmod +x /etc/s6-overlay/s6-rc.d/meilisearch/run && \
echo "longrun" > /etc/s6-overlay/s6-rc.d/meilisearch/type && \
touch /etc/s6-overlay/s6-rc.d/user/contents.d/meilisearch
# s6 service: Rails (wraps the original entrypoint logic + server start)
# with-contenv loads the full container environment (DATABASE_URL, RAILS_MASTER_KEY, etc.)
# injected by Coolify at runtime — without it those vars never reach the Rails process.
RUN mkdir -p /etc/s6-overlay/s6-rc.d/rails/env && \
printf '#!/command/with-contenv /bin/sh\ncd /rails && exec /rails/bin/docker-entrypoint /rails/bin/thrust /rails/bin/rails server\n' \
> /etc/s6-overlay/s6-rc.d/rails/run && \
chmod +x /etc/s6-overlay/s6-rc.d/rails/run && \
echo "longrun" > /etc/s6-overlay/s6-rc.d/rails/type && \
mkdir -p /etc/s6-overlay/s6-rc.d/rails/dependencies.d && \
touch /etc/s6-overlay/s6-rc.d/rails/dependencies.d/meilisearch && \
touch /etc/s6-overlay/s6-rc.d/user/contents.d/rails && \
printf '/rails\n' > /etc/s6-overlay/s6-rc.d/rails/env/PWD && \
printf 'production\n' > /etc/s6-overlay/s6-rc.d/rails/env/RAILS_ENV && \
printf '/usr/local/bundle\n' > /etc/s6-overlay/s6-rc.d/rails/env/BUNDLE_PATH && \
printf '1\n' > /etc/s6-overlay/s6-rc.d/rails/env/BUNDLE_DEPLOYMENT && \
printf 'development\n' > /etc/s6-overlay/s6-rc.d/rails/env/BUNDLE_WITHOUT
# 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 -R rails:rails db log storage tmp
USER 1000:1000
# s6-overlay takes over as PID 1 and supervises both Meilisearch and Rails
ENTRYPOINT ["/init"]
EXPOSE 80