add wordpress

This commit is contained in:
Philip Peterson 2026-06-25 21:43:10 -07:00
parent 03a4a1a7ef
commit 3ace2e661b
7 changed files with 168 additions and 0 deletions

View file

@ -0,0 +1,56 @@
{ pkgs, ... }:
{
project.name = "atitraining";
networks.atitraining.external = false;
services = {
db = {
service = {
image = "mariadb:11.4";
container_name = "atitraining-db";
restart = "unless-stopped";
networks = [ "atitraining" ];
volumes = [
"/var/atitraining/db:/var/lib/mysql"
];
environment = {
MARIADB_DATABASE = "atitraining";
MARIADB_USER = "atitraining";
MARIADB_PASSWORD = "atitraining";
MARIADB_ROOT_PASSWORD = "atitrainingroot";
};
healthcheck = {
test = [ "CMD" "healthcheck.sh" "--connect" "--innodb_initialized" ];
interval = "10s";
timeout = "5s";
retries = 10;
};
};
};
wordpress = {
service = {
# Image pre-built by build-atitraining-image.service from nixos/atitraining/Dockerfile
# Pinned to WordPress 6.7.2-php8.3-apache.
image = "atitraining-wordpress:local";
container_name = "atitraining-wordpress";
restart = "unless-stopped";
networks = [ "atitraining" ];
depends_on = [ "db" ];
ports = [ "127.0.0.1:3015:80" ];
volumes = [
"/var/atitraining/wp-uploads:/var/www/html/wp-content/uploads"
];
environment = {
WORDPRESS_DB_HOST = "db";
WORDPRESS_DB_NAME = "atitraining";
WORDPRESS_DB_USER = "atitraining";
WORDPRESS_DB_PASSWORD = "atitraining";
# Change this after first login via /wp-admin
WORDPRESS_ADMIN_PASSWORD = "changeme";
};
};
};
};
}

View file

@ -0,0 +1,3 @@
import <nixpkgs> {
system = "x86_64-linux";
}

View file

