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.
Creating & Deploying an Application
Follow these steps to deploy your Ruby application to production in under two minutes.
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.
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.
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
Dockerfileordocker-compose.ymlfor full control.
Configure Environment Variables
Provide critical runtime secrets. For Rails apps, ensure you configure SECRET_KEY_BASE:
bundle exec rails secret
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).
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=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']:
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)
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
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=redis://enkihost-redis-app:6379/0
2. Configuring Sidekiq (config/initializers/sidekiq.rb)
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') }
end3. Configuring ActionCable (config/cable.yml)
production:
adapter: redis
url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
channel_prefix: my_app_productionRuby on Rails Dockerfile
A production-ready, multi-stage Dockerfile optimized for Rails 7 / 8 with PostgreSQL, asset precompilation, jemalloc, and a non-root user.
# 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"]Sinatra Dockerfile
A fast, minimalistic Dockerfile for Sinatra applications running on Puma.
# 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"]Jekyll Dockerfile
Multi-stage build that compiles your Jekyll static site and serves it via an ultra-lightweight Alpine Nginx server.
# 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;"]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.
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: bridgeReady to deploy your Ruby application?
Get started with isolated containers, automated SSL, custom domains, and managed databases in seconds.