“Updating Failed” When Running WordPress Through linuxserver/letsencrypt Docker Container

In order to try and my docker setup, I trying to consolidate my docker containers and use docker images from a single provider. When I was getting started with docker, I found LinuxServer.io to be a great source for images. LinuxServer.io provides multiple architectures, common layers, easy user mappings, and much more.

For a while, I was running WordPress from the official docker image since that was the best one I could find at the time. I was never really happy with that container, since it didn’t allow me to easily run it under its own user account. When I was setting up the linuxserver/letsencrypt container for SSL and reverse proxy, I found out that it can host websites out of the box. I setup WordPress using this guide and instead of downloading the latest version of WordPress I just used the application files from that other docker container.

With this setup I did have one issue, every time I tried to save a draft or preview a post, I got this error:

Error: Updating failed

I also did some digging inspecting the source on the site and found this messages when WordPress was trying to POST:

POST https://slacktacular.com/wp-json/wp/v2/posts/59?_locale=user 404

With both of these errors, I was able to figure out that the problem occurred when using “pretty permalinks” in WordPress (which is enabled by default). If I switched to “Plain” permalinks things worked correctly, but I wanted to find the source of the problem. I came across this blog post that ended up getting to the right area:

https://nginxlibrary.com/wordpress-permalinks/

Things are slightly different with the linuxserver/letsencrypt container but both are based on nginx so it took a bit of playing around, but I managed to get it work. I had to do the following:

  1. Edit letsencrypt’s default file in a text editor:

    /opt/letsencrypt/nginx/site-confs/default

  2. Find the block that starts with “location /”

  3. If things are mostly default from the steps to setup word press, the fist line underneath that block should look something like this:

    try_files $uri $uri/ /index.html /index.php?$args =404;

  4. Replace this line with the following:

    try_files $uri $uri/ /index.html /index.php?$args;

  5. Restart your letsencrypt container

Once I removed that “=404” text, everything worked perfectly for me when I used the “pretty permalinks”. So far, I haven’t run across any issues with my other sites but I am not sure if/what that change would affect.

Automatically Backing Up Docker Data Volumes

After much searching, I was unable to find a script that would automatically backup my Docker data volumes. Everything I found required me to manually add container names as I deployed them and I was not interested in doing that. As a result, I wrote my own script that accomplishes this goal.

This script will create an array that contains the names of all the folders under a specific path. Next, the script will see if there is a folder name that matches the name of a container in docker. If a match does not exist, the script will skip performing a backup. If a match does exist, the script will stop that container in docker, check to see if a backup folder exists for that container, and create the folder if it does not exist. The script will then archive that data volume to the backups directory, check to see how many versions exist, and keep only the number specified. Once everything is done, the script uses docker compose to start all containers in the correct order.

Variables

  • docker – path to docker data volumes
  • backups – path to where you keep your backups
  • dcrun – alias to be able to run docker compose commands with less text
  • array – creates an array of all applications listed under specified directory
  • versions – how many versions of backups you want to keep

I am sure there are better ways to do all this, but I chose this strategy since I do everything in docker compose and name the data volumes the same thing as the docker container. I have this script run as a nightly cron job and have duplicati store a copy of these backups a cloud storage provider. Please make sure you save your backups somewhere outside of the server! If you don’t, you risk losing everything if the storage you have the backups saved on dies.

#!/bin/bash

#variables
docker="/opt"
backups="/mnt/storage/backups"
dcrun='docker-compose -f /opt/tools/docker_compose.yml '
array=( ${docker}/* ) #Array of all applications listed underneath /opt
versions="3"

#Loop through all docker apps which have app files in /opt
for path in "${array[@]}"
do
	if [ "$(docker ps -q -f name=${path##*/})" ]; then #checks if app is setup in docker	
		echo "start ${path##*/} backup"
		${dcrun} stop ${path##*/} #stop container using docker compose
		
		#docker stop ${path##*/} #uncomment this line and comment out line above if not using docker compose
		mkdir -p ${backups}/${path##*/} #makes new backup directory if new container is added
		tar -czf ${backups}/${path##*/}/${path##*/}_$(date +"%Y.%m.%d").tar.gz ${path} #take backup of app folder into archive
				ls -rt -d -1 ${backups}/${path##*/}/*| head -n -${versions}| xargs -d '\n' rm -f -- #keeps latest 3 archives in directory
		echo "end ${path##*/} backup"
		echo " "
		echo " "
	fi
done
	
#start docker containers
${dcrun} up -d

echo "backup complete"

Trimming the front and end of a video using Linux

I wanted to trim a bunch of videos that I had and wanted an easy and quick way to accomplish this task. I ended up piecing together a small script in order to cut the videos. There are two values you need to change in order to set the time in seconds you want to cut at the start of the script. The following package are needed to run the script

  • ffmpeg
  • bc

Also, be sure to create a sub-folder named “output” under whichever directory you choose to run the script in.

#!/bin/bash

for f in *.mp4; do

	#durations to cut video in seconds
	front=8
	back=15

	#trim 8 second off front of video (ss -8)
	ffmpeg -i "$f" -vcodec copy -acodec copy -ss "$front" ./output/front_"$f"
	
	#calculate total video size
	input_duration=$(ffprobe -v error -select_streams v:0 -show_entries stream=duration -of default=noprint_wrappers=1:nokey=1 "$f")
	#calculate what needs to be cut off end
	output_duration=$(bc <<< "$input_duration"-"$back")
	
	
	#trim the end
	ffmpeg -i ./output/front_"$f" -map 0 -c copy -t "$output_duration" ./output/end_"$f"
	
	#clean up temp file from front trim
	rm ./output/front_"$f"
	
	#remove metadata
	ffmpeg -i ./output/end_"$f" -map_metadata -1 -c:v copy -c:a copy ./output/"$f"
	
	#clean up file from end trim
	rm ./output/end_"$f"

done