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.0
Running 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 bash
Above 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: