Compare commits
1 commit
main
...
single-fil
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6c8e4f809d |
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -1,4 +0,0 @@
|
||||||
/.rake_tasks~
|
|
||||||
/temp.db
|
|
||||||
/vendor/
|
|
||||||
/bin/
|
|
||||||
12
Gemfile
12
Gemfile
|
|
@ -1,16 +1,4 @@
|
||||||
source 'https://rubygems.org'
|
source 'https://rubygems.org'
|
||||||
|
|
||||||
gem 'roda'
|
gem 'roda'
|
||||||
gem 'rack-unreloader'
|
|
||||||
gem 'tilt'
|
|
||||||
gem 'erubi'
|
|
||||||
gem 'sequel'
|
|
||||||
gem 'rake'
|
|
||||||
|
|
||||||
# Change to whatever database you plan to use
|
|
||||||
gem 'sqlite3'
|
|
||||||
# gem 'pg' # will also want gem sequel-pg
|
|
||||||
# gem 'mysql2'
|
|
||||||
|
|
||||||
# change to gunicorn or passenger if you prefer:
|
|
||||||
gem 'puma'
|
gem 'puma'
|
||||||
|
|
|
||||||
84
README.md
84
README.md
|
|
@ -2,29 +2,8 @@
|
||||||
|
|
||||||
For the single file app template, really the only file you need is the config.ru and run it with puma.
|
For the single file app template, really the only file you need is the config.ru and run it with puma.
|
||||||
|
|
||||||
## Database
|
|
||||||
|
|
||||||
## Views
|
|
||||||
|
|
||||||
In this template, I've taken the single-file template and split up the config.ru to put routes and app logic in app.rb and call on templates to render proper html pages. `tilt` and `erubi` gems are added to do the rendering, and `rack-unreloader` gem is added to have puma automatically load file changes while running in development mode.
|
|
||||||
|
|
||||||
My example html layout uses [Bulma](https://bulma.io/) to make it easier to make modern looking webpages.
|
|
||||||
|
|
||||||
Next Roda app template iterations will add database, then authentication.
|
|
||||||
|
|
||||||
## Setup
|
## Setup
|
||||||
|
|
||||||
### Get git
|
|
||||||
|
|
||||||
```
|
|
||||||
sudo apt install git
|
|
||||||
git config --global user.email "myemail@gmail.com"
|
|
||||||
git config --global user.name "Full Name"
|
|
||||||
git config --global credential.helper "cache"
|
|
||||||
|
|
||||||
git clone https://path/to/project.git
|
|
||||||
```
|
|
||||||
|
|
||||||
### Prereq installs
|
### Prereq installs
|
||||||
|
|
||||||
Will need ruby; install it via package manager or a ruby manager like rbenv/ruby-build. Will need the roda gem, and then an application server such as puma (recommended), gunicorn, or passenger. My examples will use system ruby and puma.
|
Will need ruby; install it via package manager or a ruby manager like rbenv/ruby-build. Will need the roda gem, and then an application server such as puma (recommended), gunicorn, or passenger. My examples will use system ruby and puma.
|
||||||
|
|
@ -34,64 +13,31 @@ Will need ruby; install it via package manager or a ruby manager like rbenv/ruby
|
||||||
With this example, will basically just ignore the project's Gemfile. Debian 12 has a pretty current ruby version so just using it.
|
With this example, will basically just ignore the project's Gemfile. Debian 12 has a pretty current ruby version so just using it.
|
||||||
|
|
||||||
```
|
```
|
||||||
sudo apt install ruby ruby-rack puma ruby-erubi ruby-tilt ruby-sequel ruby-sqlite3 rake
|
sudo apt install ruby ruby-rack puma
|
||||||
sudo gem install roda rack-unreloader
|
sudo gem install roda
|
||||||
|
|
||||||
cd my-project
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Option 2a: Bundler system package
|
#### Option 2: Bundler
|
||||||
|
|
||||||
Run the bundle install command from the project's root directory
|
Run the bundle command from the project's root directory
|
||||||
|
|
||||||
```
|
```
|
||||||
sudo apt install ruby ruby-bundler ruby-dev gcc pkgconf make g++ libyaml-dev libffi-dev
|
sudo apt install ruby ruby-bundler
|
||||||
echo 'gem: --no-document' >> ~/.gemrc
|
bundle config set --local path 'vendor/bundle'
|
||||||
sudo cp ~/.gemrc /root/
|
|
||||||
bundle config set --global path 'vendor/bundle'
|
|
||||||
sudo cp -r .bundle /root/
|
|
||||||
|
|
||||||
cd my-project
|
|
||||||
bundle install
|
bundle install
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Option 2b: Bundler system gem (recommended)
|
|
||||||
|
|
||||||
Similar to above but might as well use the gem install to get the latest bundler. The Debian apt packaged bundler is currently a bit outdated and missing some features compared to the latest.
|
|
||||||
|
|
||||||
```
|
|
||||||
sudo apt install ruby ruby-dev gcc pkgconf make g++ libyaml-dev # zlib1g-dev libffi-dev #(for rails stuff)
|
|
||||||
echo 'gem: --no-document' >> ~/.gemrc
|
|
||||||
sudo cp ~/.gemrc /root/
|
|
||||||
sudo gem install bundler
|
|
||||||
bundle config set --global path 'vendor/bundle'
|
|
||||||
sudo cp -r .bundle /root/
|
|
||||||
|
|
||||||
cd my-project
|
|
||||||
bundle install
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Option 3: Rbenv Ruby
|
|
||||||
|
|
||||||
Todo
|
|
||||||
|
|
||||||
## Run it
|
## Run it
|
||||||
|
|
||||||
In the project root directory:
|
In the project root directory:
|
||||||
|
|
||||||
```
|
```
|
||||||
bundle exec puma
|
|
||||||
|
|
||||||
# or if you did not use bundler to install puma...
|
|
||||||
puma
|
puma
|
||||||
```
|
```
|
||||||
|
|
||||||
This default to development mode. Run it in production mode with:
|
This default to development mode. Run it in production mode with:
|
||||||
|
|
||||||
```
|
```
|
||||||
RACK_ENV=production bundle exec puma
|
|
||||||
|
|
||||||
# or if you did not install puma
|
|
||||||
RACK_ENV=production puma
|
RACK_ENV=production puma
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -99,20 +45,4 @@ For development, just run it like that. For production, probably want to set up
|
||||||
|
|
||||||
### Run it with systemd in production
|
### Run it with systemd in production
|
||||||
|
|
||||||
Copy the example myapp.service file to `/etc/systemd/system/` and edit accordingly. The example assumes a user named "myapp" with a group name "myapp", the application files are in `/opt/myapp/`, and puma is the system puma. If you installed puma with bundler, the exe will be at `/opt/myapp/vendor/bundle/ruby/3.1.0/bin/puma`.
|
Copy the example myapp.service file to `/etc/systemd/system/` and edit accordingly. The example assumes a user named "myapp" with a group name "myapp", the application files are in `/opt/myapp/`, and puma is the system puma.
|
||||||
|
|
||||||
### Notes
|
|
||||||
|
|
||||||
## Unreloader
|
|
||||||
|
|
||||||
This has puma reload with any file changes while you are working on the app, when in development mode. When puma is in production mode, it loads the app on startup like normal with no performance penalty. It's very useful during development and no reason to not leave it in.
|
|
||||||
|
|
||||||
<https://github.com/jeremyevans/rack-unreloader>.
|
|
||||||
|
|
||||||
Basically, you require the app from the config.ru, and then within you app files, any "require_relative" will be "Unreloader.require" instead, plus you do need to include the file extension.
|
|
||||||
|
|
||||||
In config.ru, the `dev =` line stores true or false depending on the RACK_ENV environment variable (see above for changing from default development). Then the `:reload=>dev` uses the dev variable to tell Unreload to reload files or not. Lastly the `run` command uses the dev variable to choose between running Unreloader, or bypass Unreloader and run App like normal in production.
|
|
||||||
|
|
||||||
## Additional credit
|
|
||||||
|
|
||||||
I took a lot of inspirations from Jeremy Evans [roda-sequel-stack](https://github.com/jeremyevans/roda-sequel-stack). Jeremy Evans is the author of Roda and also Unreloader, Sequel, and a ruby core contributor, among other things.
|
|
||||||
|
|
|
||||||
33
Rakefile
33
Rakefile
|
|
@ -1,33 +0,0 @@
|
||||||
namespace :db do
|
|
||||||
|
|
||||||
migrator = lambda do |version|
|
|
||||||
require_relative 'db'
|
|
||||||
Sequel.extension :migration
|
|
||||||
Sequel::Migrator.apply(DB, 'migrate', version)
|
|
||||||
end
|
|
||||||
|
|
||||||
namespace :migrate do
|
|
||||||
|
|
||||||
desc "Perform migration up to latest migration available"
|
|
||||||
task :up do
|
|
||||||
migrator.call(nil)
|
|
||||||
end
|
|
||||||
|
|
||||||
desc "Perform migration all the way down (erase all data)"
|
|
||||||
task :down do
|
|
||||||
migrator.call(0)
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
desc "Erase all data, then bring back to latest migration"
|
|
||||||
task :reset do
|
|
||||||
migrator.call(0)
|
|
||||||
Sequel::Migrator.apply(DB, 'migrate')
|
|
||||||
end
|
|
||||||
|
|
||||||
#desc "Migrate to a specific version"
|
|
||||||
#task :migrate do |version|
|
|
||||||
#end
|
|
||||||
|
|
||||||
end
|
|
||||||
31
app.rb
31
app.rb
|
|
@ -1,31 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
require 'roda'
|
|
||||||
require 'tilt'
|
|
||||||
require 'tilt/erubi'
|
|
||||||
|
|
||||||
class App < Roda
|
|
||||||
plugin :render, escape: true
|
|
||||||
plugin :route_csrf
|
|
||||||
|
|
||||||
route do |r|
|
|
||||||
check_csrf!
|
|
||||||
|
|
||||||
r.root do
|
|
||||||
view :index
|
|
||||||
end
|
|
||||||
|
|
||||||
r.is 'users' do
|
|
||||||
@users = User.order(:id)
|
|
||||||
view :users
|
|
||||||
end
|
|
||||||
|
|
||||||
r.on 'hello' do
|
|
||||||
r.is String do |name|
|
|
||||||
@page_title = 'A Custom Greeting'
|
|
||||||
@name = name.capitalize
|
|
||||||
view :greeting
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
19
config.ru
19
config.ru
|
|
@ -1,10 +1,15 @@
|
||||||
|
require 'roda'
|
||||||
|
|
||||||
dev = ENV['RACK_ENV'] == 'development'
|
class App < Roda
|
||||||
|
route do |r|
|
||||||
|
r.root do
|
||||||
|
"<h1>Hello, World!</h1>"
|
||||||
|
end
|
||||||
|
|
||||||
require 'rack/unreloader'
|
r.is String do |name|
|
||||||
|
"<h1>Hello, #{name.capitalize}!</h1>"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
Unreloader = Rack::Unreloader.new(:subclasses=>%w'Roda Sequel::Model', reload: dev, autoload: dev){App}
|
run App
|
||||||
Unreloader.require './models.rb'
|
|
||||||
Unreloader.require './app.rb'
|
|
||||||
|
|
||||||
run(dev ? Unreloader : App)
|
|
||||||
|
|
|
||||||
4
db.rb
4
db.rb
|
|
@ -1,4 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
require 'sequel/core'
|
|
||||||
|
|
||||||
DB = Sequel.connect('sqlite://temp.db')
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
Sequel.migration do
|
|
||||||
change do
|
|
||||||
create_table(:users) do
|
|
||||||
primary_key :id
|
|
||||||
String :name, unique: true, null: false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
14
models.rb
14
models.rb
|
|
@ -1,14 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
require_relative 'db'
|
|
||||||
require 'sequel/model'
|
|
||||||
|
|
||||||
if ENV['RACK_ENV'] == 'development'
|
|
||||||
Sequel::Model.cache_associations = false
|
|
||||||
end
|
|
||||||
|
|
||||||
unless defined?(Unreloader)
|
|
||||||
require 'rack/unreloader'
|
|
||||||
Unreloader = Rack::Unreloader.new(reload: false, autoload: !ENV['NO_AUTOLOAD'])
|
|
||||||
end
|
|
||||||
|
|
||||||
Unreloader.autoload('models'){|f| Sequel::Model.send(:camelize, File.basename(f).sub(/\.rb\z/, ''))}
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
class User < Sequel::Model
|
|
||||||
end
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
<p class="subtitle">
|
|
||||||
Hello, <%= @name %>!
|
|
||||||
</p>
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
<p class="subtitle">
|
|
||||||
Welcome to my new page! Running in <%= ENV['RACK_ENV'] %> mode!
|
|
||||||
</p>
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
||||||
<title><%= @page_title || "My Website" %></title>
|
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@1/css/bulma.min.css">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<section class="section">
|
|
||||||
<div class="container">
|
|
||||||
<h1 class="title">
|
|
||||||
<%= @page_title || 'Page Title Placeholder' %>
|
|
||||||
</h1>
|
|
||||||
<%== yield %>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
<% for u in @users do %>
|
|
||||||
<p class="subtitle">
|
|
||||||
Hello, <%= u.name %>! You're #<%= u.id %>!
|
|
||||||
</p>
|
|
||||||
<% end %>
|
|
||||||
Loading…
Reference in a new issue