Skip to content

Commit e3c1fc3

Browse files
committed
Initial commit.
1 parent f4af8b6 commit e3c1fc3

29 files changed

+1113
-2
lines changed

.github/matrix.php

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
<?php
2+
/**
3+
* This script generates the matrix for the Docker image build job
4+
*
5+
* It checks if changes in the DokuWiki branch, the upstream PHP image or the docker repo have been made
6+
* since it ran last time (using the github action cache for persistence). This allows us to run this every
7+
* day to catch any updates to the upstream images, while avoiding unnecessary rebuilds.
8+
*/
9+
10+
11+
/**
12+
* Get the list of DokuWiki versions from the download server
13+
*
14+
* @return array
15+
*/
16+
function getVersions()
17+
{
18+
$data = file_get_contents('https://download.dokuwiki.org/version');
19+
return json_decode($data, true);
20+
}
21+
22+
/**
23+
* Get the last commit of a branch
24+
*
25+
* @param string $repo
26+
* @param string $branch
27+
* @return string
28+
*/
29+
function getLastCommit($repo, $branch)
30+
{
31+
$opts = [
32+
'http' => [
33+
'method' => "GET",
34+
'header' => join("\r\n", [
35+
"Accept: application/vnd.github.v3+json",
36+
"User-Agent: PHP"
37+
])
38+
]
39+
];
40+
$context = stream_context_create($opts);
41+
42+
$data = file_get_contents("https://api.github.com/repos/dokuwiki/$repo/commits/$branch", false, $context);
43+
$json = json_decode($data, true);
44+
return $json['sha'];
45+
}
46+
47+
/**
48+
* Get the image id of a given PHP image tag
49+
*
50+
* @param string $tag
51+
* @return string
52+
*/
53+
function getImageId($tag)
54+
{
55+
$repo = 'library/php';
56+
$data = file_get_contents('https://auth.docker.io/token?service=registry.docker.io&scope=repository:' . $repo . ':pull');
57+
$token = json_decode($data, true)['token'];
58+
59+
60+
$opts = [
61+
'http' => [
62+
'method' => "GET",
63+
'header' => join("\r\n", [
64+
"Authorization: Bearer $token",
65+
"Accept: application/vnd.docker.distribution.manifest.v2+json",
66+
])
67+
]
68+
];
69+
$context = stream_context_create($opts);
70+
71+
$data = file_get_contents('https://index.docker.io/v2/' . $repo . '/manifests/' . $tag, false, $context);
72+
$json = json_decode($data, true);
73+
return $json['config']['digest'];
74+
}
75+
76+
/**
77+
* Get the image tag used in the current Dockerfile
78+
*
79+
* @return string
80+
*/
81+
function getImageTag()
82+
{
83+
$df = file_get_contents('Dockerfile');
84+
preg_match('/FROM php:(?<tag>\S*)/', $df, $matches);
85+
return $matches['tag'];
86+
}
87+
88+
89+
$result = [];
90+
$self = getLastCommit('docker', 'main');
91+
$upstreamTag = getImageTag();
92+
$image = getImageId($upstreamTag);
93+
94+
foreach (getVersions() as $release => $info) {
95+
$branch = $release === 'oldstable' ? 'old-stable' : $release;
96+
$commit = getLastCommit('dokuwiki', $branch);
97+
$ident = join('-', [$release, $commit, $image, $self]);
98+
$cache = '.github/matrix.cache/' . $release;
99+
100+
$last = @file_get_contents($cache);
101+
fwrite(STDERR, "Old: $last\n");
102+
fwrite(STDERR, "New: $ident\n");
103+
if ($last === $ident) {
104+
// this combination has been built before
105+
fwrite(STDERR, "No change. Skipping $release\n");
106+
continue;
107+
}
108+
109+
// this branch needs to be built
110+
$result[] = [
111+
'version' => $info['version'],
112+
'date' => $info['date'],
113+
'name' => $info['name'],
114+
'type' => $release,
115+
];
116+
// update the cache
117+
if (!is_dir('.github/matrix.cache')) {
118+
mkdir('.github/matrix.cache');
119+
}
120+
file_put_contents($cache, $ident);
121+
}
122+
123+
// output the result
124+
if ($result) {
125+
echo "matrix=" . json_encode(['release' => $result]);
126+
} else {
127+
echo "matrix=[]";
128+
}
129+
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
name: Publish MediaWiki Helm Chart to GHCR
2+
3+
on:
4+
push:
5+
branches:
6+
- main # Or your default branch like 'master' or 'develop'
7+
paths:
8+
# Adjust these paths to your actual chart location and workflow file
9+
- 'helm/**'
10+
- '.github/workflows/publish-mediawiki-chart.yaml'
11+
12+
jobs:
13+
publish:
14+
name: Publish Helm Chart
15+
runs-on: ubuntu-latest
16+
permissions:
17+
contents: read # Required to checkout the repository code
18+
packages: write # Required to push packages to GHCR
19+
20+
steps:
21+
- name: Checkout repository
22+
uses: actions/checkout@v4
23+
24+
- name: Install Helm 3 (and verify version)
25+
uses: azure/setup-helm@v1
26+
with:
27+
# Explicitly request a Helm 3 version that supports OCI push
28+
version: 'v3.15.0'
29+
id: setup_helm
30+
31+
- name: Verify Helm Version is 3.x
32+
run: |
33+
helm version --client
34+
# Check if the client version string contains "v3."
35+
helm version --client | grep "Version:\"v3\." || {
36+
echo "Error: Helm 3 was not correctly installed. Found different version."
37+
exit 1
38+
}
39+
40+
- name: Clean Helm Cache and Ensure Home Directory
41+
run: |
42+
echo "Cleaning Helm cache directory: ~/.helm"
43+
rm -rf ~/.helm || true # Remove the entire directory, ignore if it doesn't exist
44+
mkdir -p ~/.helm/repository
45+
touch ~/.helm/repository/repositories.yaml
46+
touch ~/.helm/registry.json # This will be populated by helm registry login
47+
48+
- name: Login to GitHub Container Registry
49+
run: |
50+
echo "${{ secrets.GITHUB_TOKEN }}" | helm registry login ghcr.io \
51+
--username ${{ github.actor }} \
52+
--password-stdin
53+
54+
- name: Get Chart Version and Name
55+
id: get_chart_info
56+
run: |
57+
CHART_NAME=$(yq e '.name' helm/Chart.yaml)
58+
CHART_VERSION=$(yq e '.version' helm/Chart.yaml)
59+
echo "Chart Name: $CHART_NAME"
60+
echo "Chart Version: $CHART_VERSION"
61+
echo "chart_name=$CHART_NAME" >> "$GITHUB_OUTPUT"
62+
echo "chart_version=$CHART_VERSION" >> "$GITHUB_OUTPUT"
63+
64+
- name: Add Helm repository
65+
run: helm repo add bcgov-crunchy-postgres https://bcgov.github.io/crunchy-postgres/
66+
67+
# Update the chart dependencies
68+
- name: Update Helm dependencies
69+
run: helm dependency update ./helm
70+
71+
# Package the Helm Chart
72+
- name: Package Helm Chart
73+
run: helm package helm
74+
75+
- name: Push Helm Chart to GHCR
76+
run: |
77+
CHART_PACKAGE_NAME="${{ steps.get_chart_info.outputs.chart_name }}-${{ steps.get_chart_info.outputs.chart_version }}.tgz"
78+
CHART_OCI_PATH="oci://ghcr.io/${{ github.repository_owner }}/${{ steps.get_chart_info.outputs.chart_name }}"
79+
echo "Pushing $CHART_PACKAGE_NAME to $CHART_OCI_PATH"
80+
helm push "$CHART_PACKAGE_NAME" "$CHART_OCI_PATH"
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
name: Build and Push Docker Image to GHCR
2+
3+
on:
4+
push:
5+
branches:
6+
- main # Trigger on pushes to the main branch
7+
workflow_dispatch: # Allow manual triggering
8+
9+
jobs:
10+
build_and_push:
11+
name: Build and Push Docker Image
12+
runs-on: ubuntu-latest # Using ubuntu-latest for simplicity, consistent with Dockerfile's base image
13+
permissions:
14+
contents: read
15+
packages: write # Necessary for pushing to GHCR
16+
17+
steps:
18+
- name: Checkout Repository
19+
uses: actions/checkout@v4
20+
21+
- name: Set up QEMU
22+
uses: docker/setup-qemu-action@v3
23+
with:
24+
platforms: all # Enable building for multiple platforms
25+
26+
- name: Set up Docker Buildx
27+
uses: docker/setup-buildx-action@v3
28+
29+
- name: Login to GitHub Container Registry
30+
uses: docker/login-action@v3
31+
with:
32+
registry: ghcr.io
33+
username: ${{ github.actor }}
34+
password: ${{ secrets.GITHUB_TOKEN }}
35+
36+
- name: Prepare Docker Tags
37+
id: docker_tags
38+
run: |
39+
# Define the image name based on the GitHub repository
40+
IMAGE_NAME="ghcr.io/${{ github.repository }}"
41+
# Use a simple 'latest' tag for pushes to main, or a custom tag for workflow_dispatch if desired.
42+
# For a more robust setup, you might use:
43+
# - A version tag from a Git tag (e.g., if on: push: tags: )
44+
# - A short commit SHA for development builds
45+
46+
TAGS="${IMAGE_NAME}:latest"
47+
48+
# If you want to use the branch name as a tag (e.g., ghcr.io/user/repo:main)
49+
# if [[ "${{ github.ref }}" == "refs/heads/main" ]]; then
50+
# TAGS="${IMAGE_NAME}:main,${TAGS}"
51+
# fi
52+
53+
echo "tags=${TAGS}" >> $GITHUB_OUTPUT
54+
55+
- name: Build and Push Docker Image
56+
uses: docker/build-push-action@v5
57+
with:
58+
context: . # Build context is the current directory
59+
platforms: linux/amd64,linux/arm64 # Building for common architectures
60+
push: true
61+
tags: ${{ steps.docker_tags.outputs.tags }}
62+
# You might need build-args if your Dockerfile relies on them.
63+
# For example, if you want to pass DOKUWIKI_VERSION:
64+
# build-args: |
65+
# DOKUWIKI_VERSION=stable
66+
# Or if you want it dynamic based on a variable:
67+
# build-args: |
68+
# DOKUWIKI_VERSION=${{ env.DOKUWIKI_VERSION_ARG }}
69+
cache-from: type=gha, scope=${{ github.workflow }}
70+
cache-to: type=gha, mode=max, scope=${{ github.workflow }} # Use mode=max for better caching

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.github/matrix.cache/
2+
storage/
3+
.DS_Store

