Rails6 on Google Cloud Run
Tags: googlecloud, rails, webdev, terraform
Published: 2020-07-14 13:50:16


## What makes me look into it?
 - It works if it is containerized, no version requirements 
 - It is serverless, pay as you use, it is good for experimental projects.
 - Gcloud offers autoscaling (fully managed).
 - Gcloud console. I like how google implements web cloud console. 

## Source Code
The source code I tried in this article is here.
https://github.com/sumiki/cloud_run_rails

## Install Rails

```
rbenv install 2.7.1
gem install rails 
rails new cloud_run_rails -o
```
###### I tried rails without a database this time just to see how cloud run works.

Update rails to Edge (There is no requirement to ruby versions, so try edge)

```
# Gemfile
gem 'rails', github: 'rails/rails'
```

Then

```
bundle install
```

## Add JS 

There are no life without javascript so add some code and locally run precompile 

```
RAILS_ENV=production bundle exec assets:precompile 
```


## Dockerlize

```
# Gemfile
FROM ruby:2.7
WORKDIR /app
COPY Gemfile Gemfile.lock ./
ENV RAILS_ENV production
RUN bundle install
COPY . .
EXPOSE 3000
ENV RAILS_SERVE_STATIC_FILES true
CMD ["bin/rails", "server", "-b", "0.0.0.0"]
```
Build docker container
```
docker build -t cloud_run_rails:0.0.1 .
```

Run it locally
```
docker run -d -it -p  3000:3000  cloud_run_rails:0.0.10
```

## Deploy to Cloud Run

Push container to cloud repository 

```
GOOGLE_CLOUD_PROJECT=<your project name>

docker tag cloud_run_rails:0.0.1 us.gcr.io/${GOOGLE_CLOUD_PROJECT}/cloud_run_rails:0.0.1

docker push us.gcr.io/${GOOGLE_CLOUD_PROJECT}/cloud_run_rails:0.0.1
```

```
gcloud run deploy --image=us.gcr.io/${GOOGLE_CLOUD_PROJECT}/cloud_run_rails:0.0.1 --platform managed --concurrency 1
```

It is running
![Running Rails on Cloud Run](https://dev-to-uploads.s3.amazonaws.com/i/61ouavs64343fff2hs9w.png)


## A problem I saw

There is one thing I got stuck and could not figure out for a day.
I was able to run rails app development mode on cloud run but not production mode.

In the cloud run document there is a command to dockerize the app.

```
gcloud builds submit --tag us.gcr.io/${GOOGLE_CLOUD_PROJECT}/cloud_run_rails:0.0.1
```
https://cloud.google.com/sdk/gcloud/reference/builds/submit

This makes rails in production mode not work on cloud run.
This command is supposed to build a Docker container and push it to the repository.
But it looks like it happened remotely on gcloud. It transfers the source code using git and that’s end up miscopying config/master.key and compiled assets.
We can build container locally and use .dockerignore to prevent copying files not needed on the container.
 
## Terraform

We are also able to manage the cloud resources using terraform.

```
terraform apply -var-file=prod.tfvars
```


```
# tf/main.tf
provider "google" {
 version = "3.5.0"

 credentials = file(var.credentials_path)

 project = var.project_name
}

resource "google_cloud_run_service" "default" {
 name     = var.cloud_run_name
 location = "us-west1"

 template {
   spec {
     containers {
       image = var.docker_image_path
     }
   }
 }

 traffic {
   percent         = 100
   latest_revision = true
 }
}

data "google_iam_policy" "noauth" {
 binding {
   role = "roles/run.invoker"
   members = [
     "allUsers",
   ]
 }
}

resource "google_cloud_run_service_iam_policy" "noauth" {
 location    = google_cloud_run_service.default.location
 project     = google_cloud_run_service.default.project
 service     = google_cloud_run_service.default.name

 policy_data = data.google_iam_policy.noauth.policy_data
}

```