Wed, 22 Sep 2021

Legacy Code / Image Gallery

— SjG @ 10:36 am

One site I help manage uses WordPress and an image gallery plugin by Huge-It. Following a recent WordPress update, the gallery’s admin side has stopped allowing the admin to add images to a gallery. There’s a button, you click it, and nothing happens.

There is no obvious issue, until you look at the Javascript console and see the following error message: this._addClass is not a function. A quick web search confirms that this is likely either a conflict in Javascript libraries included by various plugins, or a jQuery version conflict.

The quick and dirty solution is to edit wp-content/plugins/gallery-and-caption/includes/admin/class-photo-gallery-wp-admin-functions.php and add the following lines:

function custom_admin_js() {
echo '"<script type="text/javascript" src=""></script>"';
add_action('admin_footer', 'custom_admin_js');

This basically forces the plugin to use a compatible version of jQuery so it’ll work again.

Hooray! The forces of entropy are held in check for another brief moment.

Thu, 2 Sep 2021

Character Encoding

— SjG @ 4:25 pm

Hm. Looks like the server upgrade from Ubuntu 18.04.5 LTS to Ubuntu 20.04.3 LTS changed some character encoding defaults somewhere. I’ll have to track down if it’s in the database (most likely), the database connection (possible), PHP, or somewhere else.

In the mean time, please forgive the occasional bad unicode character.

Filed in:

Fri, 9 Jul 2021

Virtual Apache SSL Hosts in a Docker Container

— SjG @ 1:40 pm

You might want to “containerize” your development hosting environment so you can easily migrate it from machine to machine. As a Docker noob, I had a bunch of issues getting this set up the first time, and wanted to share a working configuration. This example assumes you have Docker installed and operating. You can also skip reading this, and just download the files at GitHub.

First, we’ll need to create some directories. I create one for the Apache configurations, and one for the code projects I’ll be working on.
mkdir apache-php
mkdir project

Within project, you can check out the code for your various projects into subdirectories. For simplicity, I’ve created project1 and project2 in the sample code. The Apache web server within the container will serve content from these directories.

We’re going to use a fictional top-level domain (TLD) for our development environment. This way, the URL you use to access your sites will be the same every time you spin up a new dev environment, without having to worry about name servers. You do, however, have to worry about your /etc/hosts file (or your platform’s equivalent). Choose a TLD that will be easy to remember. For my example, I’m using “mylocal”. One thing to avoid: start the TLD with a letter rather than a number. Don’t include characters like hyphens. Please learn from my mistakes.

Edit your /etc/hosts, and add the lines: project1.mylocal project2.mylocal

Next, we’ll want to create an SSL certificate for use in development. The easiest way to do this is with mkcert. Once you have mkcert installed and working, you’ll create a wildcard certificate for your TLD:
cd php-apache
mkcert -install mylocal "*.mylocal"

Next, we create a compose.yaml file:

version: "3.9"
container_name: ApachePHPVirtual
- apache
context: .
dockerfile: PhpApacheDockerfile
- "./project:/var/www"
- 80:80
- 443:443
- "project1.mylocal:" # remember to add " project1.mylocal" to your /etc/hosts file or equivalent
- "project2.mylocal:" # remember to add " project2.mylocal" to your /etc/hosts file or equivalent
hostname: project1.mylocal # default
domainname: mylocal
tty: true # if you want to debug

This is pretty straightforward. We’re creating a container which we’ll call “ApachePHPVirtual,” it will have a network we call “apache” if we want to connect using other containers, and it links our top level project directory to /var/www in the container. We map ports 80 and 443 on our host machine to those same ports in the container. The extra_hosts directive adds our project names to the container’s /etc/hosts. We set up the container’s hostname to match our first project, and set the default domain to our “mylocal” TLD.

We then want to create configurations for each of the Apache virtual hosts. In the php-apache directory, we create config files for each project. These are just standard virtual host declarations, e.g.:

<VirtualHost *:80>
    ServerName project1.mylocal
    Redirect permanent / https://project1.mylocal/
<VirtualHost *:443>
    ServerName project1.mylocal
    DocumentRoot /var/www/project1
    ErrorLog ${APACHE_LOG_DIR}/project1-error.log
    CustomLog ${APACHE_LOG_DIR}/project1-access.log combined
    DirectoryIndex index.php

    <Directory "/var/www/project1">
        Options -Indexes +FollowSymLinks
        AllowOverride all
        Order allow,deny
        Allow from all

    SSLEngine On
    SSLCertificateFile    /etc/apache2/ssl/cert.pem
    SSLCertificateKeyFile /etc/apache2/ssl/cert-key.pem

You’ll need to create a similar configuration for each project. Note that the Document Root points at the mapped host directory. That means you won’t need to rebuild the container to see project changes.

The actual image for the Apache/PHP container is created and configured in our next file, “PhpApacheDockerfile”. So we create that:

FROM php:8.0.8-apache-buster

# add some packages
RUN docker-php-ext-install curl gd iconv pdo pdo_mysql soap zip

# Apache Config
COPY php-apache/project1.conf /etc/apache2/sites-available/project1.conf
COPY php-apache/project2.conf /etc/apache2/sites-available/project2.conf
COPY php-apache/mylocal+1-key.pem /etc/apache2/ssl/cert-key.pem
COPY php-apache/mylocal+1.pem /etc/apache2/ssl/cert.pem

# mod rewrite! SSL!
RUN a2enmod rewrite
RUN a2enmod ssl

# enable sites
RUN a2ensite project1.conf
RUN a2ensite project2.conf
RUN service apache2 restart

This pulls the php-8.0.8 image from DockerHub, adds in some PHP extensions, copies over our SSL certificate and key, copies our virtual host configuration files over, enables the projects, and restarts the Apache server.

Now, all that remains to do is build it and power it up:

docker-compose build && docker-compose up -d

You can now visit the project URls in your browser, e.g., https://project1.mylocal/

Sat, 19 Sep 2020

Goodbye Google

— SjG @ 11:08 am

I’ve finally removed the Google Ads and analytics from this site.

Many years ago, I thought it mattered where people went on the site and which posts were most useful. I also had the delusion that there would be enough visits that the ads might help pay for the hosting.

Ah, to be young, naïve, and full of hope. That ship ship has certainly sailed.

Anyway, there’s no point in cluttering up the blog with surveillance crap. I’m just sorry I left it there for so long.

Sat, 12 Sep 2020

Those pesky /usr/local/include headers under MacOS Catalina

— SjG @ 11:04 am

Here’s another of those “system upgrade moves stuff around” problems. My work iMac seems to be suffering a slow disk failure. It gets slower and slower as it tries to run.

Queue restoring TimeMachine backups onto a new iMac. A lot of stuff just works. But things like building xsendfile for the Apache development server under Mac ports threw lots of errors. The compiler couldn’t find the headers:

mod_xsendfile.c fatal error: stdio.h: no such file or directory

There are lots of suggestions out there to run xcode-select --install, but I’d already done that.

Turns out that XCode has stopped storing the SDKs in /Library/Developer/CommandLineTools/SDKs and moved them to /Applications/ I spent a bit of time trying to figure out how to pass that path to the Mac Ports version of apxs2 to use the new include path, but eventualy gave up and just did the hacky thing:
ln -s /Applications/ /Library/Developer/CommandLineTools/SDKs

Another issue, just so I rememebr next time, was that the web server and the command line were mysteriously running different versions of PHP. The key, of course, was that I had forgotten to run port select, e.g., for this project, I needed port select php php70.