Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Kamal 2 #37

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# See https://docs.docker.com/engine/reference/builder/#dockerignore-file for more about ignoring files.

# Ignore git directory.
/.git/
/.gitignore

# Ignore bundler config.
/.bundle

# Ignore all environment files.
/.env*

# Ignore all default key files.
/config/master.key
/config/credentials/*.key

# Ignore all logfiles and tempfiles.
/log/*
/tmp/*
!/log/.keep
!/tmp/.keep

# Ignore pidfiles, but keep the directory.
/tmp/pids/*
!/tmp/pids/.keep

# Ignore storage (uploaded files in development and any SQLite databases).
/storage/*
!/storage/.keep
/tmp/storage/*
!/tmp/storage/.keep

# Ignore assets.
/node_modules/
/app/assets/builds/*
!/app/assets/builds/.keep
/public/assets

# Ignore CI service files.
/.github

# Ignore development files
/.devcontainer

# Ignore Docker-related files
/.dockerignore
/Dockerfile*
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,6 @@ yarn-debug.log*

/app/assets/builds/*
!/app/assets/builds/.keep

# Ignore all environment files.
/.env*
8 changes: 8 additions & 0 deletions .kamal/secrets
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Docker registry password
KAMAL_REGISTRY_PASSWORD=$KAMAL_REGISTRY_PASSWORD

# Rails master key
RAILS_MASTER_KEY=$(cat config/credentials/production.key)

# Database password
POSTGRES_PASSWORD=$POSTGRES_PASSWORD
86 changes: 86 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# syntax=docker/dockerfile:1
# check=error=true

# This Dockerfile is designed for production, not development. Use with Kamal or build'n'run by hand:
# docker build -t anycable_rails_demo .
# docker run -d -p 80:80 -e RAILS_MASTER_KEY=<value from config/master.key> --name anycable_rails_demo anycable_rails_demo

# For a containerized dev environment, see Dev Containers: https://guides.rubyonrails.org/getting_started_with_devcontainer.html

# Make sure RUBY_VERSION matches the Ruby version in .ruby-version
ARG RUBY_VERSION=3.3.0
FROM docker.io/library/ruby:$RUBY_VERSION-slim AS base

# Rails app lives here
WORKDIR /rails

# Install base packages
RUN apt-get update -qq && \
apt-get install --no-install-recommends -y curl libjemalloc2 libvips postgresql-client && \
rm -rf /var/lib/apt/lists /var/cache/apt/archives

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

# Throw-away build stage to reduce size of final image
FROM base AS build

# Install packages needed to build gems and node modules
RUN apt-get update -qq && \
apt-get install --no-install-recommends -y build-essential git libpq-dev node-gyp pkg-config python-is-python3 && \
rm -rf /var/lib/apt/lists /var/cache/apt/archives

# Install JavaScript dependencies
ARG NODE_VERSION=22.5.1
ARG YARN_VERSION=1.22.22
ENV PATH=/usr/local/node/bin:$PATH
RUN curl -sL https://github.com/nodenv/node-build/archive/master.tar.gz | tar xz -C /tmp/ && \
/tmp/node-build-master/bin/node-build "${NODE_VERSION}" /usr/local/node && \
npm install -g yarn@$YARN_VERSION && \
rm -rf /tmp/node-build-master

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

# Install node modules
COPY package.json yarn.lock ./
RUN yarn install --frozen-lockfile

# Copy application code
COPY . .

# Precompile bootsnap code for faster boot times
RUN bundle exec bootsnap precompile app/ lib/

# Precompiling assets for production without requiring secret RAILS_MASTER_KEY
RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile


RUN rm -rf node_modules


# Final stage for app image
FROM base

# Copy built artifacts: gems, application
COPY --from=build "${BUNDLE_PATH}" "${BUNDLE_PATH}"
COPY --from=build /rails /rails

# Run and own only the runtime files as a non-root user for security
RUN groupadd --system --gid 1000 rails && \
useradd rails --uid 1000 --gid 1000 --create-home --shell /bin/bash && \
chown -R rails:rails db log tmp
USER 1000:1000

# Entrypoint prepares the database.
ENTRYPOINT ["/rails/bin/docker-entrypoint"]

# Start server via Thruster by default, this can be overwritten at runtime
EXPOSE 80
CMD ["./bin/thrust", "./bin/rails", "server"]
3 changes: 3 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ gem 'cssbundling-rails'
gem 'jsbundling-rails'
gem 'propshaft'

gem 'kamal', '~> 2.4', require: false
gem 'thruster', '~> 0.1.9', require: false

group :development, :test do
gem 'debug', '1.7.0'
gem 'rspec-rails', '~> 6.0'
Expand Down
37 changes: 36 additions & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ GEM
ruby-next-core (~> 1.0)
ast (2.4.2)
base64 (0.2.0)
bcrypt_pbkdf (1.1.1)
bcrypt_pbkdf (1.1.1-arm64-darwin)
bcrypt_pbkdf (1.1.1-x86_64-darwin)
bigdecimal (3.1.7)
bootsnap (1.18.3)
msgpack (~> 1.2)
Expand Down Expand Up @@ -121,7 +124,9 @@ GEM
irb (>= 1.5.0)
reline (>= 0.3.1)
diff-lcs (1.5.1)
dotenv (3.1.7)
drb (2.2.1)
ed25519 (1.3.0)
erubi (1.12.0)
ferrum (0.14)
addressable (~> 2.5)
Expand Down Expand Up @@ -164,6 +169,17 @@ GEM
reline (>= 0.4.2)
jsbundling-rails (1.3.0)
railties (>= 6.0.0)
kamal (2.4.0)
activesupport (>= 7.0)
base64 (~> 0.2)
bcrypt_pbkdf (~> 1.0)
concurrent-ruby (~> 1.2)
dotenv (~> 3.1)
ed25519 (~> 1.2)
net-ssh (~> 7.3)
sshkit (>= 1.23.0, < 2.0)
thor (~> 1.3)
zeitwerk (>= 2.6.18, < 3.0)
loofah (2.22.0)
crass (~> 1.0.2)
nokogiri (>= 1.12.0)
Expand All @@ -186,8 +202,13 @@ GEM
net-protocol
net-protocol (0.2.2)
timeout
net-scp (4.0.0)
net-ssh (>= 2.6.5, < 8.0.0)
net-sftp (4.0.0)
net-ssh (>= 5.0.0, < 8.0.0)
net-smtp (0.5.0)
net-protocol
net-ssh (7.3.0)
nio4r (2.7.1)
nokogiri (1.16.3-aarch64-linux)
racc (~> 1.4)
Expand All @@ -201,6 +222,7 @@ GEM
racc (~> 1.4)
nokogiri (1.16.3-x86_64-linux)
racc (~> 1.4)
ostruct (0.6.1)
paco (0.2.3)
parser (3.3.0.5)
ast (~> 2.4.1)
Expand Down Expand Up @@ -291,9 +313,20 @@ GEM
ruby-next-core (1.0.2)
ruby-next-parser (3.2.2.0)
parser (>= 3.0.3.1)
sshkit (1.23.2)
base64
net-scp (>= 1.1.2)
net-sftp (>= 2.1.2)
net-ssh (>= 2.8.0)
ostruct
stringio (3.1.0)
test-prof (1.3.2)
thor (1.3.1)
thruster (0.1.9)
thruster (0.1.9-aarch64-linux)
thruster (0.1.9-arm64-darwin)
thruster (0.1.9-x86_64-darwin)
thruster (0.1.9-x86_64-linux)
timeout (0.4.1)
turbo-rails (2.0.5)
actionpack (>= 6.0.0)
Expand All @@ -310,7 +343,7 @@ GEM
websocket-extensions (0.1.5)
xpath (3.2.0)
nokogiri (~> 1.8)
zeitwerk (2.6.13)
zeitwerk (2.7.1)

PLATFORMS
aarch64-linux
Expand All @@ -330,6 +363,7 @@ DEPENDENCIES
debug (= 1.7.0)
grpc (~> 1.37)
jsbundling-rails
kamal (~> 2.4)
nanoid
pg (~> 1.0)
propshaft
Expand All @@ -339,6 +373,7 @@ DEPENDENCIES
rspec-rails (~> 6.0)
ruby-next (~> 1.0)
test-prof
thruster (~> 0.1.9)
turbo-rails

RUBY VERSION
Expand Down
14 changes: 14 additions & 0 deletions bin/docker-entrypoint
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/bash -e

# Enable jemalloc for reduced memory usage and latency.
if [ -z "${LD_PRELOAD+x}" ]; then
LD_PRELOAD=$(find /usr/lib -name libjemalloc.so.2 -print -quit)
export LD_PRELOAD
fi

# If running the rails server then create or migrate existing database
if [ "${@: -2:1}" == "./bin/rails" ] && [ "${@: -1:1}" == "server" ]; then
./bin/rails db:prepare
fi

exec "${@}"
5 changes: 5 additions & 0 deletions bin/thrust
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env ruby
require "rubygems"
require "bundler/setup"

load Gem.bin_path("thruster", "thrust")
1 change: 1 addition & 0 deletions config/credentials/production.yml.enc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
FQ6TLkZtOGf76esz8l5PLT7MXqapk57nSaOL7tmYQbI0xL7//Evm18OcEw47bJjNf9GLdSaBljbeF2d6hp2lSuQ2CJyjpxBlU2SXWI2upHYlE0hLfloqVSLhPfngJ6STa/Z/5TOWuROMKt2tviDbE/HBGhnmoJAufvVRL4LESHZHk0Yd68LBhqIqBpGDEDuzxVnOUbm9IlI9H1w4+VrCUsI6yrY9LvQW+mrMQ7VE12/UzJ50SxaxUveEFDxK1ArrJt8rLzLz1nqS5v9dz4Bhu+q8GmDzuy1q02IAwdEva9AOPa8GnJxkXuQdOTBIRFTwYOXK8RsJYEiKss9HuB34FUIGG+W/Z4PfDdztDG34cCBbSwTuFjLmJJmEOKnj6t34zr04VN9VzVSMW4M/Y0+D3+sOGlll--g6R/+zsAm12Rz45Q--juS76hv2QA8wUZqVwBAnOg==
5 changes: 4 additions & 1 deletion config/database.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,7 @@ test:

production:
<<: *default
adapter: postgresql
host: <%= ENV['DB_HOST'] %>
database: any_rails_demo_production
username: any_rails_demo
password: <%= ENV['POSTGRES_PASSWORD'] %>
82 changes: 82 additions & 0 deletions config/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Name of your application. Used to uniquely configure containers.
service: anycable_rails_demo

# Name of the container image.
image: pjpires10/anycable_rails_demo

# Deploy to these servers.
servers:
web:
- 192.168.0.1

anycable-rpc:
hosts:
- 192.168.0.1
cmd: bundle exec anycable
options:
network-alias: anycable_rails_demo-rpc

proxy:
ssl: true
host: demo.anycable.io

registry:
# Specify the registry server, if you're not using Docker Hub
# server: registry.digitalocean.com / ghcr.io / ...
username: pjpires10

# Always use an access token rather than real password (pulled from .kamal/secrets).
password:
- KAMAL_REGISTRY_PASSWORD

env:
secret:
- RAILS_MASTER_KEY
- POSTGRES_PASSWORD
clear:
DB_HOST: anycable_rails_demo-db
REDIS_URL: "redis://anycable_rails_demo-redis:6379"
ANYCABLE_RPC_HOST: "0.0.0.0:50051"
ANYCABLE_REDIS_URL: "redis://anycable_rails_demo-redis:6379/0"
ANYCABLE_WEBSOCKET_URL: "wss://ws.demo.anycable.io/cable"

# Bridge fingerprinted assets, like JS and CSS, between versions to avoid
# hitting 404 on in-flight requests. Combines all files from new and old
# version inside the asset_path.
asset_path: /rails/public/assets

builder:
arch: amd64

accessories:
db:
image: postgres:16
host: 192.168.0.1
env:
clear:
POSTGRES_USER: any_rails_demo
POSTGRES_DB: any_rails_demo_production
secret:
- POSTGRES_PASSWORD
directories:
- data:/var/lib/postgresql/data
redis:
image: redis:7.0
host: 192.168.0.1
directories:
- data:/data
anycable-go:
image: anycable/anycable-go:1.5
host: 192.168.0.1
proxy:
host: ws.demo.anycable.io
ssl: true
app_port: 8080
healthcheck:
path: /health
env:
clear:
ANYCABLE_HOST: "0.0.0.0"
ANYCABLE_PORT: 8080
ANYCABLE_RPC_HOST: anycable_rails_demo-rpc:50051
ANYCABLE_REDIS_URL: "redis://anycable_rails_demo-redis:6379/0"
Loading