On this page
Baking Rack
Bake and Push static webpages generated by a Rack application.

Table of Contents
Why?
Why static webpages?
When paired with a good hosting service, static webpages are cheaper to host, easier to maintain, and harder to hack than dynamic ones because there are less moving parts.
Why one more Ruby static webpage generator?
BakingRack is a narrowly-focused library, not an all-encompassing framework.
Jekyll, Middleman, Nanoc, and Bridgetown are frameworks that define how your site is organized. BakingRack is only interested in your site being a Rack app (protip: all those frameworks support Rack) in order to gather its static pages and publish them to a static webserver or CDN.
Getting Started
Start by including baking_rack in your Gemfile:
gem 'baking_rack' # when deploying to S3 gem 'aws-sdk-s3'
Then run bundle install.
Configuration
BakingRack.config do |c| c.builder = BakingRack::Builder.new(app: YourRackApp) c.deployer = BakingRack::AwsS3::Deployer.new c.define_static_routes do # Render this explicit path using your Rack app. get "/about.html" # Collect routes from static data BlogPost.find_each do |post| get post.path end # Expect statuses other than 200 get "/404.html", status: 404 end end
# view available commands $ bundle exec baking_rack help # view a specific command's options $ bundle exec baking_rack help [COMMAND] # perform the build and deploy $ bundle exec baking_rack publish
Dry Run
Deployers support the dry_run keyword argument which instructs it to output what will be deployed without actually performing it.
Ruby on Rails
BakingRack provides some additional help for building static webpages from Ruby on Rails applications, just use its custom builder class:
# config/initializers/baking_rack.rb BakingRack.config do |c| c.builder = BakingRack::Rails::Build.new b.static_routes do # path helpers are exposed here get root_path end end
Intelligent defaults:
appdefaults toRails.applicationdomain_namedefaults toRails.application.config.hosts.first
AWS + Terraform + GitHub
- Define the terraform module and some outputs
module "baking_rack" { source = "git@github.com:dcunning/baking_rack.git//terraform/aws?ref=v<%= BakingRack::VERSION %>" bucket_name = "${module.label.id}-www" domain_name = var.domain_name github_repository = var.github_repository branch_name = var.github_branch_name } output "baking_rack" { value = module.baking_rack }
- Add an origin to your CloudFront distribution
origin { domain_name = module.baking_rack_bucket.website_endpoint origin_id = "S3-${module.baking_rack.bucket_name}" custom_origin_config { http_port = 80 https_port = 443 origin_protocol_policy = "http-only" origin_ssl_protocols = ["TLSv1", "TLSv1.1", "TLSv1.2"] } # Prevents S3 objects from being accessed outside CloudFront custom_header { name = "User-Agent" value = module.baking_rack.handshake } }
- Apply the terraform plan
terraform init terraform apply
- Generate a GitHub workflow
Use GitHub Actions to automatically publish the latest main to the S3 bucket. The IAM role and bucket name are outputs from the terraform apply command.
name: Publish to production on: push: branches: [ main ] env: AWS_REGION : "us-east-1" jobs: Publish: runs-on: ubuntu-latest permissions: id-token: write contents: read steps: - name: Git clone the repository uses: actions/checkout@v3 - name: Setup Ruby uses: ruby/setup-ruby@v1 with: bundler-cache: true # https://aws.amazon.com/blogs/security/use-iam-roles-to-connect-github-actions-to-actions-in-aws/ - name: configure aws credentials uses: aws-actions/configure-aws-credentials@v1.7.0 with: role-to-assume: "(FROM TERRAFORM OUTPUT)" role-session-name: GitHub_to_AWS_via_FederatedOIDC aws-region: ${{ env.AWS_REGION }} - name: Publish Site env: RAILS_ENV: production RAILS_MASTER_KEY: ${{ secrets.RAILS_MASTER_KEY }} BUCKET_NAME: "(FROM TERRAFORM OUTPUT)" run: | bin/rails assets:precompile bundle exec baking_rack publish
Contributing
If you have problems, please create a GitHub Issue.
Versioning
baking_rack follows Semantic Versioning 2.0 as defined at https://semver.org.
License
This code is free to use under the terms of the MIT license.