<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>roblog</title>
    <link>https://blog.rstokes.uk/</link>
    <description>Random musings—mostly for me, but you might accidentally find something useful too</description>
    <pubDate>Tue, 21 Jul 2026 23:08:37 +0100</pubDate>
    <item>
      <title>FIA Formula 1 2026 Regulations</title>
      <link>https://blog.rstokes.uk/fia-formula-1-2026-regulations</link>
      <description>&lt;![CDATA[The sporting, technical, financial, and operational regulations for the 2026 FIA Formula 1 World Championship.&#xA;&#xA;!--more--&#xA;&#xA;a target=&#34;blank&#34; style=&#34;border:none;&#34; href=&#34;https://api.fia.com/regulation/category/110&#34;img style=&#34;margin:-30px 0;&#34; src=&#34;https://corp.formula1.com/wp-content/uploads/2025/03/JPG-RGB-F1FIAChampionshipStkPositiveMicroRGB.jpg&#34;/a&#xA;&#xA;a target=&#34;blank&#34; href=&#34;https://www.fia.com/system/files/documents/fia2026f1regulations-sectionageneralprovisions-iss03-2026-06-25.pdf&#34;Section A: General Provisions/a&#xA;&#xA;a target=&#34;blank&#34; href=&#34;https://www.fia.com/system/files/documents/fia2026f1regulations-sectionbsporting-iss07-2026-06-25.pdf&#34;Section B: Sporting Regulations/a&#xA;&#xA;a target=&#34;blank&#34; href=&#34;https://www.fia.com/system/files/documents/fia2026f1regulations-sectionctechnical-iss19-2026-06-25.pdf&#34;Section C: Technical Regulations/a&#xA;&#xA;a target=&#34;blank&#34; href=&#34;https://www.fia.com/system/files/documents/fia2026f1regulations-sectiondfinancial-f1teams-iss07-2026-06-25.pdf&#34;Section D: Financial Regulationsbr(Formula 1 Constructors)/a&#xA;&#xA;a target=&#34;blank&#34; href=&#34;https://www.fia.com/system/files/documents/fia2026f1regulations-sectionefinancial-pumanufacturers-iss06-2026-06-25.pdf&#34;Section E: Financial Regulationsbr(Power Unit Manufacturers)/a&#xA;&#xA;a target=&#34;blank&#34; href=&#34;https://www.fia.com/system/files/documents/fia2026f1regulations-sectionfoperational-iss09-2026-06-25.pdf&#34;Section F: Operational Regulations/a&#xA;&#xA;brTags: #F1]]&gt;</description>
      <content:encoded><![CDATA[<p>The sporting, technical, financial, and operational regulations for the 2026 FIA Formula 1 World Championship.</p>



<p><a target="_blank" style="border:none;" href="https://api.fia.com/regulation/category/110"><img style="margin:-30px 0;" src="https://corp.formula1.com/wp-content/uploads/2025/03/JPG-RGB-F1_FIA_Championship_Stk_Positive_Micro_RGB.jpg"></a></p>

<p><a target="_blank" href="https://www.fia.com/system/files/documents/fia_2026_f1_regulations_-_section_a_general_provisions_-_iss_03_-_2026-06-25.pdf"><strong>Section A: General Provisions</strong></a></p>

<p><a target="_blank" href="https://www.fia.com/system/files/documents/fia_2026_f1_regulations_-_section_b_sporting_-_iss_07_-_2026-06-25.pdf"><strong>Section B: Sporting Regulations</strong></a></p>

<p><a target="_blank" href="https://www.fia.com/system/files/documents/fia_2026_f1_regulations_-_section_c_technical_-_iss_19_-_2026-06-25.pdf"><strong>Section C: Technical Regulations</strong></a></p>

<p><a target="_blank" href="https://www.fia.com/system/files/documents/fia_2026_f1_regulations_-_section_d_financial_-_f1_teams_-_iss_07_-_2026-06-25.pdf"><strong>Section D: Financial Regulations<br>(Formula 1 Constructors)</strong></a></p>

<p><a target="_blank" href="https://www.fia.com/system/files/documents/fia_2026_f1_regulations_-_section_e_financial_-_pu_manufacturers_-_iss_06_-_2026-06-25.pdf"><strong>Section E: Financial Regulations<br>(Power Unit Manufacturers)</strong></a></p>

<p><a target="_blank" href="https://www.fia.com/system/files/documents/fia_2026_f1_regulations_-_section_f_operational_-_iss_09_-_2026-06-25.pdf"><strong>Section F: Operational Regulations</strong></a></p>

<p><br>Tags: <a href="https://blog.rstokes.uk/tag:F1" class="hashtag"><span>#</span><span class="p-category">F1</span></a></p>
]]></content:encoded>
      <guid>https://blog.rstokes.uk/fia-formula-1-2026-regulations</guid>
      <pubDate>Tue, 07 Jul 2026 12:32:11 +0000</pubDate>
    </item>
    <item>
      <title>Installing Pixelfed Glitch on a Raspberry Pi</title>
      <link>https://blog.rstokes.uk/installing-pixelfed-glitch-on-a-raspberry-pi</link>
      <description>&lt;![CDATA[Although the official Pixelfed Glitch Docker docs are fairly short, I found a few rough edges when installing it on a Raspberry Pi. This guide pulls the official instructions together with the fixes I needed along the way.&#xA;&#xA;This uses the Docker version of Pixelfed Glitch, with MariaDB and Redis running as Docker containers.&#xA;&#xA;!--more--&#xA;&#xA;div style=&#34;margin-top:-20px&#34;/div&#xA;&#xA;Contents&#xA;&#xA;a href=&#34;#install-docker&#34;Step 1 – Install Docker/a&#xA;a href=&#34;#allow-your-user-to-run-docker&#34;Step 2 – Allow your user to run Docker/a&#xA;a href=&#34;#create-the-pixelfed-glitch-directory&#34;Step 3 – Create the Pixelfed Glitch directory/a&#xA;a href=&#34;#download-the-docker-files&#34;Step 4 – Download the Docker files/a&#xA;a href=&#34;#edit-the-environment-file&#34;Step 5 – Edit the environment file/a&#xA;a href=&#34;#prepare-pixelfeds-storage-directories&#34;Step 6 – Prepare Pixelfed&#39;s storage directories/a&#xA;a href=&#34;#start-pixelfed-glitch&#34;Step 7 – Start Pixelfed Glitch/a&#xA;a href=&#34;#generate-the-application-and-oauth-keys&#34;Step 8 – Generate the application and OAuth keys/a&#xA;a href=&#34;#stop-first-time-setup-from-running-again&#34;Step 9 – Stop first-time setup from running again/a&#xA;a href=&#34;#check-the-site&#34;Step 10 – Check the site/a&#xA;a href=&#34;#create-the-first-user&#34;Step 11 – Create the first user/a&#xA;a href=&#34;#create-another-user&#34;Step 12 – Create another user/a&#xA;a href=&#34;#useful-checks&#34;Step 13 – Useful checks/a&#xA;a href=&#34;#mobile-app-login-and-2fa&#34;Step 14 – Mobile app login and 2FA/a&#xA;a href=&#34;#reboot-behaviour&#34;Step 15 – Reboot behaviour/a&#xA;a href=&#34;#backups&#34;Step 16 – Backups/a&#xA;a href=&#34;#troubleshooting-notes&#34;Troubleshooting notes/a&#xA;&#xA;div id=&#34;install-docker&#34; style=&#34;margin-top:-15px&#34;/div&#xA;&#xA;Step 1. Install Docker&#xA;&#xA;Pixelfed Glitch will run inside Docker containers. This means we do not need to manually install PHP, MariaDB, Redis, Node, Composer, or most of the other application dependencies on the Raspberry Pi itself.&#xA;&#xA;i. Update the package list:&#xA;&#xA;presudo apt update &amp;&amp; sudo apt upgrade/pre&#xA;&#xA;ii. Install the packages needed to add Docker&#39;s repository:&#xA;&#xA;presudo apt install -y ca-certificates curl/pre&#xA;&#xA;iii. Create the keyrings directory:&#xA;&#xA;presudo install -m 0755 -d /etc/apt/keyrings/pre&#xA;&#xA;iv. Download Docker&#39;s GPG key:&#xA;&#xA;presudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc/pre&#xA;&#xA;v. Make the key readable:&#xA;&#xA;presudo chmod a+r /etc/apt/keyrings/docker.asc/pre&#xA;&#xA;vi. Add Docker&#39;s repository:&#xA;&#xA;presudo tee /etc/apt/sources.list.d/docker.sources &amp;lt;&amp;lt;EOF&#xA;Types: deb&#xA;URIs: https://download.docker.com/linux/debian&#xA;Suites: $(. /etc/os-release &amp;&amp; echo &#34;$VERSIONCODENAME&#34;)&#xA;Components: stable&#xA;Architectures: $(dpkg --print-architecture)&#xA;Signed-By: /etc/apt/keyrings/docker.asc&#xA;EOF/pre&#xA;&#xA;vii. Update the package list again:&#xA;&#xA;presudo apt update/pre&#xA;&#xA;viii. Install Docker and the Compose plugin:&#xA;&#xA;presudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin/pre&#xA;&#xA;ix. Check Docker is running:&#xA;&#xA;presudo systemctl status docker/pre&#xA;&#xA;x. Enable Docker to start at boot:&#xA;&#xA;presudo systemctl enable docker.service&#xA;sudo systemctl enable containerd.service/pre&#xA;&#xA;div id=&#34;allow-your-user-to-run-docker&#34; style=&#34;margin-top:-15px&#34;/div&#xA;&#xA;Step 2. Allow your user to run Docker&#xA;&#xA;By default, Docker commands need sudo. To run docker compose as your normal user, add your user to the docker group.&#xA;&#xA;i. Create the group, if it does not already exist:&#xA;&#xA;presudo groupadd docker 2  /dev/null || true/pre&#xA;&#xA;ii. Add your user to it:&#xA;&#xA;presudo usermod -aG docker $USER/pre&#xA;&#xA;iii. Log out of SSH and log back in, or reboot the Pi.&#xA;&#xA;iv. Test Docker without sudo:&#xA;&#xA;predocker run hello-world/pre&#xA;&#xA;If this works, Docker is ready.&#xA;&#xA;div id=&#34;create-the-pixelfed-glitch-directory&#34; style=&#34;margin-top:-15px&#34;/div&#xA;&#xA;Step 3. Create the Pixelfed Glitch directory&#xA;&#xA;I installed Pixelfed Glitch under my home directory:&#xA;&#xA;precd /home/pi&#xA;mkdir -p pixelfed-glitch&#xA;cd pixelfed-glitch/pre&#xA;&#xA;Change /home/pi to match your own username if needed.&#xA;&#xA;div id=&#34;download-the-docker-files&#34; style=&#34;margin-top:-15px&#34;/div&#xA;&#xA;Step 4. Download the Docker files&#xA;&#xA;Download the Docker Compose file and the example environment file from the Pixelfed Glitch repository:&#xA;&#xA;precurl -fsSL https://raw.githubusercontent.com/pixelfed-glitch/pixelfed/develop/docker-compose.yml -o docker-compose.yml&#xA;curl -fsSL https://raw.githubusercontent.com/pixelfed-glitch/pixelfed/develop/.env.docker -o .env/pre&#xA;&#xA;The docker-compose.yml file defines the containers. The .env file holds site-specific settings such as the domain name, database password, upload limits, email settings, and Docker image tags.&#xA;&#xA;div id=&#34;edit-the-environment-file&#34; style=&#34;margin-top:-15px&#34;/div&#xA;&#xA;Step 5. Edit the environment file&#xA;&#xA;Open the .env file:&#xA;&#xA;prenano .env/pre&#xA;&#xA;At minimum, change the following values.&#xA;&#xA;Set the name of the site:&#xA;&#xA;preAPPNAME=&#34;My Pixelfed Site&#34;/pre&#xA;&#xA;Set the domain name, without https:// and without a trailing slash:&#xA;&#xA;preAPPDOMAIN=&#34;photos.example.com&#34;/pre&#xA;&#xA;Leave APPURL like this:&#xA;&#xA;preAPPURL=&#34;https://${APPDOMAIN}&#34;/pre&#xA;&#xA;Leave ADMINDOMAIN like this:&#xA;&#xA;preADMINDOMAIN=&#34;${APPDOMAIN}&#34;/pre&#xA;&#xA;Set a public contact email address:&#xA;&#xA;preINSTANCECONTACTEMAIL=&#34;admin@example.com&#34;/pre&#xA;&#xA;Set a secure database password:&#xA;&#xA;preDBPASSWORD=&#34;CHANGETHISTOALONGRANDOMPASSWORD&#34;/pre&#xA;&#xA;If you do not plan to send email at first, you can disable mandatory email verification:&#xA;&#xA;preENFORCEEMAILVERIFICATION=&#34;false&#34;/pre&#xA;&#xA;Make sure OAuth is enabled, as this is needed for Pixelfed mobile apps:&#xA;&#xA;preOAUTHENABLED=&#34;true&#34;/pre&#xA;&#xA;Leave APPKEY empty at this stage:&#xA;&#xA;preAPPKEY=/pre&#xA;&#xA;Pixelfed will generate this later. If you ever set it manually, it must be one single Laravel key, for example:&#xA;&#xA;preAPPKEY=base64:CHANGETHISTOONEVALIDKEYONLY/pre&#xA;&#xA;Do not paste two keys together on the same line.&#xA;&#xA;div id=&#34;prepare-pixelfeds-storage-directories&#34; style=&#34;margin-top:-15px&#34;/div&#xA;&#xA;Step 6. Prepare Pixelfed&#39;s storage directories&#xA;&#xA;The Docker image expects several Laravel storage paths to exist. Creating them now avoids a startup error such as:&#xA;&#xA;prePlease provide a valid cache path./pre&#xA;&#xA;Run:&#xA;&#xA;precd /home/pi/pixelfed-glitch&#xA;&#xA;sudo mkdir -p docker-compose-state/data/pixelfed/storage/app/public&#xA;sudo mkdir -p docker-compose-state/data/pixelfed/storage/framework/cache/data&#xA;sudo mkdir -p docker-compose-state/data/pixelfed/storage/framework/sessions&#xA;sudo mkdir -p docker-compose-state/data/pixelfed/storage/framework/testing&#xA;sudo mkdir -p docker-compose-state/data/pixelfed/storage/framework/views&#xA;sudo mkdir -p docker-compose-state/data/pixelfed/storage/logs&#xA;sudo mkdir -p docker-compose-state/data/pixelfed/storage/docker/lock&#xA;sudo mkdir -p docker-compose-state/data/pixelfed/cache&#xA;&#xA;sudo chown -R 33:33 docker-compose-state/data/pixelfed/storage&#xA;sudo chown -R 33:33 docker-compose-state/data/pixelfed/cache/pre&#xA;&#xA;User ID 33 is www-data, which is the user Pixelfed runs as inside the container.&#xA;&#xA;div id=&#34;start-pixelfed-glitch&#34; style=&#34;margin-top:-15px&#34;/div&#xA;&#xA;Step 7. Start Pixelfed Glitch&#xA;&#xA;Start the containers:&#xA;&#xA;predocker compose up -d/pre&#xA;&#xA;This downloads the Pixelfed Glitch, MariaDB, and Redis images, creates the containers, and starts the first-time setup.&#xA;&#xA;Check the containers:&#xA;&#xA;predocker compose ps/pre&#xA;&#xA;You should eventually see web, worker, cron, db, and redis as Up.&#xA;&#xA;To watch the logs:&#xA;&#xA;predocker compose logs --tail=100 --follow/pre&#xA;&#xA;If you only want the web container logs:&#xA;&#xA;predocker compose logs --tail=100 web/pre&#xA;&#xA;div id=&#34;generate-the-application-and-oauth-keys&#34; style=&#34;margin-top:-15px&#34;/div&#xA;&#xA;Step 8. Generate the application and OAuth keys&#xA;&#xA;If the site shows a 500 error and the logs mention either of these:&#xA;&#xA;preNo application encryption key has been specified.&#xA;Invalid key supplied/pre&#xA;&#xA;run the following commands:&#xA;&#xA;predocker compose exec web php artisan key:generate --force&#xA;docker compose exec -u www-data web php artisan passport:keys --force/pre&#xA;&#xA;Then clear and rebuild Pixelfed&#39;s cached config:&#xA;&#xA;predocker compose exec -u www-data web php artisan view:clear&#xA;docker compose exec -u www-data web php artisan config:clear&#xA;docker compose exec -u www-data web php artisan cache:clear&#xA;docker compose exec -u www-data web php artisan config:cache/pre&#xA;&#xA;Restart the Pixelfed containers:&#xA;&#xA;predocker compose restart web worker cron/pre&#xA;&#xA;div id=&#34;stop-first-time-setup-from-running-again&#34; style=&#34;margin-top:-15px&#34;/div&#xA;&#xA;Step 9. Stop first-time setup from running again&#xA;&#xA;After the first-time setup has completed and the keys have been created, edit .env again:&#xA;&#xA;prenano .env/pre&#xA;&#xA;Add this line:&#xA;&#xA;preDOCKERAPPRUNONETIMESETUPTASKS=&#34;0&#34;/pre&#xA;&#xA;This stops Pixelfed from trying to recreate encryption keys on every container start.&#xA;&#xA;If this is not set, the container may restart repeatedly with an error like:&#xA;&#xA;preEncryption keys already exist. Use the --force option to overwrite them./pre&#xA;&#xA;Restart the stack:&#xA;&#xA;predocker compose down&#xA;docker compose up -d/pre&#xA;&#xA;Do not use docker compose down -v, as that removes Docker volumes.&#xA;&#xA;div id=&#34;check-the-site&#34; style=&#34;margin-top:-15px&#34;/div&#xA;&#xA;Step 10. Check the site&#xA;&#xA;Open your Pixelfed URL in a browser:&#xA;&#xA;prehttps://photos.example.com/pre&#xA;&#xA;If you are using NGINX as a reverse proxy, make sure it points to the Docker web port. In the default Pixelfed Glitch Docker file this is:&#xA;&#xA;pre8080/pre&#xA;&#xA;So the proxy target is:&#xA;&#xA;prehttp://127.0.0.1:8080/pre&#xA;&#xA;Check the running containers:&#xA;&#xA;predocker compose ps/pre&#xA;&#xA;If you see a 502 error, the web container is probably not running yet, or it is restarting. Check:&#xA;&#xA;predocker compose logs --tail=200 web/pre&#xA;&#xA;div id=&#34;create-the-first-user&#34; style=&#34;margin-top:-15px&#34;/div&#xA;&#xA;Step 11. Create the first user&#xA;&#xA;Create the first account:&#xA;&#xA;predocker compose exec -u www-data web php artisan user:create/pre&#xA;&#xA;Follow the prompts.&#xA;&#xA;To make the user an admin:&#xA;&#xA;predocker compose exec -u www-data web php artisan user:admin USERNAME/pre&#xA;&#xA;To manually verify an email address:&#xA;&#xA;predocker compose exec -u www-data web php artisan user:verifyemail USERNAME/pre&#xA;&#xA;For example:&#xA;&#xA;predocker compose exec -u www-data web php artisan user:admin rob&#xA;docker compose exec -u www-data web php artisan user:verifyemail rob/pre&#xA;&#xA;div id=&#34;create-another-user&#34; style=&#34;margin-top:-15px&#34;/div&#xA;&#xA;Step 12. Create another user&#xA;&#xA;Run the same create command again:&#xA;&#xA;predocker compose exec -u www-data web php artisan user:create/pre&#xA;&#xA;Follow the prompts and enter the new username.&#xA;&#xA;For example:&#xA;&#xA;prebnw/pre&#xA;&#xA;Only run the admin command for accounts that should have admin rights.&#xA;&#xA;div id=&#34;useful-checks&#34; style=&#34;margin-top:-15px&#34;/div&#xA;&#xA;Step 13. Useful checks&#xA;&#xA;Check container status:&#xA;&#xA;predocker compose ps/pre&#xA;&#xA;Show recent logs:&#xA;&#xA;predocker compose logs --tail=200 web/pre&#xA;&#xA;Check the current Pixelfed config values:&#xA;&#xA;predocker compose exec -u www-data web php artisan tinker --execute=&#39;&#xA;echo &#34;app.url=&#34;.config(&#34;app.url&#34;).PHPEOL;&#xA;echo &#34;oauth=&#34;.(config(&#34;pixelfed.oauthenabled&#34;) ? &#34;true&#34; : &#34;false&#34;).PHPEOL;&#xA;echo &#34;session.domain=&#34;.config(&#34;session.domain&#34;).PHPEOL;&#xA;&#39;/pre&#xA;&#xA;Check the application key:&#xA;&#xA;pregrep &#39;^APPKEY=&#39; .env/pre&#xA;&#xA;A valid key should look like one single line:&#xA;&#xA;preAPPKEY=base64:LONGRANDOMSTRINGHERE/pre&#xA;&#xA;Check the OAuth key files:&#xA;&#xA;predocker compose exec -u www-data web ls -l storage/oauth-private.key storage/oauth-public.key/pre&#xA;&#xA;div id=&#34;mobile-app-login-and-2fa&#34; style=&#34;margin-top:-15px&#34;/div&#xA;&#xA;Step 14. Mobile app login and 2FA&#xA;&#xA;The web version worked fine for me with 2FA enabled.&#xA;&#xA;The mobile app login flow was different. With 2FA enabled, the official Pixelfed app and Impressia both opened a web login pop-up, accepted the username, password, and 2FA code, then stayed in the web version inside the pop-up instead of returning to the app.&#xA;&#xA;The workaround was:&#xA;&#xA;Keep 2FA enabled on the admin account.&#xA;Use a separate non-admin account for mobile app login.&#xA;Disable 2FA on that non-admin account before logging in to the apps.&#xA;&#xA;If the web interface will not disable 2FA and clicking the green &#34;Enabled&#34; button only adds # to the URL, disable it from the database.&#xA;&#xA;First check the 2FA column names:&#xA;&#xA;predocker compose exec -u www-data web php artisan tinker --execute=&#39;&#xA;printr(arrayvalues(arrayfilter(&#xA;&#x9;Schema::getColumnListing(&#34;users&#34;),&#xA;&#x9;fn($c) =  strcontains(strtolower($c), &#34;two&#34;) || strcontains(strtolower($c), &#34;2fa&#34;) || strcontains(strtolower($c), &#34;otp&#34;)&#xA;)));&#xA;&#39;/pre&#xA;&#xA;On my install the columns were:&#xA;&#xA;pre2faenabled&#xA;2fasecret&#xA;2fabackupcodes&#xA;2fasetupat/pre&#xA;&#xA;To disable 2FA for a user called bnw:&#xA;&#xA;predocker compose exec -u www-data web php artisan tinker --execute=&#39;&#xA;DB::table(&#34;users&#34;)-  where(&#34;username&#34;, &#34;bnw&#34;)-  update([&#xA;&#x9;&#34;2faenabled&#34; =  false,&#xA;&#x9;&#34;2fasecret&#34; =  null,&#xA;&#x9;&#34;2fabackupcodes&#34; =  null,&#xA;&#x9;&#34;2fasetupat&#34; =  null,&#xA;]);&#xA;echo &#34;2FA disabled for bnw\n&#34;;&#xA;&#39;/pre&#xA;&#xA;After that, app login worked.&#xA;&#xA;div id=&#34;reboot-behaviour&#34; style=&#34;margin-top:-15px&#34;/div&#xA;&#xA;Step 15. Reboot behaviour&#xA;&#xA;The docker-compose.yml file uses:&#xA;&#xA;prerestart: unless-stopped/pre&#xA;&#xA;This means the containers should come back up after a reboot, as long as Docker itself starts on boot.&#xA;&#xA;Check Docker is enabled:&#xA;&#xA;presystemctl is-enabled docker/pre&#xA;&#xA;If needed:&#xA;&#xA;presudo systemctl enable docker/pre&#xA;&#xA;After a reboot, check Pixelfed:&#xA;&#xA;precd /home/pi/pixelfed-glitch&#xA;docker compose ps/pre&#xA;&#xA;One thing to remember: if you run this command:&#xA;&#xA;predocker compose down/pre&#xA;&#xA;the containers are removed. Docker cannot restart removed containers at boot. To recreate and start them:&#xA;&#xA;precd /home/pi/pixelfed-glitch&#xA;docker compose up -d/pre&#xA;&#xA;div id=&#34;backups&#34; style=&#34;margin-top:-15px&#34;/div&#xA;&#xA;Step 16. Backups&#xA;&#xA;At minimum, back up the Pixelfed Glitch install directory:&#xA;&#xA;pre/home/pi/pixelfed-glitch/pre&#xA;&#xA;This contains:&#xA;&#xA;predocker-compose.yml&#xA;.env&#xA;docker-compose-state//pre&#xA;&#xA;The .env file contains secrets, including the database password and application key, so store backups securely.&#xA;&#xA;The docker-compose-state directory contains the MariaDB data, Redis data, Pixelfed storage, and cache folders. For a live database, a proper database dump is safer than only copying files while containers are running.&#xA;&#xA;A simple manual MariaDB dump can be created with:&#xA;&#xA;precd /home/pi/pixelfed-glitch&#xA;docker compose exec db mariadb-dump -u pixelfed -p pixelfedprod   pixelfeddbbackup.sql/pre&#xA;&#xA;You will be prompted for the database password from .env.&#xA;&#xA;div id=&#34;troubleshooting-notes&#34; style=&#34;margin-top:-15px&#34;/div&#xA;&#xA;Troubleshooting notes&#xA;&#xA;a href=&#34;#docker-permission-denied&#34;Docker permission denied/a&#xA;a href=&#34;#missing-cache-path&#34;Missing cache path/a&#xA;a href=&#34;#invalid-application-key&#34;Invalid application key/a&#xA;a href=&#34;#first-time-setup-keeps-running&#34;First-time setup keeps running/a&#xA;&#xA;div id=&#34;docker-permission-denied&#34; style=&#34;margin-top:-5px&#34;/div&#xA;&#xA;Docker permission denied&#xA;&#xA;If you see:&#xA;&#xA;prepermission denied while trying to connect to the docker API at unix:///var/run/docker.sock/pre&#xA;&#xA;your user is not in the docker group, or the current login session has not picked up the new group membership.&#xA;&#xA;Fix:&#xA;&#xA;presudo usermod -aG docker $USER/pre&#xA;&#xA;Then log out and back in.&#xA;&#xA;div id=&#34;missing-cache-path&#34; style=&#34;margin-top:-5px&#34;/div&#xA;&#xA;Missing cache path&#xA;&#xA;If the web container restarts and logs show:&#xA;&#xA;prePlease provide a valid cache path./pre&#xA;&#xA;create the Laravel storage and cache folders from Step 6.&#xA;&#xA;div id=&#34;invalid-application-key&#34; style=&#34;margin-top:-5px&#34;/div&#xA;&#xA;Invalid application key&#xA;&#xA;If the site shows a 500 error and logs show:&#xA;&#xA;preUnsupported cipher or incorrect key length/pre&#xA;&#xA;check .env:&#xA;&#xA;pregrep &#39;^APPKEY=&#39; .env/pre&#xA;&#xA;The key must be one single key. It must not look like this:&#xA;&#xA;preAPPKEY=base64:KEYONE=base64:KEYTWO/pre&#xA;&#xA;To replace it on a new install:&#xA;&#xA;prenewkey=&#34;base64:$(openssl rand -base64 32)&#34;&#xA;sudo sed -i.bak &#34;s|^APPKEY=.*|APPKEY=${newkey}|&#34; .env/pre&#xA;&#xA;Then clear the caches:&#xA;&#xA;predocker compose exec -u www-data web php artisan view:clear&#xA;docker compose exec -u www-data web php artisan config:clear&#xA;docker compose exec -u www-data web php artisan cache:clear&#xA;docker compose exec -u www-data web php artisan config:cache&#xA;docker compose restart web worker cron/pre&#xA;&#xA;div id=&#34;first-time-setup-keeps-running&#34; style=&#34;margin-top:-5px&#34;/div&#xA;&#xA;First-time setup keeps running&#xA;&#xA;If the web container keeps restarting and logs show:&#xA;&#xA;preEncryption keys already exist. Use the --force option to overwrite them./pre&#xA;&#xA;set this in .env:&#xA;&#xA;preDOCKERAPPRUNONETIMESETUPTASKS=&#34;0&#34;/pre&#xA;&#xA;Then restart:&#xA;&#xA;predocker compose down&#xA;docker compose up -d/pre&#xA;&#xA;div style=&#34;margin-top:-10px&#34;/div&#xA;&#xA;span style=&#34;font-size:0.95em;font-weight:bold;&#34;Sources:/span&#xA;span style=&#34;font-size:0.85em;&#34;Pixelfed Glitch Docker installation docs&#xA;Pixelfed Glitch configuration docs&#xA;Docker Engine Debian installation docs&#xA;Docker Linux post-installation docs&#xA;/span&#xA;&#xA;brTags: #Pixelfed #RaspberryPi]]&gt;</description>
      <content:encoded><![CDATA[<p>Although the official Pixelfed Glitch Docker docs are fairly short, I found a few rough edges when installing it on a Raspberry Pi. This guide pulls the official instructions together with the fixes I needed along the way.</p>

<p>This uses the Docker version of Pixelfed Glitch, with MariaDB and Redis running as Docker containers.</p>



<div style="margin-top:-20px"></div>

<h3 id="contents">Contents</h3>

<p><a href="#install-docker">Step 1 – Install Docker</a>
<a href="#allow-your-user-to-run-docker">Step 2 – Allow your user to run Docker</a>
<a href="#create-the-pixelfed-glitch-directory">Step 3 – Create the Pixelfed Glitch directory</a>
<a href="#download-the-docker-files">Step 4 – Download the Docker files</a>
<a href="#edit-the-environment-file">Step 5 – Edit the environment file</a>
<a href="#prepare-pixelfeds-storage-directories">Step 6 – Prepare Pixelfed&#39;s storage directories</a>
<a href="#start-pixelfed-glitch">Step 7 – Start Pixelfed Glitch</a>
<a href="#generate-the-application-and-oauth-keys">Step 8 – Generate the application and OAuth keys</a>
<a href="#stop-first-time-setup-from-running-again">Step 9 – Stop first-time setup from running again</a>
<a href="#check-the-site">Step 10 – Check the site</a>
<a href="#create-the-first-user">Step 11 – Create the first user</a>
<a href="#create-another-user">Step 12 – Create another user</a>
<a href="#useful-checks">Step 13 – Useful checks</a>
<a href="#mobile-app-login-and-2fa">Step 14 – Mobile app login and 2FA</a>
<a href="#reboot-behaviour">Step 15 – Reboot behaviour</a>
<a href="#backups">Step 16 – Backups</a>
<a href="#troubleshooting-notes">Troubleshooting notes</a></p>

<div id="install-docker" style="margin-top:-15px"></div>

<h3 id="step-1-install-docker">Step 1. Install Docker</h3>

<p>Pixelfed Glitch will run inside Docker containers. This means we do not need to manually install PHP, MariaDB, Redis, Node, Composer, or most of the other application dependencies on the Raspberry Pi itself.</p>

<p>i. Update the package list:</p>

<pre>sudo apt update &amp;&amp; sudo apt upgrade</pre>

<p>ii. Install the packages needed to add Docker&#39;s repository:</p>

<pre>sudo apt install -y ca-certificates curl</pre>

<p>iii. Create the keyrings directory:</p>

<pre>sudo install -m 0755 -d /etc/apt/keyrings</pre>

<p>iv. Download Docker&#39;s GPG key:</p>

<pre>sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc</pre>

<p>v. Make the key readable:</p>

<pre>sudo chmod a+r /etc/apt/keyrings/docker.asc</pre>

<p>vi. Add Docker&#39;s repository:</p>

<pre>sudo tee /etc/apt/sources.list.d/docker.sources &lt;&lt;EOF
Types: deb
URIs: https://download.docker.com/linux/debian
Suites: $(. /etc/os-release &amp;&amp; echo &#34;$VERSION_CODENAME&#34;)
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF</pre>

<p>vii. Update the package list again:</p>

<pre>sudo apt update</pre>

<p>viii. Install Docker and the Compose plugin:</p>

<pre>sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin</pre>

<p>ix. Check Docker is running:</p>

<pre>sudo systemctl status docker</pre>

<p>x. Enable Docker to start at boot:</p>

<pre>sudo systemctl enable docker.service
sudo systemctl enable containerd.service</pre>

<div id="allow-your-user-to-run-docker" style="margin-top:-15px"></div>

<h3 id="step-2-allow-your-user-to-run-docker">Step 2. Allow your user to run Docker</h3>

<p>By default, Docker commands need <code>sudo</code>. To run <code>docker compose</code> as your normal user, add your user to the <code>docker</code> group.</p>

<p>i. Create the group, if it does not already exist:</p>

<pre>sudo groupadd docker 2&gt;/dev/null || true</pre>

<p>ii. Add your user to it:</p>

<pre>sudo usermod -aG docker $USER</pre>

<p>iii. Log out of SSH and log back in, or reboot the Pi.</p>

<p>iv. Test Docker without <code>sudo</code>:</p>

<pre>docker run hello-world</pre>

<p>If this works, Docker is ready.</p>

<div id="create-the-pixelfed-glitch-directory" style="margin-top:-15px"></div>

<h3 id="step-3-create-the-pixelfed-glitch-directory">Step 3. Create the Pixelfed Glitch directory</h3>

<p>I installed Pixelfed Glitch under my home directory:</p>

<pre>cd /home/pi
mkdir -p pixelfed-glitch
cd pixelfed-glitch</pre>

<p>Change <code>/home/pi</code> to match your own username if needed.</p>

<div id="download-the-docker-files" style="margin-top:-15px"></div>

<h3 id="step-4-download-the-docker-files">Step 4. Download the Docker files</h3>

<p>Download the Docker Compose file and the example environment file from the Pixelfed Glitch repository:</p>

<pre>curl -fsSL https://raw.githubusercontent.com/pixelfed-glitch/pixelfed/develop/docker-compose.yml -o docker-compose.yml
curl -fsSL https://raw.githubusercontent.com/pixelfed-glitch/pixelfed/develop/.env.docker -o .env</pre>

<p>The <code>docker-compose.yml</code> file defines the containers. The <code>.env</code> file holds site-specific settings such as the domain name, database password, upload limits, email settings, and Docker image tags.</p>

<div id="edit-the-environment-file" style="margin-top:-15px"></div>

<h3 id="step-5-edit-the-environment-file">Step 5. Edit the environment file</h3>

<p>Open the <code>.env</code> file:</p>

<pre>nano .env</pre>

<p>At minimum, change the following values.</p>

<p>Set the name of the site:</p>

<pre>APP_NAME=&#34;My Pixelfed Site&#34;</pre>

<p>Set the domain name, without <code>https://</code> and without a trailing slash:</p>

<pre>APP_DOMAIN=&#34;photos.example.com&#34;</pre>

<p>Leave <code>APP_URL</code> like this:</p>

<pre>APP_URL=&#34;https://${APP_DOMAIN}&#34;</pre>

<p>Leave <code>ADMIN_DOMAIN</code> like this:</p>

<pre>ADMIN_DOMAIN=&#34;${APP_DOMAIN}&#34;</pre>

<p>Set a public contact email address:</p>

<pre>INSTANCE_CONTACT_EMAIL=&#34;admin@example.com&#34;</pre>

<p>Set a secure database password:</p>

<pre>DB_PASSWORD=&#34;CHANGE_THIS_TO_A_LONG_RANDOM_PASSWORD&#34;</pre>

<p>If you do not plan to send email at first, you can disable mandatory email verification:</p>

<pre>ENFORCE_EMAIL_VERIFICATION=&#34;false&#34;</pre>

<p>Make sure OAuth is enabled, as this is needed for Pixelfed mobile apps:</p>

<pre>OAUTH_ENABLED=&#34;true&#34;</pre>

<p>Leave <code>APP_KEY</code> empty at this stage:</p>

<pre>APP_KEY=</pre>

<p>Pixelfed will generate this later. If you ever set it manually, it must be one single Laravel key, for example:</p>

<pre>APP_KEY=base64:CHANGE_THIS_TO_ONE_VALID_KEY_ONLY</pre>

<p>Do not paste two keys together on the same line.</p>

<div id="prepare-pixelfeds-storage-directories" style="margin-top:-15px"></div>

<h3 id="step-6-prepare-pixelfed-s-storage-directories">Step 6. Prepare Pixelfed&#39;s storage directories</h3>

<p>The Docker image expects several Laravel storage paths to exist. Creating them now avoids a startup error such as:</p>

<pre>Please provide a valid cache path.</pre>

<p>Run:</p>

<pre>cd /home/pi/pixelfed-glitch

sudo mkdir -p docker-compose-state/data/pixelfed/storage/app/public
sudo mkdir -p docker-compose-state/data/pixelfed/storage/framework/cache/data
sudo mkdir -p docker-compose-state/data/pixelfed/storage/framework/sessions
sudo mkdir -p docker-compose-state/data/pixelfed/storage/framework/testing
sudo mkdir -p docker-compose-state/data/pixelfed/storage/framework/views
sudo mkdir -p docker-compose-state/data/pixelfed/storage/logs
sudo mkdir -p docker-compose-state/data/pixelfed/storage/docker/lock
sudo mkdir -p docker-compose-state/data/pixelfed/cache

sudo chown -R 33:33 docker-compose-state/data/pixelfed/storage
sudo chown -R 33:33 docker-compose-state/data/pixelfed/cache</pre>

<p>User ID <code>33</code> is <code>www-data</code>, which is the user Pixelfed runs as inside the container.</p>

<div id="start-pixelfed-glitch" style="margin-top:-15px"></div>

<h3 id="step-7-start-pixelfed-glitch">Step 7. Start Pixelfed Glitch</h3>

<p>Start the containers:</p>

<pre>docker compose up -d</pre>

<p>This downloads the Pixelfed Glitch, MariaDB, and Redis images, creates the containers, and starts the first-time setup.</p>

<p>Check the containers:</p>

<pre>docker compose ps</pre>

<p>You should eventually see <code>web</code>, <code>worker</code>, <code>cron</code>, <code>db</code>, and <code>redis</code> as <code>Up</code>.</p>

<p>To watch the logs:</p>

<pre>docker compose logs --tail=100 --follow</pre>

<p>If you only want the web container logs:</p>

<pre>docker compose logs --tail=100 web</pre>

<div id="generate-the-application-and-oauth-keys" style="margin-top:-15px"></div>

<h3 id="step-8-generate-the-application-and-oauth-keys">Step 8. Generate the application and OAuth keys</h3>

<p>If the site shows a 500 error and the logs mention either of these:</p>

<pre>No application encryption key has been specified.
Invalid key supplied</pre>

<p>run the following commands:</p>

<pre>docker compose exec web php artisan key:generate --force
docker compose exec -u www-data web php artisan passport:keys --force</pre>

<p>Then clear and rebuild Pixelfed&#39;s cached config:</p>

<pre>docker compose exec -u www-data web php artisan view:clear
docker compose exec -u www-data web php artisan config:clear
docker compose exec -u www-data web php artisan cache:clear
docker compose exec -u www-data web php artisan config:cache</pre>

<p>Restart the Pixelfed containers:</p>

<pre>docker compose restart web worker cron</pre>

<div id="stop-first-time-setup-from-running-again" style="margin-top:-15px"></div>

<h3 id="step-9-stop-first-time-setup-from-running-again">Step 9. Stop first-time setup from running again</h3>

<p>After the first-time setup has completed and the keys have been created, edit <code>.env</code> again:</p>

<pre>nano .env</pre>

<p>Add this line:</p>

<pre>DOCKER_APP_RUN_ONE_TIME_SETUP_TASKS=&#34;0&#34;</pre>

<p>This stops Pixelfed from trying to recreate encryption keys on every container start.</p>

<p>If this is not set, the container may restart repeatedly with an error like:</p>

<pre>Encryption keys already exist. Use the --force option to overwrite them.</pre>

<p>Restart the stack:</p>

<pre>docker compose down
docker compose up -d</pre>

<p>Do not use <code>docker compose down -v</code>, as that removes Docker volumes.</p>

<div id="check-the-site" style="margin-top:-15px"></div>

<h3 id="step-10-check-the-site">Step 10. Check the site</h3>

<p>Open your Pixelfed URL in a browser:</p>

<pre>https://photos.example.com</pre>

<p>If you are using NGINX as a reverse proxy, make sure it points to the Docker web port. In the default Pixelfed Glitch Docker file this is:</p>

<pre>8080</pre>

<p>So the proxy target is:</p>

<pre>http://127.0.0.1:8080</pre>

<p>Check the running containers:</p>

<pre>docker compose ps</pre>

<p>If you see a 502 error, the <code>web</code> container is probably not running yet, or it is restarting. Check:</p>

<pre>docker compose logs --tail=200 web</pre>

<div id="create-the-first-user" style="margin-top:-15px"></div>

<h3 id="step-11-create-the-first-user">Step 11. Create the first user</h3>

<p>Create the first account:</p>

<pre>docker compose exec -u www-data web php artisan user:create</pre>

<p>Follow the prompts.</p>

<p>To make the user an admin:</p>

<pre>docker compose exec -u www-data web php artisan user:admin USERNAME</pre>

<p>To manually verify an email address:</p>

<pre>docker compose exec -u www-data web php artisan user:verifyemail USERNAME</pre>

<p>For example:</p>

<pre>docker compose exec -u www-data web php artisan user:admin rob
docker compose exec -u www-data web php artisan user:verifyemail rob</pre>

<div id="create-another-user" style="margin-top:-15px"></div>

<h3 id="step-12-create-another-user">Step 12. Create another user</h3>

<p>Run the same create command again:</p>

<pre>docker compose exec -u www-data web php artisan user:create</pre>

<p>Follow the prompts and enter the new username.</p>

<p>For example:</p>

<pre>bnw</pre>

<p>Only run the admin command for accounts that should have admin rights.</p>

<div id="useful-checks" style="margin-top:-15px"></div>

<h3 id="step-13-useful-checks">Step 13. Useful checks</h3>

<p>Check container status:</p>

<pre>docker compose ps</pre>

<p>Show recent logs:</p>

<pre>docker compose logs --tail=200 web</pre>

<p>Check the current Pixelfed config values:</p>

<pre>docker compose exec -u www-data web php artisan tinker --execute=&#39;
echo &#34;app.url=&#34;.config(&#34;app.url&#34;).PHP_EOL;
echo &#34;oauth=&#34;.(config(&#34;pixelfed.oauth_enabled&#34;) ? &#34;true&#34; : &#34;false&#34;).PHP_EOL;
echo &#34;session.domain=&#34;.config(&#34;session.domain&#34;).PHP_EOL;
&#39;</pre>

<p>Check the application key:</p>

<pre>grep &#39;^APP_KEY=&#39; .env</pre>

<p>A valid key should look like one single line:</p>

<pre>APP_KEY=base64:LONG_RANDOM_STRING_HERE</pre>

<p>Check the OAuth key files:</p>

<pre>docker compose exec -u www-data web ls -l storage/oauth-private.key storage/oauth-public.key</pre>

<div id="mobile-app-login-and-2fa" style="margin-top:-15px"></div>

<h3 id="step-14-mobile-app-login-and-2fa">Step 14. Mobile app login and 2FA</h3>

<p>The web version worked fine for me with 2FA enabled.</p>

<p>The mobile app login flow was different. With 2FA enabled, the official Pixelfed app and Impressia both opened a web login pop-up, accepted the username, password, and 2FA code, then stayed in the web version inside the pop-up instead of returning to the app.</p>

<p>The workaround was:</p>
<ol><li>Keep 2FA enabled on the admin account.</li>
<li>Use a separate non-admin account for mobile app login.</li>
<li>Disable 2FA on that non-admin account before logging in to the apps.</li></ol>

<p>If the web interface will not disable 2FA and clicking the green “Enabled” button only adds <code>#</code> to the URL, disable it from the database.</p>

<p>First check the 2FA column names:</p>

<pre>docker compose exec -u www-data web php artisan tinker --execute=&#39;
print_r(array_values(array_filter(
    Schema::getColumnListing(&#34;users&#34;),
    fn($c) =&gt; str_contains(strtolower($c), &#34;two&#34;) || str_contains(strtolower($c), &#34;2fa&#34;) || str_contains(strtolower($c), &#34;otp&#34;)
)));
&#39;</pre>

<p>On my install the columns were:</p>

<pre>2fa_enabled
2fa_secret
2fa_backup_codes
2fa_setup_at</pre>

<p>To disable 2FA for a user called <code>bnw</code>:</p>

<pre>docker compose exec -u www-data web php artisan tinker --execute=&#39;
DB::table(&#34;users&#34;)-&gt;where(&#34;username&#34;, &#34;bnw&#34;)-&gt;update([
    &#34;2fa_enabled&#34; =&gt; false,
    &#34;2fa_secret&#34; =&gt; null,
    &#34;2fa_backup_codes&#34; =&gt; null,
    &#34;2fa_setup_at&#34; =&gt; null,
]);
echo &#34;2FA disabled for bnw\n&#34;;
&#39;</pre>

<p>After that, app login worked.</p>

<div id="reboot-behaviour" style="margin-top:-15px"></div>

<h3 id="step-15-reboot-behaviour">Step 15. Reboot behaviour</h3>

<p>The <code>docker-compose.yml</code> file uses:</p>

<pre>restart: unless-stopped</pre>

<p>This means the containers should come back up after a reboot, as long as Docker itself starts on boot.</p>

<p>Check Docker is enabled:</p>

<pre>systemctl is-enabled docker</pre>

<p>If needed:</p>

<pre>sudo systemctl enable docker</pre>

<p>After a reboot, check Pixelfed:</p>

<pre>cd /home/pi/pixelfed-glitch
docker compose ps</pre>

<p>One thing to remember: if you run this command:</p>

<pre>docker compose down</pre>

<p>the containers are removed. Docker cannot restart removed containers at boot. To recreate and start them:</p>

<pre>cd /home/pi/pixelfed-glitch
docker compose up -d</pre>

<div id="backups" style="margin-top:-15px"></div>

<h3 id="step-16-backups">Step 16. Backups</h3>

<p>At minimum, back up the Pixelfed Glitch install directory:</p>

<pre>/home/pi/pixelfed-glitch</pre>

<p>This contains:</p>

<pre>docker-compose.yml
.env
docker-compose-state/</pre>

<p>The <code>.env</code> file contains secrets, including the database password and application key, so store backups securely.</p>

<p>The <code>docker-compose-state</code> directory contains the MariaDB data, Redis data, Pixelfed storage, and cache folders. For a live database, a proper database dump is safer than only copying files while containers are running.</p>

<p>A simple manual MariaDB dump can be created with:</p>

<pre>cd /home/pi/pixelfed-glitch
docker compose exec db mariadb-dump -u pixelfed -p pixelfed_prod &gt; pixelfed_db_backup.sql</pre>

<p>You will be prompted for the database password from <code>.env</code>.</p>

<div id="troubleshooting-notes" style="margin-top:-15px"></div>

<h3 id="troubleshooting-notes">Troubleshooting notes</h3>

<p><a href="#docker-permission-denied">Docker permission denied</a>
<a href="#missing-cache-path">Missing cache path</a>
<a href="#invalid-application-key">Invalid application key</a>
<a href="#first-time-setup-keeps-running">First-time setup keeps running</a></p>

<div id="docker-permission-denied" style="margin-top:-5px"></div>

<h4 id="docker-permission-denied">Docker permission denied</h4>

<p>If you see:</p>

<pre>permission denied while trying to connect to the docker API at unix:///var/run/docker.sock</pre>

<p>your user is not in the <code>docker</code> group, or the current login session has not picked up the new group membership.</p>

<p>Fix:</p>

<pre>sudo usermod -aG docker $USER</pre>

<p>Then log out and back in.</p>

<div id="missing-cache-path" style="margin-top:-5px"></div>

<h4 id="missing-cache-path">Missing cache path</h4>

<p>If the web container restarts and logs show:</p>

<pre>Please provide a valid cache path.</pre>

<p>create the Laravel storage and cache folders from Step 6.</p>

<div id="invalid-application-key" style="margin-top:-5px"></div>

<h4 id="invalid-application-key">Invalid application key</h4>

<p>If the site shows a 500 error and logs show:</p>

<pre>Unsupported cipher or incorrect key length</pre>

<p>check <code>.env</code>:</p>

<pre>grep &#39;^APP_KEY=&#39; .env</pre>

<p>The key must be one single key. It must not look like this:</p>

<pre>APP_KEY=base64:KEY_ONE=base64:KEY_TWO</pre>

<p>To replace it on a new install:</p>

<pre>new_key=&#34;base64:$(openssl rand -base64 32)&#34;
sudo sed -i.bak &#34;s|^APP_KEY=.*|APP_KEY=${new_key}|&#34; .env</pre>

<p>Then clear the caches:</p>

<pre>docker compose exec -u www-data web php artisan view:clear
docker compose exec -u www-data web php artisan config:clear
docker compose exec -u www-data web php artisan cache:clear
docker compose exec -u www-data web php artisan config:cache
docker compose restart web worker cron</pre>

<div id="first-time-setup-keeps-running" style="margin-top:-5px"></div>

<h4 id="first-time-setup-keeps-running">First-time setup keeps running</h4>

<p>If the web container keeps restarting and logs show:</p>

<pre>Encryption keys already exist. Use the --force option to overwrite them.</pre>

<p>set this in <code>.env</code>:</p>

<pre>DOCKER_APP_RUN_ONE_TIME_SETUP_TASKS=&#34;0&#34;</pre>

<p>Then restart:</p>

<pre>docker compose down
docker compose up -d</pre>

<div style="margin-top:-10px"></div>

<p><span style="font-size:0.95em;font-weight:bold;">Sources:</span>
<span style="font-size:0.85em;"><a href="https://pixelfed-glitch.github.io/docs/running-pixelfed/docker/installation.html">Pixelfed Glitch Docker installation docs</a>
<a href="https://pixelfed-glitch.github.io/docs/configuration/configuration.html">Pixelfed Glitch configuration docs</a>
<a href="https://docs.docker.com/engine/install/debian/">Docker Engine Debian installation docs</a>
<a href="https://docs.docker.com/engine/install/linux-postinstall/">Docker Linux post-installation docs</a>
</span></p>

<p><br>Tags: <a href="https://blog.rstokes.uk/tag:Pixelfed" class="hashtag"><span>#</span><span class="p-category">Pixelfed</span></a> <a href="https://blog.rstokes.uk/tag:RaspberryPi" class="hashtag"><span>#</span><span class="p-category">RaspberryPi</span></a></p>
]]></content:encoded>
      <guid>https://blog.rstokes.uk/installing-pixelfed-glitch-on-a-raspberry-pi</guid>
      <pubDate>Sun, 05 Jul 2026 09:48:47 +0000</pubDate>
    </item>
    <item>
      <title>TV 2025</title>
      <link>https://blog.rstokes.uk/tv-2025</link>
      <description>&lt;![CDATA[An end-of-year summary of the best television I watched in 2025.&#xA;&#xA;!--more--&#xA;&#xA;markhighlighted/mark = strong recommendationbrspan style=&#34;color:red;&#34;red/span = well worth a watch if you have the time&#xA;&#xA;div style=&#34;margin-top:-30px;&#34;/div&#xA;&#xA;Vera (S14)&#xA;Guy Martin: Arctic Warrior&#xA;span style=&#34;color:red;&#34;2024: The Year From Space (doc)/span&#xA;markBlack Doves (S1)/mark&#xA;7/7: The London Bombings (doc)&#xA;markSAS: Rogue Heroes (S1–S2)/mark&#xA;markTaskmaster (S1–20)/mark&#xA;Travel Man: 48 Hours In… (S13)&#xA;8 Out of 10 Cats Does Countdown (S27)&#xA;span style=&#34;color:red;&#34;Helmand: Tour of Duty (doc)/span&#xA;Top Guns: Inside the RAF (doc)&#xA;Edward vs George: The Windsors at War (doc)&#xA;Surviving Black Hawk Down (doc)&#xA;Untold: Hope Solo vs US Soccer (doc)&#xA;span style=&#34;color:red;&#34;Concorde: The Race for Supersonic (doc)/span&#xA;David Mitchell’s Outsiders (S3)&#xA;markPrime Target/mark&#xA;American Murder: Gabby Petito (doc)&#xA;Full Swing (S3)&#xA;Out There&#xA;Guy Martin: Top Gun&#xA;markLast One Laughing UK (S1)/mark&#xA;Kinahan: The True Story of Ireland’s Mafia (doc)&#xA;markMindhunter (S1–2)/mark&#xA;markBlack Mirror (S7)/mark&#xA;markLouis Theroux: The Settlers (doc)/mark&#xA;Dave Gorman’s Googlewhack Adventure&#xA;span style=&#34;color:red;&#34;Clarkson’s Farm (S4)/span&#xA;markThe Last of Us (S2)/mark&#xA;markThis City Is Ours (S1)/mark&#xA;span style=&#34;color:red;&#34;Fred &amp; Rose West: A British Horror Story (doc)/span&#xA;span style=&#34;color:red;&#34;American Manhunt: Osama Bin Laden (doc)/span&#xA;The Fall: Skydive Murder Plot (doc)&#xA;Titan: The OceanGate Submersible Disaster (doc)&#xA;markThe Gold (S1–2)/mark&#xA;Flight 149: Hostage of War (doc)&#xA;markShifty/mark&#xA;Welcome to Wrexham (S4)&#xA;markThe Bear (S4)/mark&#xA;Glastonbury Festival 2025&#xA;Trainwreck: Mayor of Mayhem (doc)&#xA;markHamza&#39;s Hidden Wild Isles (doc)/mark&#xA;Earth&#39;s Tropical Islands: Hawaii (doc)&#xA;Trainwreck: Poop Cruise (doc) &#xA;markWise Guy: David Chase and The Sopranos (doc)/mark&#xA;markThe Penguin/mark&#xA;Smoke&#xA;Resident Alien (S4)&#xA;markSlow Horses (S5)/mark&#xA;Grand Designs (S27)&#xA;markHuman (doc)/mark&#xA;markHow Are You? It&#39;s Alan (Partridge)/mark&#xA;Cocaine Quarterback (doc)&#xA;markBlue Lights (S3)/mark&#xA;span style=&#34;color:red;&#34;Down Cemetery Road/span&#xA;span style=&#34;color:red;&#34;Only Connect (S21)/span&#xA;span style=&#34;color:red;&#34;Man Like Mobeen (S1–5)/span&#xA;markThe Studio (S1)/mark&#xA;markCommunity (S1–6)/mark&#xA;King of Lies: Football&#39;s Greatest Con (doc)&#xA;span style=&#34;color:red;&#34;Fatboy Slim: Right Here, Right Now (doc)/span&#xA;span style=&#34;color:red;&#34;The Diplomat (S3)/span&#xA;span style=&#34;color:red;&#34;Rick and Morty (S1)/span&#xA;Heat Vision and Jack&#xA;Sean Combs: The Reckoning (doc)&#xA;markPluribus (S1)/mark&#xA;&#xA;brTags: #TV #EndOfYearReview]]&gt;</description>
      <content:encoded><![CDATA[<p>An end-of-year summary of the best television I watched in 2025.</p>



<h5 id="mark-highlighted-mark-strong-recommendation-br-span-style-color-red-red-span-well-worth-a-watch-if-you-have-the-time"><mark>highlighted</mark> = strong recommendation<br><span style="color:red;"><strong>red</strong></span> = well worth a watch if you have the time</h5>

<div style="margin-top:-30px;"></div>
<ul><li>Vera (S14)</li>
<li>Guy Martin: Arctic Warrior</li>
<li><span style="color:red;"><strong>2024: The Year From Space (doc)</strong></span></li>
<li><mark><strong>Black Doves (S1)</strong></mark></li>
<li>7/7: The London Bombings (doc)</li>
<li><mark><strong>SAS: Rogue Heroes (S1–S2)</strong></mark></li>
<li><mark><strong>Taskmaster (S1–20)</strong></mark></li>
<li>Travel Man: 48 Hours In… (S13)</li>
<li>8 Out of 10 Cats Does Countdown (S27)</li>
<li><span style="color:red;"><strong>Helmand: Tour of Duty (doc)</strong></span></li>
<li>Top Guns: Inside the RAF (doc)</li>
<li>Edward vs George: The Windsors at War (doc)</li>
<li>Surviving Black Hawk Down (doc)</li>
<li>Untold: Hope Solo vs US Soccer (doc)</li>
<li><span style="color:red;"><strong>Concorde: The Race for Supersonic (doc)</strong></span></li>
<li>David Mitchell’s Outsiders (S3)</li>
<li><mark><strong>Prime Target</strong></mark></li>
<li>American Murder: Gabby Petito (doc)</li>
<li>Full Swing (S3)</li>
<li>Out There</li>
<li>Guy Martin: Top Gun</li>
<li><mark><strong>Last One Laughing UK (S1)</strong></mark></li>
<li>Kinahan: The True Story of Ireland’s Mafia (doc)</li>
<li><mark><strong>Mindhunter (S1–2)</strong></mark></li>
<li><mark><strong>Black Mirror (S7)</strong></mark></li>
<li><mark><strong>Louis Theroux: The Settlers (doc)</strong></mark></li>
<li>Dave Gorman’s Googlewhack Adventure</li>
<li><span style="color:red;"><strong>Clarkson’s Farm (S4)</strong></span></li>
<li><mark><strong>The Last of Us (S2)</strong></mark></li>
<li><mark><strong>This City Is Ours (S1)</strong></mark></li>
<li><span style="color:red;"><strong>Fred &amp; Rose West: A British Horror Story (doc)</strong></span></li>
<li><span style="color:red;"><strong>American Manhunt: Osama Bin Laden (doc)</strong></span></li>
<li>The Fall: Skydive Murder Plot (doc)</li>
<li>Titan: The OceanGate Submersible Disaster (doc)</li>
<li><mark><strong>The Gold (S1–2)</strong></mark></li>
<li>Flight 149: Hostage of War (doc)</li>
<li><mark><strong>Shifty</strong></mark></li>
<li>Welcome to Wrexham (S4)</li>
<li><mark><strong>The Bear (S4)</strong></mark></li>
<li>Glastonbury Festival 2025</li>
<li>Trainwreck: Mayor of Mayhem (doc)</li>
<li><mark><strong>Hamza&#39;s Hidden Wild Isles (doc)</strong></mark></li>
<li>Earth&#39;s Tropical Islands: Hawaii (doc)</li>
<li>Trainwreck: Poop Cruise (doc)</li>
<li><mark><strong>Wise Guy: David Chase and The Sopranos (doc)</strong></mark></li>
<li><mark><strong>The Penguin</strong></mark></li>
<li>Smoke</li>
<li>Resident Alien (S4)</li>
<li><mark><strong>Slow Horses (S5)</strong></mark></li>
<li>Grand Designs (S27)</li>
<li><mark><strong>Human (doc)</strong></mark></li>
<li><mark><strong>How Are You? It&#39;s Alan (Partridge)</strong></mark></li>
<li>Cocaine Quarterback (doc)</li>
<li><mark><strong>Blue Lights (S3)</strong></mark></li>
<li><span style="color:red;"><strong>Down Cemetery Road</strong></span></li>
<li><span style="color:red;"><strong>Only Connect (S21)</strong></span></li>
<li><span style="color:red;"><strong>Man Like Mobeen (S1–5)</strong></span></li>
<li><mark><strong>The Studio (S1)</strong></mark></li>
<li><mark><strong>Community (S1–6)</strong></mark></li>
<li>King of Lies: Football&#39;s Greatest Con (doc)</li>
<li><span style="color:red;"><strong>Fatboy Slim: Right Here, Right Now (doc)</strong></span></li>
<li><span style="color:red;"><strong>The Diplomat (S3)</strong></span></li>
<li><span style="color:red;"><strong>Rick and Morty (S1)</strong></span></li>
<li>Heat Vision and Jack</li>
<li>Sean Combs: The Reckoning (doc)</li>
<li><mark><strong>Pluribus (S1)</strong></mark></li></ul>

<p><br>Tags: <a href="https://blog.rstokes.uk/tag:TV" class="hashtag"><span>#</span><span class="p-category">TV</span></a> <a href="https://blog.rstokes.uk/tag:EndOfYearReview" class="hashtag"><span>#</span><span class="p-category">EndOfYearReview</span></a></p>
]]></content:encoded>
      <guid>https://blog.rstokes.uk/tv-2025</guid>
      <pubDate>Thu, 01 Jan 2026 00:26:36 +0000</pubDate>
    </item>
    <item>
      <title>Film 2025</title>
      <link>https://blog.rstokes.uk/film-2025</link>
      <description>&lt;![CDATA[An end-of-year summary of the films I watched in 2025.&#xA;&#xA;!--more--&#xA;&#xA;div style=&#34;margin:12px 0 -45px 0;&#34;h3Ratings/h3&amp;nbsp;&amp;nbsp;span style=&#34;font-size:0.85em;&#34;(a href=&#34;https://blog.rstokes.uk/movie-ratings-updated&#34;more info/a)/span/div&#xA;&#xA;5★ Masterpiecebr4½★ Amazingbr4★ Great br3★ Good/Decentbr2★ Okay/Mehbr1★ Bad&#xA;&#xA;div style=&#34;margin:25px 0 -30px 0;&#34;h3Top Tier/h3&amp;nbsp;&amp;nbsp;span style=&#34;font-size:0.85em;font-style:italic;&#34;(not seen before)/span/div&#xA;&#xA;Casablanca (1942) ★★★★★&#xA;A Real Pain (2024) ★★★★½&#xA;Warfare (2025) ★★★★½&#xA;Apocalypse Now (Final Cut) (1979) ★★★★★&#xA;Sinners (2025) ★★★★½&#xA;Apollo 11 (2019) ★★★★½&#xA;Hamilton (2020) ★★★★★&#xA;Bo Burnham: Inside (2021) ★★★★½&#xA;&#xA;div style=&#34;margin:15px 0 -30px 0;&#34;h3Recommended/h3&amp;nbsp;&amp;nbsp;span style=&#34;font-size:0.85em;font-style:italic;&#34;(not seen before)/span/div&#xA;&#xA;Monkey Man (2024) ★★★★&#xA;The Holdovers (2023) ★★★★&#xA;The Substance (2024) ★★★★&#xA;Black Bag (2025) ★★★★&#xA;The Thing (1982) ★★★★&#xA;F1: The Movie (2025) ★★★★&#xA;Super/Man: The Christopher Reeve Story (2024) (doc) ★★★★&#xA;Happy Gilmore 2 (2025) ★★★★&#xA;Weapons (2025) ★★★★&#xA;Fargo (1996) ★★★★&#xA;&#xA;div style=&#34;margin:15px 0 -30px 0;&#34;h3Underwhelming/h3&amp;nbsp;&amp;nbsp;span style=&#34;font-size:0.85em;font-style:italic;&#34;(not seen before)/span/div&#xA;&#xA;Nosferatu (2024) ★★&#xA;Smokescreen (1964) ★★&#xA;Plane (2023) ★★&#xA;Mickey 17 (2025) ★★&#xA;Angels and Demons (2009) ★★&#xA;Big Trouble in Little China (1986) ★★&#xA;Stardust (2007) ★★&#xA;Mission: Impossible – Final Reckoning (2025) ★★&#xA;Star Trek: Beyond (2016) ★★&#xA;&#xA;div style=&#34;margin:15px 0 -30px 0;&#34;h3Trash/h3/div&#xA;&#xA;Get Away (2024) ★&#xA;The Thursday Murder Club (2025) ★&#xA;&#xA;div style=&#34;margin:20px 0 -30px 0;&#34;h3The Full List/h3/div&#xA;&#xA;markhighlighted/mark = 4½★ or 5★ — the bestbrspan style=&#34;color:red;&#34;red/span = 4★ recommendationsbrN = new release (in 2025 or late-2024)brR = seen before (rewatch)&#xA;&#xA;div style=&#34;margin-top:-35px;&#34;&#34;/div&#xA;&#xA;markCasablanca (1942) ★★★★★/mark&#xA;Nosferatu (2024) ★★ N&#xA;span style=&#34;color:red;&#34;Monkey Man (2024) ★★★★/span&#xA;Smokescreen (1964) ★★&#xA;span style=&#34;color:red;&#34;The Holdovers (2023) ★★★★/span&#xA;Get Away (2024) ★ N&#xA;markA Real Pain (2024) ★★★★½ N/mark&#xA;Wolf Man (2025) ★★★ N&#xA;markSexy Beast (2000) ★★★★½ R/mark&#xA;10. span style=&#34;color:red;&#34;Indiana Jones and the Last Crusade (1989) ★★★★ R/span&#xA;11. markSin City (2005) ★★★★½ R/mark&#xA;12. Companion (2025) ★★★ N&#xA;13. September 5 (2025) ★★★ N&#xA;14. span style=&#34;color:red;&#34;The Substance (2024) ★★★★/span&#xA;15. markHeat (1995) ★★★★★ R/mark&#xA;16. The Monkey (2025) ★★★ N&#xA;17. span style=&#34;color:red;&#34;Zombieland (2009) ★★★★ R/span&#xA;18. Zombieland: Double Tap (2019) ★★★&#xA;19. markThe Big Lebowski (1998) ★★★★★ R/mark&#xA;20. Plane (2023) ★★&#xA;21. Mickey 17 (2025) ★★ N&#xA;22. span style=&#34;color:red;&#34;Black Bag (2025) ★★★★ N/span&#xA;23. Last Breath (2025) ★★★ N&#xA;24. Bad Boys (1995) ★★★ R&#xA;25. The Da Vinci Code (2006) ★★★&#xA;26. Angels and Demons (2009) ★★&#xA;27. markInterstellar (2014) (IMAX) ★★★★★ R/mark&#xA;28. markThe Shining (1980) ★★★★★ R/mark&#xA;29. span style=&#34;color:red;&#34;Snatch (2000) ★★★★ R/span&#xA;30. mark2001: A Space Odyssey (1968) ★★★★★ R/mark&#xA;31. markWarfare (2025) ★★★★½ N/mark&#xA;32. markApocalypse Now (Final Cut) (1979) ★★★★★/mark&#xA;33. markSinners (2025) ★★★★½ N/mark&#xA;34. Office Space (1999) ★★★&#xA;35. Big Trouble in Little China (1986) ★★&#xA;36. span style=&#34;color:red;&#34;Terminator 2: Judgment Day (1991) ★★★★ R/span&#xA;37. markDjango Unchained (2012) ★★★★½ R/mark&#xA;38. Stardust (2007) ★★&#xA;39. markHot Fuzz (2007) ★★★★½ R/mark&#xA;40. markOnce Upon a Time… in Hollywood (2019) ★★★★½ R/mark&#xA;41. span style=&#34;color:red;&#34;Hotel Mumbai (2018) ★★★★ R/span&#xA;42. span style=&#34;color:red;&#34;Collateral (2004) ★★★★ R/span&#xA;43. Mountainhead (2025) ★★★ N&#xA;44. span style=&#34;color:red;&#34;The Thing (1982) ★★★★/span&#xA;45. markSicario (2015) ★★★★½ R/mark&#xA;46. markDog Day Afternoon (1975) ★★★★½ R/mark&#xA;47. span style=&#34;color:red;&#34;The Wind in the Willows (1983) ★★★★ R/span&#xA;48. span style=&#34;color:red;&#34;28 Days Later (2002) ★★★★ R/span&#xA;49. span style=&#34;color:red;&#34;F1: The Movie (2025) (IMAX) ★★★★ N/span&#xA;50. Popstar: Never Stop Never Stopping (2016) ★★★&#xA;51. 28 Years Later (2025) ★★★ N&#xA;52. Mission: Impossible – Final Reckoning (2025) ★★ N&#xA;53. Sicario 2: Soldado (2018) ★★★&#xA;54. span style=&#34;color:red;&#34;Shallow Grave (1994) ★★★★ R/span&#xA;55. Hill (2025) (doc) ★★★ N&#xA;56. Star Trek: Into Darkness (2013) ★★★&#xA;57. Star Trek: Beyond (2016) ★★&#xA;58. The Amateur (2025) ★★★ N&#xA;59. span style=&#34;color:red;&#34;Super/Man: The Christopher Reeve Story (2024) (doc) ★★★★ N/span&#xA;60. Red Riding: 1974 (2009) ★★★&#xA;61. Bring Her Back (2025) ★★★ N&#xA;62. span style=&#34;color:red;&#34;Happy Gilmore 2 (2025) ★★★★ N/span&#xA;63. Red Riding: 1980 (2009) ★★★&#xA;64. Red Riding: 1983 (2009) ★★★&#xA;65. markThe Covenant (2023) ★★★★½ R/mark&#xA;66. span style=&#34;color:red;&#34;The Commitments (1991) ★★★★ R/span&#xA;67. span style=&#34;color:red;&#34;Nobody (2021) ★★★★ R/span&#xA;68. span style=&#34;color:red;&#34;Weapons (2025) (IMAX) ★★★★ N/span&#xA;69. Nobody 2 (2025) ★★★ N&#xA;70. Army of Darkness (1992) ★★★ R&#xA;71. span style=&#34;color:red;&#34;2010: The Year We Make Contact (1984) ★★★★ R/span&#xA;72. span style=&#34;color:red;&#34;Jaws (1975) (IMAX) ★★★★ R/span&#xA;73. TRON: Legacy (2010) ★★★ R&#xA;74. span style=&#34;color:red;&#34;Baby Driver (2017) ★★★★ R/span&#xA;75. The Thursday Murder Club (2025) ★ N&#xA;76. span style=&#34;color:red;&#34;Grosse Pointe Blank (1997) ★★★★ R/span&#xA;77. span style=&#34;color:red;&#34;The Fifth Element (1997) ★★★★ R/span&#xA;78. markApollo 13 (1995) ★★★★½ R/mark&#xA;79. GoldenEye (1995) ★★★ R&#xA;80. Lethal Weapon 3 (1992) ★★★ R&#xA;81. markApollo 11 (2019) ★★★★½/mark&#xA;82. The &#39;Burbs (1989) ★★★&#xA;83. markHamilton (2020) ★★★★★/mark&#xA;84. markInterstellar (2015) ★★★★★ R/mark&#xA;85. span style=&#34;color:red;&#34;Batman Begins (2005) ★★★★ R/span&#xA;86. Nosferatu (1922) ★★★&#xA;87. markThe Dark Knight (2008) ★★★★½ R/mark&#xA;88. The Lost Bus (2025) ★★★ N&#xA;89. span style=&#34;color:red;&#34;Fargo (1996) ★★★★/span&#xA;90. span style=&#34;color:red;&#34;Star Wars: Episode IV – A New Hope (1977) ★★★★ R/span&#xA;91. span style=&#34;color:red;&#34;Skyfall (2012) ★★★★ R/span&#xA;92. markScrooge (1951) ★★★★½ R/mark&#xA;93. span style=&#34;color:red;&#34;Die Hard 2 (1990) ★★★★ R/span&#xA;94. markThe Muppet Christmas Carol (1992) ★★★★½ R/mark&#xA;95. markDie Hard (1988) ★★★★★ R/mark&#xA;96. span style=&#34;color:red;&#34;Gremlins (1984) ★★★★ R/span&#xA;97. span style=&#34;color:red;&#34;Home Alone (1990) ★★★★ R/span&#xA;98. Four Weddings and a Funeral (1994) ★★★ R&#xA;99. markFantastic Mr. Fox (2009) ★★★★★ R/mark&#xA;100. markBo Burnham: Inside (2021) ★★★★½/mark&#xA;&#xA;brTags: #Movies #EndOfYearReview]]&gt;</description>
      <content:encoded><![CDATA[<p>An end-of-year summary of the films I watched in 2025.</p>



<div style="margin:12px 0 -45px 0;"><h3>Ratings</h3>  <span style="font-size:0.85em;">(<a href="https://blog.rstokes.uk/movie-ratings-updated">more info</a>)</span></div>

<h5 id="5-masterpiece-br-4½-amazing-br-4-great-br-3-good-decent-br-2-okay-meh-br-1-bad">5★ Masterpiece<br>4½★ Amazing<br>4★ Great <br>3★ Good/Decent<br>2★ Okay/Meh<br>1★ Bad</h5>

<div style="margin:25px 0 -30px 0;"><h3>Top Tier</h3>  <span style="font-size:0.85em;font-style:italic;">(not seen before)</span></div>
<ul><li><strong>Casablanca (1942) ★★★★★</strong></li>
<li><strong>A Real Pain (2024) ★★★★½</strong></li>
<li><strong>Warfare (2025) ★★★★½</strong></li>
<li><strong>Apocalypse Now (Final Cut) (1979) ★★★★★</strong></li>
<li><strong>Sinners (2025) ★★★★½</strong></li>
<li><strong>Apollo 11 (2019) ★★★★½</strong></li>
<li><strong>Hamilton (2020) ★★★★★</strong></li>
<li><strong>Bo Burnham: Inside (2021) ★★★★½</strong></li></ul>

<div style="margin:15px 0 -30px 0;"><h3>Recommended</h3>  <span style="font-size:0.85em;font-style:italic;">(not seen before)</span></div>
<ul><li>Monkey Man (2024) ★★★★</li>
<li>The Holdovers (2023) ★★★★</li>
<li>The Substance (2024) ★★★★</li>
<li>Black Bag (2025) ★★★★</li>
<li>The Thing (1982) ★★★★</li>
<li>F1: The Movie (2025) ★★★★</li>
<li>Super/Man: The Christopher Reeve Story (2024) (doc) ★★★★</li>
<li>Happy Gilmore 2 (2025) ★★★★</li>
<li>Weapons (2025) ★★★★</li>
<li>Fargo (1996) ★★★★</li></ul>

<div style="margin:15px 0 -30px 0;"><h3>Underwhelming</h3>  <span style="font-size:0.85em;font-style:italic;">(not seen before)</span></div>
<ul><li>Nosferatu (2024) ★★</li>
<li>Smokescreen (1964) ★★</li>
<li>Plane (2023) ★★</li>
<li>Mickey 17 (2025) ★★</li>
<li>Angels and Demons (2009) ★★</li>
<li>Big Trouble in Little China (1986) ★★</li>
<li>Stardust (2007) ★★</li>
<li>Mission: Impossible – Final Reckoning (2025) ★★</li>
<li>Star Trek: Beyond (2016) ★★</li></ul>

<div style="margin:15px 0 -30px 0;"><h3>Trash</h3></div>
<ul><li>Get Away (2024) ★</li>
<li>The Thursday Murder Club (2025) ★</li></ul>

<div style="margin:20px 0 -30px 0;"><h3>The Full List</h3></div>

<h5 id="mark-highlighted-mark-4½-or-5-the-best-br-span-style-color-red-red-span-4-recommendations-br-n-new-release-in-2025-or-late-2024-br-r-seen-before-rewatch"><mark>highlighted</mark> = 4½★ or 5★ — the best<br><span style="color:red;">red</span> = 4★ recommendations<br>N = new release (in 2025 or late-2024)<br>R = seen before (rewatch)</h5>

<div style="margin-top:-35px;"></div>
<ol><li><mark><strong>Casablanca (1942) ★★★★★</strong></mark></li>
<li>Nosferatu (2024) ★★ N</li>
<li><span style="color:red;"><strong>Monkey Man (2024) ★★★★</strong></span></li>
<li>Smokescreen (1964) ★★</li>
<li><span style="color:red;"><strong>The Holdovers (2023) ★★★★</strong></span></li>
<li>Get Away (2024) ★ N</li>
<li><mark><strong>A Real Pain (2024) ★★★★½ N</strong></mark></li>
<li>Wolf Man (2025) ★★★ N</li>
<li><mark><strong>Sexy Beast (2000) ★★★★½ R</strong></mark></li>
<li><span style="color:red;"><strong>Indiana Jones and the Last Crusade (1989) ★★★★ R</strong></span></li>
<li><mark><strong>Sin City (2005) ★★★★½ R</strong></mark></li>
<li>Companion (2025) ★★★ N</li>
<li>September 5 (2025) ★★★ N</li>
<li><span style="color:red;"><strong>The Substance (2024) ★★★★</strong></span></li>
<li><mark><strong>Heat (1995) ★★★★★ R</strong></mark></li>
<li>The Monkey (2025) ★★★ N</li>
<li><span style="color:red;"><strong>Zombieland (2009) ★★★★ R</strong></span></li>
<li>Zombieland: Double Tap (2019) ★★★</li>
<li><mark><strong>The Big Lebowski (1998) ★★★★★ R</strong></mark></li>
<li>Plane (2023) ★★</li>
<li>Mickey 17 (2025) ★★ N</li>
<li><span style="color:red;"><strong>Black Bag (2025) ★★★★ N</strong></span></li>
<li>Last Breath (2025) ★★★ N</li>
<li>Bad Boys (1995) ★★★ R</li>
<li>The Da Vinci Code (2006) ★★★</li>
<li>Angels and Demons (2009) ★★</li>
<li><mark><strong>Interstellar (2014) (IMAX) ★★★★★ R</strong></mark></li>
<li><mark><strong>The Shining (1980) ★★★★★ R</strong></mark></li>
<li><span style="color:red;"><strong>Snatch (2000) ★★★★ R</strong></span></li>
<li><mark><strong>2001: A Space Odyssey (1968) ★★★★★ R</strong></mark></li>
<li><mark><strong>Warfare (2025) ★★★★½ N</strong></mark></li>
<li><mark><strong>Apocalypse Now (Final Cut) (1979) ★★★★★</strong></mark></li>
<li><mark><strong>Sinners (2025) ★★★★½ N</strong></mark></li>
<li>Office Space (1999) ★★★</li>
<li>Big Trouble in Little China (1986) ★★</li>
<li><span style="color:red;"><strong>Terminator 2: Judgment Day (1991) ★★★★ R</strong></span></li>
<li><mark><strong>Django Unchained (2012) ★★★★½ R</strong></mark></li>
<li>Stardust (2007) ★★</li>
<li><mark><strong>Hot Fuzz (2007) ★★★★½ R</strong></mark></li>
<li><mark><strong>Once Upon a Time… in Hollywood (2019) ★★★★½ R</strong></mark></li>
<li><span style="color:red;"><strong>Hotel Mumbai (2018) ★★★★ R</strong></span></li>
<li><span style="color:red;"><strong>Collateral (2004) ★★★★ R</strong></span></li>
<li>Mountainhead (2025) ★★★ N</li>
<li><span style="color:red;"><strong>The Thing (1982) ★★★★</strong></span></li>
<li><mark><strong>Sicario (2015) ★★★★½ R</strong></mark></li>
<li><mark><strong>Dog Day Afternoon (1975) ★★★★½ R</strong></mark></li>
<li><span style="color:red;"><strong>The Wind in the Willows (1983) ★★★★ R</strong></span></li>
<li><span style="color:red;"><strong>28 Days Later (2002) ★★★★ R</strong></span></li>
<li><span style="color:red;"><strong>F1: The Movie (2025) (IMAX) ★★★★ N</strong></span></li>
<li>Popstar: Never Stop Never Stopping (2016) ★★★</li>
<li>28 Years Later (2025) ★★★ N</li>
<li>Mission: Impossible – Final Reckoning (2025) ★★ N</li>
<li>Sicario 2: Soldado (2018) ★★★</li>
<li><span style="color:red;"><strong>Shallow Grave (1994) ★★★★ R</strong></span></li>
<li>Hill (2025) (doc) ★★★ N</li>
<li>Star Trek: Into Darkness (2013) ★★★</li>
<li>Star Trek: Beyond (2016) ★★</li>
<li>The Amateur (2025) ★★★ N</li>
<li><span style="color:red;"><strong>Super/Man: The Christopher Reeve Story (2024) (doc) ★★★★ N</strong></span></li>
<li>Red Riding: 1974 (2009) ★★★</li>
<li>Bring Her Back (2025) ★★★ N</li>
<li><span style="color:red;"><strong>Happy Gilmore 2 (2025) ★★★★ N</strong></span></li>
<li>Red Riding: 1980 (2009) ★★★</li>
<li>Red Riding: 1983 (2009) ★★★</li>
<li><mark><strong>The Covenant (2023) ★★★★½ R</strong></mark></li>
<li><span style="color:red;"><strong>The Commitments (1991) ★★★★ R</strong></span></li>
<li><span style="color:red;"><strong>Nobody (2021) ★★★★ R</strong></span></li>
<li><span style="color:red;"><strong>Weapons (2025) (IMAX) ★★★★ N</strong></span></li>
<li>Nobody 2 (2025) ★★★ N</li>
<li>Army of Darkness (1992) ★★★ R</li>
<li><span style="color:red;"><strong>2010: The Year We Make Contact (1984) ★★★★ R</strong></span></li>
<li><span style="color:red;"><strong>Jaws (1975) (IMAX) ★★★★ R</strong></span></li>
<li>TRON: Legacy (2010) ★★★ R</li>
<li><span style="color:red;"><strong>Baby Driver (2017) ★★★★ R</strong></span></li>
<li>The Thursday Murder Club (2025) ★ N</li>
<li><span style="color:red;"><strong>Grosse Pointe Blank (1997) ★★★★ R</strong></span></li>
<li><span style="color:red;"><strong>The Fifth Element (1997) ★★★★ R</strong></span></li>
<li><mark><strong>Apollo 13 (1995) ★★★★½ R</strong></mark></li>
<li>GoldenEye (1995) ★★★ R</li>
<li>Lethal Weapon 3 (1992) ★★★ R</li>
<li><mark><strong>Apollo 11 (2019) ★★★★½</strong></mark></li>
<li>The &#39;Burbs (1989) ★★★</li>
<li><mark><strong>Hamilton (2020) ★★★★★</strong></mark></li>
<li><mark><strong>Interstellar (2015) ★★★★★ R</strong></mark></li>
<li><span style="color:red;"><strong>Batman Begins (2005) ★★★★ R</strong></span></li>
<li>Nosferatu (1922) ★★★</li>
<li><mark><strong>The Dark Knight (2008) ★★★★½ R</strong></mark></li>
<li>The Lost Bus (2025) ★★★ N</li>
<li><span style="color:red;"><strong>Fargo (1996) ★★★★</strong></span></li>
<li><span style="color:red;"><strong>Star Wars: Episode IV – A New Hope (1977) ★★★★ R</strong></span></li>
<li><span style="color:red;"><strong>Skyfall (2012) ★★★★ R</strong></span></li>
<li><mark><strong>Scrooge (1951) ★★★★½ R</strong></mark></li>
<li><span style="color:red;"><strong>Die Hard 2 (1990) ★★★★ R</strong></span></li>
<li><mark><strong>The Muppet Christmas Carol (1992) ★★★★½ R</strong></mark></li>
<li><mark><strong>Die Hard (1988) ★★★★★ R</strong></mark></li>
<li><span style="color:red;"><strong>Gremlins (1984) ★★★★ R</strong></span></li>
<li><span style="color:red;"><strong>Home Alone (1990) ★★★★ R</strong></span></li>
<li>Four Weddings and a Funeral (1994) ★★★ R</li>
<li><mark><strong>Fantastic Mr. Fox (2009) ★★★★★ R</strong></mark></li>
<li><mark><strong>Bo Burnham: Inside (2021) ★★★★½</strong></mark></li></ol>

<p><br>Tags: <a href="https://blog.rstokes.uk/tag:Movies" class="hashtag"><span>#</span><span class="p-category">Movies</span></a> <a href="https://blog.rstokes.uk/tag:EndOfYearReview" class="hashtag"><span>#</span><span class="p-category">EndOfYearReview</span></a></p>
]]></content:encoded>
      <guid>https://blog.rstokes.uk/film-2025</guid>
      <pubDate>Thu, 01 Jan 2026 00:23:41 +0000</pubDate>
    </item>
    <item>
      <title>Movie Ratings (updated)</title>
      <link>https://blog.rstokes.uk/movie-ratings-updated</link>
      <description>&lt;![CDATA[As the year goes on and I&#39;m 60+ films deep (and I look back at last year&#39;s 100+ ratings), it&#39;s dawned on me that I rate far too many films as 7 or 8 out of 10 and very few films 5/10 (I don&#39;t think I&#39;ve ever given below a 4/10).&#xA;&#xA;It skews my ratings artificially high and devalues the top ratings for those films that deserve it. Conversely, the stinkers don&#39;t get singled out either. To demonstrate this, my a href=&#34;https://boxd.it/1qVP&#34;Letterboxd/a ratings span style=&#34;text-decoration: line-through;&#34;are/span emwere/em&amp;ast; a mess. A different approach is needed.&#xA;&#xA;span style=&#34;font-size: 0.8em;&#34;&amp;ast;emLetterboxd ratings now amended!/em/span&#xA;&#xA;!--more--&#xA;&#xA;This was my old scale:&#xA;&#xA;10 • Masterpiece&#xA;9 • Amazing&#xA;8 • Great&#xA;7 • Good&#xA;6 • Okay&#xA;5 • Mediocre&#xA;4 • Poor&#xA;3 • Bad&#xA;2 • Awful&#xA;1 • Unwatchable&#xA;&#xA;I made it too complicated with so many choices; the idea was to provide nuance by using a scale out of ten, but it&#39;s not worked out as intended.&#xA;&#xA;I&#39;m switching back to the tried-and-tested 5★ rating, with an added 4½★ option available for those films that deserve special mention but don&#39;t quite hit masterpiece status.&#xA;&#xA;This will now be my guide: &#xA;&#xA;5★ (Masterpiece) → 1–2% of films&#xA;Only the very best across all my watching life. The &#34;desert island&#34; films. Generally, if I&#39;m giving more than one or two 5★ in a year for new releases, I&#39;m probably being too generous.&#xA;→ &#34;Blew me away. I loved every minute. I’d watch it again tomorrow. This is among the best films I’ve ever seen.&#34;&#xA;&#xA;4½★ (Amazing) → 5–10% of films&#xA;Films I absolutely loved, nearly flawless. If I see 100 films in a year, maybe up to 10 earn this.&#xA;→ &#34;I really loved it. Nearly perfect for me. I’d recommend it without hesitation, though maybe not one of the all-time greats.&#34;&#xA;&#xA;4★ (Great) → 15–20% of films&#xA;Memorable, rewatchable, strong. These are the ones I&#39;d recommend to friends.&#xA;→ &#34;I had a really good time. I’d gladly watch it again. Strong, memorable, but doesn’t quite reach personal favourite status.&#34;&#xA;&#xA;3★ (Good/Decent) → 35–40% of films&#xA;The largest category. Fun enough, competent, but not a standout. This is where most decent cinema lands — the backbone of my watch list.&#xA;→ &#34;Enjoyable. Solid. Glad I watched it, but I probably won’t revisit it often.&#34;&#xA;&#xA;2★ (Okay/Meh) → 20–25% of films&#xA;Didn’t do much for me, but not outright painful. Forgettable.&#xA;→ &#34;Meh. Didn’t grab me. I wouldn’t recommend it, but it wasn’t a total waste.&#34;&#xA;&#xA;1★ (Bad) → 5–10% of films&#xA;Rare, but I should actually use it. This is my dumping ground for the duds. &#xA;→ &#34;If I had known how it would be, I wouldn’t have watched it. I’d warn others away.&#34;&#xA;&#xA;This should produce more of a bell curve distribution and force me to be more measured. It should stop the 4★ inflation and keep the top ratings rare, so they mean something special when they&#39;re used. I don&#39;t need the fine slicing at the bottom end either as I never use them; one bucket of &#34;not good&#34; is enough.&#xA;&#xA;I also need to remind myself that I&#39;m no film critic and that my ratings largely reflect my personal enjoyment (so a fluffy but fun film could get 4★) rather than being solely a critical judgement of the filmmaking (where even if I enjoyed a film, if it’s technically weak it gets 2–3★). It does play a small part however, so ratings should in theory be based on an approx. 80/20 split of these factors. &#xA;&#xA;So, when I start giving a lot more ★★★ ratings in future, it doesn&#39;t mean they&#39;re not good; in fact it actively means they are good. IMO. &#xA;&#xA;brtags: #Movies]]&gt;</description>
      <content:encoded><![CDATA[<p>As the year goes on and I&#39;m 60+ films deep (and I look back at last year&#39;s 100+ ratings), it&#39;s dawned on me that I rate far too many films as 7 or 8 out of 10 and very few films 5/10 (I don&#39;t think I&#39;ve ever given below a 4/10).</p>

<p>It skews my ratings artificially high and devalues the top ratings for those films that deserve it. Conversely, the stinkers don&#39;t get singled out either. To demonstrate this, my <a href="https://boxd.it/1qVP"><strong>Letterboxd</strong></a> ratings <span style="text-decoration: line-through;">are</span> <em>were</em>* a mess. A different approach is needed.</p>

<p><span style="font-size: 0.8em;">*<em>Letterboxd ratings now amended!</em></span></p>



<p>This was my old scale:</p>

<p>10 • Masterpiece
9 • Amazing
8 • Great
7 • Good
6 • Okay
5 • Mediocre
4 • Poor
3 • Bad
2 • Awful
1 • Unwatchable</p>

<p>I made it too complicated with so many choices; the idea was to provide nuance by using a scale out of ten, but it&#39;s not worked out as intended.</p>

<p>I&#39;m switching back to the tried-and-tested 5★ rating, with an added 4½★ option available for those films that deserve special mention but don&#39;t quite hit masterpiece status.</p>

<p>This will now be my guide:</p>

<p><strong>5★ (Masterpiece)</strong> → <em>1–2% of films</em>
Only the very best across all my watching life. The “desert island” films. Generally, if I&#39;m giving more than one or two 5★ in a year for new releases, I&#39;m probably being too generous.
→ <em>“Blew me away. I loved every minute. I’d watch it again tomorrow. This is among the best films I’ve ever seen.”</em></p>

<p><strong>4½★ (Amazing)</strong> → <em>5–10% of films</em>
Films I absolutely loved, nearly flawless. If I see 100 films in a year, maybe up to 10 earn this.
→ <em>“I really loved it. Nearly perfect for me. I’d recommend it without hesitation, though maybe not one of the all-time greats.”</em></p>

<p><strong>4★ (Great)</strong> → <em>15–20% of films</em>
Memorable, rewatchable, strong. These are the ones I&#39;d recommend to friends.
→ <em>“I had a really good time. I’d gladly watch it again. Strong, memorable, but doesn’t quite reach personal favourite status.”</em></p>

<p><strong>3★ (Good/Decent)</strong> → <em>35–40% of films</em>
The largest category. Fun enough, competent, but not a standout. This is where most decent cinema lands — the backbone of my watch list.
→ <em>“Enjoyable. Solid. Glad I watched it, but I probably won’t revisit it often.”</em></p>

<p><strong>2★ (Okay/Meh)</strong> → <em>20–25% of films</em>
Didn’t do much for me, but not outright painful. Forgettable.
→ <em>“Meh. Didn’t grab me. I wouldn’t recommend it, but it wasn’t a total waste.”</em></p>

<p><strong>1★ (Bad)</strong> → <em>5–10% of films</em>
Rare, but I should actually use it. This is my dumping ground for the duds.
→ <em>“If I had known how it would be, I wouldn’t have watched it. I’d warn others away.”</em></p>

<p>This should produce more of a bell curve distribution and force me to be more measured. It should stop the 4★ inflation and keep the top ratings rare, so they mean something special when they&#39;re used. I don&#39;t need the fine slicing at the bottom end either as I never use them; one bucket of “not good” is enough.</p>

<p>I also need to remind myself that I&#39;m no film critic and that my ratings largely reflect my personal enjoyment (so a fluffy but fun film could get 4★) rather than being solely a critical judgement of the filmmaking (where even if I enjoyed a film, if it’s technically weak it gets 2–3★). It does play a small part however, so ratings should <em>in theory</em> be based on an approx. 80/20 split of these factors.</p>

<p>So, when I start giving a lot more ★★★ ratings in future, it doesn&#39;t mean they&#39;re not good; in fact it actively means they <strong>are</strong> good. IMO.</p>

<p><br>tags: <a href="https://blog.rstokes.uk/tag:Movies" class="hashtag"><span>#</span><span class="p-category">Movies</span></a></p>
]]></content:encoded>
      <guid>https://blog.rstokes.uk/movie-ratings-updated</guid>
      <pubDate>Sat, 16 Aug 2025 18:49:50 +0000</pubDate>
    </item>
    <item>
      <title>Show Your Stripes</title>
      <link>https://blog.rstokes.uk/show-your-stripes</link>
      <description>&lt;![CDATA[Today is Show Your Stripes Day; a global moment to share our concern about how the climate is changing and the need for urgent action.&#xA;&#xA;!--more--&#xA;&#xA;&#34;Warming stripes&#34; are a powerful visual representation of how temperatures have increased around the world since the Industrial Revolution.&#xA;&#xA;Temperature change in the UK – warming stripes&#xA;&#xA;Temperature change in the UK – bar chart&#xA;&#xA;Created by climate scientist a href=&#34;https://fediscience.org/@ed_hawkins&#34;Professor Ed Hawkins/a at the a href=&#34;https://www.reading.ac.uk/research/themes/theme-environment/rd-climate&#34;University of Reading/a, each stripe represents one year. The colours transition from cool blues to warm reds to represent the temperature increases seen throughout the past 150 years or more.&#xA;&#xA;Show your stripes at:&#xA;a href=&#34;https://showyourstripes.info&#34;showyourstripes.info/a&#xA;&#xA;brtags: #Science #Climate]]&gt;</description>
      <content:encoded><![CDATA[<p>Today is <strong>Show Your Stripes Day</strong>; a global moment to share our concern about how the climate is changing and the need for urgent action.</p>



<p><em>“Warming stripes”</em> are a powerful visual representation of how temperatures have increased around the world since the Industrial Revolution.</p>

<p><img src="https://showyourstripes.info/stripes/EUROPE-United_Kingdom-%3CAll%20of%20United%20Kingdom%3E-1884-2025-MO-withlabels.png" alt="Temperature change in the UK – warming stripes"></p>

<p><img src="https://showyourstripes.info/stripes/EUROPE-United_Kingdom-%3CAll%20of%20United%20Kingdom%3E-1884-2025-MO-barslabel.png" alt="Temperature change in the UK – bar chart"></p>

<p>Created by climate scientist <a href="https://fediscience.org/@ed_hawkins">Professor Ed Hawkins</a> at the <a href="https://www.reading.ac.uk/research/themes/theme-environment/rd-climate">University of Reading</a>, each stripe represents one year. The colours transition from cool blues to warm reds to represent the temperature increases seen throughout the past 150 years or more.</p>

<p>Show your stripes at:
<a href="https://showyourstripes.info"><strong>showyourstripes.info</strong></a></p>

<p><br>tags: <a href="https://blog.rstokes.uk/tag:Science" class="hashtag"><span>#</span><span class="p-category">Science</span></a> <a href="https://blog.rstokes.uk/tag:Climate" class="hashtag"><span>#</span><span class="p-category">Climate</span></a></p>
]]></content:encoded>
      <guid>https://blog.rstokes.uk/show-your-stripes</guid>
      <pubDate>Sat, 21 Jun 2025 11:53:35 +0000</pubDate>
    </item>
    <item>
      <title>TV 2024</title>
      <link>https://blog.rstokes.uk/tv-2024</link>
      <description>&lt;![CDATA[An end-of-year summary of the best television I watched in 2024.&#xA;&#xA;!--more--&#xA;&#xA;markhighlighted/mark = strong recommendationbrspan style=&#34;color:red;&#34;bold/span = well worth a watch if you have the timebr&#xA;&#xA;markFargo (S5) (FX)/mark&#xA;span style=&#34;color:red;&#34;Mr. Bates vs. The Post Office (ITV)/span&#xA;markMasters of the Air (Apple)/mark&#xA;Griselda (Netflix)&#xA;American Nightmare (doc) (Netflix)&#xA;Deadwater Fell (Channel 4)&#xA;span style=&#34;color:red;&#34;Curb Your Enthusiasm (S12) (HBO)/span&#xA;span style=&#34;color:red;&#34;The Space Shuttle That Fell To Earth (doc) (BBC)/span&#xA;Alice &amp; Jack (Channel 4)&#xA;markKin (S2) (RTE/BBC)/mark&#xA;Tell Them You Love Me (doc) (Sky)&#xA;span style=&#34;color:red;&#34;The Reckoning (BBC)/span&#xA;span style=&#34;color:red;&#34;The Gentlemen (Amazon)/span&#xA;Full Swing (S2) (Netflix)&#xA;markHow To with John Wilson (HBO)/mark&#xA;The Dropout (Hulu/Disney)&#xA;span style=&#34;color:red;&#34;The Hunt for Raoul Moat (ITV)/span&#xA;True Detective: Night Country (S4) (HBO)&#xA;span style=&#34;color:red;&#34;The Jinx (doc) (HBO)/span&#xA;The Regime (HBO)&#xA;Resident Alien (S3) (SyFy)&#xA;span style=&#34;color:red;&#34;Blue Lights (BBC)/span&#xA;markRipley (Netflix)/mark&#xA;Clarkson&#39;s Farm (S3) (Amazon)&#xA;markThe Responder (BBC)/mark&#xA;Vera (S13) (ITV)&#xA;markShōgun (FX/Disney)/mark&#xA;The Boys (S4) (Amazon)&#xA;span style=&#34;color:red;&#34;House of the Dragon (S2) (HBO)/span&#xA;Dark Matter (Apple)&#xA;markSugar (Apple)/mark&#xA;Young Sheldon (S7) (Channel 4)&#xA;span style=&#34;color:red;&#34;The Diplomat (S2) (Netflix)/span&#xA;markThe Bear (S3) (FX/Disney)/mark&#xA;The Old Man (S2) (FX/Disney)&#xA;Tom Brady: Man in the Arena (ESPN/Disney)&#xA;markRivals (Disney)/mark&#xA;Lucan (doc) (BBC)&#xA;markBad Monkey (Apple)/mark&#xA;Shrinking (S2) (Apple)&#xA;span style=&#34;color:red;&#34;Industry (S3) (HBO/BBC)/span&#xA;The Day of the Jackal (Sky/Universal)&#xA;markJames Blunt: One Brit Wonder (doc) (Netflix)/mark&#xA;The Perfect Couple (Netflix)&#xA;markA Man On The Inside (Netflix)/mark&#xA;markSolar System (doc) (BBC)/mark&#xA;The Tourist (BBC)&#xA;markNobody Wants This (Netflix)/mark&#xA;Cheaters (BBC)&#xA;span style=&#34;color:red;&#34;Game of Throws: Inside Darts (doc) (Sky)/span&#xA;markWolf Hall (BBC)/mark&#xA;Bad Sisters (S2) (Apple)&#xA;&#xA;brTags: #TV #EndOfYearReview]]&gt;</description>
      <content:encoded><![CDATA[<p>An end-of-year summary of the best television I watched in 2024.</p>



<h5 id="mark-highlighted-mark-strong-recommendation-br-span-style-color-red-bold-span-well-worth-a-watch-if-you-have-the-time-br"><mark>highlighted</mark> = strong recommendation<br><span style="color:red;"><strong>bold</strong></span> = well worth a watch if you have the time<br></h5>
<ul><li><mark><strong>Fargo (S5) (FX)</strong></mark></li>
<li><span style="color:red;"><strong>Mr. Bates vs. The Post Office (ITV)</strong></span></li>
<li><mark><strong>Masters of the Air (Apple)</strong></mark></li>
<li>Griselda (Netflix)</li>
<li>American Nightmare (doc) (Netflix)</li>
<li>Deadwater Fell (Channel 4)</li>
<li><span style="color:red;"><strong>Curb Your Enthusiasm (S12) (HBO)</strong></span></li>
<li><span style="color:red;"><strong>The Space Shuttle That Fell To Earth (doc) (BBC)</strong></span></li>
<li>Alice &amp; Jack (Channel 4)</li>
<li><mark><strong>Kin (S2) (RTE/BBC)</strong></mark></li>
<li>Tell Them You Love Me (doc) (Sky)</li>
<li><span style="color:red;"><strong>The Reckoning (BBC)</strong></span></li>
<li><span style="color:red;"><strong>The Gentlemen (Amazon)</strong></span></li>
<li>Full Swing (S2) (Netflix)</li>
<li><mark><strong>How To with John Wilson (HBO)</strong></mark></li>
<li>The Dropout (Hulu/Disney)</li>
<li><span style="color:red;"><strong>The Hunt for Raoul Moat (ITV)</strong></span></li>
<li>True Detective: Night Country (S4) (HBO)</li>
<li><span style="color:red;"><strong>The Jinx (doc) (HBO)</strong></span></li>
<li>The Regime (HBO)</li>
<li>Resident Alien (S3) (SyFy)</li>
<li><span style="color:red;"><strong>Blue Lights (BBC)</strong></span></li>
<li><mark><strong>Ripley (Netflix)</strong></mark></li>
<li>Clarkson&#39;s Farm (S3) (Amazon)</li>
<li><mark><strong>The Responder (BBC)</strong></mark></li>
<li>Vera (S13) (ITV)</li>
<li><mark><strong>Shōgun (FX/Disney)</strong></mark></li>
<li>The Boys (S4) (Amazon)</li>
<li><span style="color:red;"><strong>House of the Dragon (S2) (HBO)</strong></span></li>
<li>Dark Matter (Apple)</li>
<li><mark><strong>Sugar (Apple)</strong></mark></li>
<li>Young Sheldon (S7) (Channel 4)</li>
<li><span style="color:red;"><strong>The Diplomat (S2) (Netflix)</strong></span></li>
<li><mark><strong>The Bear (S3) (FX/Disney)</strong></mark></li>
<li>The Old Man (S2) (FX/Disney)</li>
<li>Tom Brady: Man in the Arena (ESPN/Disney)</li>
<li><mark><strong>Rivals (Disney)</strong></mark></li>
<li>Lucan (doc) (BBC)</li>
<li><mark><strong>Bad Monkey (Apple)</strong></mark></li>
<li>Shrinking (S2) (Apple)</li>
<li><span style="color:red;"><strong>Industry (S3) (HBO/BBC)</strong></span></li>
<li>The Day of the Jackal (Sky/Universal)</li>
<li><mark><strong>James Blunt: One Brit Wonder (doc) (Netflix)</strong></mark></li>
<li>The Perfect Couple (Netflix)</li>
<li><mark><strong>A Man On The Inside (Netflix)</strong></mark></li>
<li><mark><strong>Solar System (doc) (BBC)</strong></mark></li>
<li>The Tourist (BBC)</li>
<li><mark><strong>Nobody Wants This (Netflix)</strong></mark></li>
<li>Cheaters (BBC)</li>
<li><span style="color:red;"><strong>Game of Throws: Inside Darts (doc) (Sky)</strong></span></li>
<li><mark><strong>Wolf Hall (BBC)</strong></mark></li>
<li>Bad Sisters (S2) (Apple)</li></ul>

<p><br>Tags: <a href="https://blog.rstokes.uk/tag:TV" class="hashtag"><span>#</span><span class="p-category">TV</span></a> <a href="https://blog.rstokes.uk/tag:EndOfYearReview" class="hashtag"><span>#</span><span class="p-category">EndOfYearReview</span></a></p>
]]></content:encoded>
      <guid>https://blog.rstokes.uk/tv-2024</guid>
      <pubDate>Sun, 29 Dec 2024 14:47:50 +0000</pubDate>
    </item>
    <item>
      <title>Film 2024</title>
      <link>https://blog.rstokes.uk/film-2024</link>
      <description>&lt;![CDATA[An end-of-year summary of the films I watched in 2024.&#xA;&#xA;!--more--&#xA;&#xA;div style=&#34;margin:12px 0 -45px 0;&#34;h3Ratings/h3&amp;nbsp;&amp;nbsp;span style=&#34;font-size:0.85em;&#34;(a href=&#34;https://blog.rstokes.uk/movie-ratings-updated&#34;more info/a)/span/div&#xA;&#xA;10 = Masterpiecebr9 = Amazingbr8 = Greatbr7 = Goodbr6 = Okaybr5 = Mediocrebr4 = Poorbr3 = Badbr2 = Awfulbr1 = Unwatchable&#xA;markhighlighted/mark = 8/10 or better (recommendation)brbold = new release (in 2024 or late-2023)britalic = seen before (rewatch)&#xA;&#xA;div style=&#34;margin:25px 0 -30px 0;&#34;h3The Best Films/h3/div&#xA;&#xA;Poor Things (2023) 10/10&#xA;The Favourite (2018) 10/10&#xA;Ex Machina (2015) 10/10&#xA;Interstellar (2014) 10/10&#xA;Tinker Tailor Soldier Spy (2011) 10/10&#xA;The Shawshank Redemption (1994) 10/10&#xA;Conclave (2024) 9/10&#xA;Dune: Part Two (2024) 9/10&#xA;Wallace and Gromit: Vengeance Most Fowl (2024) 9/10&#xA;Killers of the Flower Moon (2023) 9/10&#xA;Asteroid City (2023) 9/10&#xA;Nope (2022) 9/10&#xA;Pig (2021) 9/10&#xA;Once Upon A Time In... Hollywood (2019) 9/10&#xA;Apollo 11 (2019) (doc) 9/10&#xA;Hotel Mumbai (2018) 9/10&#xA;The Killing Of A Sacred Deer (2017) 9/10&#xA;Sicario (2015) 9/10&#xA;Gladiator (2000) 9/10&#xA;Traffic (2000) 9/10&#xA;&#xA;div style=&#34;margin:15px 0 -30px 0;&#34;h3The Solid Recommendations/h3/div&#xA;&#xA;Heretic (2024) 8/10&#xA;Civil War (2024) 8/10&#xA;The Old Oak (2023) 8/10&#xA;Ferrari (2023) 8/10&#xA;Mission: Impossible – Dead Reckoning Part One (2023) 8/10&#xA;The Unlikely Pilgrimage of Harold Fry (2023) 8/10&#xA;X (2022) 8/10&#xA;The Menu (2022) 8/10&#xA;A Man Called Otto (2022) 8/10&#xA;The Outfit (2022) 8/10&#xA;Buried: The 1982 Alpine Meadows Avalanche (2022) (doc) 8/10&#xA;Dune: Part One (2021) 8/10&#xA;The French Dispatch (2021) 8/10&#xA;The Dig (2021) 8/10&#xA;9/11: Inside the President&#39;s War Room (2021) (doc) 8/10&#xA;Just Mercy (2019) 8/10&#xA;Dirty God (2019) 8/10&#xA;The Ballad of Buster Scruggs (2018) 8/10&#xA;The Little Stranger (2018) 8/10&#xA;Kursk (2018) 8/10&#xA;The Founder (2016) 8/10&#xA;The Light Between Oceans (2016) 8/10&#xA;The Lobster (2015) 8/10&#xA;Seven Psychopaths (2012) 8/10&#xA;We Need To Talk About Kevin (2011) 8/10&#xA;Red State (2011) 8/10&#xA;Layer Cake (2004) 8/10&#xA;Shaun of the Dead (2004) 8/10&#xA;Catch Me If You Can (2002) 8/10&#xA;The Beach (2000) 8/10&#xA;10 Things I Hate About You (1999) 8/10&#xA;What Ever Happened To Baby Jane? (1962) 8/10&#xA;The Man Between (1953) 8/10&#xA;&#xA;div style=&#34;margin:15px 0 -30px 0;&#34;h3The Disappointments/h3/div&#xA;&#xA;Gladiator 2 (2024) 5/10&#xA;Trap (2024) 5/10&#xA;The Creator (2023) 5/10&#xA;Cocaine Bear (2023) 5/10&#xA;&#xA;div style=&#34;margin:15px 0 -30px 0;&#34;h3The Stinkers/h3/div&#xA;&#xA;Maggie Moore(s) (2023) 4/10&#xA;Poker Face (2022) 4/10&#xA;Ambulance (2022) 4/10&#xA;Gunpowder Milkshake (2021) 4/10&#xA;The Commuter (2018) 4/10&#xA;Zulu (1964) 4/10&#xA;&#xA;div style=&#34;margin:15px 0 -30px 0;&#34;h3The Full List/h3/div&#xA;&#xA;The Godfather Coda: The Death of Michael Corleone (1990) (Director’s Recut, 2020) 6/10&#xA;Zulu (1964) 4/10&#xA;The Hitman&#39;s Bodyguard (2017) 6/10&#xA;Widows (2017) 6/10&#xA;markThe Dig (2021) 8/10/mark&#xA;Reptile (2023) 6/10&#xA;markThe Founder (2016) 8/10/mark&#xA;markTraffic (2000) 9/10/mark&#xA;Promising Young Woman (2020) 6/10&#xA;10. The Duke (2020) 6/10&#xA;11. Gunpowder Milkshake (2021) 4/10&#xA;12. The Men Who Stare At Goats (2009) 6/10&#xA;13. Days of Thunder (1990) 6/10&#xA;14. Green Zone (2010) 6/10&#xA;15. markX (2022) 8/10/mark&#xA;16. The Commuter (2018) 4/10&#xA;17. Gorillas In The Mist (1988) 6/10&#xA;18. markThe Killing Of A Sacred Deer (2017) 9/10/mark&#xA;19. markPoor Things (2023) 10/10/mark&#xA;20. markThe Man Between (1953) 8/10/mark&#xA;21. markEx Machina (2015) 10/10/mark&#xA;22. Greed (2019) 6/10&#xA;23. markThe Unlikely Pilgrimage of Harold Fry (2023) 8/10/mark&#xA;24. markLayer Cake (2004) 8/10/mark&#xA;25. markThe Little Stranger (2018) 8/10/mark&#xA;26. markThe Favourite (2018) 10/10/mark&#xA;27. markThe Lobster (2015) 8/10/mark&#xA;28. markThe Light Between Oceans (2016) 8/10/mark&#xA;29. markA Man Called Otto (2022) 8/10/mark&#xA;30. French Exit (2020) 6/10&#xA;31. Operation Mincemeat (2021) 6/10&#xA;32. markHotel Mumbai (2018) 9/10/mark&#xA;33. Maggie Moore(s) (2023) 4/10&#xA;34. Poker Face (2022) 4/10&#xA;35. markKillers of the Flower Moon (2023) 9/10/mark&#xA;36. Sister Act (1992) 6/10&#xA;37. markNope (2022) 9/10/mark&#xA;38. The Monuments Men (2014) 6/10&#xA;39. markThe Outfit (2022) 8/10/mark&#xA;40. Ambulance (2022) 4/10&#xA;41. markSeven Psychopaths (2012) 8/10/mark&#xA;42. Three Billboards Outside Ebbing, Missouri (2017) 6/10&#xA;43. The Card Counter (2021) 6/10&#xA;44. markThe Ballad of Buster Scruggs (2018) 8/10/mark&#xA;45. markMission: Impossible – Dead Reckoning Part One (2023) 8/10/mark&#xA;46. markAsteroid City (2023) 9/10/mark&#xA;47. Dog Soldiers (2002) 6/10&#xA;48. markSicario (2015) 9/10/mark&#xA;49. markFerrari (2023) 8/10/mark&#xA;50. markThe Old Oak (2023) 8/10/mark&#xA;51. Cocaine Bear (2023) 5/10&#xA;52. markApollo 11 (2019) (documentary) 9/10/mark&#xA;53. mark9/11: Inside the President&#39;s War Room (2021) (documentary) 8/10/mark&#xA;54. markJust Mercy (2019) 8/10/mark&#xA;55. The Mule (2018) 7/10&#xA;56. markDune: Part One (2021) 8/10/mark&#xA;57. markDune: Part Two (2024) 9/10/mark&#xA;58. markBuried: The 1982 Alpine Meadows Avalanche (2022) (documentary) 8/10/mark&#xA;59. markPig (2021) 9/10/mark&#xA;60. Lost In Translation (2003) 6/10&#xA;61. markRed State (2011) 8/10/mark&#xA;62. Annihilation (2018) 6/10&#xA;63. markOnce Upon A Time In... Hollywood (2019) 9/10/mark&#xA;64. Emily The Criminal (2022) 7/10&#xA;65. markDirty God (2019) 8/10/mark&#xA;66. Draft Day (2014) 6/10&#xA;67. markCivil War (2024) 8/10/mark&#xA;68. mark10 Things I Hate About You (1999) 8/10/mark&#xA;69. Hellboy (2004) 6/10&#xA;70. markKursk (2018) 8/10/mark&#xA;71. markWe Need To Talk About Kevin (2011) 8/10/mark&#xA;72. Rush (2013) 7/10&#xA;73. markWhat Ever Happened To Baby Jane? (1962) 8/10/mark&#xA;74. markThe Menu (2022) 8/10/mark&#xA;75. markTinker Tailor Soldier Spy (2011) 10/10/mark&#xA;76. The Creator (2023) 5/10&#xA;77. Kinds of Kindness (2024) 6/10&#xA;78. Longlegs (2024) 6/10&#xA;79. Beverly Hills Cop (1984) 7/10&#xA;80. Beverly Hills Cop II (1987) 7/10&#xA;81. Beverly Hills Cop: Axel F (2024) 6/10&#xA;82. markThe Beach (2000) 8/10/mark&#xA;83. Trap (2024) 5/10&#xA;84. Blink Twice (2024) 6/10&#xA;85. Speak No Evil (2024) 7/10&#xA;86. markInterstellar (IMAX) (10th ann.) (2014) 10/10/mark&#xA;87. Wolfs (2024) 6/10&#xA;88. markShaun of the Dead (20th ann.) (2004) 8/10/mark&#xA;89. markGladiator (2000) 9/10/mark&#xA;90. Arcadian (2024) 6/10&#xA;91. markHeretic (2024) 8/10/mark&#xA;92. markThe Shawshank Redemption (1994) 10/10/mark&#xA;93. markThe French Dispatch (2021) 8/10/mark&#xA;94. Daddio (2024) 6/10&#xA;95. Spike Island (2012) 6/10&#xA;96. Gladiator 2 (2024) 5/10&#xA;97. The Ministry of Ungentlemanly Warfare (2024) 7/10&#xA;98. markConclave (2024) 9/10/mark&#xA;99. markWallace and Grommit: Vengeance Most Fowl (2024) 9/10/mark&#xA;100. markCatch Me If You Can (2002) 8/10/mark&#xA;101. Next Goal Wins (2023) 7/10&#xA;&#xA;brTags: #Movies #EndOfYearReview]]&gt;</description>
      <content:encoded><![CDATA[<p>An end-of-year summary of the films I watched in 2024.</p>



<div style="margin:12px 0 -45px 0;"><h3>Ratings</h3>  <span style="font-size:0.85em;">(<a href="https://blog.rstokes.uk/movie-ratings-updated">more info</a>)</span></div>

<h5 id="10-masterpiece-br-9-amazing-br-8-great-br-7-good-br-6-okay-br-5-mediocre-br-4-poor-br-3-bad-br-2-awful-br-1-unwatchable">10 = Masterpiece<br>9 = Amazing<br>8 = Great<br>7 = Good<br>6 = Okay<br>5 = Mediocre<br>4 = Poor<br>3 = Bad<br>2 = Awful<br>1 = Unwatchable</h5>

<h5 id="mark-highlighted-mark-8-10-or-better-recommendation-br-bold-new-release-in-2024-or-late-2023-br-italic-seen-before-rewatch"><mark>highlighted</mark> = 8/10 or better (recommendation)<br>bold = new release (in 2024 or late-2023)<br><em>italic</em> = seen before (rewatch)</h5>

<div style="margin:25px 0 -30px 0;"><h3>The Best Films</h3></div>
<ul><li><strong>Poor Things (2023) 10/10</strong></li>
<li>The Favourite (2018) 10/10</li>
<li>Ex Machina (2015) 10/10</li>
<li><em>Interstellar (2014) 10/10</em></li>
<li><em>Tinker Tailor Soldier Spy (2011) 10/10</em></li>
<li><em>The Shawshank Redemption (1994) 10/10</em></li>
<li><strong>Conclave (2024) 9/10</strong></li>
<li><strong>Dune: Part Two (2024) 9/10</strong></li>
<li><strong>Wallace and Gromit: Vengeance Most Fowl (2024) 9/10</strong></li>
<li><strong>Killers of the Flower Moon (2023) 9/10</strong></li>
<li>Asteroid City (2023) 9/10</li>
<li>Nope (2022) 9/10</li>
<li>Pig (2021) 9/10</li>
<li><em>Once Upon A Time In... Hollywood (2019) 9/10</em></li>
<li>Apollo 11 (2019) (doc) 9/10</li>
<li>Hotel Mumbai (2018) 9/10</li>
<li>The Killing Of A Sacred Deer (2017) 9/10</li>
<li><em>Sicario (2015) 9/10</em></li>
<li><em>Gladiator (2000) 9/10</em></li>
<li><em>Traffic (2000) 9/10</em></li></ul>

<div style="margin:15px 0 -30px 0;"><h3>The Solid Recommendations</h3></div>
<ul><li><strong>Heretic (2024) 8/10</strong></li>
<li><strong>Civil War (2024) 8/10</strong></li>
<li><strong>The Old Oak (2023) 8/10</strong></li>
<li><strong>Ferrari (2023) 8/10</strong></li>
<li>Mission: Impossible – Dead Reckoning Part One (2023) 8/10</li>
<li>The Unlikely Pilgrimage of Harold Fry (2023) 8/10</li>
<li>X (2022) 8/10</li>
<li>The Menu (2022) 8/10</li>
<li>A Man Called Otto (2022) 8/10</li>
<li>The Outfit (2022) 8/10</li>
<li>Buried: The 1982 Alpine Meadows Avalanche (2022) (doc) 8/10</li>
<li><em>Dune: Part One (2021) 8/10</em></li>
<li>The French Dispatch (2021) 8/10</li>
<li>The Dig (2021) 8/10</li>
<li>9/11: Inside the President&#39;s War Room (2021) (doc) 8/10</li>
<li>Just Mercy (2019) 8/10</li>
<li>Dirty God (2019) 8/10</li>
<li>The Ballad of Buster Scruggs (2018) 8/10</li>
<li>The Little Stranger (2018) 8/10</li>
<li>Kursk (2018) 8/10</li>
<li>The Founder (2016) 8/10</li>
<li>The Light Between Oceans (2016) 8/10</li>
<li>The Lobster (2015) 8/10</li>
<li>Seven Psychopaths (2012) 8/10</li>
<li>We Need To Talk About Kevin (2011) 8/10</li>
<li><em>Red State (2011) 8/10</em></li>
<li><em>Layer Cake (2004) 8/10</em></li>
<li><em>Shaun of the Dead (2004) 8/10</em></li>
<li><em>Catch Me If You Can (2002) 8/10</em></li>
<li><em>The Beach (2000) 8/10</em></li>
<li><em>10 Things I Hate About You (1999) 8/10</em></li>
<li>What Ever Happened To Baby Jane? (1962) 8/10</li>
<li>The Man Between (1953) 8/10</li></ul>

<div style="margin:15px 0 -30px 0;"><h3>The Disappointments</h3></div>
<ul><li>Gladiator 2 (2024) 5/10</li>
<li>Trap (2024) 5/10</li>
<li>The Creator (2023) 5/10</li>
<li>Cocaine Bear (2023) 5/10</li></ul>

<div style="margin:15px 0 -30px 0;"><h3>The Stinkers</h3></div>
<ul><li>Maggie Moore(s) (2023) 4/10</li>
<li>Poker Face (2022) 4/10</li>
<li>Ambulance (2022) 4/10</li>
<li>Gunpowder Milkshake (2021) 4/10</li>
<li>The Commuter (2018) 4/10</li>
<li>Zulu (1964) 4/10</li></ul>

<div style="margin:15px 0 -30px 0;"><h3>The Full List</h3></div>
<ol><li>The Godfather Coda: The Death of Michael Corleone (1990) (Director’s Recut, 2020) 6/10</li>
<li>Zulu (1964) 4/10</li>
<li>The Hitman&#39;s Bodyguard (2017) 6/10</li>
<li>Widows (2017) 6/10</li>
<li><mark>The Dig (2021) 8/10</mark></li>
<li>Reptile (2023) 6/10</li>
<li><mark>The Founder (2016) 8/10</mark></li>
<li><em><mark>Traffic (2000) 9/10</mark></em></li>
<li>Promising Young Woman (2020) 6/10</li>
<li>The Duke (2020) 6/10</li>
<li>Gunpowder Milkshake (2021) 4/10</li>
<li>The Men Who Stare At Goats (2009) 6/10</li>
<li>Days of Thunder (1990) 6/10</li>
<li>Green Zone (2010) 6/10</li>
<li><mark>X (2022) 8/10</mark></li>
<li>The Commuter (2018) 4/10</li>
<li>Gorillas In The Mist (1988) 6/10</li>
<li><mark>The Killing Of A Sacred Deer (2017) 9/10</mark></li>
<li><mark>Poor Things (2023) 10/10</mark></li>
<li><mark>The Man Between (1953) 8/10</mark></li>
<li><mark>Ex Machina (2015) 10/10</mark></li>
<li>Greed (2019) 6/10</li>
<li><mark>The Unlikely Pilgrimage of Harold Fry (2023) 8/10</mark></li>
<li><em><mark>Layer Cake (2004) 8/10</mark></em></li>
<li><mark>The Little Stranger (2018) 8/10</mark></li>
<li><mark>The Favourite (2018) 10/10</mark></li>
<li><mark>The Lobster (2015) 8/10</mark></li>
<li><mark>The Light Between Oceans (2016) 8/10</mark></li>
<li><mark>A Man Called Otto (2022) 8/10</mark></li>
<li>French Exit (2020) 6/10</li>
<li>Operation Mincemeat (2021) 6/10</li>
<li><mark>Hotel Mumbai (2018) 9/10</mark></li>
<li>Maggie Moore(s) (2023) 4/10</li>
<li>Poker Face (2022) 4/10</li>
<li><mark>Killers of the Flower Moon (2023) 9/10</mark></li>
<li><em>Sister Act (1992) 6/10</em></li>
<li><mark>Nope (2022) 9/10</mark></li>
<li>The Monuments Men (2014) 6/10</li>
<li><mark>The Outfit (2022) 8/10</mark></li>
<li>Ambulance (2022) 4/10</li>
<li><mark>Seven Psychopaths (2012) 8/10</mark></li>
<li>Three Billboards Outside Ebbing, Missouri (2017) 6/10</li>
<li>The Card Counter (2021) 6/10</li>
<li><mark>The Ballad of Buster Scruggs (2018) 8/10</mark></li>
<li><mark>Mission: Impossible – Dead Reckoning Part One (2023) 8/10</mark></li>
<li><mark>Asteroid City (2023) 9/10</mark></li>
<li>Dog Soldiers (2002) 6/10</li>
<li><em><mark>Sicario (2015) 9/10</mark></em></li>
<li><mark>Ferrari (2023) 8/10</mark></li>
<li><mark>The Old Oak (2023) 8/10</mark></li>
<li>Cocaine Bear (2023) 5/10</li>
<li><mark>Apollo 11 (2019) (documentary) 9/10</mark></li>
<li><mark>9/11: Inside the President&#39;s War Room (2021) (documentary) 8/10</mark></li>
<li><mark>Just Mercy (2019) 8/10</mark></li>
<li>The Mule (2018) 7/10</li>
<li><em><mark>Dune: Part One (2021) 8/10</mark></em></li>
<li><strong><mark>Dune: Part Two (2024) 9/10</mark></strong></li>
<li><mark>Buried: The 1982 Alpine Meadows Avalanche (2022) (documentary) 8/10</mark></li>
<li><mark>Pig (2021) 9/10</mark></li>
<li>Lost In Translation (2003) 6/10</li>
<li><em><mark>Red State (2011) 8/10</mark></em></li>
<li>Annihilation (2018) 6/10</li>
<li><em><mark>Once Upon A Time In... Hollywood (2019) 9/10</mark></em></li>
<li>Emily The Criminal (2022) 7/10</li>
<li><mark>Dirty God (2019) 8/10</mark></li>
<li>Draft Day (2014) 6/10</li>
<li><strong><mark>Civil War (2024) 8/10</mark></strong></li>
<li><em><mark>10 Things I Hate About You (1999) 8/10</mark></em></li>
<li>Hellboy (2004) 6/10</li>
<li><mark>Kursk (2018) 8/10</mark></li>
<li><mark>We Need To Talk About Kevin (2011) 8/10</mark></li>
<li><em>Rush (2013) 7/10</em></li>
<li><mark>What Ever Happened To Baby Jane? (1962) 8/10</mark></li>
<li><mark>The Menu (2022) 8/10</mark></li>
<li><em><mark>Tinker Tailor Soldier Spy (2011) 10/10</mark></em></li>
<li>The Creator (2023) 5/10</li>
<li><strong>Kinds of Kindness (2024) 6/10</strong></li>
<li><strong>Longlegs (2024) 6/10</strong></li>
<li><em>Beverly Hills Cop (1984) 7/10</em></li>
<li><em>Beverly Hills Cop II (1987) 7/10</em></li>
<li><strong>Beverly Hills Cop: Axel F (2024) 6/10</strong></li>
<li><em><mark>The Beach (2000) 8/10</mark></em></li>
<li><strong>Trap (2024) 5/10</strong></li>
<li><strong>Blink Twice (2024) 6/10</strong></li>
<li><strong>Speak No Evil (2024) 7/10</strong></li>
<li><em><mark>Interstellar (IMAX) (10th ann.) (2014) 10/10</mark></em></li>
<li><strong>Wolfs (2024) 6/10</strong></li>
<li><em><mark>Shaun of the Dead (20th ann.) (2004) 8/10</mark></em></li>
<li><em><mark>Gladiator (2000) 9/10</mark></em></li>
<li><strong>Arcadian (2024) 6/10</strong></li>
<li><strong><mark>Heretic (2024) 8/10</mark></strong></li>
<li><em><mark>The Shawshank Redemption (1994) 10/10</mark></em></li>
<li><mark>The French Dispatch (2021) 8/10</mark></li>
<li><strong>Daddio (2024) 6/10</strong></li>
<li>Spike Island (2012) 6/10</li>
<li><strong>Gladiator 2 (2024) 5/10</strong></li>
<li><strong>The Ministry of Ungentlemanly Warfare (2024) 7/10</strong></li>
<li><strong><mark>Conclave (2024) 9/10</mark></strong></li>
<li><strong><mark>Wallace and Grommit: Vengeance Most Fowl (2024) 9/10</mark></strong></li>
<li><em><mark>Catch Me If You Can (2002) 8/10</mark></em></li>
<li>Next Goal Wins (2023) 7/10</li></ol>

<p><br>Tags: <a href="https://blog.rstokes.uk/tag:Movies" class="hashtag"><span>#</span><span class="p-category">Movies</span></a> <a href="https://blog.rstokes.uk/tag:EndOfYearReview" class="hashtag"><span>#</span><span class="p-category">EndOfYearReview</span></a></p>
]]></content:encoded>
      <guid>https://blog.rstokes.uk/film-2024</guid>
      <pubDate>Sun, 29 Dec 2024 14:15:27 +0000</pubDate>
    </item>
    <item>
      <title>Installing Mastodon 4.3 on a Raspberry Pi</title>
      <link>https://blog.rstokes.uk/installing-mastodon-4-3-on-a-raspberry-pi</link>
      <description>&lt;![CDATA[Although the official Mastodon installation docs are quite thorough, I did find a few quirks when installing on a Raspberry Pi (both 4B and 5). I&#39;ve brought together various guides that I used (sources are cited) into a single set of instructions which have repeatedly worked for me.&#xA;&#xA;!--more--&#xA;&#xA;div style=&#34;margin-top:-20px&#34;/div&#xA;&#xA;Contents&#xA;&#xA;a href=&#34;#increase-the-swap-file&#34;Step 1 – Increase the swap file/a&#xA;a href=&#34;#ssh-keys&#34;Step 2 – SSH Keys/a&#xA;a href=&#34;#nginx-web-server&#34;Step 3 – NGINX web server/a&#xA;a href=&#34;#ssl-certificates&#34;Step 4 – SSL certificates/a&#xA;a href=&#34;#mastodon-pre-installation&#34;Step 5 – Mastodon pre-installation/a&#xA;a href=&#34;#install-nodejs&#34;Step 6 – Install NodeJS/a&#xA;a href=&#34;#install-postgresql-and-enable-yarn&#34;Step 7 – Install PostgreSQL (and enable Yarn)/a&#xA;a href=&#34;#install-ruby&#34;Step 8 – Install Ruby/a&#xA;a href=&#34;#install-mastodon&#34;Step 9 – Install Mastodon/a&#xA;a href=&#34;#post-installation-customisation&#34;Step 10 – Post-installation customisation/a&#xA;&#xA;div id=&#34;increase-the-swap-file&#34; style=&#34;margin-top:-15px&#34;/div&#xA;&#xA;Step 1. Increase the swap file&#xA;&#xA;If you&#39;re using a 4GB Raspberry Pi (4B or 5), you will need to increase the size of the swap file, at least temporarily, otherwise the process (in Step 9) to compile CSS/JS assets may crash. Obviously, the 1GB and 2GB models should not be used here as they lack sufficient memory.&#xA;&#xA;You can set the swap file back to its original size—once Mastodon is installed—by following these steps again, but this is not necessary.&#xA;&#xA;⚠️ &amp;nbsp;If you&#39;re using a Raspberry Pi (4B or 5) with 8GB of RAM, you can safely skip this and move straight on to Step 2.br&#xA;&#xA;Stop the system from using the current swap file:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;sudo dphys-swapfile swapoff/pre&#xA;&#xA;Open the swap file configuration file:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;sudo nano /etc/dphys-swapfile/pre&#xA;&#xA;Find the following line of text within the file (value may vary):&#xA;&#xA;    pre style=&#34;margin-bottom:-22px;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;CONFSWAPSIZE=200/pre&#xA;&#xA;    and change the value to 2048 (MB):&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;CONFSWAPSIZE=2048/pre&#xA;&#xA;Save the file by pressing CTRL + X, followed by Y, then Enter.&#xA;&#xA;Re-initialise the swap file (removes the original swap file and recreates it to fit the newly defined size):&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;sudo dphys-swapfile setup/pre&#xA;&#xA;Turn the swap back on:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;sudo dphys-swapfile swapon/pre&#xA;&#xA;Reboot the device to allow all programs to be reloaded with access to the new memory pool:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;sudo reboot/pre&#xA;&#xA;div id=&#34;ssh-keys&#34; style=&#34;margin-top:-15px&#34;/div&#xA;&#xA;Step 2. SSH Keys&#xA;&#xA;Using SSH keys for authentication instead of passwords is a great way of securing the Raspberry Pi, as well as making logins much quicker.br&#xA;&#xA;Find your public SSH key on your computer. On macOS, this will be a file ending .pub in the ~/.ssh directory.&#xA;&#xA;Create a .ssh directory in your home directory on the Raspberry Pi:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;install -d -m 700 ~/.ssh/pre&#xA;&#xA;Create (and edit) an authorizedkeys file in the new directory:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;nano ~/.ssh/authorizedkeys/pre&#xA;&#xA;Paste the contents of your public SSH key into this file, then save.&#xA;&#xA;Ensure the file has the correct permissions:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;sudo chmod 644 ~/.ssh/authorizedkeys/pre&#xA;&#xA;Ensure the file has the correct owner (if not using pi as the default user, replace it below with the name of your default user):&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;sudo chown pi:pi ~/.ssh/authorizedkeys/pre&#xA;&#xA;div id=&#34;nginx-web-server&#34; style=&#34;margin-top:-15px&#34;/div&#xA;&#xA;Step 3. NGINX web server&#xA;&#xA;We want the ability to host other websites on this server so we will use NGINX as a reverse proxy for Mastodon.br&#xA;&#xA;Update the package list and upgrade existing packages:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;sudo apt update &amp;&amp; sudo apt upgrade/pre&#xA;&#xA;Install NGINX:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;sudo apt install -y nginx/pre&#xA;&#xA;Start the NGINX service:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;sudo systemctl start nginx/pre&#xA;&#xA;Install PHP-FPM and recommended PHP modules:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;sudo apt install -y php8.2-fpm php8.2-mbstring php8.2-mysql php8.2-curl php8.2-gd php8.2-zip php8.2-xml/pre&#xA;&#xA;div id=&#34;ssl-certificates&#34; style=&#34;margin-top:-15px&#34;/div&#xA;&#xA;Step 4. SSL certificates&#xA;&#xA;I am using Cloudflare for DNS and tunnelling so I need to follow these steps to create and deploy an Origin CA certificate.&#xA;&#xA;⚠️ &amp;nbsp;If you don&#39;t use Cloudflare, install your own SSL certificate here instead of following the exact instructions below.br&#xA;&#xA;Log in to the Cloudflare dashboard and select an account.&#xA;&#xA;Choose your domain.&#xA;&#xA;Go to SSL/TLS   Origin Server.&#xA;&#xA;Select Create Certificate.&#xA;&#xA;Choose Generate private key and CSR with Cloudflare and leave all other options as they are. Click the Create button.&#xA;&#xA;Ensure the Key Format is PEM and then copy the signed Origin Certificate and Private Key into separate .pem and .key files. Click the OK button.&#xA;&#xA;Copy the .pem and .key files to your Raspberry Pi in the /etc/ssl directory.&#xA;&#xA;Change the owner of both files to root:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;sudo chown root:root /etc/ssl/filename.key /etc/ssl/filename.pem/pre&#xA;&#xA;Restart NGINX:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;sudo systemctl restart nginx/pre&#xA;&#xA;10. Back in the Cloudflare dashboard, go to SSL/TLS   Overview and click Configure. Under the option Custom SSL/TLS click Select. Change the option to Full (Strict) and click Save.&#xA;&#xA;div id=&#34;mastodon-pre-installation&#34; style=&#34;margin-top:-15px&#34;/div&#xA;&#xA;Step 5. Mastodon pre-installationbr&#xA;&#xA;Update and upgrade system packages:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;sudo apt update &amp;&amp; sudo apt upgrade/pre&#xA;&#xA;Install dependencies:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;sudo apt install -y curl lsb-release imagemagick ffmpeg libpq-dev libxml2-dev libxslt1-dev file git-core g++ libprotobuf-dev protobuf-compiler pkg-config nodejs gcc autoconf bison build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm-dev nginx redis-server redis-tools certbot python3-certbot-nginx libidn11-dev libicu-dev libjemalloc-dev/pre&#xA;&#xA;Create a mastodon user:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;sudo useradd mastodon -m/pre&#xA;&#xA;div id=&#34;install-nodejs&#34; style=&#34;margin-top:-15px&#34;/div&#xA;&#xA;Step 6. Install NodeJSbr&#xA;&#xA;Update the package list and upgrade existing packages:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;sudo apt update &amp;&amp; sudo apt upgrade/pre&#xA;&#xA;To ensure we have all of the packages we need to access the Nodesource repository, run the following command:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;sudo apt install -y ca-certificates curl gnupg/pre&#xA;&#xA;Download the Nodesource GPG key and store it within the /usr/share/keyrings directory:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;curl -fsSL httpsnolink://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /usr/share/keyrings/nodesource.gpg/pre&#xA;&#xA;Set an environment variable that we will reference next:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;NODEMAJOR=20/pre&#xA;&#xA;Add the NodeJS repository to your sources list:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;echo &#34;deb [signed-by=/usr/share/keyrings/nodesource.gpg] httpsnolink://deb.nodesource.com/node$NODEMAJOR.x nodistro main&#34; | sudo tee /etc/apt/sources.list.d/nodesource.list/pre&#xA;&#xA;Since we made changes to the sources list, we need to update the package list:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;sudo apt update/pre&#xA;&#xA;Install the NodeJS package:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;sudo apt install -y nodejs/pre&#xA;&#xA;div id=&#34;install-postgresql-and-enable-yarn&#34; style=&#34;margin-top:-15px&#34;/div&#xA;&#xA;Step 7. Install PostgreSQL (and enable Yarn)br&#xA;&#xA;Save the GPG key for the PostgreSQL repository:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;curl -L httpsnolink://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | sudo tee /usr/share/keyrings/postgresql-archive-keyring.gpg   /dev/null/pre&#xA;&#xA;Add the repository to our sources list:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;echo &#34;deb [arch=arm64 signed-by=/usr/share/keyrings/postgresql-archive-keyring.gpg] httpnolink://apt.postgresql.org/pub/repos/apt $(lsbrelease -cs)-pgdg main&#34; | sudo tee  /etc/apt/sources.list.d/postgresql.list/pre&#xA;&#xA;As we changed the available repositories, we need to update the package list cache again:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;sudo apt update/pre&#xA;&#xA;Install the PostgreSQL package:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;sudo apt install -y postgresql postgresql-contrib/pre&#xA;&#xA;Launch the PostgreSQL command line interface (CLI):&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;sudo -u postgres psql/pre&#xA;&#xA;Create a PostgreSQL user named mastodon:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;CREATE USER mastodon CREATEDB;/pre&#xA;&#xA;Quit out of the CLI:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;\q/pre&#xA;&#xA;To build and run Mastodon, we need to enable Yarn (the NodeJS package manager). Do this now:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;sudo corepack enable &amp;&amp; sudo yarn set version classic/pre&#xA;&#xA;div id=&#34;install-ruby&#34; style=&#34;margin-top:-15px&#34;/div&#xA;&#xA;Step 8. Install Rubybr&#xA;&#xA;Switch to the mastodon user:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;sudo su mastodon/pre&#xA;&#xA;Change to the home directory:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;cd ~/pre&#xA;&#xA;Clone the code repository for the rbenv utility:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;git clone httpsnolink://github.com/rbenv/rbenv.git ~/.rbenv/pre&#xA;&#xA;Clone the code repository for the ruby-build plugin:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;git clone httpsnolink://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build/pre&#xA;&#xA;Adjust the .bashrc file to initialise the rbenv utility to set up the Ruby environment:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;echo &#39;eval &#34;$(~/.rbenv/bin/rbenv init - bash)&#34;&#39;     ~/.bashrc/pre&#xA;&#xA;To ensure the changes we made are available immediately:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;exec bash/pre&#xA;&#xA;Install Ruby 3.3.5:&#xA;&#xA;    pre style=&#34;margin-bottom:-25px;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;RUBYCONFIGUREOPTS=--with-jemalloc rbenv install 3.3.5/pre&#xA;&#xA;    ##### ⚠️ &amp;nbsp;This step can take a long time to complete.&#xA;&#xA;Declare the installed Ruby version 3.3.5 as the global version to use:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;rbenv global 3.3.5/pre&#xA;&#xA;Use the Ruby package manager to install bundler:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;gem install bundler --no-document/pre&#xA;&#xA;div id=&#34;install-mastodon&#34; style=&#34;margin-top:-15px&#34;/div&#xA;&#xA;Step 9. Install Mastodonbr&#xA;&#xA;Make sure that you are still running as the mastodon user; switch to that user now, if not:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;sudo su mastodon/pre&#xA;&#xA;Change to the home directory:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;cd ~/pre&#xA;&#xA;Clone the code repository for Mastodon, then change to the new live directory:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;git clone httpsnolink://github.com/mastodon/mastodon.git live &amp;&amp; cd live/pre&#xA;&#xA;Change to the latest stable release of Mastodon:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;git checkout $(git tag -l | grep &#39;^v[0-9.]$&#39; | sort -V | tail -n 1)/pre&#xA;&#xA;Set the deployment option to true and exclude any packages that are only used for development or test purposes:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;bundle config deployment &#39;true&#39; &amp;&amp; bundle config without &#39;development test&#39;/pre&#xA;&#xA;Install all of the Ruby dependencies for Mastodon:&#xA;&#xA;    pre style=&#34;margin-bottom:-25px;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;bundle install -j$(nproc)/pre&#xA;&#xA;    Note: we use the -j option to tell the package manager to use as many CPU cores as we have.&#xA;&#xA;Install all of the NodeJS dependencies for Mastodon:&#xA;&#xA;    pre style=&#34;margin-bottom:-25px;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;yarn install/pre&#xA;&#xA;    ##### ⚠️ &amp;nbsp;You can safely ignore any warnings thrown here.&#xA;&#xA;Configure Mastodon:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;RAILSENV=production bundle exec rake mastodon:setup/pre&#xA;&#xA;Follow the on-screen prompts for how you would like to set up Mastodon. You can leave the PostgreSQL and Redis options as default (just press Enter on each option).&#xA;&#xA;10. Switch back to your default user:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;exit/pre&#xA;&#xA;11. Update the default NGINX host file using the template provided on the Mastodon docs website, or replace the file with a copy of a previously backed-up host file.&#xA;&#xA;12. Reload NGINX web server:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;sudo systemctl reload nginx/pre&#xA;&#xA;13. Copy the systemd services for Mastodon to the relevant directory:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;sudo cp /home/mastodon/live/dist/mastodon-.service /etc/systemd/system//pre&#xA;&#xA;14. Start the services now and enable them to start automatically at logon in future:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;sudo systemctl enable --now mastodon-web mastodon-sidekiq mastodon-streaming/pre&#xA;&#xA;div id=&#34;post-installation-customisation&#34; style=&#34;margin-top:-15px&#34;/div&#xA;&#xA;Step 10. Post-installation customisation (optional)&#xA;&#xA;a href=&#34;#import-a-blocklist&#34;Import a blocklist/a&#xA;a href=&#34;#change-the-maximum-post-length-and-poll-limit&#34;Change the maximum post length and poll limit/a&#xA;a href=&#34;#change-the-username-display-name-and-notes-limits&#34;Change the username, display name, and notes limits/a&#xA;&#xA;div id=&#34;import-a-blocklist&#34; style=&#34;margin-top:-30px&#34;/div&#xA;&#xA;Import a blocklist&#xA;&#xA;Download this blocklist.&#xA;&#xA;In Mastodon, go to Moderation   Federation and click on the Import button at the top of the page.&#xA;&#xA;Choose the blocklist file you previously downloaded and click Upload.&#xA;&#xA;You should now see a long list of domain blocks. Make sure the Select All checkbox is selected and then click on Import.&#xA;&#xA;div id=&#34;change-the-maximum-post-length-and-poll-limit&#34; style=&#34;margin-top:-25px&#34;/div&#xA;&#xA;Change the maximum post length and poll limit&#xA;&#xA;Switch to the mastodon user:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;sudo su mastodon/pre&#xA;&#xA;Change to the home directory:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;cd ~/pre&#xA;&#xA;Edit the compose\form\container.js file:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;nano -w live/app/javascript/mastodon/features/compose/containers/composeformcontainer.js/pre&#xA;&#xA;Search for the line:&#xA;&#xA;    pre style=&#34;margin-bottom:-25px;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;maxChars: state.getIn([&#39;server&#39;, &#39;server&#39;, &#39;configuration&#39;, &#39;statuses&#39;, &#39;maxcharacters&#39;], 500)/pre&#xA;&#xA;    and change the value 500 to the new limit (e.g. 2000).&#xA;&#xA;Save the file by pressing CTRL + X, followed by Y, then Enter.&#xA;&#xA;Edit the status\length\validator.rb file:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;nano -w live/app/validators/statuslengthvalidator.rb/pre&#xA;&#xA;Search for the line:&#xA;&#xA;    pre style=&#34;margin-bottom:-25px;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;MAXCHARS = 500/pre&#xA;&#xA;    and change the value 500 to the same new limit as above.&#xA;&#xA;Save the file by pressing CTRL + X, followed by Y, then Enter.&#xA;&#xA;Edit the poll\options\validator.rb file:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;nano -w live/app/validators/polloptionsvalidator.rb/pre&#xA;&#xA;10. Search for the line:&#xA;&#xA;    pre style=&#34;margin-bottom:-25px;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;MAXOPTIONS = 4/pre&#xA;&#xA;    and change the value 4 to the new limit (e.g. 12).&#xA;&#xA;11. Save the file by pressing CTRL + X, followed by Y, then Enter.&#xA;&#xA;12. Rebuild the assets:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;cd live &amp;&amp; RAILSENV=production bundle exec rails assets:precompile/pre&#xA;&#xA;13. Switch back to the main user:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;exit/pre&#xA;&#xA;14. Restart the Mastodon services:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;sudo systemctl restart mastodon-sidekiq mastodon-web mastodon-streaming/pre&#xA;&#xA;div id=&#34;change-the-username-display-name-and-notes-limits&#34; style=&#34;margin-top:-25px&#34;/div&#xA;&#xA;Change the username, display name, and notes limits&#xA;&#xA;Switch to the mastodon user:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;sudo su mastodon/pre&#xA;&#xA;Change to the home directory:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;cd ~/pre&#xA;&#xA;Edit the account.rb file:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;nano -w live/app/models/account.rb/pre&#xA;&#xA;Search for the following lines and amend as required:&#xA;&#xA;    pre style=&#34;margin-bottom:-50px;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;USERNAMELENGTHLIMIT = 30/pre&#xA;&#xA;    pre style=&#34;margin-bottom:-50px;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;DISPLAYNAMELENGTHLIMIT = 30/pre&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;NOTELENGTH_LIMIT = 500/pre&#xA;&#xA;Save the file by pressing CTRL + X, followed by Y, then Enter.&#xA;&#xA;Restart the Mastodon services:&#xA;&#xA;    pre style=&#34;white-space:pre-wrap;font-size:1em;font-weight:bold;&#34;sudo systemctl restart mastodon-sidekiq mastodon-web mastodon-streaming/pre&#xA;&#xA;div style=&#34;margin-top:-10px&#34;/div&#xA;&#xA;span style=&#34;font-size:0.95em;font-weight:bold;&#34;Sources:/spanspan style=&#34;font-size:0.85em;&#34;&#xA;Increasing Swap on a Raspberry Pi&#xA;How to Setup SSH Keys on your Raspberry Pi&#xA;Build your own Raspberry Pi NGINX Web Server&#xA;Cloudflare origin CA&#xA;How to create a CSR using OpenSSL &amp; install your SSL certificate on a Nginx server&#xA;Installing Mastodon on the Raspberry Pi&#xA;Installing NodeJS on the Raspberry Pi&#xA;Mastodon blocklists&#xA;Increasing the Mastodon post character and poll options limit&#xA;/span&#xA;&#xA;brTags: #Mastodon #RaspberryPi]]&gt;</description>
      <content:encoded><![CDATA[<p>Although the official Mastodon installation docs are quite thorough, I did find a few quirks when installing on a Raspberry Pi (both 4B and 5). I&#39;ve brought together various guides that I used (sources are cited) into a single set of instructions which have repeatedly worked for me.</p>



<div style="margin-top:-20px"></div>

<h3 id="contents">Contents</h3>

<p><a href="#increase-the-swap-file">Step 1 – Increase the swap file</a>
<a href="#ssh-keys">Step 2 – SSH Keys</a>
<a href="#nginx-web-server">Step 3 – NGINX web server</a>
<a href="#ssl-certificates">Step 4 – SSL certificates</a>
<a href="#mastodon-pre-installation">Step 5 – Mastodon pre-installation</a>
<a href="#install-nodejs">Step 6 – Install NodeJS</a>
<a href="#install-postgresql-and-enable-yarn">Step 7 – Install PostgreSQL (and enable Yarn)</a>
<a href="#install-ruby">Step 8 – Install Ruby</a>
<a href="#install-mastodon">Step 9 – Install Mastodon</a>
<a href="#post-installation-customisation">Step 10 – Post-installation customisation</a></p>

<div id="increase-the-swap-file" style="margin-top:-15px"></div>

<h3 id="step-1-increase-the-swap-file">Step 1. Increase the swap file</h3>

<p>If you&#39;re using a <strong>4GB</strong> Raspberry Pi (4B or 5), you will need to increase the size of the swap file, at least temporarily, otherwise the process (in Step 9) to compile CSS/JS assets may crash. Obviously, the 1GB and 2GB models should <strong>not</strong> be used here as they lack sufficient memory.</p>

<p>You can set the swap file back to its original size—once Mastodon is installed—by following these steps again, but this is not necessary.</p>

<h5 id="nbsp-if-you-re-using-a-raspberry-pi-4b-or-5-with-8gb-of-ram-you-can-safely-skip-this-and-move-straight-on-to-step-2-br">⚠️  If you&#39;re using a Raspberry Pi (4B or 5) with 8GB of RAM, you can safely skip this and move straight on to Step 2.<br></h5>
<ol><li><p>Stop the system from using the current swap file:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">sudo dphys-swapfile swapoff</pre></li>

<li><p>Open the swap file configuration file:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">sudo nano /etc/dphys-swapfile</pre></li>

<li><p>Find the following line of text within the file (value may vary):</p>

<pre style="margin-bottom:-22px;white-space:pre-wrap;font-size:1em;font-weight:bold;">CONF_SWAPSIZE=200</pre>

<p>and change the value to 2048 (MB):</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">CONF_SWAPSIZE=2048</pre></li>

<li><p>Save the file by pressing <strong>CTRL + X</strong>, followed by <strong>Y</strong>, then <strong>Enter</strong>.</p></li>

<li><p>Re-initialise the swap file (removes the original swap file and recreates it to fit the newly defined size):</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">sudo dphys-swapfile setup</pre></li>

<li><p>Turn the swap back on:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">sudo dphys-swapfile swapon</pre></li>

<li><p>Reboot the device to allow all programs to be reloaded with access to the new memory pool:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">sudo reboot</pre></li></ol>

<div id="ssh-keys" style="margin-top:-15px"></div>

<h3 id="step-2-ssh-keys">Step 2. SSH Keys</h3>

<p>Using SSH keys for authentication instead of passwords is a great way of securing the Raspberry Pi, as well as making logins much quicker.<br></p>
<ol><li><p>Find your public SSH key on your computer. On macOS, this will be a file ending <strong>.pub</strong> in the <strong>~/.ssh</strong> directory.</p></li>

<li><p>Create a <strong>.ssh</strong> directory in your home directory on the Raspberry Pi:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">install -d -m 700 ~/.ssh</pre></li>

<li><p>Create (and edit) an <strong>authorized_keys</strong> file in the new directory:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">nano ~/.ssh/authorized_keys</pre></li>

<li><p>Paste the contents of your public SSH key into this file, then save.</p></li>

<li><p>Ensure the file has the correct permissions:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">sudo chmod 644 ~/.ssh/authorized_keys</pre></li>

<li><p>Ensure the file has the correct owner (if not using <strong>pi</strong> as the default user, replace it below with the name of your default user):</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">sudo chown pi:pi ~/.ssh/authorized_keys</pre></li></ol>

<div id="nginx-web-server" style="margin-top:-15px"></div>

<h3 id="step-3-nginx-web-server">Step 3. NGINX web server</h3>

<p>We want the ability to host other websites on this server so we will use NGINX as a reverse proxy for Mastodon.<br></p>
<ol><li><p>Update the package list and upgrade existing packages:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">sudo apt update &amp;&amp; sudo apt upgrade</pre></li>

<li><p>Install NGINX:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">sudo apt install -y nginx</pre></li>

<li><p>Start the NGINX service:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">sudo systemctl start nginx</pre></li>

<li><p>Install PHP-FPM and recommended PHP modules:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">sudo apt install -y php8.2-fpm php8.2-mbstring php8.2-mysql php8.2-curl php8.2-gd php8.2-zip php8.2-xml</pre></li></ol>

<div id="ssl-certificates" style="margin-top:-15px"></div>

<h3 id="step-4-ssl-certificates">Step 4. SSL certificates</h3>

<p>I am using Cloudflare for DNS and tunnelling so I need to follow these steps to create and deploy an Origin CA certificate.</p>

<h5 id="nbsp-if-you-don-t-use-cloudflare-install-your-own-ssl-certificate-here-instead-of-following-the-exact-instructions-below-br">⚠️  If you don&#39;t use Cloudflare, install your own SSL certificate here instead of following the exact instructions below.<br></h5>
<ol><li><p>Log in to the Cloudflare dashboard and select an account.</p></li>

<li><p>Choose your domain.</p></li>

<li><p>Go to <strong>SSL/TLS &gt; Origin Server</strong>.</p></li>

<li><p>Select <strong>Create Certificate</strong>.</p></li>

<li><p>Choose <strong>Generate private key and CSR with Cloudflare</strong> and leave all other options as they are. Click the <strong>Create</strong> button.</p></li>

<li><p>Ensure the <strong>Key Format</strong> is <strong>PEM</strong> and then copy the signed <strong>Origin Certificate</strong> and <strong>Private Key</strong> into separate <strong>.pem</strong> and <strong>.key</strong> files. Click the <strong>OK</strong> button.</p></li>

<li><p>Copy the <strong>.pem</strong> and <strong>.key</strong> files to your Raspberry Pi in the <strong>/etc/ssl</strong> directory.</p></li>

<li><p>Change the owner of both files to <strong>root</strong>:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">sudo chown root:root /etc/ssl/filename.key /etc/ssl/filename.pem</pre></li>

<li><p>Restart NGINX:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">sudo systemctl restart nginx</pre></li>

<li><p>Back in the Cloudflare dashboard, go to <strong>SSL/TLS &gt; Overview</strong> and click <strong>Configure</strong>. Under the option <strong>Custom SSL/TLS</strong> click <strong>Select</strong>. Change the option to <strong>Full (Strict)</strong> and click <strong>Save</strong>.</p></li></ol>

<div id="mastodon-pre-installation" style="margin-top:-15px"></div>

<h3 id="step-5-mastodon-pre-installation-br">Step 5. Mastodon pre-installation<br></h3>
<ol><li><p>Update and upgrade system packages:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">sudo apt update &amp;&amp; sudo apt upgrade</pre></li>

<li><p>Install dependencies:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">sudo apt install -y curl lsb-release imagemagick ffmpeg libpq-dev libxml2-dev libxslt1-dev file git-core g++ libprotobuf-dev protobuf-compiler pkg-config nodejs gcc autoconf bison build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm-dev nginx redis-server redis-tools certbot python3-certbot-nginx libidn11-dev libicu-dev libjemalloc-dev</pre></li>

<li><p>Create a <strong>mastodon</strong> user:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">sudo useradd mastodon -m</pre></li></ol>

<div id="install-nodejs" style="margin-top:-15px"></div>

<h3 id="step-6-install-nodejs-br">Step 6. Install NodeJS<br></h3>
<ol><li><p>Update the package list and upgrade existing packages:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">sudo apt update &amp;&amp; sudo apt upgrade</pre></li>

<li><p>To ensure we have all of the packages we need to access the Nodesource repository, run the following command:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">sudo apt install -y ca-certificates curl gnupg</pre></li>

<li><p>Download the Nodesource GPG key and store it within the <strong>/usr/share/keyrings</strong> directory:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /usr/share/keyrings/nodesource.gpg</pre></li>

<li><p>Set an environment variable that we will reference next:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">NODE_MAJOR=20</pre></li>

<li><p>Add the NodeJS repository to your sources list:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">echo &#34;deb [signed-by=/usr/share/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main&#34; | sudo tee /etc/apt/sources.list.d/nodesource.list</pre></li>

<li><p>Since we made changes to the sources list, we need to update the package list:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">sudo apt update</pre></li>

<li><p>Install the NodeJS package:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">sudo apt install -y nodejs</pre></li></ol>

<div id="install-postgresql-and-enable-yarn" style="margin-top:-15px"></div>

<h3 id="step-7-install-postgresql-and-enable-yarn-br">Step 7. Install PostgreSQL (and enable Yarn)<br></h3>
<ol><li><p>Save the GPG key for the PostgreSQL repository:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">curl -L https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | sudo tee /usr/share/keyrings/postgresql-archive-keyring.gpg &gt;/dev/null</pre></li>

<li><p>Add the repository to our sources list:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">echo &#34;deb [arch=arm64 signed-by=/usr/share/keyrings/postgresql-archive-keyring.gpg] http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main&#34; | sudo tee  /etc/apt/sources.list.d/postgresql.list</pre></li>

<li><p>As we changed the available repositories, we need to update the package list cache again:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">sudo apt update</pre></li>

<li><p>Install the PostgreSQL package:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">sudo apt install -y postgresql postgresql-contrib</pre></li>

<li><p>Launch the PostgreSQL command line interface (CLI):</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">sudo -u postgres psql</pre></li>

<li><p>Create a PostgreSQL user named <strong>mastodon</strong>:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">CREATE USER mastodon CREATEDB;</pre></li>

<li><p>Quit out of the CLI:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">\q</pre></li>

<li><p>To build and run Mastodon, we need to enable Yarn (the NodeJS package manager). Do this now:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">sudo corepack enable &amp;&amp; sudo yarn set version classic</pre></li></ol>

<div id="install-ruby" style="margin-top:-15px"></div>

<h3 id="step-8-install-ruby-br">Step 8. Install Ruby<br></h3>
<ol><li><p>Switch to the <strong>mastodon</strong> user:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">sudo su mastodon</pre></li>

<li><p>Change to the <em>home</em> directory:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">cd ~</pre></li>

<li><p>Clone the code repository for the <em>rbenv</em> utility:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">git clone https://github.com/rbenv/rbenv.git ~/.rbenv</pre></li>

<li><p>Clone the code repository for the <em>ruby-build</em> plugin:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build</pre></li>

<li><p>Adjust the <em>.bashrc</em> file to initialise the <em>rbenv</em> utility to set up the Ruby environment:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">echo &#39;eval &#34;$(~/.rbenv/bin/rbenv init - bash)&#34;&#39; &gt;&gt; ~/.bashrc</pre></li>

<li><p>To ensure the changes we made are available immediately:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">exec bash</pre></li>

<li><p>Install Ruby 3.3.5:</p>

<pre style="margin-bottom:-25px;white-space:pre-wrap;font-size:1em;font-weight:bold;">RUBY_CONFIGURE_OPTS=--with-jemalloc rbenv install 3.3.5</pre>

<h5 id="nbsp-this-step-can-take-a-long-time-to-complete">⚠️  This step can take a long time to complete.</h5></li>

<li><p>Declare the installed Ruby version 3.3.5 as the global version to use:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">rbenv global 3.3.5</pre></li>

<li><p>Use the Ruby package manager to install <em>bundler</em>:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">gem install bundler --no-document</pre></li></ol>

<div id="install-mastodon" style="margin-top:-15px"></div>

<h3 id="step-9-install-mastodon-br">Step 9. Install Mastodon<br></h3>
<ol><li><p>Make sure that you are still running as the <strong>mastodon</strong> user; switch to that user now, if not:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">sudo su mastodon</pre></li>

<li><p>Change to the <em>home</em> directory:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">cd ~</pre></li>

<li><p>Clone the code repository for Mastodon, then change to the new <em>live</em> directory:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">git clone https://github.com/mastodon/mastodon.git live &amp;&amp; cd live</pre></li>

<li><p>Change to the <strong>latest stable release</strong> of Mastodon:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">git checkout $(git tag -l | grep &#39;^v[0-9.]*$&#39; | sort -V | tail -n 1)</pre></li>

<li><p>Set the <em>deployment</em> option to true and exclude any packages that are only used for development or test purposes:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">bundle config deployment &#39;true&#39; &amp;&amp; bundle config without &#39;development test&#39;</pre></li>

<li><p>Install all of the Ruby dependencies for Mastodon:</p>

<pre style="margin-bottom:-25px;white-space:pre-wrap;font-size:1em;font-weight:bold;">bundle install -j$(nproc)</pre>

<p><em>Note: we use the -j option to tell the package manager to use as many CPU cores as we have.</em></p></li>

<li><p>Install all of the NodeJS dependencies for Mastodon:</p>

<pre style="margin-bottom:-25px;white-space:pre-wrap;font-size:1em;font-weight:bold;">yarn install</pre>

<h5 id="nbsp-you-can-safely-ignore-any-warnings-thrown-here">⚠️  You can safely ignore any warnings thrown here.</h5></li>

<li><p>Configure Mastodon:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">RAILS_ENV=production bundle exec rake mastodon:setup</pre></li>

<li><p>Follow the on-screen prompts for how you would like to set up Mastodon. You can leave the PostgreSQL and Redis options as default (just press <strong>Enter</strong> on each option).</p></li>

<li><p>Switch back to your default user:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">exit</pre></li>

<li><p>Update the default NGINX host file using the template provided on the Mastodon docs website, or replace the file with a copy of a previously backed-up host file.</p></li>

<li><p>Reload NGINX web server:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">sudo systemctl reload nginx</pre></li>

<li><p>Copy the <em>systemd</em> services for Mastodon to the relevant directory:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">sudo cp /home/mastodon/live/dist/mastodon-*.service /etc/systemd/system/</pre></li>

<li><p>Start the services now and enable them to start automatically at logon in future:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">sudo systemctl enable --now mastodon-web mastodon-sidekiq mastodon-streaming</pre></li></ol>

<div id="post-installation-customisation" style="margin-top:-15px"></div>

<h3 id="step-10-post-installation-customisation-optional">Step 10. Post-installation customisation <em>(optional)</em></h3>

<p><a href="#import-a-blocklist">Import a blocklist</a>
<a href="#change-the-maximum-post-length-and-poll-limit">Change the maximum post length and poll limit</a>
<a href="#change-the-username-display-name-and-notes-limits">Change the username, display name, and notes limits</a></p>

<div id="import-a-blocklist" style="margin-top:-30px"></div>

<h3 id="import-a-blocklist">Import a blocklist</h3>
<ol><li><p>Download <a href="https://github.com/sgrigson/oliphant/blob/main/blocklists/mastodon/_unified_tier0_blocklist.csv">this blocklist</a>.</p></li>

<li><p>In Mastodon, go to <strong>Moderation</strong> &gt; <strong>Federation</strong> and click on the <strong>Import</strong> button at the top of the page.</p></li>

<li><p>Choose the blocklist file you previously downloaded and click <strong>Upload</strong>.</p></li>

<li><p>You should now see a long list of domain blocks. Make sure the <strong>Select All</strong> checkbox is selected and then click on <strong>Import</strong>.</p></li></ol>

<div id="change-the-maximum-post-length-and-poll-limit" style="margin-top:-25px"></div>

<h3 id="change-the-maximum-post-length-and-poll-limit">Change the maximum post length and poll limit</h3>
<ol><li><p>Switch to the <strong>mastodon</strong> user:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">sudo su mastodon</pre></li>

<li><p>Change to the <em>home</em> directory:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">cd ~</pre></li>

<li><p>Edit the <em>compose_form_container.js</em> file:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">nano -w live/app/javascript/mastodon/features/compose/containers/compose_form_container.js</pre></li>

<li><p>Search for the line:</p>

<pre style="margin-bottom:-25px;white-space:pre-wrap;font-size:1em;font-weight:bold;">maxChars: state.getIn([&#39;server&#39;, &#39;server&#39;, &#39;configuration&#39;, &#39;statuses&#39;, &#39;max_characters&#39;], 500)</pre>

<p>and change the value <strong>500</strong> to the new limit (e.g. 2000).</p></li>

<li><p>Save the file by pressing <strong>CTRL + X</strong>, followed by <strong>Y</strong>, then <strong>Enter</strong>.</p></li>

<li><p>Edit the <em>status_length_validator.rb</em> file:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">nano -w live/app/validators/status_length_validator.rb</pre></li>

<li><p>Search for the line:</p>

<pre style="margin-bottom:-25px;white-space:pre-wrap;font-size:1em;font-weight:bold;">MAX_CHARS = 500</pre>

<p>and change the value <strong>500</strong> to the same new limit as above.</p></li>

<li><p>Save the file by pressing <strong>CTRL + X</strong>, followed by <strong>Y</strong>, then <strong>Enter</strong>.</p></li>

<li><p>Edit the <em>poll_options_validator.rb</em> file:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">nano -w live/app/validators/poll_options_validator.rb</pre></li>

<li><p>Search for the line:</p>

<pre style="margin-bottom:-25px;white-space:pre-wrap;font-size:1em;font-weight:bold;">MAX_OPTIONS = 4</pre>

<p>and change the value <strong>4</strong> to the new limit (e.g. 12).</p></li>

<li><p>Save the file by pressing <strong>CTRL + X</strong>, followed by <strong>Y</strong>, then <strong>Enter</strong>.</p></li>

<li><p>Rebuild the assets:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">cd live &amp;&amp; RAILS_ENV=production bundle exec rails assets:precompile</pre></li>

<li><p>Switch back to the main user:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">exit</pre></li>

<li><p>Restart the Mastodon services:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">sudo systemctl restart mastodon-sidekiq mastodon-web mastodon-streaming</pre></li></ol>

<div id="change-the-username-display-name-and-notes-limits" style="margin-top:-25px"></div>

<h3 id="change-the-username-display-name-and-notes-limits">Change the username, display name, and notes limits</h3>
<ol><li><p>Switch to the <strong>mastodon</strong> user:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">sudo su mastodon</pre></li>

<li><p>Change to the <em>home</em> directory:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">cd ~</pre></li>

<li><p>Edit the <em>account.rb</em> file:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">nano -w live/app/models/account.rb</pre></li>

<li><p>Search for the following lines and amend as required:</p>

<pre style="margin-bottom:-50px;white-space:pre-wrap;font-size:1em;font-weight:bold;">USERNAME_LENGTH_LIMIT = 30</pre>

<pre style="margin-bottom:-50px;white-space:pre-wrap;font-size:1em;font-weight:bold;">DISPLAY_NAME_LENGTH_LIMIT = 30</pre>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">NOTE_LENGTH_LIMIT = 500</pre></li>

<li><p>Save the file by pressing <strong>CTRL + X</strong>, followed by <strong>Y</strong>, then <strong>Enter</strong>.</p></li>

<li><p>Restart the Mastodon services:</p>

<pre style="white-space:pre-wrap;font-size:1em;font-weight:bold;">sudo systemctl restart mastodon-sidekiq mastodon-web mastodon-streaming</pre></li></ol>

<div style="margin-top:-10px"></div>

<p><span style="font-size:0.95em;font-weight:bold;">Sources:</span><span style="font-size:0.85em;">
<a href="https://pimylifeup.com/raspberry-pi-swap-file">Increasing Swap on a Raspberry Pi</a>
<a href="https://pimylifeup.com/raspberry-pi-ssh-keys">How to Setup SSH Keys on your Raspberry Pi</a>
<a href="https://pimylifeup.com/raspberry-pi-nginx">Build your own Raspberry Pi NGINX Web Server</a>
<a href="https://developers.cloudflare.com/ssl/origin-configuration/origin-ca">Cloudflare origin CA</a>
<a href="https://www.digicert.com/kb/csr-ssl-installation/nginx-openssl.htm">How to create a CSR using OpenSSL &amp; install your SSL certificate on a Nginx server</a>
<a href="https://pimylifeup.com/raspberry-pi-mastodon">Installing Mastodon on the Raspberry Pi</a>
<a href="https://pimylifeup.com/raspberry-pi-nodejs">Installing NodeJS on the Raspberry Pi</a>
<a href="https://github.com/sgrigson/oliphant/tree/main/blocklists/mastodon">Mastodon blocklists</a>
<a href="https://fouquet.me/2024/10/10/mastodon-4-3-char-limit">Increasing the Mastodon post character and poll options limit</a>
</span></p>

<p><br>Tags: <a href="https://blog.rstokes.uk/tag:Mastodon" class="hashtag"><span>#</span><span class="p-category">Mastodon</span></a> <a href="https://blog.rstokes.uk/tag:RaspberryPi" class="hashtag"><span>#</span><span class="p-category">RaspberryPi</span></a></p>
]]></content:encoded>
      <guid>https://blog.rstokes.uk/installing-mastodon-4-3-on-a-raspberry-pi</guid>
      <pubDate>Sun, 20 Oct 2024 21:02:53 +0000</pubDate>
    </item>
  </channel>
</rss>