Platform Overview

Enkihost Documentation

Enkihost is a modern cloud hosting platform engineered specifically for the Ruby ecosystem. We provide fully managed runtime environments for Ruby on Rails, Sinatra, and Jekyll, with automated Git deployments, isolated containers, zero-downtime rollouts, and dedicated PostgreSQL and Redis addons.

Zero-Downtime

New containers pass healthchecks before legacy instances are gracefully stopped.

Managed Addons

Instantly provision PostgreSQL 16 and Redis 7 with automatic credentials injection.

Encrypted Secrets

Store environment variables securely with AES-256 encryption at rest.


Step-by-Step Guide

Creating & Deploying an Application

Follow these steps to deploy your Ruby application to production in under two minutes.

1

Connect your Git Provider

Log in to the Enkihost console, navigate to Settings or New Application, and connect your GitHub or GitLab account. Grant access to your public or private repositories.

2

Select Repository and Branch

Choose the repository you wish to deploy and select the production branch (e.g. main or production). Any subsequent push to this branch will automatically trigger a new deployment.

3

Select Buildpack or Docker Engine

Enkihost supports automatic buildpacks as well as custom Docker configurations:

  • Ruby on RailsAutomatic asset compilation, database migrations, and Puma server setup.
  • SinatraLightweight rackup execution using Puma or Thin on your designated port.
  • JekyllBuilds static assets and serves them with zero-latency HTTP caching.
  • Docker / Docker ComposeUses your repository's Dockerfile or docker-compose.yml for full control.
4

Configure Environment Variables

Provide critical runtime secrets. For Rails apps, ensure you configure SECRET_KEY_BASE:

Generating a secure Rails secret key
bash
bundle exec rails secret
5

Deploy & Access

Click Deploy Application. Enkihost builds the container, provisions the internal network, attaches your SSL certificate, and maps your custom or generated subdomain (e.g. my-app.enkihost.com).


Storage & Persistence

Configuring PostgreSQL

How to provision a managed PostgreSQL 16 database and link it to your Ruby application.

1. Provisioning in Console

Navigate to Dashboard → Databases and click New Database. Select PostgreSQL and link it to your application.

2. Automatic Environment Variable Injection

When a PostgreSQL database is attached to your app, Enkihost automatically injects the standard DATABASE_URL variable:

DATABASE_URL format
env
DATABASE_URL=postgres://enkihost_user:a8f93bc0912@enkihost-postgres-app:5432/my_app_production

3. Configuring Ruby on Rails (config/database.yml)

In Rails, configure your production database to read from ENV['DATABASE_URL']:

config/database.yml
yaml
default: &default
  adapter: postgresql
  encoding: unicode
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>

development:
  <<: *default
  database: my_app_development

test:
  <<: *default
  database: my_app_test

production:
  <<: *default
  url: <%= ENV['DATABASE_URL'] %>

4. Configuring Sinatra (with Sequel or ActiveRecord)

Sinatra with Sequel (app.rb)
ruby
require 'sinatra'
require 'sequel'

# Automatically connects to the PostgreSQL database injected by Enkihost
DB = Sequel.connect(ENV['DATABASE_URL'] || 'postgres://localhost/my_sinatra_dev')

get '/users' do
  content_type :json
  DB[:users].all.to_json
end

In-Memory Caching & Background Jobs

Configuring Redis

Set up Redis 7 for application caching, ActionCable WebSockets, and background workers with Sidekiq.

1. Automatic REDIS_URL Injection

When creating a Redis addon and linking it to your application, Enkihost provides:

REDIS_URL format
env
REDIS_URL=redis://enkihost-redis-app:6379/0

2. Configuring Sidekiq (config/initializers/sidekiq.rb)

config/initializers/sidekiq.rb
ruby
Sidekiq.configure_server do |config|
  config.redis = { url: ENV.fetch('REDIS_URL', 'redis://localhost:6379/0') }
end

Sidekiq.configure_client do |config|
  config.redis = { url: ENV.fetch('REDIS_URL', 'redis://localhost:6379/0') }
end

3. Configuring ActionCable (config/cable.yml)

config/cable.yml
yaml
production:
  adapter: redis
  url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
  channel_prefix: my_app_production

Production Containerfile

Ruby on Rails Dockerfile

A production-ready, multi-stage Dockerfile optimized for Rails 7 / 8 with PostgreSQL, asset precompilation, jemalloc, and a non-root user.

Dockerfile (Ruby on Rails Production)
dockerfile
# syntax = docker/dockerfile:1

# 1. Base image with Ruby
ARG RUBY_VERSION=3.3.5
FROM ruby:$RUBY_VERSION-slim AS base

WORKDIR /rails

# Set production environment variables
ENV RAILS_ENV="production" \
    BUNDLE_DEPLOYMENT="1" \
    BUNDLE_PATH="/usr/local/bundle" \
    BUNDLE_WITHOUT="development:test"

# Install base packages (libpq for PostgreSQL, curl for healthcheck)
RUN apt-get update -qq && \
    apt-get install --no-install-recommends -y curl libpq-dev libjemalloc2 && \
    rm -rf /var/lib/apt/lists /var/cache/apt/archives

# Enable jemalloc for reduced memory fragmentation in Ruby
ENV LD_PRELOAD="/usr/lib/x86_64-linux-gnu/libjemalloc.so.2"

# 2. Build stage for gems and asset precompilation
FROM base AS build

# Install build tools for native gem extensions (e.g. pg, nokogiri)
RUN apt-get update -qq && \
    apt-get install --no-install-recommends -y build-essential git pkg-config && \
    rm -rf /var/lib/apt/lists /var/cache/apt/archives

# Install application gems
COPY Gemfile Gemfile.lock ./
RUN bundle install && \
    rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git

# Copy application code
COPY . .

# Precompile assets without requiring a live database connection
RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile

# 3. Final execution stage
FROM base

# Run as non-root user for maximum container security
RUN useradd rails --create-home --shell /bin/bash && \
    chown -R rails:rails /rails

COPY --chown=rails:rails --from=build /usr/local/bundle /usr/local/bundle
COPY --chown=rails:rails --from=build /rails /rails

USER rails:rails

# Expose port (configured via ENV or defaults to 3000)
EXPOSE 3000
ENV PORT=3000

# Start Puma web server
CMD ["./bin/thrust", "./bin/rails", "server"]

Lightweight Microframework

Sinatra Dockerfile

A fast, minimalistic Dockerfile for Sinatra applications running on Puma.

Dockerfile (Sinatra Production)
dockerfile
# syntax = docker/dockerfile:1
FROM ruby:3.3-slim

WORKDIR /app

ENV RACK_ENV="production" \
    BUNDLE_DEPLOYMENT="1" \
    BUNDLE_PATH="/usr/local/bundle" \
    BUNDLE_WITHOUT="development:test"

# Install dependencies (libpq-dev for postgres, build-essential for native gems)
RUN apt-get update -qq && \
    apt-get install --no-install-recommends -y build-essential libpq-dev curl && \
    rm -rf /var/lib/apt/lists /var/cache/apt/archives

# Copy dependency definitions
COPY Gemfile Gemfile.lock ./
RUN bundle install

# Copy application code
COPY . .

# Run as non-root user
RUN useradd -m sinatra && chown -R sinatra:sinatra /app
USER sinatra

EXPOSE 4567
ENV PORT=4567

# Launch via bundle exec puma or rackup
CMD ["bundle", "exec", "puma", "-p", "4567", "-e", "production"]

Static Site Generation

Jekyll Dockerfile

Multi-stage build that compiles your Jekyll static site and serves it via an ultra-lightweight Alpine Nginx server.

Dockerfile (Jekyll with Alpine Nginx)
dockerfile
# 1. Build stage: compile static site with Jekyll
FROM ruby:3.3-alpine AS builder

WORKDIR /srv/jekyll

RUN apk add --no-cache build-base gcc cmake git

COPY Gemfile Gemfile.lock ./
RUN bundle install

COPY . .
ENV JEKYLL_ENV=production
RUN bundle exec jekyll build --destination /srv/jekyll/_site

# 2. Production stage: serve with high-performance Nginx
FROM nginx:alpine

# Copy compiled static HTML/CSS/JS to webroot
COPY --from=builder /srv/jekyll/_site /usr/share/nginx/html

# Custom nginx config for SPA routing and caching if needed
RUN printf "server {\n\
    listen 80;\n\
    server_name localhost;\n\
    location / {\n\
        root /usr/share/nginx/html;\n\
        index index.html index.htm;\n\
        try_files \$uri \$uri/ /index.html;\n\
    }\n\
}\n" > /etc/nginx/conf.d/default.conf

EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

Full Multi-Container Stack

Production docker-compose.yml

A complete docker-compose.yml demonstrating your web service orchestrated with PostgreSQL 16 and Redis 7, persistent volumes, and health checks.

docker-compose.yml
yaml
version: "3.8"

services:
  # 1. Main Web Application
  web:
    build:
      context: .
      dockerfile: Dockerfile
    restart: unless-stopped
    ports:
      - "3000:3000"
    environment:
      - RAILS_ENV=production
      - PORT=3000
      - DATABASE_URL=postgres://enkihost:securepassword123@db:5432/my_app_production
      - REDIS_URL=redis://redis:6379/0
      - SECRET_KEY_BASE=${SECRET_KEY_BASE}
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_healthy
    networks:
      - enkihost-network

  # 2. Managed PostgreSQL Database
  db:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      POSTGRES_USER: enkihost
      POSTGRES_PASSWORD: securepassword123
      POSTGRES_DB: my_app_production
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U enkihost -d my_app_production"]
      interval: 5s
      timeout: 5s
      retries: 5
    networks:
      - enkihost-network

  # 3. Managed Redis Cache & Queue
  redis:
    image: redis:7-alpine
    restart: unless-stopped
    command: ["redis-server", "--appendonly", "yes"]
    volumes:
      - redis_data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      timeout: 3s
      retries: 5
    networks:
      - enkihost-network

volumes:
  postgres_data:
    driver: local
  redis_data:
    driver: local

networks:
  enkihost-network:
    driver: bridge

Ready to deploy your Ruby application?

Get started with isolated containers, automated SSL, custom domains, and managed databases in seconds.