Containerize for GKE deployment - #27
Conversation
8aefe5f to
8a61a95
Compare
| Config::define('SITE_ID_CURRENT_SITE', 1); | ||
| Config::define('BLOG_ID_CURRENT_SITE', 1); |
There was a problem hiding this comment.
Note: it seems to be important for the site ID to match the domain - so as we add domains this number will need to increment AND we'll need to map each site foo.gpo.ca -> 1, bar.gpo.ca -> 2, etc.
We need to do some investigation into how these two config options will play with multisite.
There was a problem hiding this comment.
Both of these are variables for wordpress multisite. As we are only doing 1 main site and multiple sub-sites, I believe that setting it to 1 is correct form.
These variables are for more complex networks that have more main sites, like say if we are somehow also handling the Green Party of Alberta's websites (I doubt we will), that's when we should dynamically define these.
| @@ -0,0 +1,38 @@ | |||
| server { | |||
There was a problem hiding this comment.
Note: because we are already using GCLB we won't need an additional reverse proxy in staging / prod, but this MIGHT be helpful for local dev to handle request routing and so on.
There was a problem hiding this comment.
As PHP works a little differently, it seems like the reverse proxy here is for a layer down.
Instead of
GCLB proxy → another proxy → PHP
It is
GCLB → pod's HTTP-to-FastCGI bridge → PHP-FPM
Here is what the request path looks like:
Visitor's browser
↓ HTTPS
Google Cloud Load Balancer ← decrypts TLS, picks a container
↓ HTTP
nginx (inside the container) ← translates HTTP → FastCGI
↓ FastCGI
PHP-FPM ← actually runs WordPress
This being said, this is more difficult for me to understand, so please take what I'm saying with a grain of salt.
There was a problem hiding this comment.
Good point about needing something to translate HTTP -> FastCGI.
Stuffing an nginx inside every application pod is probably okay in the short term but it's a bummer because it means we cannot scale them independently. If we need to add more WP instances, we have no choice but to add more nginx instances, when it's very likely that a single nginx could handle all our traffic. And putting the nginx config directly inside the docker image means we have to restart all our WP instances any time we make an nginx config change.
Anyway, it's good enough to get us started but we'll probably want to revisit this decision at some point.
There was a problem hiding this comment.
That makes sense. I wrote an issue to fix this later on:
#42
| NONCE_SALT='generateme' | ||
|
|
||
| # Multisite (subdomain install) | ||
| DOMAIN_CURRENT_SITE='example.com' |
There was a problem hiding this comment.
We can probably drop this in favour of using WP_HOME instead.
There was a problem hiding this comment.
Great call. It's fixed on this PR. 1ca9b9f
I did leave the comment be, as it seems like someone used to dealing with wordpress multisites might look for it here.
| # Object cache (Memorystore Redis) | ||
| REDIS_HOST='127.0.0.1' | ||
| REDIS_PORT='6379' | ||
| WP_CACHE_KEY_SALT='example.com' |
There was a problem hiding this comment.
We can probably drop this all together, it only seems to be necessary in sitiuations where multiple separate WP installs are sharing the same redis server (we're not there yet).
There was a problem hiding this comment.
Great!
I believe it's probably best to do without. staging and prod should be on different redis servers, right? Other than those two, I don't see any other WP installs in sight.
Removed:
4825a36
| */ | ||
| Config::define('AUTOMATIC_UPDATER_DISABLED', true); | ||
| Config::define('DISABLE_WP_CRON', env('DISABLE_WP_CRON') ?: false); | ||
| Config::define('DISABLE_WP_CRON', env('DISABLE_WP_CRON') ?: true); |
There was a problem hiding this comment.
false ?: true is true 😬. I think what you want is null coalescing false ?? true is false.
There was a problem hiding this comment.
Yep, that's a bug. Fixed!
| if ! wp core is-installed --network 2>/dev/null; then | ||
| if ! wp core is-installed 2>/dev/null; then | ||
| echo "==> Installing WordPress" | ||
| wp core install \ |
There was a problem hiding this comment.
I'm not sure if we're going to run into this issue, but I believe there's a bit of a chicken and egg issue with WordPress multi-site. On a fresh database, WordPress loading with MULTISITE=true will look for wp_site and wp_blogs, which don't exist yet, and bail before wp core install can run. The usual work around is to have an env var (env('MULTISITE') ?: false) so a fresh install can come up single-site, convert, and then flip the flag.
There was a problem hiding this comment.
Claude touted a better fix.
In our bin/setup-local.sh, we have multisite-convert and it said that multisite-convert "Transforms an existing single-site installation into a multisite installation".
It says that the better fix would be to do a multisite-install saying that it "Installs WordPress multisite from scratch".
I will try this fix out and report back.
There was a problem hiding this comment.
where will this file be used? I don't think we need a .env file in k8s as the env vars will be managed by k8s.
There was a problem hiding this comment.
bootstrap-secrets.sh pulls a secret payload from GCP Secret Manager and writes it to .env.local so a developer can run WordPress locally against real-shaped secrets instead of hand-typing placeholder values. (dev environment)
IanEdington
left a comment
There was a problem hiding this comment.
In general this looks good. There's a lot going on though, I'm seeing at least 3 parts to this PR. I wonder if it would be faster to merge one piece at a time.
| @@ -0,0 +1,55 @@ | |||
| name: Deploy staging | |||
There was a problem hiding this comment.
Right now this workflow just builds and pushes an image, is the intention to have this workflow actually perform a deployment in the future? If not it might reduce confusion to rename this.
Multi-stage Dockerfile (Composer vendor stage -> PHP-FPM runtime) with opcache tuning and php-fpm pool config fixes (clear_env=no, worker output capture, stderr logging). Adds an nginx config for HTTP-facing routing (not yet wired into the image - see PR discussion on sidecar-per-pod vs a shared nginx tier) and a /healthz endpoint for k8s liveness/readiness probes. The CI pipeline builds and pushes the image to Artifact Registry; the build/push logic is a reusable workflow (build-image.yml) so a future production pipeline can call the same logic instead of duplicating it.
0293e38 to
5bb7282
Compare
Summary
clear_env=no, worker output capture, stderr logging)/healthzendpoint for k8s liveness/readiness probesbuild-image.yml) so a future production pipeline can call the same logic instead of duplicating itSplit from the original scope
This PR originally carried more — multisite network config/bootstrap tooling and staging media offload config have been split out into separate, independently reviewable PRs (#43, #44) so this one stays focused on the container image and its build pipeline.
Test plan
vendor/bin/pestpassesdocker buildsucceeds (no Docker daemon available in the sandbox this was authored in — needs a build check in CI or locally)/healthzendpoint responds correctly once deployed🤖 Generated with Claude Code