Category Archives: Docker

Backup Docker Container configuration script

A while ago I looked into a good way to backup Docker configurations for each container.  This is useful if you have many containers and want a backup strategy that includes container settings.

The below script is from https://github.com/007revad/Docker_Autocompose and does rely on the image red5d/docker-autocompose which the script will download if not already present on your Docker server.

Save the following script as docker-autocompose.sh and run with the commands shown at the top.

#!/usr/bin/env sh
#--------------------------------------------------------------------------------------
# A script to create docker-compose.yml files from docker containers.
#
# Script can be run with a container name parameter to only process that container:
# sudo -s docker-autocompose.sh plex
#
# Or with no parameter, or the "all" parameter, to process all containers:
# sudo -s docker-autocompose.sh all
#
# https://github.com/007revad/Docker_Autocompose
# Adapted from: https://www.synoforum.com/threads/docker-autocompose.4644/#post-20341
#--------------------------------------------------------------------------------------
# REQUIRED:
#
# Needs Red5d/docker-autocompose installed in docker.
# Red5d/docker-autocompose should not be started in docker.
#--------------------------------------------------------------------------------------

# Set the path where you want to .yml files saved to. If blank will save in your home.
saveto="/opt/backup-docker"

# Set to yes to include hostname in the folder name.
# Handy if you have multiple devices that backup to the same location.
IncludeHostname=yes

# Set to yes to backup all containers (running or stopped), or no to backup only running containers.
BackupAllContainers=yes

#--------------------------------------------------------------------------------------

autocompose="red5d/docker-autocompose"

# Check script is running as root (or docker.sock won't run)
if [ $( whoami ) != "root" ]; then
    echo "Script needs to run as root. Aborting."
    exit 1
fi

# Check our saveto path exists (if saveto is set)
if [ ! -d "${saveto}" ]; then
    echo "saveto path not found. Files will be saved in your home."
    saveto=
fi 

# Get hostname if IncludeHostname is yes
echo "IncludeHostname is set to: '${IncludeHostname}'"  # Debugging
if [ "${IncludeHostname}" = "yes" ]; then
    host="$(hostname)_"
fi

# Create subfolder with date
if [ -d "${saveto}" ]; then
    Now=$( date '+%Y%m%d')
    if mkdir -p "${saveto}/${Now}_${host}docker-autocompose"; then
        path="${saveto}/${Now}_${host}docker-autocompose/"
    fi
fi

# Function to process a single container
process_container() {
    container_name="${1}"
    container_id=$(docker container ls -a -q --filter name="${container_name}")
    
    # Check if container exists
    if [ -z "${container_id}" ]; then
        echo "Container '${container_name}' not found. Skipping."
        return
    fi

    # Skip non-running containers if BackupAllContainers=no
    if [ "${BackupAllContainers}" != "yes" ]; then
        is_running=$(docker container inspect -f '{{.State.Running}}' "${container_id}")
        if [ "${is_running}" != "true" ]; then
            echo "Container '${container_name}' is not running. Skipping (BackupAllContainers=no)."
            return
        fi
    fi

    # Check if container is running
    is_running=$(docker container inspect -f '{{.State.Running}}' "${container_id}")
    
    if [ "${is_running}" != "true" ] && [ "${BackupAllContainers}" = "yes" ]; then
        echo "Starting container '${container_name}' temporarily..."
        if docker start "${container_id}" > /dev/null 2>&1; then
            # Generate docker-compose.yml
            docker run --rm -v /var/run/docker.sock:/var/run/docker.sock "${autocompose}" "${container_id}" > "${path}${container_name}-compose.yml"
            # Stop the container after generating the file
            docker stop "${container_id}" > /dev/null 2>&1
            echo "Generated docker-compose.yml for '${container_name}' and stopped it."
        else
            echo "Failed to start container '${container_name}'. Skipping."
            return
        fi
    else
        # Container is already running, generate docker-compose.yml directly
        docker run --rm -v /var/run/docker.sock:/var/run/docker.sock "${autocompose}" "${container_id}" > "${path}${container_name}-compose.yml"
        echo "Generated docker-compose.yml for running container '${container_name}'."
    fi
}

# Do the magic
case "${1}" in
    all|"")
        # Create a docker-compose.yml file for each container
        # Clear existing arguments
        while [ "${1}" ]; do
            shift
        done
        # Create array of container names based on BackupAllContainers setting
        if [ "${BackupAllContainers}" = "yes" ]; then
            set -- $(docker container ls -a --format '{{.Names}}')
            echo "Backing up all containers (running and stopped)."
        else
            set -- $(docker ps --format '{{.Names}}')
            echo "Backing up only running containers."
        fi
        while [ "${1}" ]; do
            process_container "${1}"
            shift
        done
        ;;
    *)
        # Only process specified container
        process_container "${1}"
        ;;
esac

echo "All done"
exit 0

 

How to Set Up a Raspberry Pi Web Server

This tutorial aims to host a simple web server on a Raspberry Pi. This produces a very lightweight web server and works well to host a microservice or to test a website without deploying a full web server on the cloud. We will use Docker on Raspbian OS and spin up an Apache 2.4 container from Docker Hub.

Prerequisites

The only prerequisite to following this guide is that you have SSH connection enabled, Raspberry Pi 1, 2, 3, 4 or Pi Zero W with a running Raspbian OS.

