Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[REQ] Is there a plan to support Alpine Linux in dockerfile-rails instead of the Debian OS? #69

Closed
papakvy72 opened this issue Dec 11, 2023 · 7 comments
Assignees

Comments

@papakvy72
Copy link

Dear dockerfile-rails Team,

Regarding the issue mentioned in the title, I am searching for a gem that supports Alpine Linux in the Dockerfile and Docker Compose for development purposes. Do you have any ideas? 😄

Regards

@rubys
Copy link
Collaborator

rubys commented Dec 11, 2023

A pull request that implemented alpine complete with tests would likely get merged.

Technically, the changes are not difficult. apt-get only shows up in two files.

But before those changes can be made, some research would need to be done. There are three places where packages are added:

  • def base_packages
    packages = []
    packages += @@packages["base"] if @@packages["base"]
    if using_execjs?
    if node_version == "lts"
    packages += %w(nodejs npm)
    else
    packages += %w(curl)
    end
    end
    if using_puppeteer?
    packages += %w(curl gnupg)
    end
    # charlock_holmes. Placed here as the library itself is
    # libicu63 in buster, libicu67 in bullseye, libiclu72 in bookworm...
    packages << "libicu-dev" if @gemfile.include? "charlock_holmes"
    if @gemfile.include? "webp-ffi"
    # https://github.com/le0pard/webp-ffi#requirements
    packages += %w(libjpeg-dev libpng-dev libtiff-dev libwebp-dev)
    end
    # Passenger
    packages << "passenger" if using_passenger?
    packages.sort.uniq
    end

  • def build_packages
    # start with the essentials
    packages = %w(build-essential)
    packages += @@packages["build"] if @@packages["build"]
    packages += %w(nodejs npm) if (node_version == "lts") && (not using_execjs?)
    # add databases: sqlite3, postgres, mysql
    packages << "pkg-config" if options.sqlite3? || @sqlite3
    packages << "libpq-dev" if options.postgresql? || @postgresql
    packages << "freetds-dev" if options.sqlserver? || @sqlserver
    if (options.mysql? || @mysql) && !using_trilogy?
    packages << "default-libmysqlclient-dev"
    end
    # add git if needed to install gems
    packages << "git" if @git
    # ActiveStorage preview support
    packages << "libvips" if @gemfile.include? "ruby-vips"
    # Rmagick gem
    packages += %w[pkg-config libmagickwand-dev] if @gemfile.include? "rmagick"
    # node support, including support for building native modules
    if using_node?
    packages += %w(node-gyp pkg-config)
    unless using_execjs? || using_puppeteer?
    packages << "curl"
    packages << "unzip" if using_bun?
    end
    # module build process depends on Python, and debian changed
    # how python is installed with the bullseye release. Below
    # is based on debian release included with the Ruby images on
    # Dockerhub.
    case RUBY_VERSION
    when /^2\.7/
    bullseye = RUBY_VERSION >= "2.7.4"
    when /^3\.0/
    bullseye = RUBY_VERSION >= "3.0.2"
    when /^2\./
    bullseye = false
    else
    bullseye = true
    end
    if bullseye
    packages << "python-is-python3"
    else
    packages << "python"
    end
    end
    packages.sort.uniq
    end

  • def deploy_packages
    packages = %w(curl) # work with the default healthcheck strategy in MRSK
    packages += @@packages["deploy"] if @@packages["deploy"]
    # start with databases: sqlite3, postgres, mysql
    packages << "postgresql-client" if options.postgresql? || @postgresql
    packages << "default-mysql-client" if options.mysql? || @mysql
    packages << "freetds-bin" if options.sqlserver? || @sqlserver
    packages << "libjemalloc2" if options.jemalloc? && !options.fullstaq?
    if options.sqlite3? || @sqlite3
    packages << "libsqlite3-0" unless packages.include? "sqlite3"
    end
    # litefs
    packages += ["ca-certificates", "fuse3", "sudo"] if options.litefs?
    # ActiveStorage preview support
    packages << "libvips" if @gemfile.include? "ruby-vips"
    # Rmagick gem
    if @gemfile.include?("rmagick") || @gemfile.include?("mini_magick")
    packages << "imagemagick"
    end
    # Puppeteer
    if using_puppeteer?
    if options.platform&.include? "amd"
    packages << "google-chrome-stable"
    else
    packages += %w(chromium chromium-sandbox)
    end
    end
    # Passenger
    packages << "libnginx-mod-http-passenger" if using_passenger?
    # nginx
    packages << "nginx" if options.nginx? || using_passenger?
    # sudo
    packages << "sudo" if options.sudo?
    if !options.procfile.blank? || (procfile.size > 1)
    packages << "ruby-foreman"
    end
    packages.sort
    end

Somebody would need to do the investigation to find out what the equivalent alpine package is for each of the packages listed there.

As an example, the Alpine equivalent of build-essential appears to be build-base.

@papakvy72
Copy link
Author

@rubys

A pull request that implements Alpine, complete with tests, would likely get merged.

Thank you very much for the information 🙏
I'll continue waiting for that pull request to be merged into the main branch.

@rubys
Copy link
Collaborator

rubys commented Dec 12, 2023

Just to clarify, I personally don't have the experience needed to identify alpine equivalents of the packages I've identified. Somebody with that experience would be the one to create a pull request. I've just outlined the what questions they would need to be prepared to answer before proceeding.

@rubys
Copy link
Collaborator

rubys commented Dec 13, 2023

I spent a few minutes looking at alpine packages, and came up with a first pass:

same:
ca-certificates
chromium
curl
freedts-dev
fuse3
git
imagemagick
libpq-dev
libwebp-dev
nginx
nodejs
npm
postgresql-client
sudo

mappings:
build-essential => build-base
chromium-sandbox => chromium-chromedriver
default-libmysqlclient-dev => mysql-client
default-mysqlclient => mysql-client
freedts-bin => freedts
libicu-dev => icu-dev
libjemalloc => jemalloc-dev
libjpeg-dev => jpeg-dev
libmagickwand-dev => imagemagick-libs
libsqlite3-0 => sqlite-dev
libtiff-dev => tiff-dev
libvips => vips-dev
node-gyp => gyp
pkg-config => pkgconfig
python => python3
python-is-python3 => python3

not found:
google-chrome-stable
passenger
ruby-foreman

Based on this, I'll take a look at adding an experimental flag for alpine in the next few days.

@rubys rubys self-assigned this Dec 13, 2023
@rubys
Copy link
Collaborator

rubys commented Dec 14, 2023

Proof of concept:

# syntax = docker/dockerfile:1

FROM ruby:alpine as base

FROM base as build

RUN apk update && \
    apk add build-base git libpq-dev

RUN gem install rails
RUN rails new demo --minimal --database postgresql

FROM base

RUN apk update && \
    apk add --no-cache tzdata libpq && \
    rm /var/cache/apk/*

COPY --from=build /usr/local/bundle /usr/local/bundle
COPY --from=build /demo /demo

COPY <<-"EOF" /demo/config/routes.rb
Rails.application.routes.draw { root "rails/welcome#index" }
EOF

WORKDIR demo
ENV RAILS_ENV=production
EXPOSE 3000
CMD bin/rails server

Notes:

  • git needs to be installed during the build phase
  • tzdata and libpq need to be installed to deploy
  • if the sqlite3 gem is included in your Gemfile, the app will fail to load

@rubys
Copy link
Collaborator

rubys commented Dec 14, 2023

There apparently is a breaking change in alpine 3.19. sqlite3 works on 3.18:

# syntax = docker/dockerfile:1

FROM ruby:3-alpine3.18 as base

FROM base as build

RUN apk update && \
    apk add build-base git sqlite-dev

RUN gem install rails
RUN rails new demo --minimal

FROM base

RUN apk update && \
    apk add --no-cache tzdata sqlite-libs && \
    rm /var/cache/apk/*

COPY --from=build /usr/local/bundle /usr/local/bundle
COPY --from=build /demo /demo

COPY <<-"EOF" /demo/config/routes.rb
Rails.application.routes.draw { root "rails/welcome#index" }
EOF

WORKDIR demo
ENV RAILS_ENV=production
EXPOSE 3000
CMD bin/rails server

@rubys
Copy link
Collaborator

rubys commented Dec 17, 2023

Released: https://github.com/fly-apps/dockerfile-rails/releases/tag/v1.6.0

update to the latest version, then run:

bin/rails generate dockerfile --alpine

@rubys rubys closed this as completed Dec 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants