<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/atom.xsl" type="text/xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Posts tagged: litestream</title>
  <id>https://pype.dev/tags/litestream/atom.xml</id>
  <updated>2025-08-07T15:14:45Z</updated>
  <subtitle>All posts with the tag &#34;litestream&#34;</subtitle>
  <link href="https://pype.dev/tags/litestream/" rel="alternate" type="text/html"></link>
  <link href="https://pype.dev/tags/litestream/atom.xml" rel="self" type="application/atom+xml"></link>
  <author>
    <name>Nic Payne</name>
  </author>
  <generator uri="https://github.com/WaylonWalker/markata-go">markata-go</generator>
  <entry>
    <title>Using Litestream to Restore My Database for Easy Development</title>
    <id>https://pype.dev/using-litestream-to-restore-my-database-for-easy-development/</id>
    <updated>2025-08-07T15:14:45Z</updated>
    <published>2025-08-07T15:14:45Z</published>
    <link href="https://pype.dev/using-litestream-to-restore-my-database-for-easy-development/" rel="alternate" type="text/html"></link>
    <summary type="text">see using-litestream-to-backup-quadtasks-sqlite-db for how I setup litestream replication for quadtask</summary>
    <content type="html">&lt;h1 id=&#34;litestream&#34;&gt;&lt;span class=&#34;heading-wear-glyph&#34;&gt;&lt;a href=&#34;/litestream/&#34; class=&#34;glossary-term&#34; title=&#34;Litestream is a simple way to replicate SQLite databases&#34; data-hover-title=&#34;Litestream&#34;&gt;Litestream&lt;/a&gt;&lt;/span&gt;&lt;/h1&gt;&#xA;&lt;p&gt;see &lt;a href=&#34;/using-litestream-to-backup-quadtasks-sqlite-db/&#34; class=&#34;wikilink&#34; data-title=&#34;Using Litestream to Backup QuadTask&amp;#39;s SQLite DB&#34; data-description=&#34;This post will be a walkthrough of installing litestream in a docker container that runs my FastAPI app in order to replicate the sqlite db in the data...&#34; data-date=&#34;2025-08-05&#34; data-preview=&#34;This post will be a walkthrough of installing litestream in a docker container that runs my FastAPI app in order to replicate the sqlite db in the data...&#34;&gt;Using Litestream to Backup QuadTask&#39;s SQLite DB&lt;/a&gt; for how I setup litestream replication for &lt;a href=&#34;/quadtask/&#34; class=&#34;wikilink&#34; data-title=&#34;QuadTask&#34; data-description=&#34;Eisenhower Matrix based task manager&#34; data-date=&#34;2025-06-13&#34; data-preview=&#34;Eisenhower Matrix based task manager&#34;&gt;QuadTask&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;I have the entrypoint to my app container check if the sqlite database exists&#xA;or not - in production or with local volume mounts, it will and then we start&#xA;litestream replication and then the app like normal. But what&amp;rsquo;s awesome about&#xA;this little trick I got from &lt;a href=&#34;https://github.com/benbjohnson/litestream-docker-example/tree/main&#34;&gt;this litestream&#xA;example&lt;/a&gt; is&#xA;I can &lt;a href=&#34;/docker/&#34; class=&#34;glossary-term&#34; title=&#34;docker - container runtime&#34; data-hover-title=&#34;docker&#34;&gt;docker&lt;/a&gt; compose up locally without the data directory volume mounted in,&#xA;and get a fresh copy of my production data right there locally to work with!&lt;/p&gt;&#xA;&lt;p&gt;My entrypoint script now looks like:&lt;/p&gt;&#xA;&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#!/bin/bash&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Exit on error, undefined vars, and fail on pipe errors&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt; -euo pipefail&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Restore the database if it does not already exist.&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt; -f /app/data/quadtask.db &lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Database already exists, skipping restore&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;No database found, restoring from replica if exists&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; litestream restore -v /app/data/quadtask.db&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Run litestream with your app as the subprocess.&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;exec&lt;/span&gt; litestream replicate -exec &lt;span class=&#34;s2&#34;&gt;&amp;#34;uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload --log-level debug&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;appropriate-and-safe-replication&#34;&gt;&lt;span class=&#34;heading-wear-glyph&#34;&gt;Appropriate and Safe Replication&lt;/span&gt; &lt;a href=&#34;#appropriate-and-safe-replication&#34; class=&#34;heading-anchor&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;The way to get prod data in automatically is to restore from the production&#xA;backup but I don&amp;rsquo;t want to replicate to the production backup with my local&#xA;work, so it&amp;rsquo;s not the best but I have a manual step that makes it pretty easy&lt;/p&gt;&#xA;&lt;p&gt;I first &lt;code&gt;just sync-db&lt;/code&gt;&lt;/p&gt;&#xA;&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Sync production database locally&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sync-db:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    fly ssh console -a quadtask -C &lt;span class=&#34;s1&#34;&gt;&amp;#39;cat /app/data/quadtask.db&amp;#39;&lt;/span&gt; &amp;gt; ./litestream/source/quadtask-prod.db&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and this brings my database down to a folder I maintain locally.&lt;/p&gt;&#xA;&lt;p&gt;I have litestream installed on my desktop obviously, and here&amp;rsquo;s the relevant litestream configuration I use:&lt;/p&gt;&#xA;&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;dbs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;/home/nic/projects/personal/quadtask/litestream/source/quadtask-prod.db&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;replicas&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;quadtask-prod&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;s3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;bucket&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;litestream&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;quadtask-local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;endpoint&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;s3.example.com&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;skip-verify&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;region&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;us-east-1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;So on my desktop if I &lt;code&gt;litestream replicate&lt;/code&gt; then basically I&amp;rsquo;m taking the&#xA;output of &lt;code&gt;just synd-db&lt;/code&gt; and replicating to my litestream bucket to the&#xA;&lt;code&gt;quadtask-local&lt;/code&gt; path.&lt;/p&gt;&#xA;&lt;p&gt;Then I start up my app, it restores from that point and I&amp;rsquo;m working with fresh&#xA;prod data!&lt;/p&gt;&#xA;&lt;h2 id=&#34;how-to-handle-environments&#34;&gt;&lt;span class=&#34;heading-wear-glyph&#34;&gt;How To Handle Environments?&lt;/span&gt; &lt;a href=&#34;#how-to-handle-environments&#34; class=&#34;heading-anchor&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;I have this working for different environments too, with a little bit of&#xA;process but basically thanks to &lt;a href=&#34;https://litestream.io/reference/config/#variable-expansion&#34;&gt;litestream expanding env&#xA;vars&lt;/a&gt; in the config&#xA;we can do something like this:&lt;/p&gt;&#xA;&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;dbs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;/app/data/quadtask.db&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;replicas&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;quadtask&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;s3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;bucket&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;litestream&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;quadtask-${ENVIRONMENT}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;endpoint&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;s3.example.com&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;skip-verify&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;region&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;us-east-1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And so wherever I spin up quadtask: local, dev, or prod - the replication will&#xA;happen to and from a different path in my litestream bucket!&lt;/p&gt;&#xA;&lt;h1 id=&#34;update&#34;&gt;&lt;span class=&#34;heading-wear-glyph&#34;&gt;Update&lt;/span&gt;&lt;/h1&gt;&#xA;&lt;p&gt;I updated the &lt;code&gt;docker-entrypoint.sh&lt;/code&gt; of my quadtask container to look like this now:&lt;/p&gt;&#xA;&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Restore the database if it does not already exist.&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt; -f /app/data/quadtask.db &lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Database already exists, skipping restore&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;No database found, restoring from replica&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;nv&#34;&gt;ENVIRONMENT&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;prod&amp;#34;&lt;/span&gt; litestream restore -v /app/data/quadtask.db&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Run litestream with your app as the subprocess.&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;exec&lt;/span&gt; litestream replicate -exec &lt;span class=&#34;s2&#34;&gt;&amp;#34;uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload --log-level debug&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;if&lt;/code&gt; block checks if there&amp;rsquo;s a db at the filepath it should be in in the continer - if it&amp;rsquo;s not there is the little bit of magic to me right now&amp;hellip;&lt;/p&gt;&#xA;&lt;p&gt;My litestream config has a parameterized &lt;code&gt;ENVIRONMENT&lt;/code&gt; variable in the db path,&#xA;so by overwritting it for just the &lt;code&gt;restore&lt;/code&gt; command, I can very simply always&#xA;pull a fresh copy of the prod database into an ephemeral container to test&#xA;things against real data in a very convenient way&lt;/p&gt;&#xA;</content>
    <author>
      <name>Nic Payne</name>
      <uri>https://pype.dev</uri>
    </author>
  </entry>
  <entry>
    <title>Using Litestream to Backup QuadTask’s SQLite DB</title>
    <id>https://pype.dev/using-litestream-to-backup-quadtasks-sqlite-db/</id>
    <updated>2025-08-05T19:34:19Z</updated>
    <published>2025-08-05T19:34:19Z</published>
    <link href="https://pype.dev/using-litestream-to-backup-quadtasks-sqlite-db/" rel="alternate" type="text/html"></link>
    <summary type="text">This post will be a walkthrough of installing litestream in a docker container that runs my FastAPI app in order to replicate the sqlite db in the data...</summary>
    <content type="html">&lt;h1 id=&#34;litestream&#34;&gt;&lt;span class=&#34;heading-wear-glyph&#34;&gt;&lt;a href=&#34;/litestream/&#34; class=&#34;glossary-term&#34; title=&#34;Litestream is a simple way to replicate SQLite databases&#34; data-hover-title=&#34;Litestream&#34;&gt;Litestream&lt;/a&gt;&lt;/span&gt;&lt;/h1&gt;&#xA;&lt;p&gt;This post will be a walkthrough of installing &lt;a href=&#34;/litestream/&#34; class=&#34;wikilink&#34; data-title=&#34;Litestream&#34; data-description=&#34;Litestream is a simple way to replicate SQLite databases&#34; data-date=&#34;2025-08-05&#34; data-preview=&#34;Litestream is a simple way to replicate SQLite databases&#34;&gt;Litestream&lt;/a&gt; in a &lt;a href=&#34;/docker/&#34; class=&#34;glossary-term&#34; title=&#34;docker - container runtime&#34; data-hover-title=&#34;docker&#34;&gt;docker&lt;/a&gt; container&#xA;that runs my FastAPI app in order to replicate the sqlite db in the data volume&#xA;currently hosted in Fly&amp;rsquo;s volume manager to my MinIO instance. From there, on&#xA;my development machine I can use litestream to restore the prod database to my&#xA;dev environment to practice whatever I may need to practice with real&#xA;production data!&lt;/p&gt;&#xA;&lt;h2 id=&#34;dockerfile&#34;&gt;&lt;span class=&#34;heading-wear-glyph&#34;&gt;Dockerfile&lt;/span&gt; &lt;a href=&#34;#dockerfile&#34; class=&#34;heading-anchor&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;Installing litestream in the dockerfile is 2-3 lines of code - no sweat. Configuration file is further down the post.&lt;/p&gt;&#xA;&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;python:3.11-slim&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;WORKDIR&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;/app&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;# Install uv&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;COPY&lt;/span&gt; --from&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;ghcr.io/astral-sh/uv:latest /uv /uvx /bin/&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;# Install litestream&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;ADD&lt;/span&gt; https://github.com/benbjohnson/litestream/releases/download/v0.3.8/litestream-v0.3.8-linux-amd64-static.tar.gz /tmp/litestream.tar.gz&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;RUN&lt;/span&gt; tar -C /usr/local/bin -xzf /tmp/litestream.tar.gz&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;COPY&lt;/span&gt; etc/litestream.yml /etc/litestream.yml&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;# Install dependencies&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;COPY&lt;/span&gt; requirements.txt .&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;RUN&lt;/span&gt; uv pip install --no-cache -r requirements.txt&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;# Copy the rest of the application&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;COPY&lt;/span&gt; . .&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;# Install the app package in development mode&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;RUN&lt;/span&gt; uv pip install -e .&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;# Run the application&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;CMD&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;docker-entrypoint.sh&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;litestream-configuration&#34;&gt;&lt;span class=&#34;heading-wear-glyph&#34;&gt;Litestream Configuration&lt;/span&gt; &lt;a href=&#34;#litestream-configuration&#34; class=&#34;heading-anchor&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;Taking care to set &lt;code&gt;ENVIRONMENT&lt;/code&gt; appropriately in each environment, the&#xA;litestream configuration gets that env var templated out to the path for the&#xA;litestream target. See &lt;a href=&#34;https://litestream.io/reference/config/#variable-expansion&#34;&gt;docs&lt;/a&gt;&lt;/p&gt;&#xA;&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;#/etc/litestream.yml&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;dbs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- &lt;span class=&#34;nt&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;/app/data/quadtask.db&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;replicas&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;quadtask&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;s3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;bucket&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;litestream&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;quadtask-${ENVIRONMENT}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;endpoint&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;s3.example.com&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;skip-verify&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;region&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;us-east-1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;authentication&#34;&gt;&lt;span class=&#34;heading-wear-glyph&#34;&gt;Authentication&lt;/span&gt; &lt;a href=&#34;#authentication&#34; class=&#34;heading-anchor&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;In your docker container you&amp;rsquo;ll need to set &lt;code&gt;LITESTREAM_ACCESS_KEY_ID&lt;/code&gt; and&#xA;&lt;code&gt;LITESTREAM_SECRET_ACCESS_KEY&lt;/code&gt; which you setup in Minio - see&#xA;&lt;a href=&#34;/setup-remote-minio-s3-backend-target-for-litestream/&#34; class=&#34;wikilink&#34; data-title=&#34;Setup Remote MinIO S3 Backend Target for Litestream&#34; data-description=&#34;I am starting to think through some patterns for replicating sqlite databases, exploring them, standardizing on schemas/models I use across projects, etc......&#34; data-date=&#34;2025-08-05&#34; data-preview=&#34;I am starting to think through some patterns for replicating sqlite databases, exploring them, standardizing on schemas/models I use across projects, etc......&#34;&gt;Setup Remote MinIO S3 Backend Target for Litestream&lt;/a&gt;. I have these set as&#xA;secrets in my fly configuration, and locally in a .env file that gets sourced&#xA;with my compose stack&lt;/p&gt;&#xA;&lt;h2 id=&#34;example-log-from-dev&#34;&gt;&lt;span class=&#34;heading-wear-glyph&#34;&gt;Example Log from Dev&lt;/span&gt; &lt;a href=&#34;#example-log-from-dev&#34; class=&#34;heading-anchor&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;My fly dev machine has this log message showing the &lt;code&gt;ENVIRONMENT&lt;/code&gt; var &lt;code&gt;dev&lt;/code&gt; gets expanded into the config so the s3 path includes &lt;code&gt;quadtask-dev&lt;/code&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;replicating to: name=&amp;quot;quadtask&amp;quot; type=&amp;quot;s3&amp;quot; bucket=&amp;quot;litestream&amp;quot; path=&amp;quot;quadtask-dev&amp;quot; region=&amp;quot;us-east-1&amp;quot; endpoint=&amp;quot;s3.&amp;lt;redacted&amp;gt;.com&amp;quot; sync-interval=1s&lt;/code&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;example-usage-for-local-development&#34;&gt;&lt;span class=&#34;heading-wear-glyph&#34;&gt;Example Usage for Local Development&lt;/span&gt; &lt;a href=&#34;#example-usage-for-local-development&#34; class=&#34;heading-anchor&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;/using-litestream-to-restore-my-database-for-easy-development/&#34; class=&#34;wikilink&#34; data-title=&#34;Using Litestream to Restore My Database for Easy Development&#34; data-description=&#34;see using-litestream-to-backup-quadtasks-sqlite-db for how I setup litestream replication for quadtask&#34; data-date=&#34;2025-08-07&#34; data-preview=&#34;see using-litestream-to-backup-quadtasks-sqlite-db for how I setup litestream replication for quadtask&#34;&gt;Using Litestream to Restore My Database for Easy Development&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;</content>
    <author>
      <name>Nic Payne</name>
      <uri>https://pype.dev</uri>
    </author>
  </entry>
  <entry>
    <title>Setup Remote MinIO S3 Backend Target for Litestream</title>
    <id>https://pype.dev/setup-remote-minio-s3-backend-target-for-litestream/</id>
    <updated>2025-08-05T08:39:16Z</updated>
    <published>2025-08-05T08:39:16Z</published>
    <link href="https://pype.dev/setup-remote-minio-s3-backend-target-for-litestream/" rel="alternate" type="text/html"></link>
    <summary type="text">I am starting to think through some patterns for replicating sqlite databases, exploring them, standardizing on schemas/models I use across projects, etc......</summary>
    <content type="html">&lt;h2 id=&#34;intro&#34;&gt;&lt;span class=&#34;heading-wear-glyph&#34;&gt;Intro&lt;/span&gt; &lt;a href=&#34;#intro&#34; class=&#34;heading-anchor&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;I am starting to think through some patterns for replicating sqlite databases,&#xA;exploring them, standardizing on schemas/models I use across projects, etc&amp;hellip;&#xA;Thanks to &lt;a href=&#34;https://waylonwalker.com&#34;&gt;Waylon&lt;/a&gt; I know about &lt;a href=&#34;/litestream/&#34; class=&#34;wikilink&#34; data-title=&#34;Litestream&#34; data-description=&#34;Litestream is a simple way to replicate SQLite databases&#34; data-date=&#34;2025-08-05&#34; data-preview=&#34;Litestream is a simple way to replicate SQLite databases&#34;&gt;Litestream&lt;/a&gt; and&#xA;finally I started playing with it. Their&#xA;&lt;a href=&#34;https://litestream.io/getting-started/&#34;&gt;quickstart&lt;/a&gt; is good, but it assumes&#xA;you&amp;rsquo;ll run MinIO on the same machine you run &lt;a href=&#34;/litestream/&#34; class=&#34;glossary-term&#34; title=&#34;Litestream is a simple way to replicate SQLite databases&#34; data-hover-title=&#34;Litestream&#34;&gt;litestream&lt;/a&gt; on.&lt;/p&gt;&#xA;&lt;p&gt;I, however, have MinIO setup in my homelab with the api endpoint accessible via&#xA;DNS - &lt;code&gt;s3.mydomain.com&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Before starting - I realize I left the credential aspect out - Litestream&#xA;explains how to setup API keys in MinIO for their application&#xA;&lt;a href=&#34;https://litestream.io/getting-started/#setting-up-minio&#34;&gt;here&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;Basically after generating the keys I set &lt;code&gt;LITESTREAM_ACCESS_KEY_ID&lt;/code&gt; and &lt;code&gt;LITESTREAM_SECRET_ACCESS_KEY&lt;/code&gt; as env vars&lt;/p&gt;&#xA;&lt;p&gt;So let&amp;rsquo;s see what happens and then get to [the fix]&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;⬢ [devbox] ❯ litestream replicate quadtask-prod.db s3://s3.example.com/litestream/qt.db    &#xA;2025/08/05 08:50:09 INFO litestream version=v0.3.13&#xA;2025/08/05 08:50:09 INFO initialized db path=/home/nic/projects/personal/quadtask/litestream/source/quadtask-prod.db&#xA;2025/08/05 08:50:09 INFO replicating to name=s3 type=s3 sync-interval=1s bucket=s3.example.com path=litestream/qt.db region=&amp;quot;&amp;quot; endpoint=&amp;quot;&amp;quot;&#xA;2025/08/05 08:50:10 INFO sync: new generation db=/home/nic/projects/personal/quadtask/litestream/source/quadtask-prod.db generation=209692854ccd85d5 reason=&amp;quot;no generation exists&amp;quot;&#xA;2025/08/05 08:50:10 ERROR monitor error db=/home/nic/projects/personal/quadtask/litestream/source/quadtask-prod.db replica=s3 error=&amp;quot;cannot lookup bucket region: InvalidAccessKeyId: The AWS Access Key Id you provided does not exist in our records.\n\tstatus code: 403, request id: ERHZD4RD61Y8ADMD, host id: dOjPn5j8Oa+mkwOqROXDvCdKNxzxG0B8JJOPtGXDZA7qKxwAWqaSXhGYzK2mkoJQV7hJhaoJcag=&amp;quot;&#xA;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;So that &lt;code&gt;403&lt;/code&gt; is pretty simple&amp;hellip; my login is wrong&amp;hellip; but wait&amp;hellip;&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;2025/08/05 08:50:09 INFO replicating to name=s3 type=s3 sync-interval=1s bucket=s3.example.com path=litestream/qt.db region=&amp;quot;&amp;quot; endpoint=&amp;quot;&amp;quot;&lt;/code&gt;&lt;/p&gt;&#xA;&lt;p&gt;Notice this line - &lt;code&gt;endpoint=&amp;quot;&amp;quot;&lt;/code&gt;&amp;hellip; so &lt;code&gt;s3://s3.example.com&lt;/code&gt; was not the right replacement for &lt;code&gt;s3://mybkt.localhost:9000/target.db&lt;/code&gt;. Also the inferred &lt;code&gt;bucket&lt;/code&gt; is the entire &lt;code&gt;s3.example.com&lt;/code&gt;&amp;hellip;&lt;/p&gt;&#xA;&lt;p&gt;Oh! Well I didn&amp;rsquo;t specify a bucket in the subdomain - I did it with a route on the URL&amp;hellip;&lt;/p&gt;&#xA;&lt;p&gt;ok let&amp;rsquo;s try &lt;code&gt;litestream replicate quadtask-prod.db s3://litestream.example.com/qt.db&lt;/code&gt;&lt;/p&gt;&#xA;&lt;p&gt;We got the same &lt;a href=&#34;/kind/&#34; class=&#34;glossary-term&#34; title=&#34;kind - kubernetes in docker&#34; data-hover-title=&#34;kind&#34;&gt;kind&lt;/a&gt; of error&amp;hellip;&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;2025/08/05 08:53:45 INFO replicating to name=s3 type=s3 sync-interval=1s bucket=litestream.example.com path=qt.db region=&amp;quot;&amp;quot; endpoint=&amp;quot;&amp;quot;&lt;/code&gt;&lt;/p&gt;&#xA;&lt;p&gt;This time the inferred bucket was &lt;code&gt;litestream.example.com&lt;/code&gt;&amp;hellip; ok that&amp;rsquo;s consistent with above as well - so the endpoint is still wrong/null and the bucket inference is wrong&amp;hellip;&lt;/p&gt;&#xA;&lt;p&gt;Turns out for Litestream, and probably many other tools that use s3-compatible storage, that there&amp;rsquo;s an inference problem if the configuration leans on the shorthand &lt;code&gt;s3://&lt;/code&gt; - &lt;a href=&#34;https://github.com/benbjohnson/litestream/issues/398&#34;&gt;see this GitHub issue&lt;/a&gt; and &lt;a href=&#34;https://github.com/benbjohnson/litestream/issues/219&#34;&gt;this one about localhost&lt;/a&gt;. There&amp;rsquo;s a few options for using your own &lt;code&gt;s3.mydomain.example&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-fix&#34;&gt;&lt;span class=&#34;heading-wear-glyph&#34;&gt;The Fix&lt;/span&gt; &lt;a href=&#34;#the-fix&#34; class=&#34;heading-anchor&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;If you&amp;rsquo;re familiar with the &lt;code&gt;awscli&lt;/code&gt; then maybe you&amp;rsquo;ve heard of a config option &lt;code&gt;AWS_S3_ENDPOINT_URL&lt;/code&gt; which allows you to use the boto sdk with s3-compatibile resources while still using the &lt;code&gt;s3://&lt;/code&gt; shorthand. Litestream has a way to set this configuration right on config:&lt;/p&gt;&#xA;&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;dbs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;/home/nic/projects/personal/quadtask/litestream/source/quadtask-prod.db&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;replicas&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;s3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;bucket&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;litestream&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;endpoint&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;s3.example.com &lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# &amp;lt;---- right here!&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;skip-verify&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# set to false if you have TLS and want more security&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# note you acn set these sensitive values as env vars per the Litestream Quickstart&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# access-key-id: &amp;lt;ACCESS-KEY-ID&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# secret-access-key: &amp;lt;SECRET-ACCESS-KEY&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;details class=&#34;admonition danger&#34; open&gt;&#xA;&lt;summary class=&#34;admonition-title&#34;&gt;UPDATE&lt;/summary&gt;&#xA;&lt;p&gt;I added a &lt;code&gt;path&lt;/code&gt; key to give the backups a folder basically on s3, so under &amp;ldquo;bucket: listream&amp;rdquo; I have &amp;ldquo;path: &lt;my desired path&gt;&amp;rdquo;&lt;/p&gt;&#xA;&lt;/details&gt;&#xA;&lt;p&gt;So with that config in place we can actually JUST &lt;code&gt;litestream replicate&lt;/code&gt; from anywhere&amp;hellip;&lt;/p&gt;&#xA;&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;⬢ &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;devbox&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; ❯ litestream replicate                                                      &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;2025-08-05T08:56:11.353-05:00 &lt;span class=&#34;nv&#34;&gt;level&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;INFO &lt;span class=&#34;nv&#34;&gt;msg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;litestream &lt;span class=&#34;nv&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;v0.3.13&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;2025-08-05T08:56:11.353-05:00 &lt;span class=&#34;nv&#34;&gt;level&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;INFO &lt;span class=&#34;nv&#34;&gt;msg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;initialized db&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/home/nic/projects/personal/quadtask/litestream/source/quadtask-prod.db&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;2025-08-05T08:56:11.353-05:00 &lt;span class=&#34;nv&#34;&gt;level&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;INFO &lt;span class=&#34;nv&#34;&gt;msg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;replicating to&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;s3 &lt;span class=&#34;nv&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;s3 sync-interval&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;1s &lt;span class=&#34;nv&#34;&gt;bucket&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;litestream &lt;span class=&#34;nv&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;region&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;endpoint&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;s3.example.com&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;2025-08-05T08:56:12.399-05:00 &lt;span class=&#34;nv&#34;&gt;level&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;INFO &lt;span class=&#34;nv&#34;&gt;msg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;write snapshot&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;db&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/home/nic/projects/personal/quadtask/litestream/source/quadtask-prod.db &lt;span class=&#34;nv&#34;&gt;replica&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;s3 &lt;span class=&#34;nv&#34;&gt;position&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;209692854ccd85d5/00000000:4152&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;2025-08-05T08:56:12.489-05:00 &lt;span class=&#34;nv&#34;&gt;level&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;INFO &lt;span class=&#34;nv&#34;&gt;msg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;snapshot written&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;db&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/home/nic/projects/personal/quadtask/litestream/source/quadtask-prod.db &lt;span class=&#34;nv&#34;&gt;replica&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;s3 &lt;span class=&#34;nv&#34;&gt;position&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;209692854ccd85d5/00000000:4152 &lt;span class=&#34;nv&#34;&gt;elapsed&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;89.994626ms &lt;span class=&#34;nv&#34;&gt;sz&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;909437&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;2025-08-05T08:56:12.492-05:00 &lt;span class=&#34;nv&#34;&gt;level&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;INFO &lt;span class=&#34;nv&#34;&gt;msg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;write wal segment&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;db&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/home/nic/projects/personal/quadtask/litestream/source/quadtask-prod.db &lt;span class=&#34;nv&#34;&gt;replica&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;s3 &lt;span class=&#34;nv&#34;&gt;position&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;209692854ccd85d5/00000000:0&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;2025-08-05T08:56:12.510-05:00 &lt;span class=&#34;nv&#34;&gt;level&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;INFO &lt;span class=&#34;nv&#34;&gt;msg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;wal segment written&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;db&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/home/nic/projects/personal/quadtask/litestream/source/quadtask-prod.db &lt;span class=&#34;nv&#34;&gt;replica&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;s3 &lt;span class=&#34;nv&#34;&gt;position&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;209692854ccd85d5/00000000:0 &lt;span class=&#34;nv&#34;&gt;elapsed&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;17.572784ms &lt;span class=&#34;nv&#34;&gt;sz&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;4152&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&#34;admonition success&#34;&gt;&#xA;&lt;p class=&#34;admonition-title&#34;&gt;It works!&lt;/p&gt;&#xA;&lt;p&gt;Notice that the endpoint is properly s3.example.com, and the bucket is litestream (the name of my taret bucket in MinIO)&lt;/p&gt;&#xA;&lt;/div&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;You can use a local config with &lt;code&gt;-c config.yaml&lt;/code&gt; or something if you want to avoid the global &lt;code&gt;/etc/litestream.yml&lt;/code&gt;&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;h2 id=&#34;what-about-restore&#34;&gt;&lt;span class=&#34;heading-wear-glyph&#34;&gt;What About Restore?&lt;/span&gt; &lt;a href=&#34;#what-about-restore&#34; class=&#34;heading-anchor&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;Should work just fine&amp;hellip; Let&amp;rsquo;s move the database on my host and see if I can use litestream to restore it&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;nic in quadtask/litestream   database-clean-up   ×21  ×2  ×9 via   v3.11.10(quadtask)   (dev) 󰒄 &#xA;⬢ [devbox] ❯ mv ./source/quadtask-prod.db ./source/quadtask-prod.db.backup                 &#xA;&#xA;nic in quadtask/litestream   database-clean-up   ×21  ×2  ×9 via   v3.11.10(quadtask)   (dev) 󰒄 &#xA;⬢ [devbox] ❯ litestream restore ./source/quadtask-prod.db              &#xA;time=2025-08-05T09:06:25.826-05:00 level=INFO msg=&amp;quot;restoring snapshot&amp;quot; db=/home/nic/projects/personal/quadtask/litestream/source/quadtask-prod.db replica=quadtask-prod generation=209692854ccd85d5 index=0 path=/home/nic/projects/personal/quadtask/litestream/source/quadtask-prod.db.tmp&#xA;time=2025-08-05T09:06:25.843-05:00 level=INFO msg=&amp;quot;restoring wal files&amp;quot; db=/home/nic/projects/personal/quadtask/litestream/source/quadtask-prod.db replica=quadtask-prod generation=209692854ccd85d5 index_min=0 index_max=0&#xA;time=2025-08-05T09:06:25.845-05:00 level=INFO msg=&amp;quot;downloaded wal&amp;quot; db=/home/nic/projects/personal/quadtask/litestream/source/quadtask-prod.db replica=quadtask-prod generation=209692854ccd85d5 index=0 elapsed=2.103514ms&#xA;time=2025-08-05T09:06:25.856-05:00 level=INFO msg=&amp;quot;applied wal&amp;quot; db=/home/nic/projects/personal/quadtask/litestream/source/quadtask-prod.db replica=quadtask-prod generation=209692854ccd85d5 index=0 elapsed=10.871034ms&#xA;time=2025-08-05T09:06:25.856-05:00 level=INFO msg=&amp;quot;renaming database from temporary location&amp;quot; db=/home/nic/projects/personal/quadtask/litestream/source/quadtask-prod.db replica=quadtask-prod&#xA;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;The command &lt;code&gt;litestream restore &amp;lt;db path&amp;gt;&lt;/code&gt; was confusing at first because I was trying to replicate to a new place, but couldn&amp;rsquo;t get the config to line up. The general understanding here is DR I believe - so the configuration is relatively static and when you &lt;code&gt;restore&lt;/code&gt; you are restoring a specific database, not just standing up a copy from a backup&amp;hellip;&lt;/p&gt;&#xA;&lt;div class=&#34;admonition note&#34;&gt;&#xA;&lt;p class=&#34;admonition-title&#34;&gt;But would we setup a copy from a backup?&lt;/p&gt;&#xA;&lt;p&gt;ie. restore to a different file?&lt;/p&gt;&#xA;&lt;/div&gt;&#xA;&lt;p&gt;Yes, but it&amp;rsquo;s confusing - at least it was to me&amp;hellip; it looks to me like litestream uses the path of a db as the identifier in the config, and you reference the config not by an object&amp;rsquo;s name (if it has one) but by the &lt;code&gt;path&lt;/code&gt;&amp;hellip;&lt;/p&gt;&#xA;&lt;p&gt;So the command is &lt;code&gt;litestream restore -o &amp;lt;output path&amp;gt; &amp;lt;db path&amp;gt;&lt;/code&gt;. This makes sense in light of the fact that the configuration is relative to this host - so &lt;code&gt;&amp;lt;db path&amp;gt;&lt;/code&gt; being the path of the source db whose backup you are restoring from to &lt;code&gt;&amp;lt;output path&amp;gt;&lt;/code&gt; makes some amount of sense&amp;hellip; if I wanted to replicate to another machine, then THAT machine would need &lt;code&gt;/etc/litestream.yaml&lt;/code&gt; and if the filesystem hierarchy was different then an appropriate &lt;code&gt;path&lt;/code&gt; for the &amp;ldquo;source&amp;rdquo; of the db to replicate back to.&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;⬢ [devbox] ❯ litestream restore -o /tmp/db ./source/quadtask-prod.db          &#xA;time=2025-08-05T09:09:04.784-05:00 level=INFO msg=&amp;quot;restoring snapshot&amp;quot; db=/home/nic/projects/personal/quadtask/litestream/source/quadtask-prod.db replica=quadtask-prod generation=209692854ccd85d5 index=0 path=/tmp/db.tmp&#xA;time=2025-08-05T09:09:04.797-05:00 level=INFO msg=&amp;quot;restoring wal files&amp;quot; db=/home/nic/projects/personal/quadtask/litestream/source/quadtask-prod.db replica=quadtask-prod generation=209692854ccd85d5 index_min=0 index_max=0&#xA;time=2025-08-05T09:09:04.799-05:00 level=INFO msg=&amp;quot;downloaded wal&amp;quot; db=/home/nic/projects/personal/quadtask/litestream/source/quadtask-prod.db replica=quadtask-prod generation=209692854ccd85d5 index=0 elapsed=2.128594ms&#xA;time=2025-08-05T09:09:04.800-05:00 level=INFO msg=&amp;quot;applied wal&amp;quot; db=/home/nic/projects/personal/quadtask/litestream/source/quadtask-prod.db replica=quadtask-prod generation=209692854ccd85d5 index=0 elapsed=610.75µs&#xA;time=2025-08-05T09:09:04.800-05:00 level=INFO msg=&amp;quot;renaming database from temporary location&amp;quot; db=/home/nic/projects/personal/quadtask/litestream/source/quadtask-prod.db replica=quadtask-prod&#xA;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;</content>
    <author>
      <name>Nic Payne</name>
      <uri>https://pype.dev</uri>
    </author>
  </entry>
</feed>