Initial commit

This commit is contained in:
Autonomic Cooperative
2025-10-09 14:15:29 +00:00
commit 425b396c34
9 changed files with 465 additions and 0 deletions

33
.drone.yml Normal file
View File

@ -0,0 +1,33 @@
---
kind: pipeline
name: deploy main branch to live site
steps:
- name: php syntax check
image: php:8.3.7-cli
commands:
- for f in $(find /drone -name '*.php'); do php -l "f"; done
# If a custom block is in use, uncomment this (and make sure package.json
# includes `scripts.build`, and change the `depends_on` below
# - name: compile custom block
# image: node:18.18.2
# commands:
# - npm install
# - npm run build
# depends_on:
# - php syntax check
- name: docker cp deploy
image: git.coopcloud.tech/coop-cloud/docker-cp-deploy:latest
settings:
host: server.example.com
service: qicn_site
source: wp-content/themes/qicn-site
exec_pre: rm -rf /var/www/html/wp-content/themes/qicn-site/*
exec: composer install
dest: /var/www/html/
deploy_key:
from_secret: drone_ssh_server.example.com
depends_on:
- php syntax check
when:
branch:
- main

41
.env.sample Normal file
View File

@ -0,0 +1,41 @@
##############################################################################
# REQUIRED SETTINGS (you will need these) #
##############################################################################
# What username should `set_local_password` operate on?
USERNAME=admin
##############################################################################
# COMMON SETTINGS (you may need these) #
##############################################################################
# If you don't have docker-compose, but do have newer docker, uncomment this
#DOCKER_COMPOSE=docker compose
# Uncomment the following line if you need `sudo` to run Docker commands
#DOCKER_SUDO=1
# Wordpress debugging
WORDPRESS_DEBUG=1
##############################################################################
# RARE SETTINGS (you probably won't need these) #
##############################################################################
# TODO: insert template "connect to a remote database" settings here
##############################################################################
# INFINITE NERD DEPTH SETTINGS (if you're changing these, good luck!) #
##############################################################################
# Docker container names, probably just needs to be set once per project
PROJECT_NAME=qicn_site
# Site URL, also just needs to be set once per project
SITE_URL=qicn_site.tld
# Multi-site config
#WORDPRESS_CONFIG_EXTRA="define('MULTISITE', true); define('SUBDOMAIN_INSTALL', true); define('DOMAIN_CURRENT_SITE', 'frms.localhost'); define('PATH_CURRENT_SITE', '/'); define('SITE_ID_CURRENT_SITE', 1); define('BLOG_ID_CURRENT_SITE', 1); define('SUNRISE', true);"
# Use composer for plugin installation
#USE_COMPOSER=1

13
.gitignore vendored Normal file
View File

@ -0,0 +1,13 @@
/.env
/wp-content/**
# Add an exception here for any custom plugins or themes to be included, e.g.
#!/wp-content/themes/qicn_site
/data/**
!/data/.gitkeep
.vscode/
**.tar.gz
**.sql
**.zip

109
README.md Normal file
View File

@ -0,0 +1,109 @@
A template for Autonomic Wordpress projects, including local set-up, and auto-deployment.
# Usage
1. Make a new repository, using this as a template
2. Remove this notice from `README.md` (everything until the `---`)
3. Create and deploy a Co-op Cloud Wordpress app
4. Edit `.env.sample` to set `SITE_URL` (and customise `PROJECT_NAME`, if
needed)
- Change USERNAME to whatever the wordpress admin username is / should be
- Set SITE_URL to the live site URL
- Set PROJECT_NAME to some identifier for the project
5. Make sure `.drone.yml` has the right settings for the server you'd like to
deploy
- Change host to the FQDN of the host, likely smol-wp.autonomic.zone
- Set service to the docker service name, usually <app_name_snake_case>_app so like display_distribute_com_app
- Update source and exec_pre to the path to the theme
- Comment exec: composer install if composer isn't in use
- Set `deploy_key: from_secret:` to the secret name of the SSH key to access the server. this requires logging into drone as autonomic admin, then checking "organisation secrets" on the repo settings page of any repo in the same org. or you can use drone CLI and do drone orgsecret ls
6. Add any custom plugins / themes to `wp-content`
- Copying / moving files into the repo in wp-content, and possibly / probably excluding them from .gitignore
7. "Activate" this repository in Drone
- e.g. click "activate repository" here https://drone.autonomic.zone/autonomic-cooperative/display-distribute/settings
8. Commit to the repo to test and monitor the drone interface to troubleshoot
---
# qicn-site
_Wordpress local set-up and custom theme/plugins_
## Local development
### Initial set-up
Install Docker (and, if your Docker version doesn't include `docker compose`,
the separate `docker-compose` programme).
Check out the code:
```
git clone ssh://git@git.autonomic.zone:2222/autonomic-cooperative/qicn-site.git
cd qicn-site
```
Copy the default environment file into place
```
cp .env.sample .env
```
Edit `.env` as needed for your local config; read the descriptions for
`DOCKER_SUDO` and `DOCKER_COMPOSE`, and set them if you need to.
Then, download and start the Docker images:
```
make up # 💄
```
Download uploaded media (beware possibly-large filesize) and plugins from the live site:
```
make uploads_pull
make plugins_pull
```
Then fetch and load the database:
```
make db_pull set_local_password
```
If this process is interrupted for any reason but the database was downloaded in
full, you can skip the dump/download process and just load the database and set
the URL with:
```
make db_load fix_url
```
Lastly, install any parent themes in use on the site:
```
make theme_pull
```
The site should now be available:
- **wordpress**: http://qicn-site.localhost/
- **mailhog**: http://qicn-site.localhost:8025
### Updating your local version
Run `git pull` frequently.
Refresh from the live site as often as you can:
```sh
make plugins_pull theme_pull db_pull set_local_password
```
### Running WPCLI commands
The `make wp` shortcut doesn't support `--flag` arguments, which are used in a
lot of `wp` commands. As an alternative, a shell alias is provided:
```
source shell-aliases
wp post list --post_type page
```

0
data/.gitkeep Normal file
View File

55
docker-compose.yml Normal file
View File

@ -0,0 +1,55 @@
---
version: "3"
services:
wordpress:
image: "wordpress:6.5.3"
ports:
- "80:80"
dns: 4.2.2.4
volumes:
- "./entrypoint.sh:/usr/local/bin/entrypoint.sh:z"
- "./mailhog-smtp.php:/var/www/html/wp-content/mu-plugins/mailhog-smtp.php:z"
- "./wp-content:/var/www/html/wp-content/:z"
- "./composer.json:/var/www/html/composer.json:z"
- "./composer.lock:/var/www/html/composer.lock:z"
entrypoint: ["/usr/local/bin/entrypoint.sh"]
networks:
- backend
environment:
- WORDPRESS_DB_HOST=${WORDPRESS_DB_HOST:-db}
- WORDPRESS_DB_USER=${WORDPRESS_DB_USER:-wordpress}
- WORDPRESS_DB_PASSWORD=${WORDPRESS_DB_PASSWORD:-wordpress}
- WORDPRESS_DB_NAME=wordpress
- WORDPRESS_CONFIG_EXTRA=${WORDPRESS_CONFIG_EXTRA}
- WORDPRESS_DEBUG=${WORDPRESS_DEBUG}
- PHP_EXTENSIONS=calendar
- PAGER=more
container_name: "${PROJECT_NAME}_wordpress"
db:
image: "mariadb:10.6"
volumes:
- "${MARIADB_VOLUME:-mariadb}:/var/lib/mysql"
networks:
- backend
environment:
- MYSQL_ROOT_PASSWORD=wordpress
- MYSQL_DATABASE=wordpress
- MYSQL_USER=wordpress
- MYSQL_PASSWORD=wordpress
container_name: "${PROJECT_NAME}_db"
mailhog:
image: "mailhog/mailhog"
networks:
- backend
ports:
- "8025:8025"
container_name: "${PROJECT_NAME}_mailhog"
volumes:
mariadb:
networks:
backend:

47
entrypoint.sh Executable file
View File

@ -0,0 +1,47 @@
#!/bin/bash
if [ -n "$PHP_EXTENSIONS" ]; then
for extension in $PHP_EXTENSIONS; do
if ! php -m | grep -q $extension; then
docker-php-ext-install $PHP_EXTENSIONS
fi
done
fi
if ! id -u "user" >/dev/null 2>&1; then
useradd -u 1000 -m user
mkdir /var/www/html/vendor
chown -R user:user /var/www/html/vendor
fi
if [ ! -x /usr/bin/zip ]; then
apt update && apt install unzip
fi
if [ ! -x /usr/local/bin/wp ]; then
curl -z /usr/local/bin/wp -o /usr/local/bin/wp https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
chmod +x /usr/local/bin/wp
fi
if [ -n "$USE_COMPOSER" ] && [ ! -x /usr/local/bin/composer ]; then
mkdir -p /var/www/.composer
chown user:user /var/www/.composer
curl https://getcomposer.org/installer -o /tmp/composer-setup.php
php -r "if (hash_file('sha384', '/tmp/composer-setup.php') === 'dac665fdc30fdd8ec78b38b9800061b4150413ff2e3b6f88543c636f7cd84f6db9189d43a81e5503cda447da73c7e5b6') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php /tmp/composer-setup.php
rm /tmp/composer-setup.php
mv /var/www/html/composer.phar /usr/local/bin/composer
fi
export APACHE_RUN_USER=user
export APACHE_RUN_GROUP=user
if [ -n "$@" ]; then
"$@"
fi
# Upstream ENTRYPOINT
# https://github.com/docker-library/wordpress/blob/master/php7.4/apache/Dockerfile#L120
/usr/local/bin/docker-entrypoint.sh apache2-foreground

21
mailhog-smtp.php Normal file
View File

@ -0,0 +1,21 @@
<?php
// Send outgoing mails through Mailhog
function action_wp_mail_failed($wp_error) {
print_r($wp_error, true);
exit;
}
add_action('wp_mail_failed', 'action_wp_mail_failed', 10, 1);
add_action('phpmailer_init', function ($phpmailer) {
$phpmailer->isSMTP();
$phpmailer->SMTPAuth = false;
$phpmailer->SMTPSecure = false;
$phpmailer->SMTPAutoTLS = false;
$phpmailer->Host = "mailhog";
$phpmailer->Port = 1025;
$phpmailer->From = "noreply@radhr.localhost";
$phpmailer->FromName = "noreply@radhr.localhost";
$phpmailer->Username = null;
$phpmailer->Password = null;
});

146
makefile Normal file
View File

@ -0,0 +1,146 @@
include .env
.PHONY: up down stop prune ps shell shell_root wp logs
default: up
#######################################
# Variable admin
#######################################
REQUIRED_BINS := docker
$(foreach bin,$(REQUIRED_BINS),\
$(if $(shell command -v $(bin) 2> /dev/null),$(true),$(error Please install `$(bin)`)))
ifeq ($(SITE_URL),)
$(error SITE_URL is not set)
endif
ABRA ?= abra
DOCKER_COMPOSE ?= docker-compose
ifeq ($(DOCKER_SUDO), 1)
DOCKER = sudo docker
_DOCKER_COMPOSE = sudo $(DOCKER_COMPOSE)
else
DOCKER = docker
_DOCKER_COMPOSE = $(DOCKER_COMPOSE)
endif
#######################################
# Core commands
#######################################
## Start up containers.
up:
@echo "Starting up containers for $(PROJECT_NAME)..."
$(_DOCKER_COMPOSE) pull
$(_DOCKER_COMPOSE) up -d --remove-orphans
## Stop containers.
down: stop
## Start containers without updating.
start:
@echo "Starting containers for $(PROJECT_NAME) from where you left off..."
@$(_DOCKER_COMPOSE) start
## Stop containers.
stop:
@echo "Stopping containers for $(PROJECT_NAME)..."
@$(_DOCKER_COMPOSE) stop
## Remove containers and their volumes.
## You can optionally pass an argument with the service name to prune single container
prune:
@echo "Removing containers for $(PROJECT_NAME)..."
@$(_DOCKER_COMPOSE) down -v $(filter-out $@,$(MAKECMDGOALS))
ps:
@$(_DOCKER_COMPOSE) ps
shell:
@$(_DOCKER_COMPOSE) exec -u user wordpress bash
shell_root:
@$(_DOCKER_COMPOSE) exec wordpress bash
## Executes `wp cli`
## Doesn't support --flag arguments.
wp:
$(_DOCKER_COMPOSE) exec -u user wordpress wp $(filter-out $@,$(MAKECMDGOALS))
## composer
## Doesn't support --flag arguments.
composer:
$(_DOCKER_COMPOSE) exec -u user wordpress composer $(filter-out $@,$(MAKECMDGOALS))
## Show vontainers' logs
## You can optinally pass an argument with the service name to limit logs
logs:
@$(_DOCKER_COMPOSE) logs -f $(filter-out $@,$(MAKECMDGOALS))
## Check that all required variables are defined
check:
@echo "$$(tput setaf 125)Watch out for any lines starting '-', which indicate settings in .env.sample which aren't in .env$$(tput sgr0)"
diff -u <(grep -v '^#' .env.sample | grep -v '^$$' | sed -e 's/=.*//g' | sort) <(grep -v '^#' .env | grep -v '^$$' | sed -e 's/=.*//g' | sort) || true
@echo "$$(tput setaf 125)The following command shouldn't show any differences; if it does, re-copy WORDPRESS_CONFIG_EXTRA fr4om .env.sample to .env$$(tput sgr0)"
diff -wu <(grep 'CONFIG_EXTRA' .env.sample ) <(grep 'CONFIG_EXTRA' .env)
#######################################
# Content management
#######################################
## Download wp-content files from site
uploads_fetch:
@echo -n "About to download ~1.5GB of data, overwriting existing data/uploads.tar.gz. - are you sure? [Y/n] " && read ans && if [ $${ans:-'Y'} = 'n' ]; then \
printf $(_ERROR) "Aborting as requested\n"; \
exit 1 ; \
else \
printf $(_SUCCESS) "OK" "Continuing" ; \
$(ABRA) app run --no-tty $(SITE_URL) app tar --owner=0 --group=0 --no-same-owner --no-same-permissions -czf- /var/www/html/wp-content/uploads/ > data/uploads.tar.gz; \
fi
## Load latest wp-content from data/uploads.tar.gz
uploads_load:
tar -C wp-content --strip-components=4 -xzf data/uploads.tar.gz
#######################################
# Wacky commands you probably won't need to use
#######################################
## Download database from dev site
db_fetch:
$(ABRA) app run $(SITE_URL) db bash -c 'mariadb-dump -u root -p"$$(cat /run/secrets/db_root_password)" wordpress' | gzip > data/dbdump.sql.gz
## Load latest database from ~/.abra/backups
db_load:
zcat data/dbdump.sql.gz | $(_DOCKER_COMPOSE) exec -T db mysql -u wordpress -pwordpress wordpress
## Replace site URL
fix_url:
$(_DOCKER_COMPOSE) exec -u user wordpress wp --url=https://$(SITE_URL) search-replace --all-tables-with-prefix 'https://$(SITE_URL)' 'http://$(PROJECT_NAME).localhost'
set_local_password:
$(_DOCKER_COMPOSE) exec -u user wordpress wp user update $(USERNAME) --user_pass=password
db_pull: db_fetch db_load fix_url
## Sync wp-content from site
uploads_pull: uploads_fetch uploads_load
## Download wp-content files from site
plugins_fetch:
$(ABRA) app run --no-tty $(SITE_URL) app tar --owner=0 --group=0 --no-same-owner --no-same-permissions -czf- /var/www/html/wp-content/plugins/ > data/plugins.tar.gz
## Load latest plugins from data/plugins.tar.gz
plugins_load:
tar -C wp-content --strip-components=4 -xzf data/plugins.tar.gz
## Sync plugins from site
plugins_pull: plugins_fetch plugins_load
# "Arguments" for makefiles..
# https://stackoverflow.com/a/6273809/1826109
%: