I've decided to jump into the world of e-commerce engines built on Ruby on Rails. I'm gonna start by tinkering around with Solidus. Nothing too fancy, just some notes for my future self in case I need it for a client's project.
I wonder if it's possible to run Solidus on the latest Ruby on Rails version with all its features, like Hotwire, TurboStream, TurboFrame, and Stimulus. Perhaps it could lead me to a series of articles. Also, I am going to record live coding videos to practice my English.
The goal of this article - run Solidus inside docker.
Since I love to keep my projects in Docker, I usually use Nick Janitakis's template. Nick has done an amazing job. Instructions are just beyond expectations. Check it out https://github.com/nickjj/docker-rails-example.
It shouldn't be so hard to make it work. But you never know. Every time you deal with third-party engines of such complexity, things could turn out in an unpredictable way.
Installing Ruby on Rails 7 new project using Docker Compose
So, let's start with the installation of the new Rails application; just follow the instructions from Nick's template.
If you still don't have Docker on your computer, you have to install it.
Don't forget to run docker compose down -v
after you rename the project; otherwise, you'll get an error related to the database connection that kept me stuck for a while.
Installing Solidus gem
Add gem "solidus", "~> 4.1.0"
to the Gemfile and run ./run bundle:install
in a console.
Choose starter
- so all the controllers and views will be generated in your project.
Then choose Stripe
or Braintree
, or another payment system of your choice.
I've encountered a Could not find a JavaScript runtime
error in the web Docker container.
Actually, I have a Javascript runtime (Node.js) installed, but in the assets containers. For Solidus, we need it to be installed in the main container as well.
I made some changes in the Dockerfile, so it'll have the assets
containers merged into web
.
Also, I've received an error message caused by a lack of libraries required by the Braintree payment system.
I've added libxml2-dev
to the Dockerfile.
And also, I've added two more libraries for processing media files: glib-2.0
and libvips
.
So, the final version of my Dockerfile:
FROM ruby:3.2.2-slim-bullseye AS app
WORKDIR /app
ARG UID=1000
ARG GID=1000
RUN bash -c "set -o pipefail && apt-get update \
&& apt-get install -y --no-install-recommends build-essential curl git libpq-dev libxml2-dev glib-2.0 libvips \
&& curl -sSL https://deb.nodesource.com/setup_18.x | bash - \
&& curl -sSL https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
&& echo 'deb https://dl.yarnpkg.com/debian/ stable main' | tee /etc/apt/sources.list.d/yarn.list \
&& apt-get update && apt-get install -y --no-install-recommends nodejs yarn \
&& rm -rf /var/lib/apt/lists/* /usr/share/doc /usr/share/man \
&& apt-get clean \
&& groupadd -g \"${GID}\" ruby \
&& useradd --create-home --no-log-init -u \"${UID}\" -g \"${GID}\" ruby \
&& mkdir /node_modules && chown ruby:ruby -R /node_modules /app"
USER ruby
COPY --chown=ruby:ruby bin/ ./bin
RUN chmod 0755 bin/*
COPY --chown=ruby:ruby Gemfile* ./
RUN bundle install
COPY --chown=ruby:ruby package.json *yarn* ./
RUN yarn install
ARG RAILS_ENV="production"
ARG NODE_ENV="production"
ENV RAILS_ENV="${RAILS_ENV}" \
NODE_ENV="${NODE_ENV}" \
PATH="${PATH}:/home/ruby/.local/bin:/node_modules/.bin" \
USER="ruby"
COPY --chown=ruby:ruby . .
ENTRYPOINT ["/app/bin/docker-entrypoint-web"]
EXPOSE 8000
CMD ["rails", "s"]
and docker-compose.yml:
x-app: &default-app
build:
context: "."
target: "app"
args:
- "UID=${UID:-1000}"
- "GID=${GID:-1000}"
- "RAILS_ENV=${RAILS_ENV:-production}"
- "NODE_ENV=${NODE_ENV:-production}"
depends_on:
- "postgres"
- "redis"
env_file:
- ".env"
restart: "${DOCKER_RESTART_POLICY:-unless-stopped}"
stop_grace_period: "3s"
tty: true
volumes:
- "${DOCKER_WEB_VOLUME:-./public:/app/public}"
services:
postgres:
deploy:
resources:
limits:
cpus: "${DOCKER_POSTGRES_CPUS:-0}"
memory: "${DOCKER_POSTGRES_MEMORY:-0}"
environment:
POSTGRES_USER: "${POSTGRES_USER}"
POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}"
image: "postgres:15.3-bullseye"
profiles: ["postgres"]
restart: "${DOCKER_RESTART_POLICY:-unless-stopped}"
stop_grace_period: "3s"
volumes:
- "postgres:/var/lib/postgresql/data"
redis:
deploy:
resources:
limits:
cpus: "${DOCKER_REDIS_CPUS:-0}"
memory: "${DOCKER_REDIS_MEMORY:-0}"
image: "redis:7.0.11-bullseye"
profiles: ["redis"]
restart: "${DOCKER_RESTART_POLICY:-unless-stopped}"
stop_grace_period: "3s"
volumes:
- "redis:/data"
web:
<<: *default-app
deploy:
resources:
limits:
cpus: "${DOCKER_WEB_CPUS:-0}"
memory: "${DOCKER_WEB_MEMORY:-0}"
healthcheck:
test: "${DOCKER_WEB_HEALTHCHECK_TEST:-curl localhost:8000/up}"
interval: "60s"
timeout: "3s"
start_period: "5s"
retries: 3
ports:
- "${DOCKER_WEB_PORT_FORWARD:-127.0.0.1:8000}:${PORT:-8000}"
profiles: ["web"]
worker:
<<: *default-app
command: "bundle exec sidekiq -C config/sidekiq.yml"
entrypoint: []
deploy:
resources:
limits:
cpus: "${DOCKER_WORKER_CPUS:-0}"
memory: "${DOCKER_WORKER_MEMORY:-0}"
profiles: ["worker"]
cable:
<<: *default-app
command: "puma -p 28080 cable/config.ru"
entrypoint: []
deploy:
resources:
limits:
cpus: "${DOCKER_CABLE_CPUS:-0}"
memory: "${DOCKER_CABLE_MEMORY:-0}"
ports:
- "${DOCKER_CABLE_PORT_FORWARD:-127.0.0.1:28080}:28080"
profiles: ["cable"]
volumes:
postgres: {}
redis: {}
Also, we need to comment out one line in the file /bin/docker-entrypoint-web
cp -r /public /app