Compare commits
12 Commits
gitea-acti
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 5a51420d5e | |||
| f092e99c6b | |||
| d79b9a9a1d | |||
| 942d75dd86 | |||
| 1e8af71026 | |||
| e8235f246f | |||
| 4ea40c091e | |||
| 7f61795ad9 | |||
| 6e52b56302 | |||
| 8926e6c33b | |||
| e5b56493e8 | |||
| 3ec56cb967 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -29,4 +29,4 @@ site
|
||||
root.password
|
||||
docker-compose.yml
|
||||
*.zip
|
||||
|
||||
.claude
|
||||
|
||||
@@ -5,7 +5,7 @@ EXPOSE 8989
|
||||
|
||||
# Install ImageMagick (used for image thumbnailing)
|
||||
RUN apt-get update && \
|
||||
apt-get install -y imagemagick && \
|
||||
apt-get install -y --no-install-recommends imagemagick && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Copy skins, config files, and other particulars into container
|
||||
@@ -24,28 +24,25 @@ RUN apt-get update && \
|
||||
COPY charlesreid1-config/mediawiki/extensions/Math /var/www/html/extensions/Math
|
||||
COPY charlesreid1-config/mediawiki/extensions/ParserFunctions /var/www/html/extensions/ParserFunctions
|
||||
COPY charlesreid1-config/mediawiki/extensions/SyntaxHighlight_GeSHi /var/www/html/extensions/SyntaxHighlight_GeSHi
|
||||
RUN chown -R www-data:www-data /var/www/html/*
|
||||
|
||||
# Skins
|
||||
COPY charlesreid1-config/mediawiki/skins /var/www/html/skins
|
||||
RUN chown -R www-data:www-data /var/www/html/skins
|
||||
RUN touch /var/www/html/skins
|
||||
|
||||
# MathJax 3.2.2 (self-hosted, served via Apache alias at /w/mathjax/*).
|
||||
# Math extension runs in 'source' mode; MathJax renders client-side, so we
|
||||
# never call out to restbase/mathoid. See LocalSettings.php.j2.
|
||||
COPY charlesreid1-config/mediawiki/mathjax /var/www/html/mathjax
|
||||
RUN chown -R www-data:www-data /var/www/html/mathjax
|
||||
|
||||
# Settings
|
||||
COPY charlesreid1-config/mediawiki/LocalSettings.php /var/www/html/LocalSettings.php
|
||||
RUN chown -R www-data:www-data /var/www/html/LocalSettings*
|
||||
RUN chmod 600 /var/www/html/LocalSettings.php
|
||||
|
||||
# Apache conf file
|
||||
COPY charlesreid1-config/apache/*.conf /etc/apache2/sites-enabled/
|
||||
RUN a2enmod rewrite
|
||||
RUN service apache2 restart
|
||||
|
||||
RUN chown -R www-data:www-data /var/www/html/* /var/www/html/skins /var/www/html/mathjax /var/www/html/LocalSettings* && \
|
||||
touch /var/www/html/skins && \
|
||||
chmod 600 /var/www/html/LocalSettings.php && \
|
||||
a2enmod rewrite
|
||||
|
||||
# PHP conf file
|
||||
# https://hub.docker.com/_/php/
|
||||
|
||||
@@ -93,14 +93,24 @@ $wgMathValidModes = [ 'source' ];
|
||||
# which breaks air-gapped installs even when we only emit source HTML.
|
||||
$wgMathDisableTexFilter = 'always';
|
||||
$wgHooks['BeforePageDisplay'][] = function ( $out, $skin ) {
|
||||
$out->addHeadItem( 'mathjax',
|
||||
'<script>window.MathJax = {'
|
||||
. 'tex: { inlineMath: [["$","$"],["\\\\(","\\\\)"]], '
|
||||
. 'displayMath: [["$$","$$"],["\\\\[","\\\\]"]], '
|
||||
. 'processEscapes: true }, '
|
||||
. 'options: { processHtmlClass: "mwe-math-fallback-source-inline|mwe-math-fallback-source-display|mwe-math-element" } '
|
||||
. '};</script>'
|
||||
. '<script async src="/w/mathjax/tex-chtml.js"></script>'
|
||||
$out->addHeadItem( 'mathjax-config',
|
||||
'<script>'
|
||||
. 'window.MathJax = {'
|
||||
. ' tex: {'
|
||||
. ' inlineMath: [["$","$"],["\\\\(","\\\\)"]],'
|
||||
. ' displayMath: [["$$","$$"],["\\\\[","\\\\]"]],'
|
||||
. ' processEscapes: true'
|
||||
. ' },'
|
||||
. ' options: {'
|
||||
. ' enableMenu: false,'
|
||||
. ' renderActions: { addMenu: [] }'
|
||||
. ' },'
|
||||
. ' startup: { typeset: true }'
|
||||
. '};'
|
||||
. '</script>'
|
||||
);
|
||||
$out->addHeadItem( 'mathjax-script',
|
||||
'<script defer src="/w/mathjax/tex-chtml.js"></script>'
|
||||
);
|
||||
};
|
||||
|
||||
@@ -238,7 +248,7 @@ $wgSecureLogin = true;
|
||||
###################################
|
||||
# Raw html
|
||||
|
||||
$wgRawHtml = true;
|
||||
$wgRawHtml = false;
|
||||
|
||||
# but also keep things locked down
|
||||
$wgUseRCPatrol=true;
|
||||
|
||||
@@ -1,7 +1,2 @@
|
||||
FROM mysql:8.0
|
||||
MAINTAINER charles@charlesreid1.com
|
||||
|
||||
# make mysql data a volume
|
||||
VOLUME ["/var/lib/mysql"]
|
||||
|
||||
RUN chown mysql:mysql /var/lib/mysql
|
||||
|
||||
@@ -27,19 +27,44 @@ services:
|
||||
networks:
|
||||
- frontend
|
||||
|
||||
docker_socket_proxy:
|
||||
image: tecnativa/docker-socket-proxy:latest
|
||||
container_name: docker_socket_proxy
|
||||
restart: always
|
||||
privileged: true
|
||||
volumes:
|
||||
- "/var/run/docker.sock:/var/run/docker.sock:ro"
|
||||
environment:
|
||||
- CONTAINERS=1
|
||||
- IMAGES=1
|
||||
- NETWORKS=1
|
||||
- VOLUMES=1
|
||||
- EXEC=1
|
||||
- POST=1
|
||||
- ALLOW_START=1
|
||||
- ALLOW_STOP=1
|
||||
- ALLOW_RESTARTS=1
|
||||
logging:
|
||||
driver: "json-file"
|
||||
options:
|
||||
max-size: 1m
|
||||
max-file: "10"
|
||||
networks:
|
||||
- frontend
|
||||
|
||||
stormy_gitea_runner:
|
||||
image: gitea/act_runner:latest
|
||||
container_name: stormy_gitea_runner
|
||||
restart: always
|
||||
volumes:
|
||||
- "stormy_gitea_runner_data:/data"
|
||||
- "/var/run/docker.sock:/var/run/docker.sock"
|
||||
- "./d-gitea/runner/config.yaml:/etc/act_runner/config.yaml:ro"
|
||||
environment:
|
||||
- GITEA_INSTANCE_URL=http://stormy_gitea:3000
|
||||
- GITEA_RUNNER_REGISTRATION_TOKEN={{ pod_charlesreid1_gitea_runner_token }}
|
||||
- GITEA_RUNNER_NAME=stormy-runner
|
||||
- CONFIG_FILE=/etc/act_runner/config.yaml
|
||||
- DOCKER_HOST=tcp://docker_socket_proxy:2375
|
||||
logging:
|
||||
driver: "json-file"
|
||||
options:
|
||||
@@ -47,6 +72,7 @@ services:
|
||||
max-file: "10"
|
||||
depends_on:
|
||||
- stormy_gitea
|
||||
- docker_socket_proxy
|
||||
networks:
|
||||
- frontend
|
||||
|
||||
@@ -132,8 +158,6 @@ volumes:
|
||||
stormy_mysql_data:
|
||||
stormy_mw_images:
|
||||
external: true
|
||||
stormy_mw_data:
|
||||
external: true
|
||||
stormy_gitea_data:
|
||||
stormy_gitea_runner_data:
|
||||
stormy_nginx_logs:
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import socket
|
||||
import time
|
||||
from pathlib import Path
|
||||
import requests
|
||||
import boto3
|
||||
import botocore
|
||||
import subprocess
|
||||
|
||||
|
||||
webhook_url = os.environ['POD_CHARLESREID1_CANARY_WEBHOOK']
|
||||
@@ -24,18 +26,21 @@ def main():
|
||||
alert(msg)
|
||||
|
||||
# verify there is a backup newer than N days
|
||||
newer_backups = subprocess.getoutput(f'find {backup_dir}/* -mtime -{N}').split('\n')
|
||||
if len(newer_backups)==1 and newer_backups[0]=='':
|
||||
backup_path = Path(backup_dir)
|
||||
cutoff = time.time() - (N * 86400)
|
||||
newer_backups = [p for p in backup_path.iterdir() if p.stat().st_mtime > cutoff]
|
||||
if not newer_backups:
|
||||
msg = "Local Backups Error:\n"
|
||||
msg += f"The backup directory `{backup_dir}` is missing backup files from the last {N} day(s)!"
|
||||
alert(msg)
|
||||
|
||||
newest_backup_name = subprocess.getoutput(f'ls -t {backup_dir} | head -n1')
|
||||
newest_backup_path = os.path.join(backup_dir, newest_backup_name)
|
||||
newest_backup_files = subprocess.getoutput(f'find {newest_backup_path} -type f').split('\n')
|
||||
newest_backup = max(backup_path.iterdir(), key=lambda p: p.stat().st_mtime)
|
||||
newest_backup_name = newest_backup.name
|
||||
newest_backup_path = str(newest_backup)
|
||||
newest_backup_files = [str(p) for p in newest_backup.rglob('*') if p.is_file()]
|
||||
|
||||
# verify the most recent backup directory is not empty
|
||||
if len(newest_backup_files)==1 and newest_backup_files[0]=='':
|
||||
if not newest_backup_files:
|
||||
msg = "Local Backups Error:\n"
|
||||
msg += f"The most recent backup directory `{newest_backup_path}` is empty!"
|
||||
alert(msg)
|
||||
@@ -92,7 +97,7 @@ def check_exists(bucket_name, bucket_path):
|
||||
|
||||
def alert(msg):
|
||||
title = ":bangbang: pod-charlesreid1 backups canary"
|
||||
hostname = subprocess.getoutput('hostname')
|
||||
hostname = socket.gethostname()
|
||||
msg += f"\n\nHost: {hostname}"
|
||||
slack_data = {
|
||||
"username": "backups_canary",
|
||||
|
||||
@@ -53,20 +53,12 @@ if [ "$#" == "0" ]; then
|
||||
|
||||
echo "Running mysqldump inside the mysql container"
|
||||
|
||||
# Pull the root password out of the container so we don't duplicate the
|
||||
# secret on the host, and forward it in via MYSQL_PWD (which mysqldump
|
||||
# reads automatically). No -t: a PTY corrupts --default-character-set=binary
|
||||
# output (LF→CRLF translation on binary blobs) and its small kernel buffer
|
||||
# can deadlock on large dumps.
|
||||
set +x
|
||||
MYSQL_PWD="$(docker exec "${CONTAINER_NAME}" printenv MYSQL_ROOT_PASSWORD)"
|
||||
export MYSQL_PWD
|
||||
set -x
|
||||
|
||||
# The container already has MYSQL_ROOT_PASSWORD in its environment.
|
||||
# Use it directly inside the container via MYSQL_PWD so the password
|
||||
# never appears in the host process table.
|
||||
docker exec -i \
|
||||
-e MYSQL_PWD \
|
||||
"${CONTAINER_NAME}" \
|
||||
sh -c 'exec mysqldump \
|
||||
sh -c 'MYSQL_PWD="$MYSQL_ROOT_PASSWORD" exec mysqldump \
|
||||
--user=root \
|
||||
--single-transaction \
|
||||
--quick \
|
||||
@@ -77,8 +69,6 @@ if [ "$#" == "0" ]; then
|
||||
--databases wikidb' \
|
||||
> "${BACKUP_TARGET}"
|
||||
|
||||
unset MYSQL_PWD
|
||||
|
||||
# A complete mysqldump always ends with "-- Dump completed on ...".
|
||||
# Missing trailer means the dump is truncated and not restorable.
|
||||
if ! tail -c 200 "${BACKUP_TARGET}" | grep -q 'Dump completed on'; then
|
||||
|
||||
Reference in New Issue
Block a user