@ -0,0 +1,37 @@
FROM wordpress:6.7.2-php8.3-apache
# Install WP-CLI and dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
less \
default-mysql-client \
unzip \
&& curl -sL -o /usr/local/bin/wp \
https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar \
&& chmod +x /usr/local/bin/wp \
&& rm -rf /var/lib/apt/lists/*
# Pre-install the p2 theme.
# p2 turns WordPress into a real-time microblog stream (Twitter-like) —
# intentionally weird for a traditional blog context.
RUN curl -sL https://downloads.wordpress.org/theme/p2.zip -o /tmp/p2.zip \
&& unzip -q /tmp/p2.zip -d /var/www/html/wp-content/themes/ \
&& rm /tmp/p2.zip \
&& chown -R www-data:www-data /var/www/html/wp-content/themes/p2
# Tell WordPress it's behind an HTTPS reverse proxy
ENV WORDPRESS_CONFIG_EXTRA="if (isset(\$_SERVER['HTTP_X_FORWARDED_PROTO']) && \$_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') { \$_SERVER['HTTPS'] = 'on'; }"
# Blog identity — baked into the image, overridable at runtime
ENV WORDPRESS_BLOG_TITLE="ATI Training"
ENV WORDPRESS_BLOG_TAGLINE="advanced training intelligence"
ENV WORDPRESS_ADMIN_USER="admin"
ENV WORDPRESS_ADMIN_EMAIL="peterson@sent.com"
ENV WORDPRESS_ACTIVE_THEME="p2"
ENV WORDPRESS_SITEURL="https://atitraining.coldairnetworks.com"
COPY wp-init-bg.sh /usr/local/bin/wp-init-bg.sh
COPY entrypoint.sh /usr/local/bin/atitraining-entrypoint.sh
RUN chmod +x /usr/local/bin/wp-init-bg.sh /usr/local/bin/atitraining-entrypoint.sh
ENTRYPOINT ["/usr/local/bin/atitraining-entrypoint.sh"]
CMD ["apache2-foreground"]

View file

@ -0,0 +1,6 @@
#!/bin/bash
set -e
# Run WP-CLI setup in background; it waits for wp-config.php and the DB
/usr/local/bin/wp-init-bg.sh &
# Hand off to the official WordPress entrypoint (writes wp-config.php, starts Apache)
exec /usr/local/bin/docker-entrypoint.sh "$@"

View file

@ -0,0 +1,25 @@
#!/bin/bash
set -e
# Wait for the official WP entrypoint to write wp-config.php
until [ -f /var/www/html/wp-config.php ]; do sleep 1; done
# Wait for the database to accept connections
until wp --allow-root --path=/var/www/html db check 2>/dev/null; do
sleep 3
done
# Perform first-time install only if WordPress isn't installed yet
if ! wp --allow-root --path=/var/www/html core is-installed 2>/dev/null; then
wp --allow-root --path=/var/www/html core install \
--url="${WORDPRESS_SITEURL:-https://atitraining.coldairnetworks.com}" \
--title="${WORDPRESS_BLOG_TITLE:-ATI Training}" \
--admin_user="${WORDPRESS_ADMIN_USER:-admin}" \
--admin_password="${WORDPRESS_ADMIN_PASSWORD:-changeme}" \
--admin_email="${WORDPRESS_ADMIN_EMAIL:-peterson@sent.com}" \
--skip-email
wp --allow-root --path=/var/www/html theme activate \
"${WORDPRESS_ACTIVE_THEME:-p2}"
wp --allow-root --path=/var/www/html option update blogdescription \
"${WORDPRESS_BLOG_TAGLINE:-advanced training intelligence}"
fi

View file

@ -31,6 +31,8 @@
pullomatic = "${pullomaticPkg}/bin/pullomatic";
atitrainingContext = builtins.path { path = ./atitraining; name = "atitraining"; };
in {
imports = [
(import ./cloned_repos {inherit pkgs pullomatic lib;})
@ -189,6 +191,7 @@ in {
projects.pluto.settings = import ./arion-pluto/arion-compose.nix;
projects.paperless.settings = import ./arion-paperless/arion-compose.nix;
projects.openclaw.settings = import ./arion-openclaw/arion-compose.nix;
projects.atitraining.settings = import ./arion-atitraining/arion-compose.nix;
};
# The arion NixOS module sets backend = "podman-socket" but doesn't inject
@ -199,6 +202,26 @@ in {
systemd.services.arion-pluto.environment.DOCKER_HOST = "unix:///run/podman/podman.sock";
systemd.services.arion-paperless.environment.DOCKER_HOST = "unix:///run/podman/podman.sock";
systemd.services.arion-openclaw.environment.DOCKER_HOST = "unix:///run/podman/podman.sock";
systemd.services.arion-atitraining.environment.DOCKER_HOST = "unix:///run/podman/podman.sock";
# Build the WordPress image for atitraining before arion starts it.
# restartTriggers ensures the image rebuilds whenever nixos/atitraining/ changes.
systemd.services.build-atitraining-image = {
description = "Build atitraining WordPress image";
wantedBy = [ "arion-atitraining.service" ];
before = [ "arion-atitraining.service" ];
restartTriggers = [ atitrainingContext ];
path = [ pkgs.podman ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script = ''
podman build -t atitraining-wordpress:local ${atitrainingContext}
'';
};
systemd.services.arion-atitraining.after = lib.mkAfter [ "build-atitraining-image.service" ];
systemd.services.arion-atitraining.wants = [ "build-atitraining-image.service" ];
systemd.services.novnc = {
description = "noVNC WebSocket proxy for VNC desktop";
@ -294,6 +317,8 @@ in {
"d /var/coldairnetworks-db/postgres 0755 root root"
"d /var/coldairnetworks-db/pgadmin 0700 5050 5050"
"d /var/coldairnetworks-db/ssl 0755 root root"
"d /var/atitraining/db 0755 root root"
"d /var/atitraining/wp-uploads 0755 root root"
];
networking.hostName = "${hostname}";
@ -534,5 +559,6 @@ in {
"acme-selfsigned-pluto.philippeterson.com.service"
"acme-selfsigned-paperless.philippeterson.com.service"
"acme-selfsigned-db.coldairnetworks.com.service"
"acme-selfsigned-atitraining.coldairnetworks.com.service"
];
}

View file

@ -90,6 +90,21 @@
};
};
"atitraining.coldairnetworks.com" = {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://127.0.0.1:3015/";
extraConfig = ''
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
'';
};
};
"db.coldairnetworks.com" = {
enableACME = true;
forceSSL = true;