Right next to my laptop I have a Raspberry Pi 4 with a touchscreen connected to it. The screen sits idly for most of the time so I thought I could make some use of it and decided turn it into a digital picture frame using its screensaver.

I have Raspbian Buster with Recommended Software version installed on the Pi but it didn’t have screensaver installed. It can be easily installed though:

sudo apt-get install xscreensaver

The next step is to install slideshow add-on for the screensaver:

sudo apt-get install xscreensaver-gl-extra

Then I uploaded some pictures to the pi from my laptop:

scp -r /Local/Path/To/Pictures  pi@

Then on the Pi I opened screensaver options and pointed to /home/pi/Pictures/PhotoDB folder. After fiddling with the time settings to my liking my picture frame was up and running:

Another option is to use Gnome Desktop’s tool called eog which first should be installed

sudo apt-get install eog

Then can be run as

eog --slide-show /path/to/picture_directory

But this program lacks options that XScreenSaver has.



I used a guide to install Docker on new Raspberry Pi 4. For future reference I’m publishing this TIL. Also the article was corrected after its initial publish so I thought it would be safer to have a working copy here.

Tested the below commands with Raspbian Buster both on a Raspberry Pi 1 and 4 (4GB) RAM. Apart from the expected performance difference it worked perfectly on both machines.

curl -sSL https://get.docker.com | sh
sudo usermod -aG docker pi

Reboot for the permission to take affect.


sudo apt-get install libffi-dev libssl-dev

sudo apt-get install -y python python-pip

sudo apt-get remove python-configparser

Docker compose:

sudo pip install docker-compose



It’s nice to host your own blog in AWS using S3 and CloudFront but deployment can quickly become a hassle. I intend to set up a fully automated pipeline but for the time being I just developed the following script to deploy the site.

The script does the following:

  • Build Jekyll site
  • Delete the contents of the target bucket
  • Upload the site contents to the target bucket
  • Invalidate CloudFormation

Also note that it assumes:

  • The bucket is set up yo enable static wrbsite hosting
  • There is a CloudFront distribtuion setup to use this bucket as source
  • There is a DNS entry pointing to the CloudFront distribtuion.

Assuming those have already been created and set up, the deployment function works like below:

function Deploy-Blog 
      [string] $s3BucketName,
      [string] $cloudFrontDistributionId,
      [bool] $runBuild = $true
    if ($runBuild)
        Write-Host "Building blog"
        bundle exec jekyll build    
    Write-Host "Clearing bucket"
    aws s3 rm s3://$s3BucketName --recursive
    Write-Host "Uploading site to staging bucket"
    aws s3 cp ./_site s3://$s3BucketName --acl public-read --recursive
    Write-Host "Invalidate CloudFront distribution"
    aws cloudfront create-invalidation --distribution-id $cloudFrontDistributionId --paths "/*"    

and the consuming function looks like this:

To deploy to staging and confirm the changes work fine, run:

. ".\deploy.ps1" 

$STAGING_BUCKET_NAME = "staging.my.domain.com"


This script build the Jekyll site and deploys to staging. Then to promote to production, run:

. ".\deploy.ps1" 

$PROD_BUCKET_NAME = "my.domain.com"


Note the build parameter is set to false as we don’t need to build the site again. We just want to deploy the previous output we deployed to staging stragith to production.