Configuration Guide¶
This part of the documentation is aimed at people want to run the project. It assumes familarity with Linux and typical server software like databases and webservers.
Environments and Settings¶
All settings may be configured per environment (PRODUCTION
, DEVELOPMENT
, TEST
). The most important options can all be found in the sqlino.yml
Storage¶
The server currently uses two places to store its data:
- The data folder may be configured via the
data_dir
key inserver/conf/sqlino.yml
. - The database is configured via Rails in
server/conf/database.yml
Additionaly the expects to find certain assets in configurable locations (sqlino.yml
):
client_dir
must point to the compiled client with files likeindex.html
and different*.bundle.js
files.schema_dir
must point to a folder that contains various*.json
-schema files.
Server side rendering¶
You may initially render pages on the server. This drastically speeds up initial load times and provides a partial fallback for users that disable JavaScript.
Backing up and seeding data¶
The server/Makefile
contains two targets that allow to im- or export data to a running server instance: load-all-data
and dump-all-data
. The system is very basic at the moment and not formally tested, for proper backup purposes.
That said, the following things need to be included in a backup for any environment:
- The Postgres-database as denoted in
server/config/database.yml
- The
data_dir
as denoted inserver/config/sqlino.yml
Example configuration files¶
This section contains some exemplary configuration files that work well for the official server at blattwerkzeug.de.
sqlino.yml
at server/conf
¶
common: &common-settings
client_dir: ../client/dist/browser
schema_dir: ../schema/json
query_dir: ../schema/graphql/queries
mail:
default_sender: "BlattWerkzeug <system@blattwerkzeug.de>"
admin: "Marcus@GurXite.de"
ide_service:
exec:
node_binary: <%= ENV['NODE_BIN'] || '/usr/bin/node' %>
program: <%= ENV['CLI_PROGRAM'] || '../client/dist/cli/main.cli.js' %>
mode: one_shot
seed:
data_dir: ../seed
output: true
# Common users that exist in the system
users:
guest: "00000000-0000-0000-0000-000000000001"
system: "00000000-0000-0000-0000-000000000002"
# IDs for the meta language
meta:
grammar:
grammar: "89f9ca62-845c-435b-9b9a-cf52fe7df2b1"
block_language: "df3ec59c-20c0-446d-8c84-7580e1c418bf"
block_language:
grammar: "b292612e-c58f-442f-9139-00b35a22f266"
block_language: "81430cc2-bcff-4304-8cfd-6f05cf249a53"
sentry:
dsn: <%= ENV["SENTRY_DSN"] %>
auth_tokens:
access_token: 180 # 3 minutes
refresh_token: 432000 # 5 days
access_cookie: # Is empty because of the session duration
refresh_cookie: 1209600 # 14 days
auth_provider: ["Identity::Keycloak"]
auth_provider_keys:
keycloak_site: <%= ENV['KEYCLOAK_SITE'] || 'http://lvh.me:8080' %>
keycloak_realm: <%= ENV['KEYCLOAK_REALM'] || 'BlattWerkzeug' %>
development:
<<: *common-settings
name: "Blattwerkzeug (Dev)"
data_dir: <%= ENV['DATA_DIR'] || '../data/dev' %>
project_domains: ["projects.localdomain:9292"]
editor_domain: "lvh.me:9292"
auth_provider: ["Identity::Developer", "Identity::Keycloak"]
test:
<<: *common-settings
name: "Blattwerkzeug (Test)"
data_dir: "../data/test"
project_domains: ["projects.localdomain:9292"]
editor_domain: "localhost.localdomain:9292"
# The IDE service will, under most circumstances, honor the
# "mock: true" setting. This allows testcases to specify arbitrary
# languages (and speeds up the whole ordeal).
# But some tests verify that the actual code runs correctly,
# so the common "exec" configuration must be available
ide_service:
mock: true
exec:
node_binary: <%= ENV['NODE_BIN'] || '/usr/bin/node' %>
# Use the bundled version (with dependencies) on the testserver because
# it has no `node_modules` folder available.
program: <%= ENV['CLI_PROGRAM'] || '../client/dist/cli/bundle.cli.js' %>
mode: one_shot
seed:
data_dir: ../seed-test
output: <%= ENV['TEST_SEED_OUTPUT'] || false %>
# Common users that exist in the system
users:
guest: "00000000-0000-0000-0000-000000000001"
system: "00000000-0000-0000-0000-000000000002"
# IDs for the meta language
meta:
grammar:
grammar: "89f9ca62-845c-435b-9b9a-cf52fe7df2b1"
block_language: "df3ec59c-20c0-446d-8c84-7580e1c418bf"
block_language:
grammar: "b292612e-c58f-442f-9139-00b35a22f266"
block_language: "81430cc2-bcff-4304-8cfd-6f05cf249a53"
auth_provider: ["Identity::Developer"]
production:
<<: *common-settings
name: "Blattwerkzeug"
data_dir: <%= ENV['DATA_DIR'] || '../data/prod' %>
project_domains: ["blattzeug.de"]
editor_domain: "blattwerkzeug.de"
auth_provider: ["Identity::Keycloak"]
database.yml
at server/conf
¶
default: &default
adapter: postgresql
database: esqulino
host: <%= ENV['DATABASE_HOST'] || 'localhost' %>
username: <%= ENV['DATABASE_USER'] || 'esqulino' %>
password: <%= ENV['DATABASE_PASS'] || '' %>
encoding: unicode
development:
<<: *default
database: esqulino_dev
test:
<<: *default
database: esqulino_test
production:
<<: *default
database: esqulino_prod
Example systemd
configuration¶
[Unit]
Description=BlattWerkzeug - Backend Server
After=network.target
# CUSTOMIZE: Optionally add `blattwerkzeug-universal` as a dependency
Wants=postgresql nginx
[Service]
# CUSTOMIZE: Generate a secret using `rake secret`
Environment="SECRET_KEY_BASE=<CUSTOMIZE ME>"
# CUSTOMIZE: Use a dedicated user
User=blattwerkzeug
# CUSTOMIZE: Set the correct path
WorkingDirectory=/srv/htdocs/blattwerkzeug/
ExecStart=/usr/bin/make -C server run
[Install]
WantedBy=multi-user.target
[Unit]
Description=BlattWerkzeug - Universal Rendering Server
After=network.target
[Service]
# CUSTOMIZE: Use a dedicated user
User=blattwerkzeug
# CUSTOMIZE: Set the correct path
WorkingDirectory=/srv/htdocs/blattwerkzeug/
ExecStart=/usr/bin/make -C client universal-run
[Install]
WantedBy=multi-user.target
Example nginx
configuration¶
# The main IDE server
server {
listen 80;
listen 443 ssl http2;
# CUSTOMIZE: Add ssl certificates
# CUSTOMIZE: Change domains and paths
server_name www.blattwerkzeug.de blattwerkzeug.de;
root /srv/htdocs/esqulino.marcusriemer.de/client/dist/browser;
error_log /var/log/nginx/blattwerkzeug.de-error.log error;
access_log /var/log/nginx/blattwerkzeug.de-access.log;
index index.html;
# The most important route: Everything that has the smell of the API
# on it goes to the API server
location /api/ {
proxy_pass http://127.0.0.1:9292;
proxy_set_header Host $host;
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}
# Static assets should be served by nginx, no matter what
location ~* \.(css|js|svg|png)$ {
gzip_static on;
}
# Attempting to hand off requests to the universal rendering
# server, but fail gracefully if no universal rendering is available
location @non_universal_fallback {
try_files $uri /index.html;
gzip_static on;
break;
}
location ~ ^(/$|/about) {
error_page 502 = @non_universal_fallback;
proxy_pass http://127.0.0.1:9291;
proxy_set_header Host $host;
proxy_intercept_errors on;
}
# Everything that ends up here is served by the normal filesystem
location / {
try_files $uri /index.html;
gzip_static on;
}
}
# Rendering projects on subdomains
server {
listen 80;
listen 443 ssl http2;
# CUSTOMIZE: Change domains and paths
server_name *.blattwerkzeug.de *.blattzeug.de;
error_log /var/log/nginx/blattwerkzeug.de-error.log error;
access_log /var/log/nginx/blattwerkzeug.de-access.log;
location / {
proxy_pass http://127.0.0.1:9292;
proxy_set_header Host $host;
}
}