When I do kamal deploy
my image keeps being re-created from scratch (e.g. it's compiling ruby each time).
Here is my Dockerfile:
FROM debian:bullseye-slim as base
ENV BUNDLER_VERSION="2.5.5" \
BUNDLE_DEPLOYMENT="1" \
BUNDLE_PATH="/usr/local/bundle" \
BUNDLE_WITHOUT="development" \
NODE_VERSION="20.11.0" \
NPM_VERSION="10.4.0" \
RAILS_ENV="production" \
RUBY_INSTALL_VERSION="0.9.3" \
RUBY_VERSION="3.3.0" \
YARN_VERSION="1.22.19"
ENV PATH="/opt/rubies/ruby-${RUBY_VERSION}/bin:/usr/local/node/bin:${PATH}"
RUN apt-get update && \
apt-get install -y \
autoconf \
build-essential \
curl \
fish \
git \
libpq-dev \
libvips \
pandoc \
pkg-config \
postgresql-client \
vim \
wget
RUN wget "https://github.com/postmodern/ruby-install/releases/download/v${RUBY_INSTALL_VERSION}/ruby-install-${RUBY_INSTALL_VERSION}.tar.gz" \
&& tar -xzvf "ruby-install-${RUBY_INSTALL_VERSION}.tar.gz" \
&& cd "ruby-install-${RUBY_INSTALL_VERSION}" \
&& make install
RUN ruby-install -p https://github.com/ruby/ruby/pull/9371.diff ruby "${RUBY_VERSION}"
WORKDIR /rails
FROM base as build
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
COPY Gemfile Gemfile.lock ./
RUN gem install bundler -v "${BUNDLER_VERSION}"
RUN bundle install && \
rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git && \
bundle exec bootsnap precompile --gemfile
COPY package.json yarn.lock ./
RUN yarn install --frozen-lockfile
COPY . .
RUN bundle exec bootsnap precompile app/ lib/
RUN HOST=example.com \
BASE_URL=https://example.com \
RAILS_MASTER_KEY_DUMMY=1 \
SECRET_KEY_BASE_DUMMY=1 \
./bin/rails assets:precompile
FROM base
COPY --from=build /usr/local/bundle /usr/local/bundle
COPY --from=build /rails /rails
RUN useradd rails --create-home --shell /bin/bash && \
chown -R rails:rails db log storage tmp
USER rails:rails
ENTRYPOINT ["/rails/bin/docker-entrypoint"]
EXPOSE 3000
CMD ["./bin/rails", "server"]
And my config/deploy.yml
:
service: code
image: dorianmariefr/code
servers:
web:
hosts:
- 165.232.149.13
labels:
traefik.http.routers.code.rule: Host(`code.dorianmarie.com`)
traefik.http.routers.code_secure.entrypoints: websecure
traefik.http.routers.code_secure.rule: Host(`code.dorianmarie.com`)
traefik.http.routers.code_secure.tls.certresolver: letsencrypt
traefik.http.routers.code_secure.tls: true
registry:
username: dorianmariefr
password:
- KAMAL_REGISTRY_PASSWORD
env:
clear:
HOST: code.dorianmarie.com
BASE_URL: https://code.dorianmarie.com
secret:
- RAILS_MASTER_KEY
- POSTGRES_PASSWORD
traefik:
options:
publish:
- "443:443"
volume:
- "/letsencrypt/acme.json:/letsencrypt/acme.json"
args:
entryPoints.web.address: ":80"
entryPoints.websecure.address: ":443"
entryPoints.web.http.redirections.entryPoint.to: websecure
entryPoints.web.http.redirections.entryPoint.scheme: https
entryPoints.web.http.redirections.entrypoint.permanent: true
certificatesResolvers.letsencrypt.acme.email: "[email protected]"
certificatesResolvers.letsencrypt.acme.storage: "/letsencrypt/acme.json"
certificatesResolvers.letsencrypt.acme.httpchallenge: true
certificatesResolvers.letsencrypt.acme.httpchallenge.entrypoint: web
accessories:
db:
image: postgres:16.1
host: 165.232.149.13
port: 5432
env:
clear:
POSTGRES_USER: code
POSTGRES_DB: code_production
secret:
- POSTGRES_PASSWORD
directories:
- data:/var/lib/postgresql/data
Logs: https://gist.github.com/dorianmariecom/e51aba0648efcfcef66b88cd01fda24b
The solution was the build remotely on the server and from GitHub Actions:
config/deploy.yml
.github/workflows/deploy.yml