fogbound.net




Tue, 26 Aug 2025

PHPStorm/svn stall again, note to future self

— SjG @ 6:41 am

Every time this happens, I get confused and lost, and have to rediscover the solution. So here’s a note to future self.

Symptom: PHPStorm stalls on an SVN update, and sits there doing nothing. Network is OK. SSH into server that supplies SVN, watch the WebDAV logs, and there’s nothing even trying to talk to it.

PHPStorm is configured to use an external Subversion client.

Solution: Don’t (necessarily) go and mess around with the settings for PHPStorm. Open a terminal, go to the working set in question, and do an “svn up” from the command line. This is where you’ll discover that SVN has either identified the server certificate as expired or updated, and it’ll ask you to approve the certificate (in that latter case). Log in with your credential again. Now it’ll all be OK again.


Mon, 21 Apr 2025

Fixing an rsync issue under Mac OS 15.4

— SjG @ 1:18 pm

I keep some directories synchronized between my notebook and desktop with rsync. After upgrading my desktop to Mac OS 15.4.1, I started getting errors:

[sjg@BigThud 2025-04-21 13:01:05] ~/Documents/Backup
$ rsync -auP . sjg@10.3.2.xx:Documents/Backup
(sjg@10.3.2.xx) Password:
rsync: failed to set times on "/Users/sjg/Documents/Backup/Whatever": Operation not permitted (1)

Interestingly, ssh also showed an error:

[sjg@BigThud 2025-04-21 13:04:29] ~/Documents/Backup
$ ssh sjg@10.3.2.xx "ls /Users/sjg/Documents/Backup/Whatever"
(sjg@10.3.2.xx) Password:
ls: /Users/sjg/Documents/Backup/Whatever: Operation not permitted

On the desktop, I look again at Documents/Backup/Whatever, and the permissions are fine. What gives?

To make a long story short, something in the latest update on the desktop changed sshd‘s full disk access permission. Looking at System Preferences > Privacy & Security > Full Disk Access, sshd-keygen-wrapper was checked, so it should have been enabled. I tried toggling that, but it didn’t help.

Apparently, the sshd-keygen-wrapper was pointing at an old version or something? I had to go into System Preferences > General > Sharing and turn Remote Login off then on again, then go into System Preferences > Privacy & Security > Full Disk Access and re-enable sshd-keygen-wrapper.

Et voilà, I could ssh and rsync again!


Mon, 2 Dec 2024

Docker Desktop on Intel Macs

— SjG @ 12:59 pm

I had a database corruption event happen in a Docker container, one result of which was that the container was completely wedged and unusable. I spent a lot of time removing containers and images and recreating them, only to have the same problem. In my case, the symptom was I’d create a new MySQL database, and operation would be fine, until part way through a bulk data import or heavy query, and the database would crash and the container would get into an unusable state again. Docker didn’t yield anything in the log, but MySQL showed corruption:

2024-11-27T22:35:38.182396Z 8 [ERROR] [MY-013183] [InnoDB] Assertion failure: os0file.cc:2899:dir_fd != -1 thread 140305764447808
InnoDB: We intentionally generate a memory trap.
InnoDB: Submit a detailed bug report to http://bugs.mysql.com.
InnoDB: If you get repeated assertion failures or crashes, even
InnoDB: immediately after the mysqld startup, there may be
InnoDB: corruption in the InnoDB tablespace. Please refer to
InnoDB: http://dev.mysql.com/doc/refman/8.0/en/forcing-innodb-recovery.html
InnoDB: about forcing recovery.
2024-11-27T22:35:38Z UTC - mysqld got signal 6 ;
Most likely, you have hit a bug, but this error can also be caused by malfunctioning hardware.
BuildID[sha1]=511ab47ad6d5dfd73d58eea5860b1c9c9a97ce07
Thread pointer: 0x7f9ad4000fc0
Attempting backtrace. You can use the following information to find out
where mysqld died. If you see no messages after this, something went
terribly wrong...
stack_bottom = 7f9b7b3febc0 thread_stack 0x100000
/usr/sbin/mysqld(my_print_stacktrace(unsigned char const*, unsigned long)+0x41) [0x15af021]
/...

Once this problem occurred in a container, the database wouldn’t be start-able, often complaining about being unable to update permissions on /var/lib/mysql/mysql.sock.

Eventually, with much futile searching, I found this posting and switched Docker Desktop away from using VirtioFS to using gRPC FUSE for sharing the filesystem between the container and the host machine. This seems to have resolved the issue. I can load big databases again, and heavy transactions work in my development environment again.


Tue, 12 Nov 2024

Directory structure compare

— SjG @ 11:39 am

There’s gotta be a better way. But after a horrible upgrade process for a horrible commercial open-source product, I need to see which sub-directories from the old installation are missing in the new one. Don’t ask. I’ve literally been having nightmares about this upgrade.

Anyway, given tree1 and tree2 under some common point, I want a list of directories that exist in tree1 and don’t exist in tree2.

Here was my clumsy way of solving the problem.

cd tree1
find . -type d -print | sort > ../dirs_old
cd ../tree2
find . -type d -print | sort > ../dirs_new
cd ..
comm -23 dirs_old dirs_new


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:
127.0.0.1 project1.mylocal
127.0.0.1 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"
services:
php:
container_name: ApachePHPVirtual
networks:
- apache
build:
context: .
dockerfile: PhpApacheDockerfile
volumes:
- "./project:/var/www"
ports:
- 80:80
- 443:443
extra_hosts:
- "project1.mylocal:127.0.0.1" # remember to add "127.0.0.1 project1.mylocal" to your /etc/hosts file or equivalent
- "project2.mylocal:127.0.0.1" # remember to add "127.0.0.1 project2.mylocal" to your /etc/hosts file or equivalent
hostname: project1.mylocal # default
domainname: mylocal
tty: true # if you want to debug
networks:
apache:

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>
<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
    </Directory>

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

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/