LXD workflow for Firefox containers - lmmx/devnotes GitHub Wiki

Some useful aliases I've set up following some of the examples at https://blog.simos.info/using-command-aliases-in-lxd-to-exec-a-shell

The workflow I have in mind goes like this:

  1. launch a new container from a template
  2. drop into a login shell for the newly launched container
  3. start a Firefox process within the container [unconnected to any existing one(s) running in any other running containers]
  • ...surf the web, open a few tabs/windows to be revisited...
  1. snapshot the container state
  2. store this snapshot as a local image
  3. discard (stop and delete) the container instance
  • ...freeing the CPU up from running the container and making it clear (by being an image) that this task is not active...
  1. relaunch the local image as a container instance
  2. (repeat step 2) drop into a login shell...
  3. (repeat step 3) start Firefox...
  • the windows and tabs will be restored from their saved state
  • ...surf the web...
  1. either:
  • if unfinished (loop back to step 4) publish a snapshot image locally again
  • else if finished (repeat step 6) discard [stop and delete] the container instance
  1. delete the outdated image (which was relaunched in step 7)
lxc kindle ffx-mysesh # 1: launch a new container from the template
lxc login ffx-mysesh # 2: drop into a login shell for the newly launched container
firefox -no-remote & # 3

# ...surfing the web until finished for this session

lxc snapshot ffx-mysesh paused # 4: snapshot the container state
lxc publish ffx-mysesh/paused --alias my_stored_sesh # 5: store the snapshot as a local image
lxc delete -f ffx-mysesh # stop and delete # 6: discard (stop and delete) the container instance

# ... some time passes until I want to revisit the session
lxc launch my_stored_sesh --profile default --profile x11 --profile pa ffx-mysesh # 7: relaunch
lxc login ffx-mysesh # 8: (repeat step 2) drop into a login shell for the restored container
firefox -no-remote & # 9

# then IF UNFINISHED: loop back to step 4
lxc snapshot ffx-mysesh paused2 # 10a: (4 rep) 
lxc publish ffx-mysesh/paused2 --alias my_stored_sesh2 # 10b: (5 rep) store snapshot as local image

# else IF FINISHED: (repeat step 6) discard (stop and delete) the container instance
lxc delete -f ffx-mysesh

# but either way delete the outdated image (which was relaunched in step 7)
lxc image delete my_stored_sesh # 11: delete the outdated image
  • N.B. only images can have underscores in their names, containers can't

The only downside is that since aliases take all arguments (as @ARGS@) the final command cannot be simplified using an alias, because the container being launched (e.g. my_stored_sesh) is not adjacent in the command to the name being assigned to the newly launched container (e.g. ffx-mysesh)


Motivation

In brief: ‘containerised microtasking’ —- imagine you have a little thought and quickly spin up a container, “sprint” on it with full focus, spin down to an image on disk, then when you come back to it you get full focus back (no attempting to hold onto it)

While it requires more careful usage than simply (lazily) opening a new window, this effort is motivated by a number of benefits obtained in this way, and avoiding risks/harms:

  • Tabs do not "cross talk", which enforces 'separation of concerns'.
    • If you need to find a tab based on its contents then you likely do not have a good spatial mental map of your workspaces, and they should be organised by task (naming the Cinnamon desktops by task).
  • When restored, tabs will have only the history available to that session and its predecessor(s), which gives a convenient accessibility of that small domain of work. E.g. the address bar will more likely autofill to recently viewed pages, and there will be less 'clutter'/irrelevant visual distraction
  • Browsers will not by default have all the logins, which can interrupt thoughtless "wandering" onto social media when trying to mono-focus on a task (as will likely be the case when a new task has been carried out specifically in a container).
  • Not the primary reason but not without importance either: privacy. No cookies are shared between browsers and if any are stored in an image long term, then they may expire by the time the image is relaunched.
  • A README can be placed in the container, which the browser will have access to along with the gnome-terminal.
  • A tmux session can be run, and [TODO] restored similarly to the browser
    • tmux-continuum is explicitly suited to this use case
  • Both tmux and X windows can be managed by pyx-sys.
    • Since each Firefox process is distinct to the task/workspace, it will now be possible to manage these processes and the window(s) they control under the pyx-sys X session window manager
    • This is particularly nice as it suggests even uncontainerised applications (e.g. terminals on the host) can be managed as a unit alongside browser windows
    • Since it is possible to extract the LZ4-compressed JSON sessionstore-backups recovery.json containing the session windows/tabs, it would even be possible to maintain an index of the sites in a given session with a satisfying granularity to a particular task

The main risk/harms avoided in this way are:

  • Single point of failure (one big beastly process)
  • Mental ‘clump’ of browser rather than distinct (individually named!) sessions

The main disadvantages:

  • It not being ‘natural’ (it will become more so with time/practice)
  • Not having access to the host filesystem as simply from within the container but this can be worked around

The two lxc aliases which can be made to assist [and used in the code demo above] are:

  • kindle
  • login

These are documented below.

kindle

lxc alias add kindle 'launch ffx_template --profile default --profile x11 --profile pa'
  • Usage: lxc kindle ffx4
    • Initiates a Firefox-capable Ubuntu container named ffx4

login

lxc alias add login 'exec @ARGS@ -- sudo --user ubuntu --login'

Usage:

lxc login ffx4