It works but it have always struck me as weird idea: why installing Ruby first? Isn't the point of Docker, at least in part, that I do not need Ruby locally?
I am not that familiar with Docker so I decided to figure this out. Vue.js included, as it's something I want to try out and there's not a lot of stuff about it out there.
I recommend to familiarize yourself with Docker and webpacker, if not already. I am not gonna talk about them a lot.
No local Ruby and Rails
As it turns out, it's not that hard.
All I needed to do is go to the official Docker's Rails example. The document shows how to create new Rails app with PostgreSQL database without need to have Rails or Ruby installed on local machine.
Adding Vue.js to the mix changes steps a bit and that's what I will be writing about.
To be able to create new app, we first need to prepare Docker container that can run
rails new fancyapp --force --database=postgresql --webpack=vue --skip-coffee command. For that we need to have Rails so feel free to initialize your git repo and create basic
source 'https://rubygems.org' ruby '2.4.1' gem 'rails', '~> 5.1', '>= 5.1.1'
Gemfile.lock is empty at this point.
Now let's install other dependencies via
FROM ruby:2.4.1 RUN apt-get update -qq && apt-get install -y build-essential libpq-dev # Node.js RUN curl -sL https://deb.nodesource.com/setup_7.x | bash - \ && apt-get install -y nodejs RUN apt-get update && apt-get install -y curl apt-transport-https wget && \ curl -sS 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 yarn RUN mkdir /fancyapp WORKDIR /fancyapp ADD Gemfile /fancyapp/Gemfile ADD Gemfile.lock /fancyapp/Gemfile.lock RUN bundle install ADD . /fancyapp
This is pretty straightforward: we install PostgreSQL lib, Node.js and yarn. Then we create directory for our fancy app and add
Gemfile.lock there. Bundle will install Rails so we can use it to create new app.
Think about your app name here, and name the folder accordingly. Rails app will get name from it.
One last thing is
docker-compose.yml. We will use
docker-compose to run Docker commands.
version: '3' services: db: image: postgres web: build: . command: bundle exec rails s -p 3000 -b '0.0.0.0' volumes: - .:/fancyapp ports: - "3000:3000" depends_on: - db
rails new fancyapp
Now that we are all ready, we need to call
docker-compose build. Rails and all deps will get installed, so we can
docker-compose run web rails new . --force --database=postgresql --webpack=vue --skip-coffee to create new app.
We do not set application name in
rails new command, as we are calling it from inside our app directory. In our case the app will be called fancyapp.
The command mentioned will generate new app with example Vue.js code that we will use later. If you're running on Linux, the newly created files might be owned by root. To be able to work with them, run this:
sudo chown -R $USER:$USER .
Then every time when you create files with
docker-compose run ..., do it again.
Do not forget to add
ruby '2.4.1' to Gemfile again. It gets removed when using
Now you can run
docker-compose build again and
docker-compose up. Your app is available at
The app running right now is ready to run Vue.js code, but our container is not. Let's change that.
To make things easier, we will add Foreman first. For dev environment, we can have
Procfile.dev, to say what we want to run when app starts.
web: bundle exec rails s -p 3000 -b '0.0.0.0' webpacker: bundle exec bin/webpack-dev-server
Fot this to work we need to update
version: '3' services: db: image: postgres web: build: . command: bundle exec foreman start -f Procfile.dev volumes: - .:/titbitoutfit ports: - "3000:3000" - "8080:8080" depends_on: - db
We now have new command to run Foreman and we added port 8080 for webpack-dev-server. You can do
docker-compose build && docker-compose run to test it out.
All that is left now is adding some Vue.js code.
The easiest way is to add simple page via Rails generator:
docker-compose run web bundle exec rails g controller home index. We will only change the Index view by adding example Vue.js code generated in the beginning via
up with your container and you should see Hello Vue! in your browser.
Congratz, you have Rails with Vue.js app!
If you run into any issue (eg. container wont start), it might be helpful to try to run commands not via
docker-compose up, but via
docker-compose run .... This way you may get better error output.
docker-compose run web bundle exec rails s -p 3000 -b '0.0.0.0' to check whether there is something wrong with Rails starting up.
I had to do that to figure out that pid file of my Rails app was not deleted when container went down.
rails new generated example Vue.js stuff for us, but that's just the start.
As I am not familiar with Vue.js, my next step is doing exactly that. Then I will need to learn more about webpacker. With that knowledge I hope to be able to fully use all the goods that this setup is giving me.