1
0
Fork 0
arcology-elixir/deploying.org

7.8 KiB
Raw Permalink Blame History

Deploying the Arcology

,#+CCE_MODULE: arcology-deploy ,#+CCE_ANSIBLE: arcology-deploy

I have a fair bit of existing automation infrastructure for managing my systems, and I plan to rely heavily on it for Arcology. Right now, it's managed with a simple Dockerfile+systemd service template, but frankly I think I'm not going to enjoy sticking with that. It'll all be templated and weird and hard to reason about, and I intend to make that better over time for now, the design of my new server system is in flux and getting a deployment out is higher priority.

Quickly, for deploying Arcology, these links can be clicked or executed with C-c C-o:

Distillery Config

This is mostly boilerplate generated by mix distillery.init, there is some added to the release to support Runtime Configurable Elements.

use Distillery.Releases.Config,
    default_release: :default,
    default_environment: Mix.env()

environment :prod do
  set include_erts: true
  set include_src: false
  set cookie: :"As1{bTJ;}(>HQZi=@6ln>r<{wG2RZIte(>`:;C:xK(rApd&u^xJ}PnITd{Q3M|W!"
  set vm_args: "rel/vm.args"
end

release :arcology do
  set version: current_version(:arcology)
  set applications: [
    :runtime_tools
  ]
  set config_providers: [
    {Distillery.Releases.Config.Providers.Elixir, ["${RELEASE_ROOT_DIR}/etc/config.exs"]}
  ]
  set overlays: [
    {:copy, "rel/config/config.exs", "etc/config.exs"}
  ]
end

the vm.args file is used to configure the low-level Erlang VM; it's tangled with an eex suffix for mix release to compile. it doesn't do anything right now, but I'm leaving it here for my future's sake.

-smp auto

Distillery Releases

There is this shell script which creates a tarball for the release using Distillery:

set -e

APP_NAME="$(grep 'app:' mix.exs | sed -e 's/\[//g' -e 's/ //g' -e 's/app://' -e 's/[:,]//g')"
APP_VSN="$(grep 'version:' mix.exs | cut -d '"' -f2)"

mkdir -p ./rel/artifacts

# Install updated versions of hex/rebar
mix local.rebar --force
mix local.hex --if-missing --force

export MIX_ENV=prod

# Fetch deps and compile
mix deps.get --only $MIX_ENV
# Run an explicit clean to remove any build artifacts from the host
mix do clean, compile --force
# compile assets
pushd assets; npm run deploy; popd
# Digest assets
mix phx.digest
# Build the release
mix release
# Copy tarball to output
cp "_build/prod/arcology-$APP_VSN.tar.gz" rel/artifacts/"arcology-$APP_VSN.tar.gz"

docker build it

Every solution I try is worse than this so here's a dockerfile. All the build is happening outside the container which i hate but, well, every other solution i try is worse.1

FROM fedora:33
MAINTAINER ryan@whatthefuck.computer

RUN export BUILD_PACKAGES="glibc-common" \ 
    PACKAGES="findutils git pandoc emacs-nox inotify-tools sqlite glibc-langpack-en" && \
    dnf -y update && dnf -y install ${BUILD_PACKAGES} ${PACKAGES} && dnf clean all

ENV LANG=en_US.UTF-8

RUN git clone https://code.rix.si/upstreams/org-roam /opt/org-roam
RUN mkdir /opt/arcology
COPY rel/artifacts/arcology-0.1.1.tar.gz /tmp/arcology.tar.gz
RUN pushd /opt/arcology && tar -xf /tmp/arcology.tar.gz 
RUN dnf erase -y $BUILD_PACKAGES

ENV ARCOLOGY_DIRECTORY=/org
ENV ORG_ROAM_SOURCE=/opt/org-roam
ENV ARCOLOGY_DATABASE=/data/arcology.db
ENV ARCOLOGY_PORT=4000

EXPOSE ${ARCOLOGY_PORT}

CMD bash -c "/opt/arcology/bin/arcology start"

Run docker build.

Deploy the container

run it

playbook

- name: deploy arcology
  hosts: fontkeming.fail
  gather_facts: no

  roles:
  - role: arcology-deploy
    become: yes

tasks:

ansible treats any image wth a slash in the name specially, lmao, whee.

- name: image is pushed
  podman_image:
    name: arcology
    tag: latest
    push: yes
    push_args:
      dest: docker.fontkeming.fail
    auth_file: /run/user/1000/containers/auth.json
  tags:
  - arcology
  - deploy
  # hahaha
  become: no 
  connection: local
  register: push_image
  notify: restart arcology

- name: arcology image pulled
  docker_image:
    source: pull
    tag: latest
    name: docker.fontkeming.fail/arcology
  tags:
  - arcology
  - deploy
  when: push_image.changed
  notify: restart arcology

- name: systemd service template in place
  template:
    src: systemd.service.j2
    dest: /etc/systemd/system/arcology.service
  tags:
  - arcology
  - deploy
  notify: restart arcology
- name: restart arcology
  systemd:
    name: arcology
    state: restarted
    enabled: yes
    daemon_reload: yes

the Systemd unit:

[Unit]
Description=Arcology website engine
After=docker.service

[Service]
Type=simple
ExecStart=/usr/bin/docker run --name arcology -v /srv/files/services/arcology:/arcology:z -v /srv/files/rrix/org/org:/org/:z -e ARCOLOGY_DIRECTORY=/org -e ORG_ROAM_SOURCE=/opt/org-roam -e ARCOLOGY_DATABASE=/arcology/arcology.db -e ARCOLOGY_PORT=5000 -p 127.0.0.1:5000:5000 docker.fontkeming.fail/arcology
ExecStop=/bin/bash -c "/usr/bin/docker stop arcology && /usr/bin/docker rm arcology"

This will run on port 5000. It's really bare-bones, sorry!

nginx frontend is currently outside this system in legacy code on a legacy operating system. more to come below…

Footnotes


1

[2021-02-21] i tried fiddling with nix again trying to get nix-elixir working … wasted a bunch of effort and i am taking a "wait and see" with it. ansible-bender is exiting with some nonsense error and i don't feel like dealing with it! anyways that image was 2gib and didnt cache at all.