Skip to content

Instantly share code, notes, and snippets.

@itsprdp
Last active September 9, 2016 04:22
Show Gist options
  • Save itsprdp/1b6daf4ddacef3c0b016 to your computer and use it in GitHub Desktop.
Save itsprdp/1b6daf4ddacef3c0b016 to your computer and use it in GitHub Desktop.
Kuber files for Rails App + Google Container Engine
#!/bin/bash
# Crontab and Forward logs to Docker logs
APP_DIR=/rubyapp
# Fix rubygems path
export PATH=$PATH:/var/lib/gems/2.2.0/bin
# Project directory
cd $APP_DIR
# Set RAILS_ENV
if [[ -n "$1" ]]; then
RAILS_ENV=$1
else
echo "Error: Argument Missing! Pass RAILS_ENV value as argument to the script."
exit
fi
# Create .env file from mounted secrets
/usr/bin/ruby $APP_DIR/config/env.rb $APP_DIR/.env /etc/env
# Add env's to crontab
(echo "PATH=$PATH";echo "NEWRELIC_AGENT_ENABLED=false") | crontab
# Create log dirs
mkdir $APP_DIR/log && touch $APP_DIR/log/cron.log
# Update the crontab
RAILS_ENV=$RAILS_ENV bundle exec whenever --update-crontab
# Run cron in the foreground
cron -f &
# Forwards the cron.log to the Docker logs.
set -e
if [[ -e $APP_DIR/log/cron.log ]]; then
exec tail -F $APP_DIR/log/cron.log
else
exec sleep 10
fi
#!/usr/bin/env ruby
# Populate the .env file by reading the kubernetes secrets
# mounted as files under /path/to/env/mount
#
# ARGV[0]=<env-file-path>
# ARGV[1]=<env-mount-path>
env = {}
Dir["#{ARGV[1]}/*"].each do |file|
key = file.split("/").last
key = key.gsub("-", "_").upcase
env[key] = File.read(file).strip
end
File.open(ARGV[0], "w") do |file|
env.each do |key, value|
file.puts(%{export #{key}="#{value}"})
end
end
worker_processes 2;
pid /run/nginx.pid;
daemon off;
# Logging to STDOUT
error_log /dev/stdout info;
# Manually setting the path
env PATH=PATH_ENV;
events {
worker_connections 1024;
}
http {
sendfile on;
keepalive_timeout 65;
include /etc/nginx/mime.types;
default_type application/octet-stream;
passenger_root /usr/lib/ruby/vendor_ruby/phusion_passenger/locations.ini;
passenger_ruby /usr/bin/ruby;
server {
listen 8080;
server_name localhost;
root /rubyapp/public;
passenger_enabled on;
passenger_app_env RAILS_ENV;
}
server {
listen 8081;
server_name healthcheck;
location /healthcheck {
return 200;
}
location / {
return 403;
}
location /ping {
return 200;
}
}
# Logging to STDOUT
access_log /dev/stdout;
}
#!/bin/bash
# RubyApp Startup Script
# Fix rubygems path
export PATH=$PATH:/var/lib/gems/2.2.0/bin
# Set the RubyApp directory
APP_DIR=/rubyapp
# Set RAILS_ENV
if [[ -n "$1" ]]; then
RAILS_ENV=$1
else
echo "Error: Argument Missing! Pass RAILS_ENV value as argument to the script."
exit
fi
# RubyApp directory
cd $APP_DIR
# Create .env file from mounted secrets
/usr/bin/ruby $APP_DIR/config/env.rb $APP_DIR/.env /etc/env
# set rails environment
echo "export RAILS_ENV=$RAILS_ENV" >> $APP_DIR/.env
# Configure passenger environment
sed -i -e "s@PATH_ENV@$PATH@" -e "s@RAILS_ENV@$RAILS_ENV@" $APP_DIR/config/nginx.conf
# create tmp dir and add write permissions
mkdir -p $APP_DIR/tmp/cache/assets/$RAILS_ENV && chmod -R 0777 $APP_DIR/tmp/cache
# Run DB migrations and compile assets
RAILS_ENV=$RAILS_ENV bundle exec rake db:migrate
# Start Nginx
/usr/sbin/nginx -c $APP_DIR/config/nginx.conf
# Dockerfile
# Using phusion passenger as base image.
# Refer - https://github.com/phusion/passenger-docker
FROM phusion/passenger-ruby22:latest
MAINTAINER Pradeep <[email protected]>
# Set ENV variables
ENV HOME /rubyapp/
# Enable Nginx
RUN rm -f /etc/nginx/sites-enabled/default \
&& rm -f /etc/nginx/sites-available/default \
&& rm -f /etc/service/nginx/down \
&& echo "gem: --no-document" >> /etc/gemrc \
&& mkdir -p /rubyapp/
# Run bundle install
WORKDIR $HOME
ADD Gemfile* $HOME
RUN bundle install --without development test deploy --gemfile=$HOME/Gemfile --no-cache
# Copy the rubyapp source to the image at /rubyapp
ADD . /rubyapp/
#!/usr/bin/env ruby
# Encode .env file values to base64 and create json key values
require 'base64'
require 'yaml'
if ARGV[0]
env = {}
file = File.new(ARGV[0], "r")
exit unless file
data = file.read
env_vars = data.split("\n")
env_vars.each do |env_var|
next unless env_var.include?('export')
export_key, ival = env_var.split("=") if env_var
key = export_key.split("export ").last.gsub("_", "-").downcase if export_key
val = (ival)? Base64.strict_encode64(ival) : nil
env[key] = %Q("#{val}")
end
env.each {|k,v| puts "#{k}: #{v}" }
else
puts "Please pass the .env file path.\n Eg: ruby kuberenv.rb config/.env.staging\n"
end
# Background tasks Replication Controller
apiVersion: v1
kind: ReplicationController
metadata:
name: rubyapp-cron
labels:
name: rubyapp-cron
spec:
replicas: 1
selector:
name: rubyapp-cron
template:
metadata:
labels:
name: rubyapp-cron
spec:
volumes:
- name: environment-variables
secret:
secretName: rubyapp-secrets
containers:
- name: rubyapp-btasks
image: gcr.io/xxx/rubyapp:x.x.x
imagePullPolicy: Always
command: ["/bin/bash", "/rubyapp/config/crontab.sh"]
volumeMounts:
- name: environment-variables
readOnly: true
mountPath: /etc/env
apiVersion: v1
kind: Secret
metadata:
name: rubyapp-secrets
type: Opaque
data:
# Base64.strict_encode64("string")
secret-1: "c2VjcmV0LTE="
secret-2: "c2VjcmV0LTI="
# Web application service file
apiVersion: v1
kind: Service
metadata:
name: rubyapp
spec:
type: LoadBalancer
ports:
- name: http
port: 80
targetPort: 8080
protocol: TCP
- name: admin
port: 8081
targetPort: 8081
protocol: TCP
selector:
app: rubyapp
tier: frontend
# Web application Replication Controller yml
apiVersion: v1
kind: ReplicationController
metadata:
name: rubyapp-3.0.0
spec:
replicas: 4
selector:
app: rubyapp
version: 3.0.0
tier: frontend
language: ruby
template:
metadata:
labels:
app: rubyapp
version: 3.0.0
tier: frontend
language: ruby
spec:
volumes:
- name: environment-variables
secret:
secretName: rubyapp-secrets
containers:
- name: rubyapp
image: gcr.io/xxx/rubyapp:3.0.0
imagePullPolicy: Always
command: ["/bin/bash", "/rubyapp/config/startup.sh","staging"]
ports:
- containerPort: 8080
- containerPort: 8081
readinessProbe:
httpGet:
path: /healthcheck
port: 8081
initialDelaySeconds: 120
timeoutSeconds: 3
livenessProbe:
httpGet:
path: /ping
port: 8081
initialDelaySeconds: 120
timeoutSeconds: 3
volumeMounts:
- name: environment-variables
readOnly: true
mountPath: /etc/env
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment