Zack Apiratitham

WWDC 2023 Wish List

All my other WWDC wish list posts: 2016, 2017, 2019, 2020, 2021, 2022.

I've been closely following WWDCs and their announcements for at least ten years now. And every year I wish I could visit the conference in person, but due to various reasons I never made it happen. Well, this year is going to be different as I will be traveling to Cupertino for the WWDC23 week!

Though unfortunately I was not one of those lucky few who got the golden tickets to Apple Park (maybe next year 🤞), I figured it would still be fun to go meet fellow Apple nerds and join in on all the communities events happening that week in the area. So far I know I'll be attending RevenueCat's pre-WWDC Barcade Bash, iOSDevHappyHour, and perhaps the Dub Dub Climb.

Before we get to all that fun, as per tradition, here is my wish list for updates and announcements:

VR/AR Headset

All the reports around this have picked up so much in recent months that I think we'll really see it this year. At this point, it would be the biggest story of the week if Apple did not announce the long-awaited headset. I am for sure excited to see this finally, but sitting here right now I honestly don't exactly know why I would want one. The only experience I have with VR headsets is the original Oculus Quest, and that was mostly just for gaming. And we know how Apple is with gaming. What I'm expecting is for Apple to wow us in this regard like they did many times before when they introduced new product categories and give us compelling reasons why we might want one.

The rumored price tag of up to US$3,000 is unfathomably high and I will almost certainly not get one if that ended up being accurate. Perhaps we will be pleasantly surprised like with the original iPad where the actual price was half of what was rumored at the time.

iPhone Security Issue

If you've been following Apple-related news at all, you would have surely come across this bombshell report from WSJ of how thieves shoulder surf for people's iPhone passcodes before stealing them. And with just the passcode, they were able to change the Apple ID password and effectively locking the owners out of their iCloud accounts.

The implication of this goes deep and can really mess up more than just your digital life. Not only would thieves get access to all your iCloud stuff (photos, email, files, etc.), but if you also use the built-in password manager, the thieves could gain access to your bank account and other sensitive information. They really should not let people change the Apple ID password just by using the iPhone passcode. The chain is only as strong as its weakest link, and a 6-digit passcode is too weak for something as important as the iCloud account. I know that people forget their Apple ID passwords all the time and I can kind of get why Apple decided that it is worth the risk to make it easier for those people to gain back access to their accounts. But I think the risk here is too great.

I do hope they address this flaw in the system and come up with a mechanism to make this less likely to happen. For now given how we do so much on our phones, we would be better off switching to an alphanumeric password and treating typing it in on our phones as a sensitive operation, like for ATM PIN or bank account password, so that people can't easily shoulder surf for it.

Apple Music and Music App for macOS

