Creating new Rails and Vue.js app with Docker
Posted under ruby rails docker vuejs onThe most of Rails and Docker tutorials either show how to dockerize your existing app, or how to create new Rails app by installing Rails locally and then adding Docker as second step.
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.
The result should be basic example of Vue.js and Rails app running inside Docker container. And for that, I'd like to use webpacker gem. One more thing: no CoffeeScript (which is default for Rails).
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.
Docker container
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 Gemfile
.
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 Dockerfile
.
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
and 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 --force
.
Now you can run docker-compose build
again and docker-compose up
. Your app is available at localhost:3000
.
Adding Vue.js
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 new service in our docker-compose
running webpacker in development enviroment.
version: '3'
services:
db:
image: postgres
webpacker:
build: .
command: bundle exec bin/webpack-dev-server
volumes:
- .:/fancyapp
ports:
- "8080:8080"
web:
build: .
command: bundle exec rails s -p 3000 -b '0.0.0.0'
volumes:
- .:/fancyapp
ports:
- "3000:3000"
depends_on:
- db
- webpacker
You might need to run docker-compose run web yarn install
to get node packages installed. That's one part I haven't figured out yet.
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 javascript_pack_tag
that will execute code in app/javascript/packs/hello_vue.js
.
<h1><%= javascript_pack_tag 'hello_vue' %></h1>
Go up
with your container and you should see Hello Vue! in your browser.
Congratz, you have Rails with Vue.js app!
Debugging
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.
One might 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.
Next steps
The 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.
Did you enjoy this? Copy-paste the link from the address bar to your favourite social network to share. Subscribe here.
comments powered by Disqus