Dockerfile

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# Start from the official DokuWiki image.
2+
# Using 'latest' or a specific version like '2024-02-06a' is recommended for stability.
3+
FROM dokuwiki/dokuwiki:latest
4+
5+
# Define build argument for the SMTP plugin version.
6+
# Check https://github.com/splitbrain/dokuwiki-plugin-smtp/releases for the latest stable version.
7+
ARG SMTP_PLUGIN_VERSION="2023-01-20"
8+
ARG SMTP_PLUGIN_PATH="https://github.com/splitbrain/dokuwiki-plugin-smtp/zipball/master"
9+
10+
# Switch to root user to install system packages and modify configurations.
11+
USER root
12+
13+
# Install necessary dependencies for downloading and extracting the plugin.
14+
# --no-install-recommends reduces image size by avoiding recommended but not strictly necessary packages.
15+
RUN apt-get update && \
16+
apt-get install -y --no-install-recommends \
17+
curl \
18+
unzip && \
19+
rm -rf /var/lib/apt/lists/* # Clean up apt cache to keep image small
20+
21+
# --- Apache Port Configuration ---
22+
# The official DokuWiki image's Apache typically listens on port 80.
23+
# To align with your Helm charts and previous Dockerfile's EXPOSE 8080,
24+
# we need to modify Apache's configuration to listen on 8080.
25+
RUN sed -i 's/^Listen 80/Listen 8080/' /etc/apache2/ports.conf && \
26+
sed -i 's/<VirtualHost \*:80>/<VirtualHost \*:8080>/' /etc/apache2/sites-available/000-default.conf
27+
28+
# --- Healthcheck File ---
29+
# Based on your previous Dockerfile and Helm probe configurations,
30+
# it's assumed you have a `health.php` file for readiness/liveness checks.
31+
# This command copies your local `root/var/www/html/health.php` into the image.
32+
# Ensure this file exists in your Docker build context.
33+
COPY root/var/www/html/health.php /var/www/html/health.php
34+
35+
# --- DokuWiki SMTP Plugin Installation ---
36+
# Set the working directory to a temporary location for downloading the plugin.
37+
WORKDIR /tmp
38+
39+
# --- DokuWiki SMTP Plugin Installation ---
40+
# Set the working directory to a temporary location for downloading and processing.
41+
# We create a unique temporary directory to avoid conflicts if /tmp contains other files.
42+
WORKDIR /tmp/dokuwiki_plugin_install
43+
44+
# Download the SMTP plugin.
45+
RUN set -eux; \
46+
curl -fL -o smtp.zip ${SMTP_PLUGIN_PATH}; \
47+
48+
# Unzip the plugin into the current temporary directory.
49+
# This will create the plugin's root folder (e.g., 'dokuwiki-plugin-smtp-2023-01-20')
50+
# inside '/tmp/dokuwiki_plugin_install/'.
51+
RUN set -eux; \
52+
unzip smtp.zip; \
53+
# Find the name of the extracted plugin directory.
54+
# 'find . -maxdepth 1 -mindepth 1 -type d' looks for directories only one level deep.
55+
# '-print -quit' prints the first one found and exits, assuming there's only one.
56+
EXTRACTED_DIR=$(find . -maxdepth 1 -mindepth 1 -type d -print -quit); \
57+
# Move the detected extracted directory to the final 'smtp' location.
58+
# This directly renames the extracted folder to 'smtp' under /dokuwiki/lib/plugins/
59+
mv "${EXTRACTED_DIR}" /dokuwiki/lib/plugins/smtp; \
60+
# Clean up the downloaded zip file and the temporary working directory.
61+
rm smtp.zip; \
62+
rm -rf /tmp/dokuwiki_plugin_install # Remove the temporary working directory
63+
64+
# ... (rest of the Dockerfile remains the same) ...
65+
66+
# --- Permissions for added files and directories ---
67+
# The official `dokuwiki/dokuwiki` image primarily uses the `www-data` user (UID/GID 33).
68+
# We must ensure that the `health.php` and the newly installed `smtp` plugin directory
69+
# are owned by this user so DokuWiki can access and execute them.
70+
RUN chown www-data:www-data /var/www/html/health.php && \
71+
chmod +x /var/www/html/health.php && \
72+
chown -R www-data:www-data /dokuwiki/lib/plugins/smtp
73+
74+
# Expose the custom port that Apache is now configured to listen on.
75+
# This matches the `targetPort` in your Helm service definition.
76+
EXPOSE 8080
77+
78+
# Switch to the non-root user `www-data`.
79+
# The base image's Dockerfile usually sets this, but it's good practice to be explicit
80+
# to ensure all subsequent commands (if any) and the container's runtime
81+
# operate under this non-privileged user.
82+
USER www-data
83+
84+
# The official dokuwiki/dokuwiki image provides its own ENTRYPOINT.
85+
# We do not need to define one here unless you require custom startup logic
86+
# that is not handled by the official image's entrypoint.

0 commit comments

Comments
 (0)