mirror of
https://github.com/magicbug/Cloudlog
synced 2026-08-13 17:49:35 -04:00
Merge 860cd5e01c into 6c1c98f132
This commit is contained in:
commit
bc015f4c75
8 changed files with 236 additions and 83 deletions
11
.env.sample
11
.env.sample
|
|
@ -1,3 +1,6 @@
|
|||
# CodeIgniter environment: development | testing | production (developer UI / error display)
|
||||
CLOUDLOG_ENV=development
|
||||
|
||||
MYSQL_ROOT_PASSWORD=rootpassword
|
||||
MYSQL_DATABASE=cloudlog
|
||||
MYSQL_USER=cloudlog
|
||||
|
|
@ -6,4 +9,10 @@ MYSQL_HOST=db
|
|||
MYSQL_PORT=3306
|
||||
BASE_LOCATOR=IO91WM
|
||||
WEBSITE_URL=http://localhost
|
||||
DIRECTORY=/var/www/html
|
||||
DIRECTORY=/var/www/html
|
||||
|
||||
# Docker images (GitHub Container Registry). Override for forks, e.g. ghcr.io/yourusername
|
||||
# CLOUDLOG_IMAGE_REGISTRY=ghcr.io/magicbug
|
||||
# CLOUDLOG_IMAGE_TAG=latest
|
||||
#
|
||||
# Compose: development uses docker-compose.yml (default); production uses docker-compose.prod.yml
|
||||
|
|
|
|||
2
.github/workflows/cypress-tests.yml
vendored
2
.github/workflows/cypress-tests.yml
vendored
|
|
@ -48,7 +48,7 @@ jobs:
|
|||
sudo chmod +x /usr/local/bin/docker-compose
|
||||
|
||||
- name: Build Docker services
|
||||
run: docker-compose up -d
|
||||
run: docker-compose up -d --build
|
||||
|
||||
- name: Wait for services to start
|
||||
run: |
|
||||
|
|
|
|||
61
.github/workflows/docker-publish.yml
vendored
Normal file
61
.github/workflows/docker-publish.yml
vendored
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
name: Publish Docker images
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
jobs:
|
||||
build-and-push:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- dockerfile: Dockerfile
|
||||
image: cloudlog-web
|
||||
- dockerfile: Dockerfile-db
|
||||
image: cloudlog-db
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Log in to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Extract Docker metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: ghcr.io/${{ github.repository_owner }}/${{ matrix.image }}
|
||||
tags: |
|
||||
type=semver,pattern={{version}}
|
||||
type=sha
|
||||
type=raw,value=latest,enable=${{ github.ref_type == 'tag' }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: ${{ matrix.dockerfile }}
|
||||
push: true
|
||||
platforms: linux/amd64,linux/arm64
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
52
Dockerfile
52
Dockerfile
|
|
@ -1,39 +1,35 @@
|
|||
# Use the official image for PHP and Apache
|
||||
FROM php:7.4-apache
|
||||
|
||||
# Set the working directory to /var/www/html
|
||||
WORKDIR /var/www/html
|
||||
|
||||
# Install system dependencies, including git and libxml2
|
||||
RUN apt-get update && apt-get install -y \
|
||||
libcurl4-openssl-dev \
|
||||
libxml2-dev \
|
||||
libzip-dev \
|
||||
zlib1g-dev \
|
||||
libpng-dev \
|
||||
libonig-dev \
|
||||
default-mysql-client \
|
||||
curl \
|
||||
&& apt-get clean \
|
||||
# Single layer: APT cleanup + PHP extensions (curl used by application PHP code)
|
||||
RUN apt-get update \
|
||||
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||
libcurl4-openssl-dev \
|
||||
libxml2-dev \
|
||||
libzip-dev \
|
||||
zlib1g-dev \
|
||||
libpng-dev \
|
||||
libonig-dev \
|
||||
default-mysql-client \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& docker-php-ext-install pdo_mysql \
|
||||
&& docker-php-ext-install mysqli \
|
||||
&& docker-php-ext-install gd \
|
||||
&& docker-php-ext-install mbstring \
|
||||
&& docker-php-ext-install zip \
|
||||
&& docker-php-ext-install xml \
|
||||
&& docker-php-ext-install -j"$(nproc)" curl pdo_mysql mysqli gd mbstring zip xml \
|
||||
&& a2enmod rewrite
|
||||
|
||||
# Copy script.sh and make it executable
|
||||
COPY . /var/www/html/
|
||||
|
||||
# Duplicate for seeding an empty Docker volume mounted over /var/www/html (Compose cloudlog_html)
|
||||
RUN cp -a /var/www/html /usr/local/share/cloudlog-stock
|
||||
|
||||
COPY script.sh /usr/local/bin/startup.sh
|
||||
RUN sed -i 's/\r$//' /usr/local/bin/startup.sh && chmod +x /usr/local/bin/startup.sh
|
||||
|
||||
# Configure PHP for larger file uploads (30MB)
|
||||
RUN echo "upload_max_filesize = 30M" >> /usr/local/etc/php/conf.d/uploads.ini \
|
||||
&& echo "post_max_size = 35M" >> /usr/local/etc/php/conf.d/uploads.ini \
|
||||
&& echo "memory_limit = 64M" >> /usr/local/etc/php/conf.d/uploads.ini \
|
||||
&& echo "max_execution_time = 300" >> /usr/local/etc/php/conf.d/uploads.ini \
|
||||
&& echo "max_input_time = 300" >> /usr/local/etc/php/conf.d/uploads.ini
|
||||
RUN printf '%s\n' \
|
||||
'upload_max_filesize = 30M' \
|
||||
'post_max_size = 35M' \
|
||||
'memory_limit = 64M' \
|
||||
'max_execution_time = 300' \
|
||||
'max_input_time = 300' \
|
||||
> /usr/local/etc/php/conf.d/uploads.ini
|
||||
|
||||
# Expose port 80
|
||||
EXPOSE 80
|
||||
EXPOSE 80
|
||||
|
|
|
|||
|
|
@ -4,9 +4,13 @@ FROM mariadb:latest
|
|||
# Add the install.sql file to the docker image
|
||||
ADD install/assets/install.sql /docker-entrypoint-initdb.d
|
||||
|
||||
# Create a healthcheck script that uses mariadb-admin
|
||||
RUN echo '#!/bin/bash\nmariadb-admin ping -h "localhost" --silent' > /usr/local/bin/healthcheck.sh \
|
||||
# Healthcheck: must use DB credentials (MariaDB 12 rejects anonymous/root-without-password probes → log spam)
|
||||
RUN printf '%s\n' \
|
||||
'#!/bin/bash' \
|
||||
'set -e' \
|
||||
'exec mariadb-admin ping -h localhost --silent -u"${MYSQL_USER}" -p"${MYSQL_PASSWORD}"' \
|
||||
> /usr/local/bin/healthcheck.sh \
|
||||
&& chmod +x /usr/local/bin/healthcheck.sh
|
||||
|
||||
# Expose port 3306
|
||||
EXPOSE 3306
|
||||
EXPOSE 3306
|
||||
|
|
|
|||
|
|
@ -1,15 +1,19 @@
|
|||
|
||||
networks:
|
||||
mynet:
|
||||
|
||||
services:
|
||||
web:
|
||||
build: .
|
||||
image: ghcr.io/magicbug/cloudlog-web:latest
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
env_file:
|
||||
- .env
|
||||
ports:
|
||||
- "80:80"
|
||||
volumes:
|
||||
- ./:/var/www/html:rw
|
||||
- ./web:/var/www/html
|
||||
command: ["/usr/local/bin/startup.sh"]
|
||||
depends_on:
|
||||
db:
|
||||
|
|
@ -19,13 +23,14 @@ services:
|
|||
restart: on-failure
|
||||
|
||||
db:
|
||||
image: ghcr.io/magicbug/cloudlog-db:latest
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile-db
|
||||
env_file:
|
||||
- .env
|
||||
volumes:
|
||||
- db_data:/var/lib/mysql
|
||||
- ./db_data:/var/lib/mysql
|
||||
networks:
|
||||
- mynet
|
||||
healthcheck:
|
||||
|
|
@ -35,5 +40,3 @@ services:
|
|||
interval: 10s
|
||||
start_period: 40s
|
||||
|
||||
volumes:
|
||||
db_data: {}
|
||||
|
|
|
|||
46
index.php
46
index.php
|
|
@ -36,6 +36,40 @@
|
|||
* @filesource
|
||||
*/
|
||||
|
||||
/*
|
||||
*---------------------------------------------------------------
|
||||
* Optional .env next to this file (existing getenv/$_SERVER values are not overwritten — Docker/OS wins)
|
||||
*---------------------------------------------------------------
|
||||
*/
|
||||
$cloudlogEnvFile = __DIR__ . DIRECTORY_SEPARATOR . '.env';
|
||||
if (is_readable($cloudlogEnvFile)) {
|
||||
foreach (file($cloudlogEnvFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) as $line) {
|
||||
$line = trim($line);
|
||||
if ($line === '' || (isset($line[0]) && $line[0] === '#')) {
|
||||
continue;
|
||||
}
|
||||
$eq = strpos($line, '=');
|
||||
if ($eq === false) {
|
||||
continue;
|
||||
}
|
||||
$name = trim(substr($line, 0, $eq));
|
||||
$value = trim(substr($line, $eq + 1));
|
||||
if ($name === '') {
|
||||
continue;
|
||||
}
|
||||
if (strlen($value) >= 2
|
||||
&& (($value[0] === '"' && substr($value, -1) === '"')
|
||||
|| ($value[0] === "'" && substr($value, -1) === "'"))) {
|
||||
$value = substr($value, 1, -1);
|
||||
}
|
||||
if (getenv($name) === false) {
|
||||
putenv($name . '=' . $value);
|
||||
$_ENV[$name] = $value;
|
||||
$_SERVER[$name] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*---------------------------------------------------------------
|
||||
* APPLICATION ENVIRONMENT
|
||||
|
|
@ -51,10 +85,18 @@
|
|||
* testing
|
||||
* production
|
||||
*
|
||||
* Set CLOUDLOG_ENV or CI_ENV in .env (or in the server environment). Defaults to development.
|
||||
*
|
||||
* NOTE: If you change these, also change the error_reporting() code below
|
||||
*/
|
||||
#define('ENVIRONMENT', isset($_SERVER['CI_ENV']) ? $_SERVER['CI_ENV'] : 'development');
|
||||
define('ENVIRONMENT', 'development');
|
||||
$cloudlog_environment = getenv('CLOUDLOG_ENV');
|
||||
if ($cloudlog_environment === false || $cloudlog_environment === '') {
|
||||
$cloudlog_environment = getenv('CI_ENV');
|
||||
}
|
||||
if ($cloudlog_environment === false || $cloudlog_environment === '') {
|
||||
$cloudlog_environment = 'development';
|
||||
}
|
||||
define('ENVIRONMENT', $cloudlog_environment);
|
||||
|
||||
/*
|
||||
*---------------------------------------------------------------
|
||||
|
|
|
|||
124
script.sh
124
script.sh
|
|
@ -1,24 +1,34 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Define the file path for .env and the file to modify
|
||||
if [ -f "./.env" ]; then
|
||||
ENV_FILE="./.env"
|
||||
else
|
||||
ENV_FILE="./.env.sample"
|
||||
# App root (Dockerfile WORKDIR); ensures ./.env resolves even if the process cwd differs
|
||||
cd /var/www/html || exit 1
|
||||
|
||||
# Named volume on /var/www/html starts empty and hides image layers — copy stock tree once.
|
||||
if [ ! -f "index.php" ] && [ -d "/usr/local/share/cloudlog-stock" ]; then
|
||||
echo "Copying Cloudlog into /var/www/html from image (first run or empty volume)..."
|
||||
cp -a /usr/local/share/cloudlog-stock/. /var/www/html/
|
||||
fi
|
||||
|
||||
CONFIG_FILE="install/config/config.php"
|
||||
DATABASE_FILE="install/config/database.php"
|
||||
DEST_DIR="application/config"
|
||||
|
||||
# Check if .env file exists
|
||||
if [ ! -f "$ENV_FILE" ]; then
|
||||
echo ".env file not found!"
|
||||
# Load variables: prefer files on the bind mount; otherwise use env already injected by Compose (env_file)
|
||||
if [ -f "./.env" ]; then
|
||||
# shellcheck disable=SC1091
|
||||
source "./.env"
|
||||
elif [ -f "./.env.sample" ]; then
|
||||
# shellcheck disable=SC1091
|
||||
source "./.env.sample"
|
||||
elif [ -n "${MYSQL_DATABASE:-}" ] && [ -n "${MYSQL_USER:-}" ] && [ -n "${MYSQL_PASSWORD:-}" ] && \
|
||||
[ -n "${MYSQL_HOST:-}" ] && [ -n "${BASE_LOCATOR:-}" ] && [ -n "${WEBSITE_URL:-}" ] && [ -n "${DIRECTORY:-}" ]; then
|
||||
:
|
||||
else
|
||||
echo ".env file not found under /var/www/html and required variables are not set in the environment."
|
||||
echo "Add .env next to docker-compose.yml (bind-mounted as /var/www/html) or pass variables via Compose env_file / environment."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Read the .env file
|
||||
source $ENV_FILE
|
||||
|
||||
# Check if MYSQL_DATABASE is set
|
||||
if [ -z "${MYSQL_DATABASE}" ]; then
|
||||
echo "MYSQL_DATABASE is not set in .env file!"
|
||||
|
|
@ -55,17 +65,30 @@ if [ -z "${DIRECTORY}" ]; then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
# Normalize filesystem root (avoids //var/www/html when DIRECTORY is already absolute)
|
||||
APP_ROOT="${DIRECTORY%/}"
|
||||
case "$APP_ROOT" in
|
||||
/*) ;;
|
||||
*) APP_ROOT="/${APP_ROOT}" ;;
|
||||
esac
|
||||
|
||||
# Check if destination directory exists, if not create it
|
||||
if [ ! -d "$DEST_DIR" ]; then
|
||||
mkdir -p $DEST_DIR
|
||||
mkdir -p "$DEST_DIR"
|
||||
fi
|
||||
|
||||
# Check if configuration has already been processed
|
||||
if [ -f "$DEST_DIR/database.php" ] && [ -f "$DEST_DIR/config.php" ]; then
|
||||
echo "Configuration files already exist, skipping processing..."
|
||||
else
|
||||
if [ ! -f "$DATABASE_FILE" ] || [ ! -f "$CONFIG_FILE" ]; then
|
||||
echo "ERROR: Installer templates missing under /var/www/html (install/config/)."
|
||||
echo "Rebuild the web image so it includes the full Cloudlog tree, or bind-mount a git checkout."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Processing configuration files..."
|
||||
|
||||
|
||||
# Use sed with a different delimiter (`|`) to avoid conflicts with special characters
|
||||
# Strip any trailing whitespace/newlines from variables before using them
|
||||
CLEAN_DATABASE=$(echo "${MYSQL_DATABASE}" | tr -d '\r\n')
|
||||
|
|
@ -75,21 +98,21 @@ else
|
|||
CLEAN_LOCATOR=$(echo "${BASE_LOCATOR}" | tr -d '\r\n')
|
||||
CLEAN_URL=$(echo "${WEBSITE_URL}" | tr -d '\r\n')
|
||||
CLEAN_DIRECTORY=$(echo "${DIRECTORY}" | tr -d '\r\n')
|
||||
|
||||
sed -i "s|%DATABASE%|${CLEAN_DATABASE}|g" $DATABASE_FILE
|
||||
sed -i "s|%USERNAME%|${CLEAN_USER}|g" $DATABASE_FILE
|
||||
sed -i "s|%PASSWORD%|${CLEAN_PASSWORD}|g" $DATABASE_FILE
|
||||
sed -i "s|%HOSTNAME%|${CLEAN_HOST}|g" $DATABASE_FILE
|
||||
sed -i "s|%baselocator%|${CLEAN_LOCATOR}|g" $CONFIG_FILE
|
||||
sed -i "s|%websiteurl%|${CLEAN_URL}|g" $CONFIG_FILE
|
||||
sed -i "s|%directory%|${CLEAN_DIRECTORY}|g" $CONFIG_FILE
|
||||
|
||||
sed -i "s|%DATABASE%|${CLEAN_DATABASE}|g" "$DATABASE_FILE"
|
||||
sed -i "s|%USERNAME%|${CLEAN_USER}|g" "$DATABASE_FILE"
|
||||
sed -i "s|%PASSWORD%|${CLEAN_PASSWORD}|g" "$DATABASE_FILE"
|
||||
sed -i "s|%HOSTNAME%|${CLEAN_HOST}|g" "$DATABASE_FILE"
|
||||
sed -i "s|%baselocator%|${CLEAN_LOCATOR}|g" "$CONFIG_FILE"
|
||||
sed -i "s|%websiteurl%|${CLEAN_URL}|g" "$CONFIG_FILE"
|
||||
sed -i "s|%directory%|${CLEAN_DIRECTORY}|g" "$CONFIG_FILE"
|
||||
|
||||
# Move the files to the destination directory
|
||||
mv $CONFIG_FILE $DEST_DIR
|
||||
mv $DATABASE_FILE $DEST_DIR
|
||||
mv "$CONFIG_FILE" "$DEST_DIR"
|
||||
mv "$DATABASE_FILE" "$DEST_DIR"
|
||||
|
||||
# Delete the /install directory
|
||||
rm -rf /install
|
||||
# Remove installer templates from the bind-mounted tree (under app root, not filesystem /install)
|
||||
rm -rf ./install
|
||||
fi
|
||||
|
||||
echo "Replacement complete."
|
||||
|
|
@ -106,24 +129,39 @@ else
|
|||
echo "Database connection failed, but continuing anyway since healthcheck passed..."
|
||||
fi
|
||||
|
||||
# Set Permissions
|
||||
chown -R root:www-data /${DIRECTORY}/application/config/
|
||||
chown -R root:www-data /${DIRECTORY}/application/logs/
|
||||
chown -R root:www-data /${DIRECTORY}/assets/qslcard/
|
||||
chown -R root:www-data /${DIRECTORY}/backup/
|
||||
chown -R root:www-data /${DIRECTORY}/updates/
|
||||
chown -R root:www-data /${DIRECTORY}/uploads/
|
||||
chown -R root:www-data /${DIRECTORY}/images/eqsl_card_images/
|
||||
chown -R root:www-data /${DIRECTORY}/assets/json
|
||||
# Writable paths (create if missing, then fix ownership)
|
||||
mkdir -p \
|
||||
"${APP_ROOT}/application/config" \
|
||||
"${APP_ROOT}/application/cache" \
|
||||
"${APP_ROOT}/application/logs" \
|
||||
"${APP_ROOT}/assets/qslcard" \
|
||||
"${APP_ROOT}/backup" \
|
||||
"${APP_ROOT}/updates" \
|
||||
"${APP_ROOT}/uploads" \
|
||||
"${APP_ROOT}/images/eqsl_card_images" \
|
||||
"${APP_ROOT}/assets/json"
|
||||
|
||||
chmod -R g+rw /${DIRECTORY}/application/config/
|
||||
chmod -R g+rw /${DIRECTORY}/application/logs/
|
||||
chmod -R g+rw /${DIRECTORY}/assets/qslcard/
|
||||
chmod -R g+rw /${DIRECTORY}/backup/
|
||||
chmod -R g+rw /${DIRECTORY}/updates/
|
||||
chmod -R g+rw /${DIRECTORY}/uploads/
|
||||
chmod -R g+rw /${DIRECTORY}/images/eqsl_card_images/
|
||||
chmod -R g+rw /${DIRECTORY}/assets/json
|
||||
chown -R root:www-data \
|
||||
"${APP_ROOT}/application/config" \
|
||||
"${APP_ROOT}/application/cache" \
|
||||
"${APP_ROOT}/application/logs" \
|
||||
"${APP_ROOT}/assets/qslcard" \
|
||||
"${APP_ROOT}/backup" \
|
||||
"${APP_ROOT}/updates" \
|
||||
"${APP_ROOT}/uploads" \
|
||||
"${APP_ROOT}/images/eqsl_card_images" \
|
||||
"${APP_ROOT}/assets/json"
|
||||
|
||||
chmod -R g+rw \
|
||||
"${APP_ROOT}/application/config" \
|
||||
"${APP_ROOT}/application/cache" \
|
||||
"${APP_ROOT}/application/logs" \
|
||||
"${APP_ROOT}/assets/qslcard" \
|
||||
"${APP_ROOT}/backup" \
|
||||
"${APP_ROOT}/updates" \
|
||||
"${APP_ROOT}/uploads" \
|
||||
"${APP_ROOT}/images/eqsl_card_images" \
|
||||
"${APP_ROOT}/assets/json"
|
||||
|
||||
# Start Apache in the foreground
|
||||
exec apache2-foreground
|
||||
exec apache2-foreground
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue