Docker Implementation
This commit is contained in:
24
domain-monitor-docker/.docker/Dockerfile
Normal file
24
domain-monitor-docker/.docker/Dockerfile
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# Latest stable PHP + Apache
|
||||||
|
FROM php:apache
|
||||||
|
|
||||||
|
# Build deps for requested PHP extensions
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
|
libicu-dev libzip-dev libpng-dev libjpeg62-turbo-dev libfreetype6-dev \
|
||||||
|
libxml2-dev libcurl4-openssl-dev libonig-dev pkg-config unzip git tzdata \
|
||||||
|
&& docker-php-ext-configure gd --with-jpeg --with-freetype \
|
||||||
|
&& docker-php-ext-install -j"$(nproc)" \
|
||||||
|
pdo pdo_mysql mysqli intl zip gd bcmath mbstring curl xml \
|
||||||
|
&& a2enmod rewrite headers \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Set Apache DocumentRoot to /var/www/html/public
|
||||||
|
ARG APACHE_DOCUMENT_ROOT=/var/www/html/public
|
||||||
|
RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/000-default.conf
|
||||||
|
|
||||||
|
# Apache timeout only (no proxy needed)
|
||||||
|
RUN set -eux; \
|
||||||
|
echo "Timeout 300" > /etc/apache2/conf-available/timeouts.conf; \
|
||||||
|
a2enconf timeouts
|
||||||
|
|
||||||
|
WORKDIR /var/www/html
|
||||||
|
|
||||||
20
domain-monitor-docker/.docker/php.ini
Normal file
20
domain-monitor-docker/.docker/php.ini
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
; ---- PHP limits (as requested) ----
|
||||||
|
max_execution_time = 0
|
||||||
|
max_input_time = -1
|
||||||
|
max_input_vars = 3000
|
||||||
|
memory_limit = 512M
|
||||||
|
post_max_size = 32M
|
||||||
|
upload_max_filesize = 16M
|
||||||
|
default_socket_timeout = 120
|
||||||
|
|
||||||
|
; Recommended defaults
|
||||||
|
date.timezone = UTC
|
||||||
|
display_errors = On
|
||||||
|
error_reporting = E_ALL
|
||||||
|
|
||||||
|
; Opcache (safe defaults)
|
||||||
|
opcache.enable=1
|
||||||
|
opcache.enable_cli=1
|
||||||
|
opcache.validate_timestamps=1
|
||||||
|
opcache.revalidate_freq=2
|
||||||
|
|
||||||
50
domain-monitor-docker/.gitignore
vendored
Normal file
50
domain-monitor-docker/.gitignore
vendored
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
===
|
||||||
|
.env
|
||||||
|
.env.docker
|
||||||
|
*.env.bak*
|
||||||
|
*.env.backup*
|
||||||
|
app/.env
|
||||||
|
|
||||||
|
# === LOGS ===
|
||||||
|
app/logs/
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# === COMPOSER ===
|
||||||
|
app/vendor/
|
||||||
|
app/composer.lock
|
||||||
|
|
||||||
|
# === DOCKER / BUILD ARTIFACTS ===
|
||||||
|
dbdata/
|
||||||
|
.docker/*.pid
|
||||||
|
.docker/*.sock
|
||||||
|
.docker/.cache/
|
||||||
|
*.pid
|
||||||
|
*.sock
|
||||||
|
|
||||||
|
# === TEMPORARY FILES ===
|
||||||
|
*.tmp
|
||||||
|
*.swp
|
||||||
|
*.bak
|
||||||
|
*.orig
|
||||||
|
|
||||||
|
# === OS / EDITOR ===
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
.idea/
|
||||||
|
.vscode/
|
||||||
|
*.code-workspace
|
||||||
|
|
||||||
|
# === BACKUPS ===
|
||||||
|
*.bak.*
|
||||||
|
*.tar
|
||||||
|
*.zip
|
||||||
|
|
||||||
|
# === GIT IGNORES REPO CLONED APP (OPTIONAL) ===
|
||||||
|
# If you keep domain-monitor-docker in its own Git repo and want to ignore app/
|
||||||
|
# uncomment this line:
|
||||||
|
# app/
|
||||||
|
|
||||||
|
# === SYSTEM / MISC ===
|
||||||
|
node_modules/
|
||||||
|
coverage/
|
||||||
|
|
||||||
157
domain-monitor-docker/README.md
Normal file
157
domain-monitor-docker/README.md
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
# Domain Monitor Docker Setup
|
||||||
|
|
||||||
|
This directory contains Docker configuration for running Domain Monitor in a containerized environment.
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
1. **Configure your environment:**
|
||||||
|
- Copy `env.docker.example` to `.env.docker`
|
||||||
|
- Edit `.env.docker` and change the default passwords:
|
||||||
|
```bash
|
||||||
|
cp env.docker.example .env.docker
|
||||||
|
# Edit .env.docker with your real passwords
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Run the bootstrap script:**
|
||||||
|
```bash
|
||||||
|
chmod +x bootstrap.sh
|
||||||
|
./bootstrap.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
## What the bootstrap script does
|
||||||
|
|
||||||
|
The `bootstrap.sh` script will:
|
||||||
|
|
||||||
|
- **Clone the Domain Monitor repository** from GitHub into the `app/` folder (only if `app/` doesn't exist or is empty)
|
||||||
|
- **Set up the application environment** by creating `.env` file with database configuration
|
||||||
|
- **Install PHP dependencies** using Composer
|
||||||
|
- **Configure proper file permissions** for the web server
|
||||||
|
- **Load environment variables** from `.env.docker` into the shell
|
||||||
|
- **Start the Docker stack** (web server, database, and phpMyAdmin)
|
||||||
|
|
||||||
|
### Running bootstrap multiple times
|
||||||
|
|
||||||
|
The bootstrap script is **safe to run multiple times**:
|
||||||
|
- If `app/` folder exists and has content, it skips the git clone
|
||||||
|
- It will reinstall Composer dependencies (ensures they're up to date)
|
||||||
|
- It will restart the Docker containers with `--build` flag
|
||||||
|
- Your database data is preserved (stored in Docker volumes)
|
||||||
|
|
||||||
|
## Environment Configuration
|
||||||
|
|
||||||
|
The bootstrap script loads environment variables from `.env.docker` into the shell environment, which Docker Compose then uses for variable substitution. This approach ensures that all services get the correct database credentials.
|
||||||
|
|
||||||
|
## Services
|
||||||
|
|
||||||
|
After running the bootstrap script, you'll have:
|
||||||
|
|
||||||
|
- **Domain Monitor App**: http://localhost:8080
|
||||||
|
- **phpMyAdmin**: http://localhost:8081 (Server: `domain-monitor-mariadb`)
|
||||||
|
|
||||||
|
## Managing the Docker Stack
|
||||||
|
|
||||||
|
### Starting the stack
|
||||||
|
```bash
|
||||||
|
# First time setup (clones repo, installs dependencies, starts containers)
|
||||||
|
./bootstrap.sh
|
||||||
|
|
||||||
|
# Or if you just want to start existing containers
|
||||||
|
docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
### Stopping the stack
|
||||||
|
```bash
|
||||||
|
# Stop all containers
|
||||||
|
docker compose down
|
||||||
|
|
||||||
|
# Stop and remove volumes (WARNING: This will delete your database data!)
|
||||||
|
docker compose down -v
|
||||||
|
```
|
||||||
|
|
||||||
|
### Restarting the stack
|
||||||
|
```bash
|
||||||
|
# Restart containers (keeps data)
|
||||||
|
docker compose restart
|
||||||
|
|
||||||
|
# Rebuild and restart (if you made changes to Docker config)
|
||||||
|
docker compose up -d --build
|
||||||
|
|
||||||
|
# Full restart (stops, rebuilds, starts)
|
||||||
|
docker compose down && docker compose up -d --build
|
||||||
|
```
|
||||||
|
|
||||||
|
### Viewing logs
|
||||||
|
```bash
|
||||||
|
# View logs for all services
|
||||||
|
docker compose logs
|
||||||
|
|
||||||
|
# View logs for specific service
|
||||||
|
docker compose logs web
|
||||||
|
docker compose logs db
|
||||||
|
docker compose logs pma
|
||||||
|
|
||||||
|
# Follow logs in real-time
|
||||||
|
docker compose logs -f
|
||||||
|
```
|
||||||
|
|
||||||
|
## Environment Configuration
|
||||||
|
|
||||||
|
You need to create a `.env.docker` file with your database credentials. The script will copy `env.docker.example` to `.env.docker` if it doesn't exist, but you **must edit it** with real passwords before the script will work.
|
||||||
|
|
||||||
|
Required variables in `.env.docker`:
|
||||||
|
- `DB_DATABASE` - Database name
|
||||||
|
- `DB_USERNAME` - Database user
|
||||||
|
- `DB_PASSWORD` - Database password
|
||||||
|
- `DB_ROOT_PASSWORD` - Database root password
|
||||||
|
- `TZ` - Timezone (optional, defaults to UTC)
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
- Docker and Docker Compose
|
||||||
|
- Git
|
||||||
|
- Internet connection (to clone the repository)
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
- Make sure you're running the script from the `domain-monitor-docker` directory
|
||||||
|
- Ensure Docker is running and you have permission to use it
|
||||||
|
- Check that you've edited `.env.docker` with real passwords (not the example values)
|
||||||
|
|
||||||
|
## Quick Reference
|
||||||
|
|
||||||
|
### Common scenarios
|
||||||
|
|
||||||
|
**First time setup:**
|
||||||
|
```bash
|
||||||
|
cp env.docker.example .env.docker
|
||||||
|
# Edit .env.docker with real passwords
|
||||||
|
./bootstrap.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
**Daily usage:**
|
||||||
|
```bash
|
||||||
|
# Start (if stopped)
|
||||||
|
docker compose up -d
|
||||||
|
|
||||||
|
# Stop
|
||||||
|
docker compose down
|
||||||
|
```
|
||||||
|
|
||||||
|
**After making changes to the app:**
|
||||||
|
```bash
|
||||||
|
# Restart to pick up changes
|
||||||
|
docker compose restart web
|
||||||
|
```
|
||||||
|
|
||||||
|
**After making changes to Docker config:**
|
||||||
|
```bash
|
||||||
|
# Rebuild containers
|
||||||
|
docker compose up -d --build
|
||||||
|
```
|
||||||
|
|
||||||
|
**Complete reset (WARNING: deletes all data):**
|
||||||
|
```bash
|
||||||
|
docker compose down -v
|
||||||
|
rm -rf app/
|
||||||
|
./bootstrap.sh
|
||||||
|
```
|
||||||
131
domain-monitor-docker/bootstrap.sh
Normal file
131
domain-monitor-docker/bootstrap.sh
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
### --- CONFIG ---
|
||||||
|
GIT_URL="${GIT_URL:-https://github.com/Hosteroid/domain-monitor.git}"
|
||||||
|
APP_ENV_DEFAULT="${APP_ENV:-production}"
|
||||||
|
|
||||||
|
# Always treat the CURRENT directory as project root
|
||||||
|
PROJECT_ROOT="$(pwd)"
|
||||||
|
APP_DIR="$PROJECT_ROOT/app"
|
||||||
|
DOCKER_ENV_FILE="$PROJECT_ROOT/.env.docker"
|
||||||
|
ENV_TMPL="$APP_DIR/env.example.txt"
|
||||||
|
ENV_FILE="$APP_DIR/.env"
|
||||||
|
|
||||||
|
# Numeric IDs for php:apache (Debian) www-data
|
||||||
|
WWW_UID=33
|
||||||
|
WWW_GID=33
|
||||||
|
ROOT_UID=0
|
||||||
|
|
||||||
|
dc() {
|
||||||
|
if command -v docker &>/dev/null && docker compose version &>/dev/null; then
|
||||||
|
docker compose "$@"
|
||||||
|
elif command -v docker-compose &>/dev/null; then
|
||||||
|
docker-compose "$@"
|
||||||
|
else
|
||||||
|
echo "Error: docker compose not found." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
fail() { echo "Error: $*" >&2; exit 1; }
|
||||||
|
upsert_kv() {
|
||||||
|
local file="$1" key="$2" val="$3"
|
||||||
|
if grep -qE "^${key}=" "$file" 2>/dev/null; then
|
||||||
|
sed -i "s#^${key}=.*#${key}=${val}#g" "$file"
|
||||||
|
else
|
||||||
|
printf "%s=%s\n" "$key" "$val" >> "$file"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "==> Domain Monitor bootstrap"
|
||||||
|
|
||||||
|
[[ -f "$PROJECT_ROOT/docker-compose.yml" ]] || fail "Run this from the domain-monitor-docker folder."
|
||||||
|
|
||||||
|
# Ensure .env.docker exists (or copy example then exit)
|
||||||
|
if [[ ! -f "$DOCKER_ENV_FILE" ]]; then
|
||||||
|
if [[ -f "$PROJECT_ROOT/env.docker.example" ]]; then
|
||||||
|
echo "==> .env.docker not found. Creating from example..."
|
||||||
|
cp "$PROJECT_ROOT/env.docker.example" "$DOCKER_ENV_FILE"
|
||||||
|
echo " Edit $DOCKER_ENV_FILE with real passwords, then re-run."
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
fail ".env.docker not found (and no example to copy)."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Load Docker env
|
||||||
|
set -a
|
||||||
|
# shellcheck disable=SC1090
|
||||||
|
. "$DOCKER_ENV_FILE"
|
||||||
|
set +a
|
||||||
|
|
||||||
|
: "${DB_DATABASE:?Missing DB_DATABASE in .env.docker}"
|
||||||
|
: "${DB_USERNAME:?Missing DB_USERNAME in .env.docker}"
|
||||||
|
: "${DB_PASSWORD:?Missing DB_PASSWORD in .env.docker}"
|
||||||
|
: "${DB_ROOT_PASSWORD:?Missing DB_ROOT_PASSWORD in .env.docker}"
|
||||||
|
TZ="${TZ:-UTC}"
|
||||||
|
|
||||||
|
# Clone repo if needed
|
||||||
|
if [[ ! -d "$APP_DIR" || -z "$(ls -A "$APP_DIR" 2>/dev/null || true)" ]]; then
|
||||||
|
echo "==> Cloning $GIT_URL into app/"
|
||||||
|
git clone "$GIT_URL" "$APP_DIR"
|
||||||
|
else
|
||||||
|
echo "==> app/ exists; skipping clone"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create/merge app .env
|
||||||
|
if [[ -f "$ENV_FILE" ]]; then
|
||||||
|
cp -a "$ENV_FILE" "$ENV_FILE.bak.$(date +%s)"
|
||||||
|
echo " - Existing .env backed up."
|
||||||
|
elif [[ -f "$ENV_TMPL" ]]; then
|
||||||
|
cp "$ENV_TMPL" "$ENV_FILE"
|
||||||
|
echo " - Created .env from env.example.txt"
|
||||||
|
else
|
||||||
|
touch "$ENV_FILE"
|
||||||
|
echo " - Created empty .env (env.example.txt not found)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Write DB + env for container network
|
||||||
|
upsert_kv "$ENV_FILE" "DB_HOST" "db"
|
||||||
|
upsert_kv "$ENV_FILE" "DB_PORT" "3306"
|
||||||
|
upsert_kv "$ENV_FILE" "DB_DATABASE" "$DB_DATABASE"
|
||||||
|
upsert_kv "$ENV_FILE" "DB_USERNAME" "$DB_USERNAME"
|
||||||
|
upsert_kv "$ENV_FILE" "DB_PASSWORD" "$DB_PASSWORD"
|
||||||
|
upsert_kv "$ENV_FILE" "APP_ENV" "${APP_ENV_DEFAULT}"
|
||||||
|
|
||||||
|
# --- PERMISSIONS using numeric IDs (works across host/container) ---
|
||||||
|
echo "==> Applying permissions with numeric IDs (root:${WWW_GID} for code; ${WWW_UID}:${WWW_GID} for writable dirs)"
|
||||||
|
mkdir -p "$APP_DIR/logs"
|
||||||
|
|
||||||
|
# Code owned by root, group = www-data (33)
|
||||||
|
chown -R ${ROOT_UID}:${WWW_GID} "$APP_DIR" || true
|
||||||
|
|
||||||
|
# Dirs 755, files 644
|
||||||
|
find "$APP_DIR" -type d -print0 | xargs -0 chmod 755
|
||||||
|
find "$APP_DIR" -type f -print0 | xargs -0 chmod 644
|
||||||
|
|
||||||
|
# Writable dirs for the app at runtime
|
||||||
|
for d in logs storage cache tmp runtime; do
|
||||||
|
if [ -d "$APP_DIR/$d" ]; then
|
||||||
|
echo " - Making $d writable by ${WWW_UID}:${WWW_GID}"
|
||||||
|
chown -R ${WWW_UID}:${WWW_GID} "$APP_DIR/$d"
|
||||||
|
chmod -R 775 "$APP_DIR/$d"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# .env readable by root & group only
|
||||||
|
chmod 640 "$APP_DIR/.env" || true
|
||||||
|
|
||||||
|
# Install vendors via Composer container
|
||||||
|
echo "==> Installing Composer vendors (composer:2) ..."
|
||||||
|
docker run --rm -v "$APP_DIR":/app -w /app composer:2 install --no-interaction --prefer-dist
|
||||||
|
|
||||||
|
# Bring stack up (build/rebuild)
|
||||||
|
echo "==> Starting stack ..."
|
||||||
|
dc up -d --build
|
||||||
|
|
||||||
|
echo "==> Done."
|
||||||
|
echo " App URL: http://<SERVER_IP>:8080"
|
||||||
|
echo " phpMyAdmin: http://<SERVER_IP>:8081 (Server: domain-monitor-mariadb)"
|
||||||
|
echo " Note: On the host, UID 33 may display as 'tape'; inside the container it's www-data. This is normal."
|
||||||
50
domain-monitor-docker/docker-compose.yml
Normal file
50
domain-monitor-docker/docker-compose.yml
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
services:
|
||||||
|
web:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: .docker/Dockerfile
|
||||||
|
container_name: domain-monitor-web
|
||||||
|
ports:
|
||||||
|
- "8080:80"
|
||||||
|
volumes:
|
||||||
|
- ./app:/var/www/html:Z
|
||||||
|
- ./.docker/php.ini:/usr/local/etc/php/conf.d/custom.ini:ro,Z
|
||||||
|
environment:
|
||||||
|
APACHE_DOCUMENT_ROOT: /var/www/html/public
|
||||||
|
TZ: ${TZ:-UTC}
|
||||||
|
depends_on:
|
||||||
|
- db
|
||||||
|
|
||||||
|
db:
|
||||||
|
image: mariadb:latest
|
||||||
|
container_name: domain-monitor-mariadb
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
MARIADB_DATABASE: ${DB_DATABASE}
|
||||||
|
MARIADB_USER: ${DB_USERNAME}
|
||||||
|
MARIADB_PASSWORD: ${DB_PASSWORD}
|
||||||
|
MARIADB_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
|
||||||
|
TZ: ${TZ:-UTC}
|
||||||
|
command: [
|
||||||
|
"--character-set-server=utf8mb4",
|
||||||
|
"--collation-server=utf8mb4_unicode_ci"
|
||||||
|
]
|
||||||
|
volumes:
|
||||||
|
- dbdata:/var/lib/mysql
|
||||||
|
|
||||||
|
pma:
|
||||||
|
image: phpmyadmin:latest
|
||||||
|
container_name: domain-monitor-pma
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
PMA_HOST: domain-monitor-mariadb
|
||||||
|
UPLOAD_LIMIT: 256M
|
||||||
|
TZ: ${TZ:-UTC}
|
||||||
|
ports:
|
||||||
|
- "8081:80"
|
||||||
|
depends_on:
|
||||||
|
- db
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
dbdata:
|
||||||
|
|
||||||
12
domain-monitor-docker/env.docker.example
Normal file
12
domain-monitor-docker/env.docker.example
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
# Example Docker environment file
|
||||||
|
# Copy this file to .env.docker and update your credentials
|
||||||
|
|
||||||
|
# === Database Configuration ===
|
||||||
|
DB_DATABASE=domain_monitor
|
||||||
|
DB_USERNAME=user_example
|
||||||
|
DB_PASSWORD=example_password
|
||||||
|
DB_ROOT_PASSWORD=example_root_password
|
||||||
|
|
||||||
|
# === Timezone (for PHP, MariaDB, phpMyAdmin) ===
|
||||||
|
TZ=UTC
|
||||||
|
|
||||||
Reference in New Issue
Block a user