Apple Music the service and on macOS are in dire need of some big improvements. The macOS app is just overall a terrible app (iOS app isn't much better either): songs would refuse to play for no apparent reason, navigation is incredibly slow and clunky, searching feels broken and slow. For the Apple Music service itself, it needs to improve on the recommendation algorithms, playlist curation, and just the overall stability and reliability of the service. I think it fails to meet some basic baseline-level features that its biggest competitor, Shopify, has been doing so well for years. Having said all that, with the recent release of Apple Music Classical, I am not holding my breath that they will do much, if anything at all, about this.

Safari Tab Groups Improvements

I really want to use this feature more as I always have so many Safari tabs and windows open at any given time. But the most annoying issue with this for me is the fact that if I am actively browsing using a specific tab group, opening a link from another app will always open it using a non-tab group window. I just want a way to control where I want links to be opened in. I have countless times run into this and then had to move that tab over to the tab group window I want. In the end I just gave up and stopped using tab groups entirely. I know that you can associate a Focus with a tab group and make external links open in that tab group, but I have a lot of tab groups and they don't nicely map one-to-one with Focus modes I have.

Home App and HomeKit

One thing about HomeKit that I would like to see is the ability to create more complex conditionals for automations. Right now automations are still based on simple and limited set of triggers, but I would very much like to be able to create conditionals to perform certain automations. For example: if the humidity is below 30% and somebody is home, turn on the humidifier, except between 10pm and 8am.

And strangely the Home app still doesn't have Home Screen widgets. I hope to see these in iOS 17.

Lightning Round

  • Something needs to be done with Siri with how terrible and unreliable it is. I want to see some meaningful and substantial changes to it this year.
  • The Photos app does a pretty good job with facial recognition for people. But unlike Google Photos, it still does not recognize pets. I just want to assign names to photos of my pets.
  • The Apple Silicon Mac Pro is still a thing right? It's been well over a year since John Ternus teased us that it's coming. I believe.
  • I find Spotlight on iOS really useful and frequently utilize it for things like unit/currency conversions or dictionary. But what's missing for me is the ability to quickly translate words (or maybe even sentences) to another language. I want to just type in "Tuberculosis in Thai" and get an answer that way. Plus now that iOS comes with Translate app, I don't see why they can't do this.
  • The workout streaks should not have to be every day. Give us the ability to define weekly streaks for workouts.

2023 Thai Election


Thailand's opposition secured a stunning election win on Sunday after trouncing parties allied with the military, setting the stage for a flurry of deal-making over forming a government in a bid to end nearly a decade of conservative, army-backed rule.

The liberal Move Forward party and the populist Pheu Thai Party were far out in front with 99% of votes counted, but it was far from certain either will form the next government, with parliamentary rules written by the military after its 2014 coup skewed in its favour.

Incredible result for progressives and those of us who believe the military has no role in a democratic government. The current dictator prime minister's party only received 13% of the total votes. It’s clear that the majority of Thai population does not want military rule to continue.

But we can’t celebrate too soon. The system is rigged in favor of the pro-military camp and a minority government is within the realm of possibility.

The New York Times:

As of early Monday, it remained unclear who would ultimately lead the country. The junta rewrote the country’s Constitution in 2017 so that selecting the prime minister would come down to a joint vote between the 250-member military-appointed Senate and the popularly elected House of Representatives. The decision could take weeks or months.

Such is the story of Thai politics. We’ve had more military coup d’états than any other country in the world. Since absolute monarchy was abolished in 1932, there have already been thirteen successful coups, averaging one for every seven years. I’ve had the pleasure of living through two of those myself.

On Thursday, Narongpan Jitkaewthae, Thailand’s army chief, took pains to assure the public that things would be different this time.

He said that the country had learned its lessons from its past, and that “politics in a democratic system must continue,” although he added that he “cannot guarantee” that another coup would not happen.

What a fucking joke.

Photos from Thailand

At the end of last year, I went on a long overdue trip back to Thailand after three years. Like any other big trip, I lugged my Canon EOS 6D with me all the way there, but this time I barely used it (the reason for which is a topic for another day). So all of these were taken on my iPhone 14 Pro.

I suppose it's about time I share some photos from the trip, only just four months after I came back as per tradition. A large portion of these are, unsurprisingly, photos of food and they deserve their own separate post. So for now, these are the non-food photos that I like the most:

Picture of Phra Thinang Chakri Maha Prasat
Phra Thinang Chakri Maha Prasat (พระที่นั่งจักรีมหาปราสาท) at the Grand Palace in Bangkok

A view down the Chao Phraya river with the sun close to the horizon
The Chao Phraya river (แม่น้ำเจ้าพระยา)

A view of 4 small islets out in the ocean

A close-up view of little sand pellets on a beach
Sand pellets from sand bubbler crabs

A view of a beach with limestone cliff in the background

A view of two mountains on both banks of a river
Khao Khanab Nam (เขาขนาบน้ำ) with the Tiger Cave temple on top of a peak to the left

A bow of a long-tail boat in a mangrove forest
On a long-tail boat in the mangrove forest

A view from an airplane with a sea of cloud and mountains below it at sunset

A long-tail boat traveling in the distance with mountains in the background

A sea of yellow tents of a night market seen from a high vantage point
Weekend night market in Krabi town

Back to Tournament Golf After Eight Years

Now that it's finally getting warm again after a brutal winter here in Colorado front range, I'm really itching to do more outdoor activities. One of those activities with the lowest barrier of entry for me is golf. I recently played at a nearby city-owned golf course and quite enjoyed it. So as a way to incentivize myself to play more this season, I figured I should sign up for their men's league.

Last time I played in anything resembling tournament golf was over eight years ago in college. I also hadn't swung a club since last July, so I'm definitely quite rusty. Now with this league, I also get my USGA handicap properly established with my current index at 8.5. Today was the first event I participated in and the format was a 2-Man Modified Stableford. My team didn't do too well, finishing tied for last in our flight with -23 points.

My own performance was quite poor: I hit 39 out 48 in for an 87 (+15). The worst offender by far was the tee shot. I could not hit a tee shot to save my life at pretty much every single hole as I kept hitting it thin or not anywhere near the fairway. I hit fairways only five times (36%) and that in turns had a cascading effect to my green-in-regulation, which I only hit seven times (39%). Even though I hit one stroke better than the last round I played here, that round I had 64% fairway hits and 61% GIR.

One saving grace today was that I didn't putt as atrociously as I did last time out: my per-hole average today was 1.9 (35 putts) compared to 2.5 (45 putts). I only three-putted 3 times today, and while that should be zero, it was at least much better than 3 four-putts and 5 three-putts.

A golf scorecard showing a score of 87

Today was frustrating at times, but it was still a fun day out on the course and I met some interesting people in the community. Getting to play in a tournament again put me in a bit of a different mindset and also helped exercise my golf rules muscles (and real muscles too as I walked the whole round). I'll definitely be back doing this some more in the coming months.

My Top 5 Books of 2022

See my other top books of the year posts: 2020, 2021.

Since I began setting concrete reading goals in 2018, I was always able to meet and exceed those goals of around twenty books per year. In the past couple of years, I even felt that I was setting a pretty low bar for myself and that I should increase the number. But last year I failed to even meet my typical twenty-two-book goal, having only read sixteen books by year’s end. I’m not trying to make excuses for my shortcoming here, but my reading habit fell by the wayside in the summer due to my move to Colorado and a new job. I also read a few big novels which took me a long time to get through.

The sixteen books I read in 2022 translate to a 30% drop from 2021. But a better comparison would be the number of pages which came to 7,053, a 13% decrease.

A line graph showing the number of books and pages read since 2017

While I did not meet my expectations for the amount of reading, I did better at my other goals: to read more fiction and physical books. Last year I read six novels which made up 38%1, a healthy jump from recent years. And all but one book I read last year were physical books.

An area chart showing the split between fiction and nonfiction books read each year since 2017

On the topic of physical books, last year I also set a goal to stop buying books and focus on reading the ones I already owned to eliminate unread books on the shelves. So how did I do with that goal? Well I definitely did not stop buying books and ended up adding nine more books to my library2. But I did pare down the number of unread books by reading seven out of eight I had at the start of 2022. Accounting for new books I bought and haven’t read, the number of unread books is now down to five. I was on track to complete this goal by having already read those seven unread books by the summer, but I lost sight of that and ended up buying and reading new books from then on. We’ll revisit this again and see how I do with this in 2023.

Anyway, enough with all the numbers. Here are the top five books I read in 20223.

A stack of five books mentioned in the blog post

The Lord of the Rings by J. R. R. Tolkien (1954–1955)

This came as no surprise to me. I love the Peter Jackson’s films and have watched them through many times but I never read the book. Going into this already knowing all the main story beats did not take away from my enjoyment of the book. I was enthralled from start to finish and there was rarely any dull or slow moment. For years I had been avoiding reading this as I had this preconceived notion that it was going to be difficult to read and the plot would proceed at a glacial pace, and that it would take me months to get through it. I was happy to not find that to be the case.

"I wish it need not have happened in my time," said Frodo. "So do I," said Gandalf, "and so do all who live to see such times. But that is not for them to decide. All we have to decide is what to do with the time that is given us." (p. 51)

Braiding Sweetgrass: Indigenous Wisdom, Scientific Knowledge, and the Teachings of Plants by Robin Wall Kimmerer (2013)

You normally wouldn't find me reading a book about botany or indigenous experiences but putting those two together and combine with the author's background as a scientist made me curious enough to check it out. And I'm really glad I did.

In this book, she tells stories from her life and work as a botanist and member of the Citizen Potawatomi Nation while interleaving with insights into indigenous ways of thinking about ecology and other species on this planet. Her writing really shows off her deep love for nature and the land. I loved when she talks about how the scientific community generally ignore and look down on indigenous knowledge but they are often proven wrong, as told in her discussions of sweetgrass thriving more if harvested and trees talking to each other. A constant theme throughout the book is the emphasis on the importance of generosity and gratitude for what the land gives us, and the responsibility we bare as a species benefiting from — or, more accurately, exploiting — that generosity. It wasn't the easiest read, certain chapters could be quite a slog, but the perspectives I gained from this book really made this worth the read.

In the Western tradition there is a recognized hierarchy of beings, with, of course, the human being on top—the pinnacle of evolution, the darling of Creation—and the plants at the bottom. But in Native ways of knowing, human people are often referred to as “the younger brothers of Creation.” We say that humans have the least experience with how to live and thus the most to learn—we must look to our teachers among the other species for guidance. Their wisdom is apparent in the way that they live. They teach us by example. They’ve been on the earth far longer than we have been, and have had time to figure things out. (p. 9)

Rationality: What It Is, Why It Seems Scarce, Why It Matters by Steven Pinker (2021)

I read both The Better Angels of Our Nature and Enlightenment Now, and personally found his writing style and topics right up my alley. Rationality is a follow-up to the series and it takes a deep dive into rationality and related fields of study. A large part of this book reads like a college textbook and requires intense focus. The chapter on logic — with discussions of concepts like truth tables and "modus ponens" — took me back to my freshman year when I took "Intro to Logic" course. Same thing can be said with most of the other chapters covering probability, Bayesian reasoning, statistical decision theory, game theory, and more. Surprisingly, I still found reading those chapters engaging as I tried to keep up with them.

After nine highly technical chapters, the last two discuss the effects rationality, or the lack thereof, have in our society. He discusses conspiracy theories and offers psychological and sociological explanations into why people believe them and how they seem so widespread in today's hyperconnected world. This book is not what I expected going into it but it still taught me so much in the end.

The dream at the dawn of the internet age that giving everyone a platform would birth a new Enlightenment seems cringeworthy today, now that we are living with bots, trolls, flame wars, fake news, Twitter shaming mobs, and online harassment. As long as the currency in a digital platform consists of likes, shares, clicks, and eyeballs, we have no reason to think it will nurture rationality or truth. (p. 316)

Immune: A Journey into the Mysterious System That Keeps You Alive by Philipp Dettmer (2021)

Overall a very informative and approachable book for such a mindblowingly complex subject. The text is easily digestible and engaging in the Kurzgesagt style I’ve come to know and love. Throughout the book he uses a lot of analogies to illustrate scale or purpose of certain features of the immune system like helpful bacteria living on our skin as barbarian horde outside of the gates, the lymphatic system as superhighways and megacities, and the flu virus as soldiers in the Trojan horse. Some chapters can be long and involve multi-step in-depth explanations, but he also does not shy away from shorter chapters when the topics require it. Highly recommended for those wanting to get a better understanding of such a critical part of you staying alive.

Right now your Adaptive Immune System has a specific weapon against every possible enemy in the universe. For every single infection that has ever existed in the past, for all of them in the world right now, and for every single one that might emerge in the future but does not even exist yet. In a way, the largest library in the universe. (p. 103)

Numbers Don’t Lie: 71 Stories to Help Us Understand the Modern World by Vaclav Smil (2020)

This book is a collection of essays the author originally wrote for the IEEE Spectrum magazine which are grouped into seven main themes: people, countries, inventions, transportation, food, and environment. Full of numbers and graphs, this is a very fact-based book with no lengthy philosophical ruminations. The chapters are all succinct with no more than a few pages each which made for a quick and easy read. I cannot count how many new facts and understandings I gained from this book as it covers such a wide range of topics. Some really interesting ones are: why electric container ships are still not viable, diversity of animals vs. human-made artifacts, rational meat-eating, and better home insulation4.

Human minds have many irrational preferences: we love to speculate about wild and crazy innovations but cannot be bothered to fix common challenges by relying on practical innovation waiting to be implemented. Why do we not improve the boarding of planes rather than delude ourselves with visions of hyperloop trains and eternal life? (p. 136)

  1. Eight if you count The Lord of the Rings as three separate books, making the share of fiction 50%. ↩︎

  2. Not counting three cookbooks. ↩︎

  3. I know picking five out of sixteen isn’t that much of a curation but I’m sticking to that same number for consistency’s sake. ↩︎

  4. Brick and stone walls do not provide anywhere near as good insulation as "flimsy North American wooden things with hollow walls". And the easiest thing we can do to improve insulation and reduce energy consumption is to simply replace single pane windows with triple-paned ones. ↩︎

Focuses for Thailand Trip

The last time I traveled outside of the US was late 2019 in the beforetime, but earlier this month that thankfully came to an end. I am now spending the last month of 2022 in Thailand. To make the long journey and the stay in Thailand more streamlined, I created a few Focuses on my Apple devices to help with that.


Traveling between Colorado and Thailand takes at least 24 hours, so it was essential for me to set up my devices in a way that will help make that arduous journey less stressful. For this I created a “Travel” Focus with the following Lock Screen and Home Screen1:

iPhone screenshots of the Travel Focus

From the top, the Lock Screen shows the time in Bangkok. The widgets are Flighty, Battery, and CARROT Weather. I find the battery one to be especially useful as it’s set to automatically switch to show battery status on different devices like the Apple Watch, AirPods, and their case, depending on the context. Flighty‘s Live Activity UI also helps with more detailed information of current or upcoming flight.

For the Home Screen, on the top stack I have Delta’s widget to show my trip information and CARROT widget. The top small widget stack contains Find My to keep track of my luggage with AirTags, and Flighty for my flight status. The bottom widget stack is for time zones and battery status for my different devices.

I think the coolest part about this Focus is the “Astronomy” wallpaper which I have set to “Earth Detail” variant so it shows a close-up of my current location on the Lock Screen. It’s not that I need the Lock Screen for me to know where I am on my journey but I just think traveling across the globe is the perfect use case for this wallpaper.

Apple Watch Face screenshot of the Travel Focus

For the Watch Face, there isn’t a lot of things I could put that I don’t already have on the Lock Screen. The top left complication is for sound levels which isn’t that useful, but I didn’t know what to put there. Nonetheless it’s interesting to see the sound levels on my flights, and how much the AirPods Pro were able to cancel out.

For the middle complication, I wish I could put Flighty there but surprisingly Flighty does not have a watch app so I put CARROT there instead. On the bottom row: left is for the watch battery, middle is for TrayMinder to keep track of my Invisalign wearing time, and right is a Watchsmith complication for the current time in Thailand.


As I am spending over a month in Thailand, the apps I use regularly here are different from apps I have on my default Home Screen in the US. And so I created a “Thailand” Focus.

Screenshots of the Thailand Focus

Similar to the “Travel” Lock Screen, the top shows the time in Denver. The widgets are:

  • Temperature, to help me make sure the apartment doesn’t get too cold for the cats
  • Flighty, to show when my next flight is
  • Google Maps, to quickly launch the app to search for places
  • Halide as an app launcher

I use the “Weather” wallpaper to show the current condition.

Also similarly, the Home Screen has the CARROT widget on top and Flighty below it. The apps here are the ones I know I’ll use most frequently while in Thailand:

  • Home app to help check on the apartment while we’re away
  • Rover for our cat sitter
  • A folder for food-related apps like Line Man and Food Panda
  • Translate since my Thai is garbage these days
  • SCB Easy is my Thai bank’s app and it gets used a lot to initiate bank transfers to pay for stuff
  • myAIS is for my AIS SIM I use while I’m here
  • Line because that’s the app everybody here uses for messaging
  • Grab for finding rides while in Bangkok

For the Watch Face, the main differences are the Activity rings on the top left and the Watchsmith’s step count complication on the bottom right.


I will also be visiting Singapore for a quick weekend trip so I figured why not set up another Focus for it.

Screenshots of the Singapore Focus

The Lock Screen isn’t all that different from Thailand: it still uses the weather wallpaper, and the widgets are CARROT, Activity, and battery status. I have humidity on top and the widget below is set to show current temperature, precipitation chance, and air quality index.

As we will be mainly using public transportation, Citymapper widget is prominently featured on the top of the Home Screen. This should hopefully help with quickly finding transit directions. Below it are the usual CARROT and battery widgets. As for apps, I just threw in some Singapore-specific apps I may or may not use while I’m there plus the usual: Google Maps, Photos, and Halide.

The Watch Face again is very familiar with the main difference being the Citymapper complication in the middle.

Focus is now such a powerful and useful feature so I think it’s definitely worth the time and effort to set up my devices to best suit my needs for these different situations. This is becoming my favorite feature Apple has introduced in recent years.

  1. Shoutout to Federico Viticci’s incredible Shortcut to put Apple device frames around these screenshots. ↩︎

Migrating from Heroku to Linode

Back in August, Heroku announced that they will no longer offer a free tier for their services starting on 28 November. That would become an issue for me since I have a small Spring Boot service with a Postgres database deployed there, and they would end up costing more per month than I wanted to pay for.

In the past few months, I have been hearing more good things about Linode, so I decided to check them out. I don't need anything powerful for this purpose, so their cheapest $5/month shared CPU "Nanode" plan is more than enough. And since this is just a regular Linux server unlike Heroku's "dynos", I'm not required to use the managed database solution, making it cheaper. Plus the cheapest managed Postgres database on Heroku has a limit of 10,000 rows.

So I took on the challenge of migrating my Heroku setup over to Linode, and I'd like to share how I accomplished that here.

Table of Contents

Configuring the Server

Linode put together a very helpful guide on the basic initial configurations one should do when setting up a new instance. For the distro, I went with Ubuntu 22.04. I then just followed the guide and ran the system updates, created a limited user account, and set up SSH access from my local machine. I also set up an A record to point my custom domain to the server's IP address.

Configuring Cloud Firewall

Linode comes with a free firewall service which made it easier than configuring all these rules on the server itself. I set up the following rules to limit access to only SSH and HTTP/HTTPS traffic.

Screenshot 2022 11 26 at 11 34 12 AM

Installing Docker and Docker Compose

To help with deploying this little service, we will use Docker and Docker Compose. Installing these was easily done by following this guide for Docker and this for Docker Compose.

Docker Files

The Dockerfile I had previously for Heroku didn't require a lot of changes: it just copies the JAR from the build directory and sets up the startup command for the image:

FROM amazoncorretto:11-alpine VOLUME /tmp COPY build/libs/*.jar app.jar CMD ["java", "-Xmx300m", "-Xss512k", "-jar", "/app.jar"]

Now we need to create a new docker-compose.yml file to set up both the application image and Postgres database:

version: '3' services: estel: image: 'estel:latest' build: context: src/main/docker container_name: estel depends_on: - db ports: - restart: unless-stopped environment: - SPRING_DATASOURCE_URL=jdbc:postgresql://db:5432/estel - SPRING_DATASOURCE_USERNAME=${DB_USER} - SPRING_DATASOURCE_PASSWORD=${DB_PASSWORD} db: image: 'postgres:15.0-alpine' container_name: db ports: - restart: unless-stopped volumes: - ${DATA_DIR}:/var/lib/postgresql/data/ environment: - POSTGRES_DB=estel - POSTGRES_USER=${DB_USER} - POSTGRES_PASSWORD=${DB_PASSWORD}
  • The Postgres container is named db and is added to depends_on in the Spring application (estel) container to make sure the service starts after the database.
  • The SPRING_DATASOURCE_URL environment variable points to the db service at estel database as specified in POSTGRES_DB variable.
  • The username and password are specified via a .env file on the server, and are used in both containers.
  • The DATA_DIR variable points to a directory on the server to ensure data persistence between database restarts. Without this, all the data would be lost when we rebuild the database container.
  • I'm specifying the container ports with to ensure that they are not exposed outside of the server. I'll take care of proxying the API using Nginx below.

Configuring Nginx

For the web server, I opted to use Nginx. Here I'm setting up the subdomain to have it point to the Spring service I set up previously by using the proxy_pass directive. Requests coming in to will now get routed to port 8085 that the service is running on.

server { server_name; location / { proxy_set_header Host $host; proxy_pass; proxy_redirect off; } }

Configuring SSL

One thing I couldn't do on Heroku was enabling SSL on my dyno as that was only available with the paid plans. But now that's easily done with our plain old server. I was blown away by how easy setting up SSL was using Certbot. It configured everything correctly with my Nginx configurations, and was up and running in just a few minutes. It's also all free thanks to Let's Encrypt!

Accessing the Database

As you can see in the docker-compose file, the database is only accessible locally on the server. This made it impossible to connect to it from my local machine. I don't want to expose the database to the entire world, so the approach I went with is to connect to it via an SSH tunnel.

I use TablePlus as my database client and it supports connections over SSH. This is what my connection looks like:

Screenshot 2022 11 26 at 10 58 26 AM

If you'd like to connect via command line, the SSH tunnel can first be set up by running:

ssh -L 9955:localhost:8955 <SSH User>@<Server IP Address>
  • 9955 is the port on our local machine we will need to connect to.
  • 8955 is the port on the remote server that the database is running on.

We can then connect to the database using psql:

psql -h localhost -p 9955 -U estel estel

Configuring SSH Access with GitHub

As the docker-compose.yml is part of the project repo, to ensure we use the most up-to-date version of the file for deployments, we need to be able to pull down the latest from GitHub onto the server. This requires setting up SSH access with GitHub by following this guide. I cloned mine to ~/estel/ directory.

Creating a GitHub Actions Workflow for Deployments

Now that we have the infrastructure set up, the last thing we need is a strategy for deploying the Spring service. I came up with a GitHub Actions workflow to handle deploying this service with pushes to the main branch.

1. Setting up SSH Access

First off, we need a new SSH key so that our workflow can interact with the server. Navigate to ~/.ssh/ directory on the server and run the following to generate a new SSH key pair:

ssh-keygen -t rsa -b 4096 -C ""

When prompted, name it something different from the default "id_rsa" as to not conflict with existing key. I named mine "github-actions".

We need to add the new public key to the authorized_keys file so that the workflow using this key can access our server. In the same directory, run the following to append it to authorized_keys:

cat >> ~/.ssh/authorized_keys

Now that we have a new SSH key for our workflow, we need to add this to the repository's secrets. In the repo, navigate to "Settings" > "Secrets" > "Actions" and select "New repository secret". I named it "SSH_PRIVATE_KEY" and the value is the private key created earlier (in ~/.ssh/github-actions).

2. Adding Other Secrets

While we're here adding secrets, we need to add a few more to be used by the workflow:

  • HOST: the IP address of the Linode server
  • SSH_PORT: the SSH port on the server
  • SSH_USER: the SSH user

Here's what my Actions secrets look like now:

Screenshot 2022 11 26 at 2 10 42 AM

These three aren't necessarily secrets but I find it easier to manage them here. You can choose to hardcode these in the workflow file itself as environment variables.

3. Building the Workflow

This deployment workflow will only have one job called "build-and-deploy" which will take care of building the JAR, Docker image, transferring the image to the server, and rebuild the container with the latest image.

First we configure the environment to use Ubuntu, actions/checkout@v3 to check out our repo, and actions/setup-java@v3 for our Java environment:

jobs: build-and-deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-java@v3 with: distribution: corretto java-version: 11

Next we install the SSH key we added to the secrets earlier:

steps: # ... - name: Install SSH key uses: shimataro/ssh-key-action@v2 with: key: ${{ secrets.SSH_PRIVATE_KEY }} known_hosts: unnecessary

We're leaving known_hosts as unnecessary here as we will configure that in the next step:

steps: # ... - name: Add Known Hosts run: ssh-keyscan -p ${{ secrets.SSH_PORT}} -H ${{ secrets.HOST }} >> ~/.ssh/known_hosts

We're generating this using ssh-keyscan command and appending it to the known_hosts file.

With that setup out of the way, we now run the Gradle build:

steps: # ... - name: Setup Gradle uses: gradle/gradle-build-action@v2 - name: Execute Gradle build run: ./gradlew build

This will create a JAR file to be used in building our Docker image, which is done with the following step:

steps: # ... - name: Build the Docker image run: docker build . --file Dockerfile --tag estel

Now to get this image to our server, we could publish this to Docker Hub and have our server pull down the latest image. Unfortunately the Docker Hub free plan only allows public repositories and we'll need to upgrade to the $5/month Pro plan to publish private repositories. Instead, we're going to save the Docker image as a tar archive to be directly transferred to the server:

steps: # ... - name: Create tar archive run: docker save --output estel.tar estel

This creates an estel.tar file in our working directory. We then transfer this over to the server using scp:

steps: # ... - name: scp tar archive run: scp estel.tar ${{ secrets.SSH_USER }}@${{ secrets.HOST }}:/home/estel/docker-images/estel.tar

Lastly, we execute some commands to deploy this image:

steps: # ... - name: Execute remote commands to deploy the image uses: appleboy/ssh-action@master with: host: ${{ secrets.HOST }} username: ${{ secrets.SSH_USER }} key: ${{ secrets.SSH_PRIVATE_KEY }} port: ${{ secrets.SSH_PORT }} script: | docker load --input docker-images/estel.tar cd /home/estel/estel git fetch && git pull docker-compose up -d
  • The docker load command creates a Docker image using the tar archive we transferred over in the previous step.
  • The git commands ensure that we have the most up-to-date docker-compose.yml file from the repo.
  • docker-compose up -d then rebuilds the estel container using the latest image.

And that's it! Now every push to main branch will trigger this workflow and deploy our Spring service to the server automatically. The final workflow file can be found here.

iPhone 14 Pro

As I said in my Apple's Far Out event post, this year is my iPhone upgrade year. Coming from iPhone 12 Pro, the iPhone 14 Pro is not that huge of an upgrade. But it's different enough for me to have a few things to say about it.


The pre-ordering experience itself appeared to have gotten quite an update. After the announcement, I could pre-configure the phone with all the details from obvious ones like color and storage to carrier and even the payment method to use. This pre-order "staging" flow gets a big thumbs up from me.

As for the pre-order itself, I seemed to have won the CDN lottery which let me in right at the top of the hour. So I had the phone arriving on release day. I went with a Deep Purple one with 256GB of storage.


The conventional wisdom these days when it comes to setting up a new iPhone is to do the direct iPhone-to-iPhone transfer. I had used up about 180GB on the old phone and the initial estimate for the transfer was 50 minutes. Not too bad. Turned out that estimate was surprisingly close to reality: it was done in just over an hour and pretty much everything came over just fine. Apps needed to be re-downloaded but all of the login info, preferences, and game progresses were in place, except a couple of stragglers.

Two iPhones side-by-side doing a migration

What did not go so well was the Apple Watch transfer. I decided not to upgrade this year so I just needed to transfer over my Series 6. During the setup process, it asked me if I wanted to transfer my watch over to the new phone which I promptly said yes to. After the transfer was done and the phone was usable, I got this alert saying that there was an important software update to address iMessage and FaceTime activation issue. Wanting to avoid this and then forgetting that my watch was being transferred, I foolishly went ahead and ran the update. And sure enough, that completely messed up the watch. So I had to hard reset the watch and re-paired it from scratch. Fortunately all the watch faces I had previously were restored.


The Deep Purple color looks pretty muted, you wouldn't be able to tell it's purple unless it's in bright sunlight. I really hope one day Apple will make pro iPhones in fun colors.

The back of a purple iPhone 14 Pro

Comparing to my iPhone 12 Pro, the iPhone 14 Pro is 0.8mm (0.03") taller, 0.45mm (0.02") thicker, and 17g (0.61oz) heavier. The increase in weight was noticeable right away and I wish the iPhone would stop getting bigger. But that's not even the worst part. This phone is 7.85mm thick, which honestly isn't that thick, but that is only for the phone body, ignoring the camera "mesa" and the lens "turrets" protruding out of it. The height of that "bump" alone is more than half the thickness of the phone body! There is no way to lay this phone flat even with the case on. I hate it so damn much.


The first time I noticed the dimmed always-on lock screen, I thought that the phone wasn't locked. So I instinctively pressed the lock button expecting the screen to turn off but instead it lit back up. And when I was aware that it's supposed to be on, I expected that I could interact with the lock screen widgets or swipe down for Control Center, but in reality I first have to tap it to wake up the screen from the dimmed state, and then I could interact with it. So that took a bit to get used to. One exception to this is that if you swipe up to unlock the phone when it's in a dimmed state, it will try to do the Face ID unlock, so that's a nice touch. All these I have since gotten used to in about a week.

One aspect of the always-on display that I had forgotten to consider was around bedtime. As I put the phone on my nightstand when I go to bed, the always-on display would be entirely too bright even in its dimmed state. One easy solution is to just put the phone screen side down. But that would be impractical if you use a MagSafe charger or a regular Qi wireless charging pad. The best solution to this is to enable the Sleep Focus mode as it will automatically disable the always-on display. Oddly enough, while there is a Shortcuts action to set the Apple Watch always-on display mode, there is none for the iPhone. This is quite a glaring miss on Apple's part and I do hope they will add this in a future software update. It would be nice to have for those who don't want to use the Sleep Focus mode.

The ProMotion display was immediately obvious as soon as I picked up the phone. This was something I always noticed and wished I had every time I had to use Jess's iPhone 13 Pro Max. I love it, everything just looks and feels so smooth. The difference feels almost to the level of going from non-Retina display to Retina display.

The 2000 nits peak brightness was also really handy the handful of times I was out in super bright sunlight.

Dynamic Island

The outline around the Dynamic Island and the instruments inside were more noticeable than I expected, even with indoor lighting. But I have since gotten used to that and don't see it anymore.

Since the introduction of the notch with the iPhone X, I formed a habit of tapping on that area as a shortcut to scroll to the top of a list or webpage. But now if I have an active Live Activity session like music or timer, tapping on the Dynamic Island just sends me to the app for that activity instead of scrolling up to the top which was pretty jarring. I had to adapt to tap on either side of it instead.

Unfortunately the Live Activities API wasn't available until iOS 16.1 which was just released earlier this week. So there wasn't much interaction with Dynamic Island in the weeks I've had this phone. I'm sure in coming weeks and months we'll start to see a lot more apps utilizing this.


The new camera system is a substantial upgrade from my iPhone 12 Pro. The picture quality and low light performance are noticeably improved. I love that the 48MP sensor allows for a decent 2x digital zoom at 12MP. So now we have four focal lengths we can shoot at with 0.5x, 1x, 2x, and 3x at a good resolution.

Shooting 48MP is limited to the ProRAW mode and when doing so I could notice some sluggishness with the camera. I sometimes have to wait for a split second between shots for it to process, so I can't shoot them in as quick succession as I'd like. And previewing the photo usually takes a few seconds to become available. I'm a bit disappointed by the performance here given how great Apple touted their new A16 chip to be. I don't know what the bottleneck could be, perhaps it's the memory bandwidth. The phone also gets hot pretty quickly after shooting several 48MP photos in quick succession. This definitely will affect battery life.

But that is by no means a deal-breaker, I still love the fact that with 48MP I could crop and reframe the photo to how I like it. The size of these ProRAW DNG files comes out to around 80-90MB which is pretty hefty. I'm used to working with my 20MP Canon EOS 6D's 20MB RAW files so I'm gonna have to be a bit more mindful of how fast I'm filling up my phone storage with these.

Overall I am really happy with the incredible image quality this camera system produces. Below are some of the photos I took over in Rocky Mountain National Park using Halide. These are straight out of the camera with no post-processing done by me.

IMG 4505
Main Camera, f/1.8, 1/7000s, ISO 100

IMG 4510
Telephoto Camera, f/2.8, 1/270s, ISO 32

IMG 4549
Ultra Wide Camera, f/2.2, 1/460s, ISO 40

IMG 4603
Telephoto Camera, f/2.8, 1/99s, ISO 250

My Experience wih eSIM

I said in my previous post that I was not thrilled Apple decided to remove physical SIM card slot from the new iPhone 14 models sold in the US as that would make traveling outside of the country more troublesome. But that wasn't big enough of an issue for me to not pre-order the new iPhone 14 Pro. I'm sure I could figure something out when the time comes.

So to get ahead of the iPhone release day, I figured I should convert my current physical SIM card in my iPhone 12 Pro to be eSIM. iPhones have had support for eSIM since the iPhone XS released in 2018, I just never bothered to get on the bandwagon.

Apple has a handy support page outlining pretty much all you need to know about eSIM on iPhone. All I had to do was following the instructions on that page on how to convert physical SIM to eSIM and I was done in less than 5 minutes. For some carriers you would have to go through hoops to do this conversion, but with my AT&T SIM there was that "Convert to eSIM" button that took care of everything I needed right in the Settings app. So credits to AT&T on that.

The iPhone day came and I was able to transfer the eSIM to my iPhone 14 Pro without a hiccup even though AT&T service at my place has been utterly garbage since moving to Colorado.

Switching Carrier While on eSIM

Since AT&T service was so bad and full of dead zones here in Colorado, I decided that it's time to switch. My plan wasn't that great either as I only got 4GB of 4G data, and to upgrade to 5G with more data would cost more than I was willing to pay for.

Jess uses T-mobile and she is getting much better coverage around these parts, including 5G. Verizon Wireless was a no-go as I need a GSM phone for traveling so T-mobile was really my only option. But their cheapest plan was still more expensive than I'd like.

I had been hearing about Mint Mobile recently, and since it uses the T-mobile network I decided to check it out.

Trial with Mint Mobile

Mint Mobile offers a free 7-day trial and it could be activated right within their app (which is a much better app than AT&T app). It walked me through the steps and installed a new eSIM on my phone. Within minutes, I had a brand-new network active on my phone alongside my existing AT&T plan. No need to wait for the physical SIM card to arrive in the mail.

This was my first experience with dual SIM on my phone and I was really impressed at how nice and easy it was to configure and manage the two eSIMs on iOS. I could select which number to use for voice or data. So I could use my AT&T number for voice and Mint Mobile for data. The coolest part was the phone can automatically switch the data network depending on which one currently has better service.

Transferring Number and Activating Mint Mobile Service

It didn't take much for me to be convinced by Mint Mobile. The bar was already pretty low to begin with (no pun intended). Their plan is significantly cheaper too. I picked their 10GB plan with 5G that costs only $20 a month for the first 3 months, and $35 a month for 3 months after that. One thing to note is with Mint Mobile, you have to pay 3, 6, or 12 months in advance, which makes sense given how low their prices are.

I was paying AT&T $55 a month for my measly plan. So I’m now paying almost 2 times less per month and get more than twice the data, including 5G.

Similar to the trial, after I purchased the plan, I did the number transfer and activation right in the app. Again, the process was really smooth. I'm documenting it here in case it might be useful to others.

In your AT&T account, go to your profile page, and select the "People & permissions" tab.

Scroll down to the "Transfer phone number" section and select "Request a new PIN". This will generate a six-digit PIN that you'll need to provide to transfer the number to another provider. Also take note of the account number at the top of the page.

In the Mint Mobile app, in the activation flow, put in your AT&T account number and PIN when prompted. They will submit the number transfer request with AT&T.

You should receive a text from Mint saying that the number failed to transfer. But don't retry yet as you should also get a text from AT&T saying that they received a request to transfer your number. Follow the instructions by replying with the code in the text.

Now that you've authorized AT&T to transfer the number, resubmit the transfer request in the Mint Mobile app. This now should go through successfully.

It's probably a good idea to restart your phone at this point.

Now in Settings > Cellular, you should see two eSIMs listed both with your number. You can tell that the transfer went successfully since your number is now associated to an eSIM on Mint network, and the AT&T line shows no service. You can turn off and/or delete the old eSIM and everything should now be working.

From buying the plan to transferring my number and activating it on my phone, the whole process took less than an hour in the comfort of my home. There was no customer representative I needed to talk to, no waiting for the SIM card in the mail, or visiting a store to activate the plan. I must say I am pretty sold on the eSIM lifestyle.

I imagine once this is more widely adopted in the coming years, we’ll all look back and think how archaic it was that we needed a hole in our phone for a tiny plastic card so that we could get cell service on it, just like needing a CD drive in computers so we could play movies.

It would no doubt be a bit annoying when I go to Thailand. This Apple support page does list a couple of carriers in Thailand that support eSIM, and my research on their websites seem to suggest that I should be able to activate a phone plan with eSIM while I’m there. I’ll update this post with my experience on that.

Apple's Far Out Event Initial Reactions

Like a lot of Apple nerds, I'm on a two-year cadence with my iPhone purchases and this means my iPhone 12 Pro I bought in 2020 is due for an upgrade this year. So I was pretty eager to see what Apple would announce today at their annual iPhone event.

But before we go any further, September is Childhood Cancer Awareness Month and for the past 4 years the fine folks at Relay FM podcast network put together a fundraising for St. Jude Children's Research Hospital. We all know a whole lot of us are about to drop an absurd amount of money on new tech that we definitely do not need. To steal the pitch from ATP: a new iPhone 14 Pro starts at $999 and then we add a couple of hundred bucks more on upgrades, accessories, and tax without giving it that much thought. So if you could spend $1,000+ on unnecessary gadgets, you can certainly throw at least a couple of hundred bucks at St. Jude. I can't think of a better cause to support to than this.

Apple Watch Series 8

The Apple Watch Series 8 is a bit underwhelming to be honest. The new temperature sensor is really neat and I love that they focused its use towards ovulation tracking. They didn't make it clear in the keynote whether we can use this sensor for general body temperature tracking. It makes sense that this would be limited to only measuring body temperature changes from the baseline and not absolute body temperature since the wrist is a terrible spot for that. That's really the only update to the Apple Watch which is why I'm likely not going to upgrade this year and just stick with my Series 6.

Side note: With its diversity and inclusion efforts, I found it a bit surprising that Apple did not use a more inclusive language when discussing menstrual and ovulation tracking. They exclusively refer to only women when talking about this feature when not every woman ovulates and women aren't the only people who ovulate. So hopefully they'll do better next time.

Apple Watch Ultra

The highlight of the event for me was the Apple Watch Ultra. I've seen the rumors for months now about this new "rugged" version of the Apple Watch and never really thought much about it as it didn't sound that applicable to my use. But it really impressed me. The coolest part of this Apple Watch Ultra is its ability to be a full-featured dive computer. Before I started wearing the Apple Watch I used to wear my analog watch when scuba diving, and since the Series 2 with its 50 meters water-resistance rating I've always thought it would be cool to wear my Apple Watch while diving and potentially use it as a dive computer. And this Apple Watch Ultra pretty much delivers on that.

It has the EN 13319 certification which makes it a proper dive computer. This upcoming Oceanic+ app sounds like it's going to be doing the heavy-lifting here. They say the app will handle calculating no-decompression limits, safety stops, and providing ascent rate warning. The bare minimum for a dive computer. I love that it also tracks water temperature, GPS locations, and dive profile and can sync all that to your iPhone. Though I couldn't find any mention of no-fly time or nitrox so they might not be supported yet at launch. But the beauty of this being a smart watch is that I don't see a reason why Oceanic couldn't provide future updates to add support for those and other functionalities.

I'm curious if they're going to provide an API for developers to access data from the depth gauge and develop apps for diving purposes. Or perhaps this could also be a partnership just with Oceanic since they're a reputable company with a history of making dive computers who know what they're doing. Allowing any third-party developer to access this data to develop apps for such a critical purpose might not be a very smart thing to do.

This is also only rated for 40 meters (130 feet) which is right around the limit for recreational diving. For comparison my Suunto Zoop Novo, which is also for recreational diving, is rated for 80 meters and has no-fly time and nitrox. Its CR 2450 battery also lasts years compared to just a couple of days at most for the Ultra. If I were to get this $800 Apple Watch and use it for scuba diving, I would still bring my $300 Suunto dive computer down with me just for peace of mind.

Aside from the diving capabilities, the Ultra has a pretty cool new compass app that not only lets you mark waypoints but also keeps track of your GPS locations so that you can retrace your steps. They also really try to sell this for off-the-grid kind of adventures, but the supposed 36 hours battery life is comical for trips like those.

As someone who enjoys hiking in the mountains and scuba diving, I feel like this would be perfect for me. But it's really bulky so I don't think it will work as a day-to-day watch. It's also as expensive as the base iPhone 14. So I don't think I'm going to be getting this any time soon.

AirPods Pro 2

I love the original AirPods Pro and have been using them almost daily for the past three years. Most people who bought them a few years back would probably feel the pain of the reduced battery life by now. But I recently had mine replaced due to sound issues so the batteries on them are still fresh. This means I don't really have a reason to upgrade.

The 2x noise cancellation sounds great. But the current one already sounds so good, I can't imagine what doubling that would be like. Adding the capacitive touch to the stems for volume adjustment is for sure a big quality-of-life improvement. Allowing charging via Apple Watch charger or MagSafe gets a big thumbs up from me.

All in all, a decent update when looking at them together. I don't really see any single feature that makes me want to get these right away. I'm probably going to wait a while before upgrading.

iPhone 14

I'm glad they finally bring the larger size to the non-Pro iPhone. Also I think this is the first time ever on a brand-new iPhone that it doesn't get a new chip. But I think for those buying the regular iPhone 14, they probably wouldn't notice (or care about) a performance difference anyway. The camera upgrade looks like it's going to take much better low-light photos.

The emergency SOS via satellite is really a nice feature to have that you hope you never need. This and the car crash detection in both the Apple Watch and the iPhone make for pretty interesting marketing messages. The Find My via satellite feature sounds much more useful to me. They say this is available for free for the first two years but didn't reveal how much it will cost after that. I'm guessing it's going to be included in either iCloud+ or Apple One bundle.

Gone is the SIM tray as it now only supports eSIM, at least in the US. I'm really annoyed by this removal as it's going to be such a pain in the rear to travel abroad.

iPhone 14 Pro

iPhone 13 Pro's camera bump (mesa?) is already too big. And it's even bigger on the 14 Pro. It's now more than half the thickness of the body itself! This has gotten way out of hand and it has to stop. As good as the cameras might be, they’re not worth this obnoxious design imperfection. I just want my phone to be able to sit flat without wobbling, and cases won't fix that either. I really hope this is the end of it and that they move to periscope lens design or something else that get rid of this bump in future iterations.

The 48MP is a huge jump from 12MP, but the 4x increase makes sense with their use of the quad-pixel sensor. It also looks like the Pro has the exact same camera system as the Pro Max model which is great for me as I cannot do with the Max size. I hope they keep it this way in coming years.

The rumors were spot-on with the hole-punch notch dubbed "Dynamic Island". I think it has one big regression from the notch: compared to the iPhone 14's notch, the screen space intruded on by this pill is quite a bit lower than the notch. So you end up getting less usable vertical screen real estate. We'll find out when it's actually out and in people's hands to see how much of an issue that is. Still, the software for it is so clever and I can't wait to see what developers are going to do with it. It also looks like it's not just the screen surrounding the hole-punch that is tappable but the hole-punch itself as well. The fact that they put so much thought and attention into this made me a bit discouraged since that probably means this design imperfection is not going anywhere any time soon.

The always-on display has been pretty obvious since WWDC earlier this year with the introduction of the Lock Screen widgets. This is a long-overdue feature as it's been available on Android phones for a while now.

Unfortunately the colors of these Pro iPhones are so dull and boring again this year. I just want some fun colors for my iPhone. I'm probably going to get the deep purple one as that's the most fun color we have.

© 2012-2023 Zack Apiratitham