It has always been easier to supply the necessary tools locally. If you need to have multiple versions, then rvm or nvm solve the problem. Then came Docker. Until this year, I had successfully managed to avoid it. On projects where the guys worked with Docker, I instead installed everything locally. But, I thought that enough fighting and it's time to try to live with the idea of "docker for everything". It's simply time to admit either i work using Docker or i don't work at all.
Well I don't have ruby installed locally. And I need to generate a new Rails application or experiment in IRB.
The first thing I did was look at the official Rails image. It turned out to be deprecated, and the authors suggested Ruby as a replacement.Using Ruby image, I was unable to generate a Rails application, so Imade my own Docker image.
FROM debian:bullseye
WORKDIR /app
ARG ruby_version=2.7.1
ARG PG_MAJOR=13
ARG NODE_MAJOR=14
# Installing general packages
RUN apt update \
&& apt upgrade -y \
&& apt install libpq-dev postgresql-client-$PG_MAJOR gnupg2 git wget curl vim build-essential libssl-dev zlib1g-dev libyaml-dev libffi-dev -y
# Installing rbenv and ruby
RUN apt install rbenv -y \
&& echo 'eval "$(rbenv init -)"' >> ~/.bashrc \
&& rbenv install $ruby_version \
&& rbenv global $ruby_version \
&& eval "$(rbenv init -)" \
&& gem install rails
#Installing node and yarn
RUN curl -sL https://deb.nodesource.com/setup_$NODE_MAJOR.x | bash - \
&& apt install nodejs \
&& npm i -g yarn
ENV PATH /root/.rbenv/versions/$ruby_version/bin/:/root/.rbenv/shims:$PATH
The following command will generate a new Rails application in the current folder and install required gems in the gems folder. As you know, a container cannot change its content after it has been built.Therefore, all application files and gems will be stored on the host machine.
docker run --rm -v /$(pwd):/app rukomoynikov/rails rails new .Launching the application is not much more difficult. But, in a simple form, it will only work if you use the sqlite database.
docker run --rm -it -p 3000:3000 -v /$(pwd):/app rukomoynikov/rails rails s -b 0.0.0.0Running IRB. Or you can enter console and run ruby files from local machine.
docker run --rm -it -p 3000:3000 -v /$(pwd):/app rukomoynikov/rails bashAbove you saw an example of basic Rails application used SQLite. In order to use Postgresql and Webpacker you need something more complicated than simple Dockerfile. You need docker-compose. There you will be able to separate application into a ruby service, and the client service.
Here is example of docker-compose.yml
services:
web:
image: rukomoynikov/rails:2.7.1
volumes:
- ./:/app
- rails_cache:/app/tmp/cache
- bundle:/usr/local/bundle
ports:
- 3000:3000
tmpfs:
- /tmp
- /app/tmp/pids
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
command: bundle exec rails server -b 0.0.0.0
client:
image: rukomoynikov/rails:2.7.1
command: yarn run build -w
ports:
- '3035:3035'
volumes:
- ./:/app:cached
- bundle:/usr/local/bundle
- node_modules:/app/node_modules
- packs:/app/public/packs
environment:
WEBPACKER_DEV_SERVER_HOST: 0.0.0.0
postgres:
image: postgres:13
volumes:
- postgres:/var/lib/postgresql/data
environment:
PSQL_HISTFILE: /root/log/.psql_history
POSTGRES_PASSWORD: postgres
ports:
- 5432
healthcheck:
test: pg_isready -U postgres -h 127.0.0.1
interval: 5s
redis:
image: redis:3.2-alpine
volumes:
- redis:/data
ports:
- 6379
healthcheck:
test: redis-cli ping
interval: 1s
timeout: 3s
retries: 30
volumes:
postgres:
redis:
bundle:
rails_cache:
node_modules:
packs: