JJJ's Blog

  • WordPress
  • GitHub
  • Twitter/X
  • 19 Lessons

    1. Every good work of software starts by scratching a developer’s personal itch.
    2. Good programmers know what to write. Great ones know what to rewrite (and reuse).
    3. Plan to throw one [version] away; you will, anyhow (copied from Frederick Brooks’s The Mythical Man-Month).
    4. If you have the right attitude, interesting problems will find you.
    5. When you lose interest in a program, your last duty to it is to hand it off to a competent successor.
    6. Treating your users as co-developers is your least-hassle route to rapid code improvement and effective debugging.
    7. Release early. Release often. And listen to your customers.
    8. Given a large enough beta-tester and co-developer base, almost every problem will be characterized quickly and the fix obvious to someone.
    9. Smart data structures and dumb code works a lot better than the other way around.
    10. If you treat your beta-testers as if they’re your most valuable resource, they will respond by becoming your most valuable resource.
    11. The next best thing to having good ideas is recognizing good ideas from your users. Sometimes the latter is better.
    12. Often, the most striking and innovative solutions come from realizing that your concept of the problem was wrong.
    13. Perfection (in design) is achieved not when there is nothing more to add, but rather when there is nothing more to take away. (Attributed to Antoine de Saint-Exupéry)
    14. Any tool should be useful in the expected way, but a truly great tool lends itself to uses you never expected.
    15. When writing gateway software of any kind, take pains to disturb the data stream as little as possible—and never throw away information unless the recipient forces you to!
    16. When your language is nowhere near Turing-complete, syntactic sugar can be your friend.
    17. A security system is only as secure as its secret. Beware of pseudo-secrets.
    18. To solve an interesting problem, start by finding a problem that is interesting to you.
    19. Provided the development coordinator has a communications medium at least as good as the Internet, and knows how to lead without coercion, many heads are inevitably better than one.

    From The Cathedral and the Bazaar by Eric S. Raymond.

    JJJ

    August 16, 2021
    Software
    Open Source
  • PHP is not recommended

    The latest version of macOS makes it pretty clear how Apple feels about open web technologies that aren’t JavaScript:

    JJJ

    November 30, 2020
    Apple, Software, WordPress
    macOS, PHP
  • Raspberry Pi 4, Ubuntu 20.04, PoE Hat Fan Control

    I recently acquired an 8Gb Raspberry Pi 4 and promptly installed Ubuntu 20.04 on it to see how it worked. Right away, I was excited that the PoE Hat worked and that it booted without any problems, except that the fan on the Hat was no longer controllable the way that it used to be.

    It appears that the old way of using config.txt and friends to override those settings no longer works.

    Here’s what you need to do:

    sudo nano /etc/udev/rules.d/50-rpi-fan.rules

    Put this in it to start with, and tweak as needed for your situation:

    SUBSYSTEM=="thermal"
    KERNEL=="thermal_zone3"
    
    # If the temp hits 81C, highest RPM
    ATTR{trip_point_0_temp}="82000"
    ATTR{trip_point_0_hyst}="3000"
    #
    # If the temp hits 80C, higher RPM
    ATTR{trip_point_1_temp}="81000"
    ATTR{trip_point_1_hyst}="2000"
    #
    # If the temp hits 70C, higher RPM
    ATTR{trip_point_2_temp}="71000"
    ATTR{trip_point_2_hyst}="3000"
    #
    # If the temp hits 60C, turn on the fan
    ATTR{trip_point_3_temp}="61000"
    ATTR{trip_point_3_hyst}="5000"
    #
    # Fan is off otherwise

    JJJ

    June 11, 2020
    Software
    Raspberry Pi
  • macOS Disk Utility “Operation cancelled”

    When trying to use Disk Utility to make a backup of one of my Raspberry Pi’s, I was repeatedly seeing an error that was causing my backup to fail.

    Operation cancelled

    Disk Utility

    Not particularly helpful.

    For me, the fix involved setting the Disk Utility application to have Full Disk Access inside macOS System Preferences, under Security & Privacy, and then Privacy.

    Once I did this, everything started working again! 🥳

    JJJ

    May 13, 2020
    Software
    macOS, Raspberry Pi
  • Update GitLab signing key

    At the beginning of April, GitLab updated their repository signing key. If you try to update, you will see an error during sudo apt update :

    W: An error occurred during the signature verification. The repository is not updated and the previous index files will
    be used.
    GPG error: https://packages.gitlab.com/gitlab/gitlab-ee/ubuntu bionic InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 3F01618A51312F3F
    W: Failed to fetch https://packages.gitlab.com/gitlab/gitlab-ee/ubuntu/dists/bionic/InRelease The following signatures couldn't be verified because the public key is not available: 
    NO_PUBKEY 3F01618A51312F3F
    W: Some index files failed to download. They have been ignored, or old ones used instead.

    The easiest fix appears to be simply to update the signing key:

    curl --silent https://packages.gitlab.com/gpg.key | sudo apt-key add -

    The trailing hyphen is part of the command; don’t forget it.

    JJJ

    April 20, 2020
    Software
    GitLab
  • Easy PHP Upgrade

    I had a few servers that needed upgrading from PHP7.2 to 7.3, so I wrote this little single-line command to help simply things.

    It uses apt list to get the PHP modules that are currently installed with 7.2, and passes them through to apt install for 7.3.

    sudo apt install $(apt list --installed | grep php7.2- | cut -d'/' -f1 | sed -e 's/7.2/7.3/g')

    This can easily be modified for any PHP version later.

    JJJ

    October 22, 2019
    Software, WordPress
    PHP
  • Empty Space in macOS Dock

    defaults write com.apple.dock persistent-apps -array-add '{"tile-type"="spacer-tile";}'; killall Dock

    JJJ

    August 26, 2019
    Software
    Apple, macOS
  • Variable SSL certificate directives in nginx (part 2)

    Feeling encouraged by my friend Jeremy Felt’s blog post on the subject, I thought I may finally be able to achieve the panacea of WordPress Multi-Network SSL configurations:

    (more…)

    JJJ

    May 6, 2019
    Software, WordPress
    nginx
  • Install nginx from source

    At the time of this writing, the latest stable version of nginx is 1.16.0, and none of the package managers have updated themselves to include it.

    Before you get started, you’ll want to be logged in to an open terminal session with a user that has sudo access. The reason for this, is because nginx itself requires root access when it starts up, to bind itself to lower number ports (usually 80 and 443.)

    You’ll also notice that I use nano for editing files. Use what you prefer.

    First, stop any version of nginx that might already be running:

    sudo service nginx stop

    Next, you’re going download the latest version of nginx directly from the official website:

    cd ~/
    wget http://nginx.org/download/nginx-1.16.0.tar.gz

    Next, decompress it, and change into the new directory it made:

    tar xvf nginx-1.16.0.tar.gz nginx-1.16.0/
    cd nginx-1.16.0/

    Next, you’ll probably want to install some related dependencies. Below is a pretty general list, but if you know better for yourself, replace these as needed:

    sudo apt-get install -y curl build-essential make gcc libpcre3 libpcre3-dev libpcre++-dev zlib1g-dev libbz2-dev libxslt1-dev libxml2-dev libgd2-xpm-dev libgeoip-dev libgoogle-perftools-dev libperl-dev libssl-dev libcurl4-openssl-dev libatomic-ops-dev

    Next, you’ll want to configure nginx.

    There are about a million different ways to do this depending on your needs. For our purposes (and for most people reading this) the below approach should be sufficient:

    sudo ./configure \
    --user=nginx \
    --group=nginx \
    --prefix=/etc/nginx \
    --sbin-path=/usr/sbin/nginx \
    --modules-path=/usr/lib/nginx/modules \
    --conf-path=/etc/nginx/nginx.conf \
    --error-log-path=/var/log/nginx/error.log \
    --http-log-path=/var/log/nginx/access.log \
    --pid-path=/var/run/nginx.pid \
    --lock-path=/var/run/nginx.lock \
    --http-client-body-temp-path=/var/cache/nginx/client_temp \
    --http-proxy-temp-path=/var/cache/nginx/proxy_temp \
    --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \
    --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \
    --http-scgi-temp-path=/var/cache/nginx/scgi_temp \
    --with-select_module \
    --with-poll_module \
    --with-threads \
    --with-file-aio \
    --with-http_ssl_module \
    --with-http_v2_module \
    --with-http_realip_module \
    --with-http_addition_module \
    --with-http_xslt_module \
    --with-http_xslt_module=dynamic \
    --with-http_image_filter_module \
    --with-http_image_filter_module=dynamic \
    --with-http_geoip_module \
    --with-http_geoip_module=dynamic \
    --with-http_sub_module \
    --with-http_dav_module \
    --with-http_flv_module \
    --with-http_mp4_module \
    --with-http_gunzip_module \
    --with-http_gzip_static_module \
    --with-http_auth_request_module \
    --with-http_random_index_module \
    --with-http_secure_link_module \
    --with-http_degradation_module \
    --with-http_slice_module \
    --with-http_stub_status_module \
    --with-http_perl_module \
    --with-http_perl_module=dynamic \
    --with-mail \
    --with-mail=dynamic \
    --with-mail_ssl_module \
    --with-stream \
    --with-stream=dynamic \
    --with-stream_ssl_module \
    --with-stream_realip_module \
    --with-stream_geoip_module \
    --with-stream_geoip_module=dynamic \
    --with-stream_ssl_preread_module \
    --with-google_perftools_module \
    --with-cpp_test_module \
    --with-compat \
    --with-pcre \
    --with-pcre-jit \
    --with-zlib-asm=CPU \
    --with-libatomic \
    --with-debug \
    --with-ld-opt="-Wl,-E"

    Many of the above flags are important, but I think the most important one for our purposes is --with-debug because without that flag, you cannot log any of nginx’s important debug information, in the event something isn’t working correctly.

    Next, you need to build the executable from the configured source. You’ll make it and install it like this:

    sudo make && sudo make install

    Next, you’ll want nginx to autostart on boot, so:

    sudo nano /lib/systemd/system/nginx.service

    And put this in there:

    [Unit]
    Description=The NGINX HTTP and reverse proxy server
    After=syslog.target network.target remote-fs.target nss-lookup.target
    
    [Service]
    Type=forking
    PIDFile=/var/run/nginx.pid
    ExecStartPre=/usr/sbin/nginx -t
    ExecStart=/usr/sbin/nginx
    ExecReload=/bin/kill -s HUP $MAINPID
    ExecStop=/bin/kill -s QUIT $MAINPID
    PrivateTmp=true
    
    [Install]
    WantedBy=multi-user.target

    Then run these two commands and nginx should fire right up:

    sudo systemctl daemon-reload
    sudo service nginx start

    All done!

    JJJ

    May 1, 2019
    Software
    nginx
  • Wi-Fi Calling – macOS

    This glitchy bit of UI shows up after enabling WiFi calling on an iPhone.

    JJJ

    January 1, 2019
    Bad UI
Previous Page
1 2 3 4 … 7
Next Page

Proudly Powered by WordPress