When to use Argon2i vs Argon2d vs Argon2id? I've read the manual, and multiple articles / StackExchange posts about this topic, but still can't decide which implementation of Argon2 is best for my use case.

I want to securely encrypt passwords in a database in an unshared environment.
After first pass of the docs (pun-intended) it sounded like Argon2i is recommended in this case, but I feel like it's more likely for someone to gain access to the database directly and try to execute a GPU/ASIC/FPGA based attack to decrypt the data than someone gaining access to the network and attempting a side-channel attack.

I would like to prevent side-channel attacks if possible too, so that sounds like Argon2id is the way to go, but my understanding is the i-portion of the implementation only does one pass. Does the one pass really offer much protection against side-channel attacks (I read 3+ or even 10+ passes are needed to really secure Argon2i) and is there a way to increase the number of passes for the i-portion before the d-portion kicks in?

If Argon2id is the implementation for my use-case, but I can't increase the number of passes for the i-portion, would it make sense to effectively create my own "Argon2id" by implementing the Argon2i algorithm first, and then running the output through the Argon2d algorithm after?
If you are unsure, then always choose Argon2id. Only choose Argon2d if you need maximum security at the expense of side-channel risk, and only choose Argon2i if side-channel attacks are the primary threat.

The number of passes just increases resistance to time-memory tradeoff attacks (TMTO). What you are probably remembering is that Argon2i is more vulnerable to TMTO attacks, and thus needs more passes to obtain the equivalent level of security. Argon2id uses the Argon2i pass to resist side-channel attacks, and the subsequent Argon2d passes to make up for TMTO resistance that the first pass lacks.

If an attacker performs a perfect side-channel attack and breaks the Argon2d portion, then they will still need to perform a very extensive TMTO attack to break the Argon2i passes. Compare this with pure Argon2d, where a successful side-channel attack completely negates its memory hardness. In other words, a side-channel attack against Argon2id reduces its security to one-pass Argon2i.

Note that some of the more severe TMTO attacks against Argon2i have actually been fixed.