Installing Docker to the Raspberry Pi

Step 1: Update and Upgrade

Before installing Docker we need to make sure that the Raspberry Pi is running the latest software.

sudo apt-get update && sudo apt-get upgrade

Step 2: Download the Script to Install Docker on Raspberry Pi

downloading and running the script is very easy just copy and paste the command in the terminal:

curl -fsSL https://get.docker.com -o get-docker.sh

To execute the installation script enter this command:

sudo sh get-docker.sh

Now you have to wait for the script will install all the required packages in Raspberry Pi.

Step 3: Add a Non-Root User to the Docker Group

By default, only root users can run the docker containers. If you are not logged in as the root you will need to use the sudo prefix every time and it’s not recommended. We can easily skip by adding the non-root user to the Docker group here is how to do that:

sudo usermod -aG docker [user_name]

To add the Pi user (the default user in Raspberry Pi OS), use the command:

sudo usermod -aG docker pi

Setting up Apache on Raspberry Pi

One of the best things about the Docker ecosystem is that there are tens of standard docker containers that you can easily download and use.

In this article, we will instantiate an Apache 2.4 container named raspberry-pi-web-server, detached from the current terminal. We will use an image called httpd:2.4 from Docker Hub.

Our plan is to have requests made to raspberry pi’s local IP address on port 8080 be redirected to port 80 on the container. Also, instead of serving content from the container itself, we will serve a simple web page from /home/user/website.

We will do this by mapping /home/user/website/ on the /usr/local/apache2/htdocs/ on the container. Note that you will need to use sudo or login as root to proceed, and do not omit the forward slashes at the end of each directory.

# sudo docker run -dit --name raspberry-pi-web-server -p 8080:80 -v /home/user/website/:/usr/local/apache2/htdocs/ httpd:2.4

At this point, our Apache container should be up and running.

$ sudo docker ps

Now let’s create a simple web page named raspberry-pi-web-server.html inside the /home/user/website directory.

# vi /home/user/website/raspberry-pi-web-server.html

Add the following sample HTML content to the file.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Raspberry Pi Web Server</title>
</head>
<body>
    <h1>Learn Docker</h1>   
</body>
</html>

Next, point your browser to Server-IP:8080/raspberry-pi-web-server.html (where Server-IP is your Raspberry Pi IP address).

If you wish, you can now stop the container.

$ sudo docker stop raspberry-pi-web-server

and remove it:

$ sudo docker rm raspberry-pi-web-server

To finish cleaning up, you may want to delete the image that was used in the container (omit this step if you’re planning on creating other Apache 2.4 containers soon).

$ sudo docker image remove httpd:2.4

Conclusion

In this article, we explained how to Set Up a Raspberry Pi Web Server using docker.

Plex Database Cache Setting

The comands below are for Plex in Docker, however you can change the paths relevant to any Plex install.

To get current cache size…

sqlite3 "/opt/appdata/plex/database/Library/Application Support/Plex Media Server/Plug-in Support/Databases/com.plexapp.plugins.library.db" "PRAGMA default_cache_size;"

Change cache size (and confirm value)

sqlite3 "/opt/appdata/plex/database/Library/Application Support/Plex Media Server/Plug-in Support/Databases/com.plexapp.plugins.library.db" "PRAGMA default_cache_size = 6000000;" "PRAGMA default_cache_size;"

The default cache size is 20000, if you have thousands of movies and tv shows set it to a larger value (I changed it to 6000000, but any number will work for you)

Before making changes to the sqllite database stop the plex server and service then edit and restart.

also change the paths to your plex installation paths as mine are custom.
ALWAYS MAKE A BACKUP FIRST OF YOUR ENTIRE INSTALLATION FOLDER AND DATABASE STUFF!!!

Invalid JSON response nginx docker

I’ve recently gotten pihole setup in a docker and use nginx to access it via “dockerhostip/pihole” and all is /was working well.

Today I decided to start playing with internal domain names for my lan so I added one to reference the docker host via the “Local DNS records” section. After testing that worked I went back to the admin page to add some more local domains, however I have discovered when ever I go to the “Local DNS records” page while accessing via domain name I get:

DataTables warning: table id=customDNSTable - Invalid JSON response. For more information about this error, please see http://datatables.net/tn/1

but if I revert back to accessing via IP it works fine.

The reason for this behaviour is because The web interface is only available when accessed by the hostname, pi.hole, or the IP address set in /etc/pihole/setupVars.conf.

You can set your hostname to pihole.home if you’d like.

You could also add it as another valid domain by following these instructions:

Add this to /etc/lighttpd/external.conf (or create it if it doesn’t exist):

setenv.add-environment = ( "VIRTUAL_HOST" => "pihole.home" )

Then restart lighttpd: sudo service lighttpd restart

Automatically purge orphaned objects in Docker

Sometimes your Docker host will fill up with orphaned volumes, containers, images and netowrks.  You can use this image to automatically trim your orphaned volumes every 24 hours:

sudo docker run -d \
--name=docker-prune \
-v /var/run/docker.sock:/var/run/docker.sock \
-e INTERVAL=86400 \
-e "OBJECTS=container volume image network" \
-e "OPTIONS=--filter until=24h" \
docker.io/xjokay/prune:latest

Pulled from Docker Prune