<rss version="2.0">
  <channel>
    <title>Audio on rMdes - a place to write and think freely</title>
    <link>https://blog.rmendes.net/categories/audio/</link>
    <description></description>
    
    <language>en</language>
    
    <lastBuildDate>Mon, 29 Dec 2025 17:48:24 +0100</lastBuildDate>
    
    <item>
      <title>Upgrading Funkwhale from 1.4.0 to 2.0.0-rc5 on Debian</title>
      <link>https://blog.rmendes.net/2025/12/29/upgrading-funkwhale-from-to-rc.html</link>
      <pubDate>Mon, 29 Dec 2025 17:48:24 +0100</pubDate>
      
      <guid>http://rmdes.micro.blog/2025/12/29/upgrading-funkwhale-from-to-rc.html</guid>
      <description>&lt;p&gt;After running Funkwhale 1.4.0 for a while, I decided to upgrade to the 2.0.0-rc5 release candidate. This post documents the full upgrade process on a Debian 12 (bookworm) server, including the issues I encountered and how to resolve them.&lt;/p&gt;
&lt;h2 id=&#34;whats-new-in-funkwhale-20&#34;&gt;What&amp;rsquo;s New in Funkwhale 2.0&lt;/h2&gt;
&lt;p&gt;Funkwhale 2.0 brings significant changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Libraries replaced by Playlists&lt;/strong&gt; - The old &amp;ldquo;Libraries&amp;rdquo; concept has been migrated to a more intuitive playlist-based system&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Python 3.11+ required&lt;/strong&gt; - The minimum Python version has been bumped&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Django 5.1.6&lt;/strong&gt; - Major framework upgrade&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;venv instead of virtualenv&lt;/strong&gt; - The recommended virtual environment tool has changed&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Improved artist credits system&lt;/strong&gt; - Better handling of artist metadata&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Federation improvements&lt;/strong&gt; - Enhanced ActivityPub support (though this may break compatibility with older instances)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;prerequisites&#34;&gt;Prerequisites&lt;/h2&gt;
&lt;p&gt;Before starting the upgrade, ensure you have:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Root access to your server&lt;/li&gt;
&lt;li&gt;Sufficient disk space for backups (~2x your database size + config files)&lt;/li&gt;
&lt;li&gt;Python 3.11 installed (&lt;code&gt;python3 --version&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;python3.11-venv&lt;/code&gt; package installed&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;apt install python3.11-venv
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;step-1-create-a-full-backup&#34;&gt;Step 1: Create a Full Backup&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Never skip this step.&lt;/strong&gt; The database backup is your lifeline if something goes wrong.&lt;/p&gt;
&lt;h3 id=&#34;database-backup&#34;&gt;Database Backup&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;sudo -u postgres pg_dumpall &amp;gt; /srv/funkwhale/backups/dump_&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;date +%d-%m-%Y_%H_%M_%S&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;.sql
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;media-backup&#34;&gt;Media Backup&lt;/h3&gt;
&lt;p&gt;If you have a lot of music, consider syncing your media directory to another location:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# From your local machine (if you have rsync access)&lt;/span&gt;
rsync -avz --progress user@yourserver:/srv/funkwhale/data/music ~/funkwhale-backup/music/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Or create a compressed archive on the server:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;tar -czvf /srv/funkwhale/backups/media-backup.tar.gz /srv/funkwhale/data/music
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;configuration-backup&#34;&gt;Configuration Backup&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;cp -a /srv/funkwhale/config /srv/funkwhale/backups/config-backup
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;step-2-stop-funkwhale-services&#34;&gt;Step 2: Stop Funkwhale Services&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;systemctl stop funkwhale.target
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Verify everything is stopped:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;systemctl status funkwhale-server funkwhale-worker funkwhale-beat
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;step-3-backup-current-installation&#34;&gt;Step 3: Backup Current Installation&lt;/h2&gt;
&lt;p&gt;Before removing anything, backup the current installation for potential rollback:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;BACKUP_DIR&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/srv/funkwhale/backups/upgrade-&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;date +%Y%m%d_%H%M%S&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;
mkdir -p &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$BACKUP_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;

cp -a /srv/funkwhale/api &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$BACKUP_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;/api&amp;#34;&lt;/span&gt;
cp -a /srv/funkwhale/front &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$BACKUP_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;/front&amp;#34;&lt;/span&gt;
cp -a /srv/funkwhale/virtualenv &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$BACKUP_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;/virtualenv&amp;#34;&lt;/span&gt;
cp -a /srv/funkwhale/config &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$BACKUP_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;/config&amp;#34;&lt;/span&gt;

&lt;span style=&#34;color:#75715e&#34;&gt;# Backup systemd units&lt;/span&gt;
mkdir -p &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$BACKUP_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;/systemd&amp;#34;&lt;/span&gt;
cp /etc/systemd/system/funkwhale*.service &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$BACKUP_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;/systemd/&amp;#34;&lt;/span&gt;
cp /etc/systemd/system/funkwhale.target &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$BACKUP_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;/systemd/&amp;#34;&lt;/span&gt;

&lt;span style=&#34;color:#75715e&#34;&gt;# Backup nginx config&lt;/span&gt;
mkdir -p &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$BACKUP_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;/nginx&amp;#34;&lt;/span&gt;
cp /etc/nginx/sites-enabled/your-site.conf &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$BACKUP_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;/nginx/&amp;#34;&lt;/span&gt;
cp /etc/nginx/funkwhale_proxy.conf &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$BACKUP_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;/nginx/&amp;#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;step-4-download-funkwhale-200-rc5&#34;&gt;Step 4: Download Funkwhale 2.0.0-rc5&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;export FUNKWHALE_VERSION&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;2.0.0-rc5&amp;#34;&lt;/span&gt;
cd /srv/funkwhale

&lt;span style=&#34;color:#75715e&#34;&gt;# Download API&lt;/span&gt;
curl -L -o &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;api-&lt;/span&gt;$FUNKWHALE_VERSION&lt;span style=&#34;color:#e6db74&#34;&gt;.zip&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;https://dev.funkwhale.audio/funkwhale/funkwhale/-/jobs/artifacts/&lt;/span&gt;$FUNKWHALE_VERSION&lt;span style=&#34;color:#e6db74&#34;&gt;/download?job=build_api&amp;#34;&lt;/span&gt;

&lt;span style=&#34;color:#75715e&#34;&gt;# Download Frontend&lt;/span&gt;
curl -L -o &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;front-&lt;/span&gt;$FUNKWHALE_VERSION&lt;span style=&#34;color:#e6db74&#34;&gt;.zip&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;https://dev.funkwhale.audio/funkwhale/funkwhale/-/jobs/artifacts/&lt;/span&gt;$FUNKWHALE_VERSION&lt;span style=&#34;color:#e6db74&#34;&gt;/download?job=build_front&amp;#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;step-5-install-the-new-version&#34;&gt;Step 5: Install the New Version&lt;/h2&gt;
&lt;h3 id=&#34;remove-old-files&#34;&gt;Remove Old Files&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;rm -rf /srv/funkwhale/api/*
rm -rf /srv/funkwhale/front/*
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;extract-new-files&#34;&gt;Extract New Files&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;cd /srv/funkwhale

&lt;span style=&#34;color:#75715e&#34;&gt;# Extract API&lt;/span&gt;
unzip -q &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;api-&lt;/span&gt;$FUNKWHALE_VERSION&lt;span style=&#34;color:#e6db74&#34;&gt;.zip&amp;#34;&lt;/span&gt; -d extracted
mv extracted/api/* api/
rm -rf extracted &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;api-&lt;/span&gt;$FUNKWHALE_VERSION&lt;span style=&#34;color:#e6db74&#34;&gt;.zip&amp;#34;&lt;/span&gt;

&lt;span style=&#34;color:#75715e&#34;&gt;# Extract Frontend&lt;/span&gt;
unzip -q &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;front-&lt;/span&gt;$FUNKWHALE_VERSION&lt;span style=&#34;color:#e6db74&#34;&gt;.zip&amp;#34;&lt;/span&gt; -d extracted
mv extracted/front/* front/
rm -rf extracted &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;front-&lt;/span&gt;$FUNKWHALE_VERSION&lt;span style=&#34;color:#e6db74&#34;&gt;.zip&amp;#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;create-new-python-virtual-environment&#34;&gt;Create New Python Virtual Environment&lt;/h3&gt;
&lt;p&gt;Funkwhale 2.0 uses &lt;code&gt;venv&lt;/code&gt; instead of &lt;code&gt;virtualenv&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;cd /srv/funkwhale

&lt;span style=&#34;color:#75715e&#34;&gt;# Remove old virtualenv (if upgrading from 1.x)&lt;/span&gt;
rm -rf virtualenv

&lt;span style=&#34;color:#75715e&#34;&gt;# Create new venv&lt;/span&gt;
python3 -m venv venv
venv/bin/pip install --upgrade pip wheel

&lt;span style=&#34;color:#75715e&#34;&gt;# Install Funkwhale API&lt;/span&gt;
venv/bin/pip install --editable ./api

&lt;span style=&#34;color:#75715e&#34;&gt;# Set correct permissions&lt;/span&gt;
chown -R funkwhale:funkwhale api front venv
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;step-6-update-systemd-unit-files&#34;&gt;Step 6: Update Systemd Unit Files&lt;/h2&gt;
&lt;p&gt;The systemd unit files need to be updated to point to the new &lt;code&gt;venv&lt;/code&gt; directory instead of &lt;code&gt;virtualenv&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You can download them from the repository:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;export FUNKWHALE_VERSION&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;2.0.0-rc5&amp;#34;&lt;/span&gt;

curl -L -o &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/etc/systemd/system/funkwhale.target&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;https://dev.funkwhale.audio/funkwhale/funkwhale/raw/&lt;/span&gt;$FUNKWHALE_VERSION&lt;span style=&#34;color:#e6db74&#34;&gt;/deploy/funkwhale.target&amp;#34;&lt;/span&gt;
curl -L -o &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/etc/systemd/system/funkwhale-server.service&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;https://dev.funkwhale.audio/funkwhale/funkwhale/raw/&lt;/span&gt;$FUNKWHALE_VERSION&lt;span style=&#34;color:#e6db74&#34;&gt;/deploy/funkwhale-server.service&amp;#34;&lt;/span&gt;
curl -L -o &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/etc/systemd/system/funkwhale-worker.service&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;https://dev.funkwhale.audio/funkwhale/funkwhale/raw/&lt;/span&gt;$FUNKWHALE_VERSION&lt;span style=&#34;color:#e6db74&#34;&gt;/deploy/funkwhale-worker.service&amp;#34;&lt;/span&gt;
curl -L -o &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/etc/systemd/system/funkwhale-beat.service&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;https://dev.funkwhale.audio/funkwhale/funkwhale/raw/&lt;/span&gt;$FUNKWHALE_VERSION&lt;span style=&#34;color:#e6db74&#34;&gt;/deploy/funkwhale-beat.service&amp;#34;&lt;/span&gt;

systemctl daemon-reload
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If the curl commands return HTML instead of the service files (404 errors), you may need to clone the repository and copy the files manually:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;git clone --branch 2.0.0-rc5 --depth &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; https://dev.funkwhale.audio/funkwhale/funkwhale.git /tmp/funkwhale-2.0
cp /tmp/funkwhale-2.0/deploy/funkwhale*.service /etc/systemd/system/
cp /tmp/funkwhale-2.0/deploy/funkwhale.target /etc/systemd/system/
systemctl daemon-reload
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;step-7-update-nginx-configuration-optional&#34;&gt;Step 7: Update Nginx Configuration (Optional)&lt;/h2&gt;
&lt;p&gt;If you want to use the latest nginx configuration:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;curl -L -o /etc/nginx/funkwhale_proxy.conf &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;https://dev.funkwhale.audio/funkwhale/funkwhale/raw/&lt;/span&gt;$FUNKWHALE_VERSION&lt;span style=&#34;color:#e6db74&#34;&gt;/deploy/funkwhale_proxy.conf&amp;#34;&lt;/span&gt;

nginx -t &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; systemctl reload nginx
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;step-8-run-database-migrations&#34;&gt;Step 8: Run Database Migrations&lt;/h2&gt;
&lt;p&gt;This is the critical step that updates your database schema:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;cd /srv/funkwhale

&lt;span style=&#34;color:#75715e&#34;&gt;# Collect static files&lt;/span&gt;
sudo -u funkwhale venv/bin/funkwhale-manage collectstatic --no-input

&lt;span style=&#34;color:#75715e&#34;&gt;# Run migrations&lt;/span&gt;
sudo -u funkwhale venv/bin/funkwhale-manage migrate
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You should see output showing the migrations being applied, including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;music.0001_initial&lt;/code&gt; through various migrations&lt;/li&gt;
&lt;li&gt;&lt;code&gt;playlists&lt;/code&gt; migrations (new in 2.0)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;common&lt;/code&gt; and &lt;code&gt;federation&lt;/code&gt; updates&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;step-9-start-services&#34;&gt;Step 9: Start Services&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;systemctl start funkwhale.target
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Wait a few seconds and verify everything is running:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;systemctl status funkwhale-server funkwhale-worker funkwhale-beat
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;All three services should show &lt;code&gt;active (running)&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;step-10-verify-the-upgrade&#34;&gt;Step 10: Verify the Upgrade&lt;/h2&gt;
&lt;p&gt;Check that the API is responding:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;curl -s https://your-domain.com/api/v2/ | head -20
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You should see the API root response with version information.&lt;/p&gt;
&lt;h2 id=&#34;troubleshooting&#34;&gt;Troubleshooting&lt;/h2&gt;
&lt;h3 id=&#34;issue-ensurepip-is-not-available&#34;&gt;Issue: &amp;ldquo;ensurepip is not available&amp;rdquo;&lt;/h3&gt;
&lt;p&gt;If you see this error when creating the venv:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Error: Command &#39;[&#39;/srv/funkwhale/venv/bin/python3&#39;, &#39;-m&#39;, &#39;ensurepip&#39;, &#39;--upgrade&#39;, &#39;--default-pip&#39;]&#39; returned non-zero exit status 1.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Install the python3.11-venv package:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;apt install python3.11-venv
rm -rf /srv/funkwhale/venv
python3 -m venv /srv/funkwhale/venv
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;issue-celery-beat-fails-to-start&#34;&gt;Issue: Celery Beat Fails to Start&lt;/h3&gt;
&lt;p&gt;If funkwhale-beat keeps restarting with database errors:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;_dbm.error: cannot add item to database
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Remove the corrupted schedule database:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;rm /srv/funkwhale/api/celerybeat-schedule.db
systemctl restart funkwhale-beat
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;issue-systemd-unit-download-returns-html&#34;&gt;Issue: Systemd Unit Download Returns HTML&lt;/h3&gt;
&lt;p&gt;The GitLab raw file URLs sometimes don&amp;rsquo;t work for tags. Clone the repo and copy manually (see Step 6).&lt;/p&gt;
&lt;h3 id=&#34;issue-permission-errors&#34;&gt;Issue: Permission Errors&lt;/h3&gt;
&lt;p&gt;Always ensure the funkwhale user owns all files:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;chown -R funkwhale:funkwhale /srv/funkwhale/api /srv/funkwhale/front /srv/funkwhale/venv
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;rollback-procedure&#34;&gt;Rollback Procedure&lt;/h2&gt;
&lt;p&gt;If something goes seriously wrong, you can rollback:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Stop services:
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;systemctl stop funkwhale.target
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;Restore files from backup:
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;BACKUP_DIR&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/srv/funkwhale/backups/upgrade-YYYYMMDD_HHMMSS&amp;#34;&lt;/span&gt;
rm -rf /srv/funkwhale/api /srv/funkwhale/front /srv/funkwhale/venv
cp -a &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$BACKUP_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;/api&amp;#34;&lt;/span&gt; /srv/funkwhale/
cp -a &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$BACKUP_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;/front&amp;#34;&lt;/span&gt; /srv/funkwhale/
cp -a &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$BACKUP_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;/virtualenv&amp;#34;&lt;/span&gt; /srv/funkwhale/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;Restore systemd units:
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;cp &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$BACKUP_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;/systemd/&amp;#34;&lt;/span&gt;* /etc/systemd/system/
systemctl daemon-reload
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;Restore database (if needed):
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;sudo -u postgres psql &amp;lt; /srv/funkwhale/backups/dump_DD-MM-YYYY_HH_MM_SS.sql
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;Start services:
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;systemctl start funkwhale.target
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;automated-upgrade-script&#34;&gt;Automated Upgrade Script&lt;/h2&gt;
&lt;p&gt;For convenience, I&amp;rsquo;ve created a script that automates the entire process with rollback capability. You can find it below:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/bin/bash
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#&lt;/span&gt;
&lt;span style=&#34;color:#75715e&#34;&gt;# Funkwhale Upgrade Script: 1.4.0 -&amp;gt; 2.0.0-rc5&lt;/span&gt;
&lt;span style=&#34;color:#75715e&#34;&gt;# With rollback capability&lt;/span&gt;
&lt;span style=&#34;color:#75715e&#34;&gt;#&lt;/span&gt;
&lt;span style=&#34;color:#75715e&#34;&gt;# Usage: ./upgrade-funkwhale-2.0.sh [upgrade|rollback|status]&lt;/span&gt;
&lt;span style=&#34;color:#75715e&#34;&gt;#&lt;/span&gt;

set -e

&lt;span style=&#34;color:#75715e&#34;&gt;# Configuration&lt;/span&gt;
FUNKWHALE_VERSION&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;2.0.0-rc5&amp;#34;&lt;/span&gt;
FUNKWHALE_DIR&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/srv/funkwhale&amp;#34;&lt;/span&gt;
BACKUP_DIR&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/srv/funkwhale/backups/upgrade-&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;date +%Y%m%d_%H%M%S&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;
ROLLBACK_MARKER&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/srv/funkwhale/backups/.rollback_info&amp;#34;&lt;/span&gt;

&lt;span style=&#34;color:#75715e&#34;&gt;# Colors for output&lt;/span&gt;
RED&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;\033[0;31m&amp;#39;&lt;/span&gt;
GREEN&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;\033[0;32m&amp;#39;&lt;/span&gt;
YELLOW&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;\033[1;33m&amp;#39;&lt;/span&gt;
NC&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;\033[0m&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;# No Color&lt;/span&gt;

log_info&lt;span style=&#34;color:#f92672&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt; echo -e &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;GREEN&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;[INFO]&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;NC&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt; &lt;/span&gt;$1&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;; &lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
log_warn&lt;span style=&#34;color:#f92672&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt; echo -e &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;YELLOW&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;[WARN]&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;NC&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt; &lt;/span&gt;$1&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;; &lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
log_error&lt;span style=&#34;color:#f92672&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt; echo -e &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;RED&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;[ERROR]&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;NC&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt; &lt;/span&gt;$1&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;; &lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;

check_root&lt;span style=&#34;color:#f92672&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[[&lt;/span&gt; $EUID -ne &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;]]&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt;
        log_error &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;This script must be run as root&amp;#34;&lt;/span&gt;
        exit &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
    &lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;
&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;

check_services_stopped&lt;span style=&#34;color:#f92672&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; systemctl is-active --quiet funkwhale-server.service; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt;
        log_error &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Funkwhale services are still running. Stop them first with: systemctl stop funkwhale.target&amp;#34;&lt;/span&gt;
        exit &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
    &lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;
&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;

backup_current&lt;span style=&#34;color:#f92672&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
    log_info &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Creating backup in &lt;/span&gt;$BACKUP_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;...&amp;#34;&lt;/span&gt;
    mkdir -p &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$BACKUP_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;

    log_info &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Backing up API...&amp;#34;&lt;/span&gt;
    cp -a &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$FUNKWHALE_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;/api&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$BACKUP_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;/api&amp;#34;&lt;/span&gt;

    log_info &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Backing up frontend...&amp;#34;&lt;/span&gt;
    cp -a &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$FUNKWHALE_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;/front&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$BACKUP_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;/front&amp;#34;&lt;/span&gt;

    log_info &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Backing up virtualenv...&amp;#34;&lt;/span&gt;
    cp -a &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$FUNKWHALE_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;/virtualenv&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$BACKUP_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;/virtualenv&amp;#34;&lt;/span&gt;

    log_info &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Backing up config...&amp;#34;&lt;/span&gt;
    cp -a &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$FUNKWHALE_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;/config&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$BACKUP_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;/config&amp;#34;&lt;/span&gt;

    log_info &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Backing up systemd units...&amp;#34;&lt;/span&gt;
    mkdir -p &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$BACKUP_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;/systemd&amp;#34;&lt;/span&gt;
    cp /etc/systemd/system/funkwhale*.service &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$BACKUP_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;/systemd/&amp;#34;&lt;/span&gt; 2&amp;gt;/dev/null &lt;span style=&#34;color:#f92672&#34;&gt;||&lt;/span&gt; true
    cp /etc/systemd/system/funkwhale.target &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$BACKUP_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;/systemd/&amp;#34;&lt;/span&gt; 2&amp;gt;/dev/null &lt;span style=&#34;color:#f92672&#34;&gt;||&lt;/span&gt; true

    log_info &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Backing up nginx config...&amp;#34;&lt;/span&gt;
    mkdir -p &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$BACKUP_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;/nginx&amp;#34;&lt;/span&gt;
    cp /etc/nginx/sites-enabled/*.conf &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$BACKUP_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;/nginx/&amp;#34;&lt;/span&gt; 2&amp;gt;/dev/null &lt;span style=&#34;color:#f92672&#34;&gt;||&lt;/span&gt; true
    cp /etc/nginx/funkwhale_proxy.conf &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$BACKUP_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;/nginx/&amp;#34;&lt;/span&gt; 2&amp;gt;/dev/null &lt;span style=&#34;color:#f92672&#34;&gt;||&lt;/span&gt; true

    &lt;span style=&#34;color:#75715e&#34;&gt;# Save rollback info&lt;/span&gt;
    echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$BACKUP_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &amp;gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$ROLLBACK_MARKER&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;
    echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;BACKUP_DATE=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;date&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &amp;gt;&amp;gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$ROLLBACK_MARKER&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;
    echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;OLD_VERSION=1.4.0&amp;#34;&lt;/span&gt; &amp;gt;&amp;gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$ROLLBACK_MARKER&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;
    echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;NEW_VERSION=&lt;/span&gt;$FUNKWHALE_VERSION&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &amp;gt;&amp;gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$ROLLBACK_MARKER&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;

    log_info &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Backup complete: &lt;/span&gt;$BACKUP_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;

download_new_version&lt;span style=&#34;color:#f92672&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
    log_info &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Downloading Funkwhale &lt;/span&gt;$FUNKWHALE_VERSION&lt;span style=&#34;color:#e6db74&#34;&gt;...&amp;#34;&lt;/span&gt;

    cd &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$FUNKWHALE_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;

    log_info &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Downloading API...&amp;#34;&lt;/span&gt;
    curl -L -o &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;api-&lt;/span&gt;$FUNKWHALE_VERSION&lt;span style=&#34;color:#e6db74&#34;&gt;.zip&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;https://dev.funkwhale.audio/funkwhale/funkwhale/-/jobs/artifacts/&lt;/span&gt;$FUNKWHALE_VERSION&lt;span style=&#34;color:#e6db74&#34;&gt;/download?job=build_api&amp;#34;&lt;/span&gt;

    log_info &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Downloading Frontend...&amp;#34;&lt;/span&gt;
    curl -L -o &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;front-&lt;/span&gt;$FUNKWHALE_VERSION&lt;span style=&#34;color:#e6db74&#34;&gt;.zip&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;https://dev.funkwhale.audio/funkwhale/funkwhale/-/jobs/artifacts/&lt;/span&gt;$FUNKWHALE_VERSION&lt;span style=&#34;color:#e6db74&#34;&gt;/download?job=build_front&amp;#34;&lt;/span&gt;

    log_info &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Downloads complete&amp;#34;&lt;/span&gt;
&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;

install_new_version&lt;span style=&#34;color:#f92672&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
    log_info &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Installing Funkwhale &lt;/span&gt;$FUNKWHALE_VERSION&lt;span style=&#34;color:#e6db74&#34;&gt;...&amp;#34;&lt;/span&gt;

    cd &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$FUNKWHALE_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;

    log_info &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Removing old API and frontend...&amp;#34;&lt;/span&gt;
    rm -rf api/* front/*

    log_info &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Extracting API...&amp;#34;&lt;/span&gt;
    unzip -q &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;api-&lt;/span&gt;$FUNKWHALE_VERSION&lt;span style=&#34;color:#e6db74&#34;&gt;.zip&amp;#34;&lt;/span&gt; -d extracted
    mv extracted/api/* api/
    rm -rf extracted &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;api-&lt;/span&gt;$FUNKWHALE_VERSION&lt;span style=&#34;color:#e6db74&#34;&gt;.zip&amp;#34;&lt;/span&gt;

    log_info &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Extracting frontend...&amp;#34;&lt;/span&gt;
    unzip -q &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;front-&lt;/span&gt;$FUNKWHALE_VERSION&lt;span style=&#34;color:#e6db74&#34;&gt;.zip&amp;#34;&lt;/span&gt; -d extracted
    rm -rf front/*
    mv extracted/front/* front/
    rm -rf extracted &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;front-&lt;/span&gt;$FUNKWHALE_VERSION&lt;span style=&#34;color:#e6db74&#34;&gt;.zip&amp;#34;&lt;/span&gt;

    log_info &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Creating new Python virtual environment...&amp;#34;&lt;/span&gt;
    rm -rf venv
    python3 -m venv venv
    venv/bin/pip install --upgrade pip wheel

    log_info &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Installing Funkwhale API package...&amp;#34;&lt;/span&gt;
    venv/bin/pip install --editable ./api

    chown -R funkwhale:funkwhale api front venv

    log_info &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Installation complete&amp;#34;&lt;/span&gt;
&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;

update_systemd_units&lt;span style=&#34;color:#f92672&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
    log_info &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Updating systemd unit files...&amp;#34;&lt;/span&gt;

    curl -L -o &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/etc/systemd/system/funkwhale.target&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;https://dev.funkwhale.audio/funkwhale/funkwhale/raw/&lt;/span&gt;$FUNKWHALE_VERSION&lt;span style=&#34;color:#e6db74&#34;&gt;/deploy/funkwhale.target&amp;#34;&lt;/span&gt;
    curl -L -o &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/etc/systemd/system/funkwhale-server.service&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;https://dev.funkwhale.audio/funkwhale/funkwhale/raw/&lt;/span&gt;$FUNKWHALE_VERSION&lt;span style=&#34;color:#e6db74&#34;&gt;/deploy/funkwhale-server.service&amp;#34;&lt;/span&gt;
    curl -L -o &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/etc/systemd/system/funkwhale-worker.service&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;https://dev.funkwhale.audio/funkwhale/funkwhale/raw/&lt;/span&gt;$FUNKWHALE_VERSION&lt;span style=&#34;color:#e6db74&#34;&gt;/deploy/funkwhale-worker.service&amp;#34;&lt;/span&gt;
    curl -L -o &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/etc/systemd/system/funkwhale-beat.service&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;https://dev.funkwhale.audio/funkwhale/funkwhale/raw/&lt;/span&gt;$FUNKWHALE_VERSION&lt;span style=&#34;color:#e6db74&#34;&gt;/deploy/funkwhale-beat.service&amp;#34;&lt;/span&gt;

    systemctl daemon-reload
    log_info &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Systemd units updated&amp;#34;&lt;/span&gt;
&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;

run_migrations&lt;span style=&#34;color:#f92672&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
    log_info &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Running database migrations...&amp;#34;&lt;/span&gt;

    cd &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$FUNKWHALE_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;

    log_info &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Collecting static files...&amp;#34;&lt;/span&gt;
    sudo -u funkwhale venv/bin/funkwhale-manage collectstatic --no-input

    log_info &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Applying database migrations...&amp;#34;&lt;/span&gt;
    sudo -u funkwhale venv/bin/funkwhale-manage migrate

    log_info &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Migrations complete&amp;#34;&lt;/span&gt;
&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;

start_services&lt;span style=&#34;color:#f92672&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
    log_info &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Starting Funkwhale services...&amp;#34;&lt;/span&gt;
    systemctl start funkwhale.target
    systemctl reload nginx

    sleep &lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;

    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; systemctl is-active --quiet funkwhale-server.service; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt;
        log_info &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Funkwhale services started successfully!&amp;#34;&lt;/span&gt;
    &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt;
        log_error &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Services failed to start. Check logs with: journalctl -u funkwhale-server.service&amp;#34;&lt;/span&gt;
        exit &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
    &lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;
&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;

do_upgrade&lt;span style=&#34;color:#f92672&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
    log_info &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Starting Funkwhale upgrade to &lt;/span&gt;$FUNKWHALE_VERSION&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;
    log_warn &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Make sure you have a database backup before proceeding!&amp;#34;&lt;/span&gt;

    check_root
    check_services_stopped

    backup_current
    download_new_version
    install_new_version
    update_systemd_units
    run_migrations
    start_services

    log_info &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;==========================================&amp;#34;&lt;/span&gt;
    log_info &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Upgrade complete!&amp;#34;&lt;/span&gt;
    log_info &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Funkwhale &lt;/span&gt;$FUNKWHALE_VERSION&lt;span style=&#34;color:#e6db74&#34;&gt; is now running&amp;#34;&lt;/span&gt;
    log_info &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;==========================================&amp;#34;&lt;/span&gt;
    log_info &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;If something goes wrong, run: &lt;/span&gt;$0&lt;span style=&#34;color:#e6db74&#34;&gt; rollback&amp;#34;&lt;/span&gt;
&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;

do_rollback&lt;span style=&#34;color:#f92672&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
    log_info &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Starting rollback...&amp;#34;&lt;/span&gt;

    check_root

    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[[&lt;/span&gt; ! -f &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$ROLLBACK_MARKER&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;]]&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt;
        log_error &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;No rollback information found. Cannot rollback.&amp;#34;&lt;/span&gt;
        exit &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
    &lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;

    BACKUP_DIR&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;head -1 &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$ROLLBACK_MARKER&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;

    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[[&lt;/span&gt; ! -d &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$BACKUP_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;]]&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt;
        log_error &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Backup directory not found: &lt;/span&gt;$BACKUP_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;
        exit &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
    &lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;

    log_info &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Rolling back from backup: &lt;/span&gt;$BACKUP_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;

    systemctl stop funkwhale.target 2&amp;gt;/dev/null &lt;span style=&#34;color:#f92672&#34;&gt;||&lt;/span&gt; true

    log_info &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Restoring API...&amp;#34;&lt;/span&gt;
    rm -rf &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$FUNKWHALE_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;/api&amp;#34;&lt;/span&gt;
    cp -a &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$BACKUP_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;/api&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$FUNKWHALE_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;/api&amp;#34;&lt;/span&gt;

    log_info &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Restoring frontend...&amp;#34;&lt;/span&gt;
    rm -rf &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$FUNKWHALE_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;/front&amp;#34;&lt;/span&gt;
    cp -a &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$BACKUP_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;/front&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$FUNKWHALE_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;/front&amp;#34;&lt;/span&gt;

    log_info &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Restoring virtualenv...&amp;#34;&lt;/span&gt;
    rm -rf &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$FUNKWHALE_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;/venv&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$FUNKWHALE_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;/virtualenv&amp;#34;&lt;/span&gt;
    cp -a &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$BACKUP_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;/virtualenv&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$FUNKWHALE_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;/virtualenv&amp;#34;&lt;/span&gt;

    log_info &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Restoring systemd units...&amp;#34;&lt;/span&gt;
    cp &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$BACKUP_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;/systemd/&amp;#34;&lt;/span&gt;* /etc/systemd/system/
    systemctl daemon-reload

    log_info &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Restoring nginx config...&amp;#34;&lt;/span&gt;
    cp &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$BACKUP_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;/nginx/&amp;#34;&lt;/span&gt;* /etc/nginx/sites-enabled/ 2&amp;gt;/dev/null &lt;span style=&#34;color:#f92672&#34;&gt;||&lt;/span&gt; true
    cp &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$BACKUP_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;/nginx/funkwhale_proxy.conf&amp;#34;&lt;/span&gt; /etc/nginx/ 2&amp;gt;/dev/null &lt;span style=&#34;color:#f92672&#34;&gt;||&lt;/span&gt; true

    log_warn &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;NOTE: Database was NOT rolled back automatically.&amp;#34;&lt;/span&gt;
    log_warn &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;To restore database, run:&amp;#34;&lt;/span&gt;
    log_warn &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;  sudo -u postgres psql &amp;lt; /srv/funkwhale/backups/dump_*.sql&amp;#34;&lt;/span&gt;

    systemctl start funkwhale.target
    systemctl reload nginx

    log_info &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;==========================================&amp;#34;&lt;/span&gt;
    log_info &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Rollback complete!&amp;#34;&lt;/span&gt;
    log_info &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;==========================================&amp;#34;&lt;/span&gt;
&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;

show_status&lt;span style=&#34;color:#f92672&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
    echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Current Funkwhale installation:&amp;#34;&lt;/span&gt;
    echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;================================&amp;#34;&lt;/span&gt;

    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[[&lt;/span&gt; -d &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$FUNKWHALE_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;/venv&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;]]&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt;
        echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Virtual env: venv (2.0 style)&amp;#34;&lt;/span&gt;
        VERSION&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$FUNKWHALE_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;/venv/bin/pip&amp;#34;&lt;/span&gt; show funkwhale-api 2&amp;gt;/dev/null | grep Version | awk &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;{print $2}&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;
    &lt;span style=&#34;color:#66d9ef&#34;&gt;elif&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[[&lt;/span&gt; -d &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$FUNKWHALE_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;/virtualenv&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;]]&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt;
        echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Virtual env: virtualenv (1.x style)&amp;#34;&lt;/span&gt;
        VERSION&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$FUNKWHALE_DIR&lt;span style=&#34;color:#e6db74&#34;&gt;/virtualenv/bin/pip&amp;#34;&lt;/span&gt; show funkwhale-api 2&amp;gt;/dev/null | grep Version | awk &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;{print $2}&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;
    &lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;

    echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Installed version: &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;VERSION&lt;span style=&#34;color:#66d9ef&#34;&gt;:-&lt;/span&gt;unknown&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;
    echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;
    echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Service status:&amp;#34;&lt;/span&gt;
    systemctl status funkwhale.target --no-pager 2&amp;gt;/dev/null &lt;span style=&#34;color:#f92672&#34;&gt;||&lt;/span&gt; echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;  Not running&amp;#34;&lt;/span&gt;

    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[[&lt;/span&gt; -f &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$ROLLBACK_MARKER&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;]]&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt;
        echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;
        echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Rollback available:&amp;#34;&lt;/span&gt;
        cat &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$ROLLBACK_MARKER&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;
    &lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;
&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;

&lt;span style=&#34;color:#75715e&#34;&gt;# Main&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;1&lt;span style=&#34;color:#66d9ef&#34;&gt;:-&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; in
    upgrade&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
        do_upgrade
        ;;
    rollback&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
        do_rollback
        ;;
    status&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
        show_status
        ;;
    *&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
        echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Funkwhale Upgrade Script&amp;#34;&lt;/span&gt;
        echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;========================&amp;#34;&lt;/span&gt;
        echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;
        echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Usage: &lt;/span&gt;$0&lt;span style=&#34;color:#e6db74&#34;&gt; [command]&amp;#34;&lt;/span&gt;
        echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;
        echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Commands:&amp;#34;&lt;/span&gt;
        echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;  upgrade   - Upgrade Funkwhale to &lt;/span&gt;$FUNKWHALE_VERSION&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;
        echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;  rollback  - Rollback to previous version&amp;#34;&lt;/span&gt;
        echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;  status    - Show current installation status&amp;#34;&lt;/span&gt;
        echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;
        echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Before upgrading:&amp;#34;&lt;/span&gt;
        echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;  1. Ensure database is backed up&amp;#34;&lt;/span&gt;
        echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;  2. Ensure media files are backed up&amp;#34;&lt;/span&gt;
        echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;  3. Stop services: systemctl stop funkwhale.target&amp;#34;&lt;/span&gt;
        echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;
        ;;
&lt;span style=&#34;color:#66d9ef&#34;&gt;esac&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Save this as &lt;code&gt;upgrade-funkwhale-2.0.sh&lt;/code&gt;, make it executable with &lt;code&gt;chmod +x upgrade-funkwhale-2.0.sh&lt;/code&gt;, and run with &lt;code&gt;sudo ./upgrade-funkwhale-2.0.sh upgrade&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The upgrade from Funkwhale 1.4.0 to 2.0.0-rc5 went smoothly once I resolved the Python venv package issue and worked around the systemd unit file download problem. The database migrations ran without issues, and all my music library was preserved (now organized under the new playlist system instead of libraries).&lt;/p&gt;
&lt;p&gt;If you encounter any issues not covered here, check the &lt;a href=&#34;https://docs.funkwhale.audio/&#34;&gt;Funkwhale documentation&lt;/a&gt; or join the community on Matrix/IRC for help.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Last updated: December 2025&lt;/em&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title></title>
      <link>https://blog.rmendes.net/2025/09/11/174122.html</link>
      <pubDate>Thu, 11 Sep 2025 17:41:22 +0100</pubDate>
      
      <guid>http://rmdes.micro.blog/2025/09/11/174122.html</guid>
      <description>&lt;p&gt;Ela sabe quem é&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/ZkbuGPXJOPA?si=yeEn_RwCdumwajEX&#34;&gt;youtu.be/ZkbuGPXJO&amp;hellip;&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title></title>
      <link>https://blog.rmendes.net/2025/06/11/project-isnt-a-blueprint-its.html</link>
      <pubDate>Wed, 11 Jun 2025 18:23:14 +0100</pubDate>
      
      <guid>http://rmdes.micro.blog/2025/06/11/project-isnt-a-blueprint-its.html</guid>
      <description>&lt;p&gt;Project 2025 isn&amp;rsquo;t a blueprint, it&amp;rsquo;s already 40% enacted or completed.&lt;/p&gt;
&lt;p&gt;Surviving Trump: With Democracy On Life Support: EPISODE 29: Project 2025 Overview — Dismantling Democracy and Women’s Rights&lt;/p&gt;
&lt;p&gt;Episode webpage: &lt;a href=&#34;https://survivingtrump.buzzsprout.com&#34;&gt;survivingtrump.buzzsprout.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.buzzsprout.com/2455246/episodes/17287838-episode-29-project-2025-overview-dismantling-democracy-and-women-s-rights.mp3&#34;&gt;Listen&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title></title>
      <link>https://blog.rmendes.net/2025/06/04/on-the-media-enshttification-live.html</link>
      <pubDate>Wed, 04 Jun 2025 17:01:57 +0100</pubDate>
      
      <guid>http://rmdes.micro.blog/2025/06/04/on-the-media-enshttification-live.html</guid>
      <description>&lt;p&gt;On the Media: Ensh*ttification, Live! Micah and Cory Doctorow in Conversation&lt;/p&gt;
&lt;p&gt;Episode webpage: &lt;a href=&#34;https://www.wnycstudios.org/podcasts/otm&#34;&gt;www.wnycstudios.org/podcasts/&amp;hellip;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://pscrb.fm/rss/p/mgln.ai/e/14/pdst.fm/e/dts.podtrac.com/pts/redirect.mp3/waaa.wnyc.org/e68b6750-ddde-4b56-8121-be01a1922ff5/episodes/88db7881-d706-4801-ac1b-ccd73b5ac429/audio/128/default.mp3?aid=rss_feed&amp;amp;awCollectionId=e68b6750-ddde-4b56-8121-be01a1922ff5&amp;amp;awEpisodeId=88db7881-d706-4801-ac1b-ccd73b5ac429&amp;amp;feed=o4jAFXaw&#34;&gt;Media file&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title></title>
      <link>https://blog.rmendes.net/2025/05/05/a-ma-donn-envie-daller.html</link>
      <pubDate>Mon, 05 May 2025 09:12:23 +0100</pubDate>
      
      <guid>http://rmdes.micro.blog/2025/05/05/a-ma-donn-envie-daller.html</guid>
      <description>&lt;p&gt;Ça m&amp;rsquo;a donné envie d&amp;rsquo;aller choper le bouquin&lt;/p&gt;
&lt;p&gt;Répliques: Les jeux du cirque médiatique&lt;/p&gt;
&lt;p&gt;Episode : &lt;a href=&#34;https://www.radiofrance.fr/franceculture/podcasts/repliques/les-jeux-du-cirque-mediatique-4180103&#34;&gt;www.radiofrance.fr/francecul&amp;hellip;&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title></title>
      <link>https://blog.rmendes.net/2025/05/04/ils-vont-endoctriner-des-enfants.html</link>
      <pubDate>Sun, 04 May 2025 14:57:27 +0100</pubDate>
      
      <guid>http://rmdes.micro.blog/2025/05/04/ils-vont-endoctriner-des-enfants.html</guid>
      <description>&lt;p&gt;👀🎙️Ils vont endoctriner des enfants&lt;/p&gt;
&lt;p&gt;The New Abnormal: Stephen Miller Rolls Out MAGA’s Indoctrination Plan for Kids&lt;/p&gt;
&lt;p&gt;Episode webpage: &lt;a href=&#34;https://shows.acast.com/the-new-abnormal/episodes/stephen-miller-rolls-out-magas-indoctrination-plan-for-kids&#34;&gt;shows.acast.com/the-new-a&amp;hellip;&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Synchroniser vos podcasts entre plusieurs appareils avec AntennaPod et Nextcloud</title>
      <link>https://blog.rmendes.net/2025/05/04/synchroniser-vos-podcasts-entre-plusieurs.html</link>
      <pubDate>Sun, 04 May 2025 14:41:14 +0100</pubDate>
      
      <guid>http://rmdes.micro.blog/2025/05/04/synchroniser-vos-podcasts-entre-plusieurs.html</guid>
      <description>&lt;p&gt;Vous écoutez vos podcasts avec Spotify ou autre platforme et vous en avez assez d’être enfermé dans un écosystème fermé comme Google Podcasts ? Vous voulez pouvoir changer de téléphone ou utiliser plusieurs appareils sans perdre vos abonnements ni votre historique d’écoute ? Ce tutoriel est pour vous.&lt;/p&gt;
&lt;p&gt;Grâce à &lt;strong&gt;Nextcloud&lt;/strong&gt; et à son application &lt;strong&gt;GPodder Sync&lt;/strong&gt;, vous pouvez synchroniser automatiquement vos abonnements, la progression de lecture, et même les épisodes écoutés entre plusieurs instances d’AntennaPod — ou avec d’autres applications compatibles avec le protocole &lt;em&gt;gpodder.net&lt;/em&gt;.&lt;/p&gt;
&lt;h2 id=&#34;pourquoi-utiliser-nextcloud--gpoddersync-&#34;&gt;Pourquoi utiliser Nextcloud + GPodderSync ?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Synchronisation complète&lt;/strong&gt; entre plusieurs téléphones ou tablettes Android utilisant AntennaPod.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pas de perte de données&lt;/strong&gt; : si vous réinstallez votre téléphone, il suffit de reconnecter AntennaPod à votre Nextcloud pour tout récupérer (abonnements, position de lecture, épisodes lus).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Indépendance&lt;/strong&gt; : vous ne dépendez d’aucun service tiers (comme Google, Spotify ou Apple).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Interopérabilité&lt;/strong&gt; : compatible avec d&amp;rsquo;autres clients de podcast utilisant le protocole gpodder.net.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;prérequis&#34;&gt;Prérequis&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Un &lt;strong&gt;serveur Nextcloud&lt;/strong&gt; accessible via une URL ou une adresse IP (auto-hébergé ou chez un fournisseur).&lt;/li&gt;
&lt;li&gt;L’application &lt;strong&gt;GPodder Sync&lt;/strong&gt; installée sur votre instance Nextcloud (c’est une app Nextcloud libre).&lt;/li&gt;
&lt;li&gt;L’application &lt;strong&gt;AntennaPod&lt;/strong&gt; installée sur votre téléphone Android.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;installation-de-gpodder-sync-sur-nextcloud&#34;&gt;Installation de GPodder Sync sur Nextcloud&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Connectez-vous à l’interface web de votre Nextcloud en tant qu’administrateur.&lt;/li&gt;
&lt;li&gt;Allez dans le &lt;strong&gt;Catalogue d’applications&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Recherchez l’app &lt;strong&gt;GPodder Sync&lt;/strong&gt; et installez-la.&lt;/li&gt;
&lt;li&gt;Une fois installée, l’app sera disponible à l’adresse :&lt;br&gt;
&lt;code&gt;https://votre-nextcloud.tld/index.php/apps/gpoddersync/&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Projet officiel : &lt;a href=&#34;https://apps.nextcloud.com/apps/gpoddersync&#34;&gt;https://apps.nextcloud.com/apps/gpoddersync&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;connexion-dantennapod-à-nextcloud&#34;&gt;Connexion d’AntennaPod à Nextcloud&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Ouvrez &lt;strong&gt;AntennaPod&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Allez dans &lt;strong&gt;Paramètres &amp;gt; Synchronisation&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Appuyez sur &lt;strong&gt;Choisir le fournisseur de synchronisation&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Sélectionnez &lt;strong&gt;Nextcloud&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Entrez l’adresse de votre serveur Nextcloud, par exemple :&lt;br&gt;
&lt;code&gt;https://votre-nextcloud.tld&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Appuyez sur &lt;strong&gt;Continuer&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Une fenêtre de connexion s’ouvre dans le navigateur : entrez vos identifiants Nextcloud.&lt;/li&gt;
&lt;li&gt;Autorisez AntennaPod à accéder à votre compte.&lt;/li&gt;
&lt;li&gt;Une fois connecté, la synchronisation se fera automatiquement.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id=&#34;synchronisation-entre-plusieurs-appareils&#34;&gt;Synchronisation entre plusieurs appareils&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Répétez les étapes ci-dessus sur chaque appareil.&lt;/li&gt;
&lt;li&gt;AntennaPod synchronisera automatiquement les abonnements, les épisodes lus, et la position de lecture.&lt;/li&gt;
&lt;li&gt;Vous pouvez forcer une synchronisation manuellement via l’option &lt;strong&gt;Forcer la synchronisation&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;bonnes-pratiques&#34;&gt;Bonnes pratiques&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Faites une première &lt;strong&gt;sauvegarde OPML&lt;/strong&gt; au cas où, avant de basculer vers la synchronisation via Nextcloud.&lt;/li&gt;
&lt;li&gt;Activez la synchronisation seulement &lt;strong&gt;sur des appareils que vous utilisez réellement&lt;/strong&gt;, pour éviter les conflits.&lt;/li&gt;
&lt;li&gt;Si vous avez déjà commencé à écouter des épisodes avant de lier l’appareil, pensez à appuyer sur &lt;strong&gt;Forcer la synchronisation&lt;/strong&gt; après l’activation, afin d’envoyer les états d’écoute existants.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;alternative--utiliser-le-serveur-public-gpoddernet&#34;&gt;Alternative : utiliser le serveur public gpodder.net&lt;/h2&gt;
&lt;p&gt;Si vous ne voulez pas héberger votre propre Nextcloud :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Inscrivez-vous sur &lt;a href=&#34;https://www.gpodder.net&#34;&gt;https://www.gpodder.net&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Créez un ou plusieurs “devices” (appareils) dans l’interface web&lt;/li&gt;
&lt;li&gt;Connectez AntennaPod au serveur en suivant les mêmes étapes que ci-dessus, en choisissant cette fois le fournisseur “gPodder”&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Attention&lt;/strong&gt; : le serveur public est souvent saturé. L’expérience peut être instable.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Avec AntennaPod et Nextcloud, vous gardez le contrôle total sur vos podcasts, sans dépendance aux services fermés. C’est une solution idéale pour les utilisateurs soucieux de leur vie privée, ou tout simplement pour ceux qui veulent une synchronisation robuste entre plusieurs appareils.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title></title>
      <link>https://blog.rmendes.net/2025/05/04/podcast-what-next-tbd-how.html</link>
      <pubDate>Sun, 04 May 2025 14:28:24 +0100</pubDate>
      
      <guid>http://rmdes.micro.blog/2025/05/04/podcast-what-next-tbd-how.html</guid>
      <description>&lt;p&gt;Podcast 🎙️&lt;/p&gt;
&lt;p&gt;What Next: TBD | How Elon Wields Power&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.podtrac.com/pts/redirect.mp3/pdst.fm/e/chtbl.com/track/28D492/traffic.megaphone.fm/SLT9372781545.mp3&#34;&gt;Listen&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Anything getting in the way of &amp;ldquo;Autonomous cars&amp;rdquo; envisioned by #Musk is an enemy of &amp;ldquo;evolution&amp;rdquo; never a victim of unvetted features, pushed to sell a dream, at any costs, even death.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title></title>
      <link>https://blog.rmendes.net/2025/04/16/une-ppite-de-la-musique.html</link>
      <pubDate>Wed, 16 Apr 2025 15:53:56 +0100</pubDate>
      
      <guid>http://rmdes.micro.blog/2025/04/16/une-ppite-de-la-musique.html</guid>
      <description>&lt;p&gt;Une pépite de la musique électronique de la scène Bruxelloise : Avelyne&lt;/p&gt;
&lt;p&gt;Interview à écouter ici :
&lt;a href=&#34;https://www.mixcloud.com/VIBRATIONWAVES/waves-486-aveline-interview-15425/&#34;&gt;www.mixcloud.com/VIBRATION&amp;hellip;&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title></title>
      <link>https://blog.rmendes.net/2023/10/15/how-to-export.html</link>
      <pubDate>Sun, 15 Oct 2023 14:34:58 +0100</pubDate>
      
      <guid>http://rmdes.micro.blog/2023/10/15/how-to-export.html</guid>
      <description>&lt;p&gt;How to export your Google Podcast subscriptions to &lt;a href=&#34;https://Podcastindex.org&#34;&gt;Podcastindex.org&lt;/a&gt; and then to Any other podcast app you like?&lt;/p&gt;
&lt;p&gt;This is &lt;a href=&#34;https://github.com/lucasrangit/google-podcasts-export-opml/blob/main/README.md&#34;&gt;how&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Once you have it all in podcastindex.org, it&amp;rsquo;s easy to export your list to OPML and then import back into another podcast app.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Ceci n&#39;est pas un Podcast 🤣</title>
      <link>https://blog.rmendes.net/2023/09/25/ceci-nest-pas.html</link>
      <pubDate>Mon, 25 Sep 2023 20:57:55 +0100</pubDate>
      
      <guid>http://rmdes.micro.blog/2023/09/25/ceci-nest-pas.html</guid>
      <description>&lt;p&gt;je crois que je vais me mettre ça en sonnerie et voir comment les gens réagissent 😅&lt;/p&gt;
&lt;audio controls=&#34;controls&#34; src=&#34;https://blog.rmendes.net/uploads/2023/voice-169566953364.mp3&#34; preload=&#34;metadata&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.rmendes.net/transcripts/2023/09/25/517.html&#34; class=&#34;transcript_link&#34;&gt;Transcript&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>L&#39;affaire OKC-Spatz, Qu&#39;est-ce que c&#39;est, une dérive sectaire? Comment la reconnaît-on? </title>
      <link>https://blog.rmendes.net/2023/09/11/questce-que-cest.html</link>
      <pubDate>Mon, 11 Sep 2023 22:04:27 +0100</pubDate>
      
      <guid>http://rmdes.micro.blog/2023/09/11/questce-que-cest.html</guid>
      <description>&lt;p&gt;Au micro de Radio Laser, je raconte mon expérience dans le mouvement sectaire OKC dans lequel je suis né et ai grandi jusque dans ma vingtaine.&lt;/p&gt;
&lt;p&gt;Une version longue d&amp;rsquo;un entretien qui fait partie du reportage &amp;ldquo;focus sur les dérives sectaires&amp;rdquo; que vous pouvez retrouver &lt;a href=&#34;https://www.radiolaser.fr/podcasts/i/23391/focus-sur-les-derives-sectaires/&#34;&gt;ici&lt;/a&gt;&lt;/p&gt;
&lt;audio controls=&#34;controls&#34; src=&#34;https://blog.rmendes.net/uploads/2023/drives-sectairesle-mouvement-okc.mp3&#34; preload=&#34;metadata&#34;&gt;
</description>
    </item>
    
  </channel>
</rss>