fly
-ing huginn
close to the groundkonami are remaking MGS3. some people are trying to sell electric ekranoplans. and here i am being a freeloader nerd for the 2nd decade. ingredients:
i use its agent to crawl comic/blogs' syndication feeds, then reformat & augment them to read easily in feedme. The comics update at most daily (SMBC has been running since 2002), or thrice-weekly (Ryan North's dinosaurs have been talkin' since 2003 (lovingly crafted in XP's MS Paint). and the blogs update less frequently than that. there's no need to keep huginn web-part running 24/7, and we can also reduce the scheduler wake-up frequency.
flyctl
on MediaTek ramips mt7621it's a softfloat Little-Endian MIPS cpu, we'll build flyctl
like this:
scalar clone http://github.com/superfly/flyctl
cd flyctl/src
git sparse-checkout disable
env GOARCH=mipsle GOMIPS=softfloat make build
gzip bin/flyctl
# deliver flyctl.gz to the mips
on sentry, SMBC will have a daily check-in schedule. Dinosaur Comics posts on Mon-Wed-Fri, accounting for TZ & scheduling delay, we'll have a Tue-Thu-Sat check-in regimen. both will allow some further ~2h slack time. the monitoring slugs are readable text now, not UUIDv4 anymore. but that's guessable. along with the project's SENTRY_DSN
and quickstart for rails, we're good to go.
on glitchtip, set up a 86399-second interval uptime heartbeat (they don't accept >=86400s). we'll use the URL later.
we start simple with the supervisord
-based image. that'd keep a 1GB fly machine running all the time.
Fly people use docker images as a packaging format, they define the
environment around that. here, we bake in postgresql and the sentry
SDK gems. remember to load stackprof
first:
mkdir hug
cd hug
echo -e '.dockerignore\nDockerfile\nfly.toml\nhug-db.toml\nsentry.rb' | tee .dockerignore
tee Dockerfile <<-EOD
FROM ghcr.io/huginn/huginn:cbeb5c293ec3394dcd202b132b80e14398da8a11
ENV ADDITIONAL_GEMS=stackprof,sentry-ruby,sentry-rails
RUN APP_SECRET_TOKEN=nbd DATABASE_ADAPTER=postgresql bundle install -j 4
# we tune this often
COPY sentry.rb /app/config/initializers/sentry.rb
EOD
tee sentry.rb <<-EOR
Sentry.init do |config|
config.breadcrumbs_logger = [:active_support_logger, :http_logger]
config.traces_sample_rate = 0.5
config.profiles_sample_rate = 1.0
end
EOR
generate random for APP_SECRET_TOKEN
:
podman run --rm -it --entrypoint sh ghcr.io/huginn/huginn:cbeb5c293ec3394dcd202b132b80e14398da8a11 rake secret
Build initial fly config, along with a managed postgres:
flyctl launch \
--org personal \
--name hug \
--region fra \
--push \
--vm-cpukind shared \
--vm-cpus 1 \
--vm-memory 1024
for the postgres, you can use development, 256MB, auto scale to zero (default after 1h, but you can be more aggressive/conservative). let's write down its config file here too:
flyctl config save \
--app hug-db \
--config hug-db.toml
and it's a good idea to save the running postgres image for later use:
flyctl image show -a hug-db
load some more secrets into the app:
flyctl secrets import <<-EOS
SENTRY_DSN=your_dsn
APP_SECRET_TOKEN=your_random
INVITATION_CODE=your_knock_password
EOS
and put more app config
tee -a fly.toml <<-EOT
[[statics]]
guest_path = "/app/public"
url_prefix = "/public"
[env]
RAILS_SERVE_STATIC_FILES="false"
TIMEZONE="Hanoi"
TZ="Asia/Phnom_Penh"
DOMAIN="hug.fly.dev"
FORCE_SSL="true"
DATABASE_ADAPTER="postgresql"
RACK_ENV="production"
RAILS_LOG_TO_STDOUT="enabled"
DO_NOT_SEED="true"
IMPORT_DEFAULT_SCENARIO_FOR_ALL_USERS="true"
AGENT_LOG_LENGTH="10" # used to fit heroku 10_000 rows limit
SCHEDULER_FREQUENCY="5"
DELAYED_JOB_SLEEP_DELAY="900" # s
USE_GRAPHVIZ_DOT="dot"
DIAGRAM_DEFAULT_LAYOUT="neato"
EOT
now you try to flyctl launch
it, see the resulting 2.0GB image starts on fly regino fra
if you get context deadline exceeded for build, try wesockets mode
flyctl wg websockets enable
to attach in for debugging
flyctl ssh console -s
in there, multi-process img has pstree
to view supervisor's tree
and tail the logs
flyctl logs
here, you can open the public URL, and create an account with the invitation code. there's no admin
account because we didn't run SEED job. huginn will have created sample agents for you, explore them for idea
The current vm resource is
flyctl machine show
Inside the one machine for app
process group, there's supervisord, then foreman, managing an unicorn web.1
(master + 2workers), and the rufus scheduler jobs.1
task. the unicorn is only useful when i open the site, or inoreader comes to fetch the feed. rufus should be running all the time, to execute scheduled tasks (agents, events propagation, and cleanups). Let's split out app
to web
and jobs
, then we can let web autostop/start according to load.