Author SHA1 Message Date
coderNini f1d979640f Set up logging docker container, Grafana with Loki data source, and Grafana dashboard 2025-11-20 22:38:17 -08:00
nini.b-612 0e6ecf1f16 Update WordPress-Docker/docker-compose.yml
Added potential Grafana Loki installation code (commented it out for now just to be safe). Some changes can be made to the current commented out code, as recommended by ChatGPT.
2025-11-04 19:01:58 +00:00
20 changed files with 290 additions and 850 deletions
-24
View File
@@ -1,24 +0,0 @@
# Environment variables for OCF WordPress Hosting Platform
# Copy this file to .env and customize as needed
# Database Configuration
MYSQL_ROOT_PASSWORD=root_password_change_me
MYSQL_DATABASE=wp_master
MYSQL_USER=wp_user
MYSQL_PASSWORD=wp_password_change_me
# Apache Configuration
APACHE_HTTP_PORT=80
APACHE_HTTPS_PORT=443
# phpMyAdmin Configuration
PMA_PORT=8080
# WordPress Configuration (for user sites)
WORDPRESS_DB_HOST=db:3306
# Development vs Production
ENVIRONMENT=development
# Logging
LOG_LEVEL=info
-26
View File
@@ -1,26 +0,0 @@
# Ignore environment files with secrets
.env
# Docker volumes and user data
volumes/
# Backups
*.tar.gz
*.sql
db_backup_*.sql
backup_data*.tar.gz
# Logs
*.log
# macOS
.DS_Store
# IDE
.vscode/
.idea/
# Temporary files
*.tmp
*.swp
*~
+1 -151
View File
@@ -1,152 +1,2 @@
# Secure OCF-Style Multi-User WordPress Hosting Platform
A Docker-based hosting platform modeled after UC Berkeley's Open Computing Facility (OCF), enabling multiple users to host their own WordPress sites through a shared infrastructure with isolated volumes.
Each user volume contains:
- `site_conf/` - Apache vhost configuration
- `wordpress_content/` - WordPress files (themes, plugins, uploads)
- `database/` - SQL dumps and backups
## Quick Start
### 1. Build and Start Services
```bash
# Build and start all services
docker-compose up -d --build
# Check service status
docker-compose ps
# View logs
docker-compose logs -f apache
```
### 2. Access Your Test Site
Add this entry to `/etc/hosts` (or `C:\Windows\System32\drivers\etc\hosts` on Windows):
```
127.0.0.1 localhost testuser.local
```
Then visit:
- **Test Site**: http://localhost (shows PHP info)
- **phpMyAdmin**: http://localhost:8080 (user: `wp_user`, password: `wp_password`)
### 3. Register a New User
```bash
# Register a new user with their domain
./register_user.sh alice alice.local
# The script will:
# - Create volume structure
# - Download WordPress
# - Generate vhost configuration
# - Provide next steps
```
After running the script, you need to:
1. **Add the volume to `docker-compose.yml`**:
```yaml
volumes:
- ./volumes/data2-volume:/var/www/data2
```
2. **Restart Apache**:
```bash
docker-compose restart apache
```
3. **Add DNS entry to `/etc/hosts`**:
```
127.0.0.1 alice.local
```
4. **Visit the site**: http://alice.local
## 📁 Project Structure
```
Secure-OCF-Web-Hosting/
├── apache/
│ ├── Dockerfile # PHP 8.2 + Apache image
│ ├── conf/
│ │ └── httpd.conf # Main Apache config
│ └── vhost-templates/
│ └── user_vhost.template # Template for user sites
├── wordpress/
│ ├── Dockerfile # (Legacy - now Apache handles PHP)
│ └── wp-config.php # (Legacy)
├── volumes/
│ └── data1-volume/ # User volumes
│ ├── site_conf/
│ │ └── site.conf # User's Apache vhost
│ ├── wordpress_content/ # WordPress installation
│ └── database/ # SQL dumps
├── docker-compose.yml # Service orchestration
├── register_user.sh # User registration script
└── README.md # This file
```
## 🛠️ Management Commands
### Container Management
```bash
docker-compose up -d
docker-compose down
docker-compose restart apache
docker-compose logs -f [service_name]
docker-compose exec apache bash
```
### Database Management
```bash
docker-compose exec db mysql -u wp_user -p
docker-compose exec db mysqldump -u wp_user -p wp_master > backup.sql
docker-compose exec -T db mysql -u wp_user -p wp_master < backup.sql
```
### User Site Management
```bash
ls -la volumes/
docker-compose exec apache apachectl configtest
docker-compose exec apache apachectl graceful
docker-compose exec apache php -v
cat volumes/data1-volume/site_conf/error.log
```
## 📝 Environment Variables
Create a `.env` file for customization:
```env
# Database Configuration
MYSQL_ROOT_PASSWORD=your_secure_root_password
MYSQL_DATABASE=wp_master
MYSQL_USER=wp_user
MYSQL_PASSWORD=your_secure_password
# Apache Configuration
APACHE_HTTP_PORT=80
APACHE_HTTPS_PORT=443
# phpMyAdmin
PMA_PORT=8080
```
Then update `docker-compose.yml` to use these variables.
## 📚 Additional Resources
- [Docker Documentation](https://docs.docker.com/)
- [WordPress Codex](https://codex.wordpress.org/)
- [Apache HTTP Server Documentation](https://httpd.apache.org/docs/)
- [OCF Documentation](https://www.ocf.berkeley.edu/docs/)
# Secure-OCF-Web-Hosting
BIN
View File
Binary file not shown.
+95
View File
@@ -0,0 +1,95 @@
# WordPress Docker Setup
This repository provides a Dockerized environment for running WordPress locally using Docker Compose. It's designed for quick development and testing without complex installations.
## Architecture
- **Apache Server**: Single Apache container with `mod_userdir` enabled
- **User Data**: Shared volume containing student org home directories
- **WordPress**: Separate WordPress + MariaDB containers for testing
- **Structure**: Each org has `/home/<orgname>/public_html/` served at `http://localhost:8080/~<orgname>`
## 🚀 Quick Start
1. **Clone the repository:**
```bash
git clone https://git.1337.berkeley.edu/Committee/Secure-OCF-Web-Hosting.git
cd Secure-OCF-Web-Hosting/WordPress-Docker
```
2. **Install Docker Desktop:**
- [macOS](https://docs.docker.com/desktop/setup/install/mac-install/)
- [Windows](https://docs.docker.com/desktop/setup/install/windows-install/)
3. **Build and start the containers:**
```bash
docker-compose up -d
```
4. **Access WordPress:**
Open your browser and navigate to:
```
http://localhost:8081
```
Follow the on-screen instructions to complete the WordPress setup.
### Access sites:
- **Student org sites**:
- http://localhost:8080/~studentorg1
- http://localhost:8080/~studentorg2
- http://localhost:8080/~studentorg3
- **WordPress**: http://localhost:8081
### Add new student org:
```bash
docker exec -it ocf_apache_server bash
mkdir -p /home/neworg/public_html
echo "<h1>New Org</h1>" > /home/neworg/public_html/index.html
chown -R www-data:www-data /home/neworg
```
### View Apache logs:
```bash
docker logs ocf_apache_server
```
## ⚙️ Managing Containers
* **Start containers:**
```bash
docker-compose start
```
* **Stop containers:**
```bash
docker-compose stop
```
* **Stop and remove containers:**
```bash
docker-compose down
```
Add the `-v` flag to also remove volumes:
```bash
docker-compose down -v
```
## 🔐 Accessing phpMyAdmin
If phpMyAdmin is included in your setup:
* Open your browser and navigate to:
```
http://localhost:8081
```
Binary file not shown.
+28
View File
@@ -0,0 +1,28 @@
# Dockerfile (apache-static)
FROM httpd:2.4
LABEL maintainer="random@gmail.com"
# Enable required Apache modules for user directories and PHP
RUN sed -i \
-e 's/#LoadModule userdir_module/LoadModule userdir_module/' \
-e 's/#LoadModule vhost_alias_module/LoadModule vhost_alias_module/' \
-e 's/#LoadModule rewrite_module/LoadModule rewrite_module/' \
-e 's/#Include conf\/extra\/httpd-userdir.conf/Include conf\/extra\/httpd-userdir.conf/' \
/usr/local/apache2/conf/httpd.conf
# Add custom configuration for user directories
COPY httpd-userdir.conf /usr/local/apache2/conf/extra/httpd-userdir.conf
# Create example student org directories with basic content
RUN mkdir -p /home/studentorg1/public_html && \
echo "<h1>Welcome to Student Org 1's OCF Page</h1><p>This is a test page.</p>" > /home/studentorg1/public_html/index.html && \
mkdir -p /home/studentorg2/public_html && \
echo "<h1>Welcome to Student Org 2's OCF Page</h1><p>This is a test page.</p>" > /home/studentorg2/public_html/index.html && \
mkdir -p /home/studentorg3/public_html && \
echo "<h1>Welcome to Student Org 3's OCF Page</h1><p>This is a test page.</p>" > /home/studentorg3/public_html/index.html
# Set proper ownership
RUN chown -R www-data:www-data /home
EXPOSE 80
@@ -0,0 +1,20 @@
# Settings for user home directories
#
# Required module: mod_userdir
UserDir /home/*/public_html
#
# Control access to UserDir directories.
# Mimics OCF structure where user directories are in /home
#
<Directory "/home/*/public_html">
AllowOverride All
Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
Require all granted
# Allow .htaccess usage for student customization
<IfModule mod_rewrite.c>
RewriteEngine On
</IfModule>
</Directory>
+96
View File
@@ -0,0 +1,96 @@
version: '3.8'
services:
loki:
image: grafana/loki:3.0.0
container_name: loki
ports:
- "3100:3100"
command: -config.file=/etc/loki/local-config.yaml
restart: unless-stopped
grafana:
image: grafana/grafana:10.4.0
container_name: grafana
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=ocfsecure
depends_on:
- loki
restart: unless-stopped
alloy:
image: grafana/alloy:latest
container_name: alloy
volumes:
- ./alloy-config.yml:/etc/alloy/config.alloy
- ./logs:/var/log/scanner
ports:
- "12345:12345" # optional web UI/debug
command: run /etc/alloy/config.alloy
environment:
- ALLOY_ENABLE_WEB=true
depends_on:
- loki
restart: unless-stopped
apache:
build:
context: ./apache
ports:
- "8080:80"
networks:
- shared_net
- default
volumes:
- userdata:/home
depends_on:
- userdata
container_name: apache-static
restart: unless-stopped
userdata:
image: busybox
volumes:
- userdata:/home
container_name: user_data
command: /bin/true
db:
image: mariadb:11
container_name: wp_db
environment:
MYSQL_ROOT_PASSWORD: rootpass
MYSQL_DATABASE: wp_db
MYSQL_USER: wp_user
MYSQL_PASSWORD: wp_pass
volumes:
- db_data:/var/lib/mysql
restart: unless-stopped
wordpress:
image: wordpress:latest
container_name: wp_site
depends_on:
- db
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wp_user
WORDPRESS_DB_PASSWORD: wp_pass
WORDPRESS_DB_NAME: wp_db
ports:
- "8081:80" # WordPress site -> http://localhost:8081
volumes:
- wp_data:/var/www/html
restart: unless-stopped
volumes:
userdata:
db_data:
wp_data:
networks:
shared_net:
external: true
+2
View File
@@ -0,0 +1,2 @@
Username: admin
Password: wp_graf_pass
@@ -0,0 +1,29 @@
version: "3.8"
networks:
shared_net:
external: true
services:
loki:
image: grafana/loki:3.0.0
container_name: loki
ports:
- "3100:3100"
command: -config.file=/etc/loki/local-config.yaml
networks:
- shared_net
grafana:
image: grafana/grafana:10.4.0
container_name: grafana
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=admin
depends_on:
- loki
networks:
- shared_net
+19
View File
@@ -0,0 +1,19 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Local Apache Static Landing</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<style>
body { font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; background:#0f172a; color:#e6eef8; text-align:center; padding-top:8vh; }
h1 { color:#10b981; }
p { color:#cbd5e1; }
a { color:#93c5fd; text-decoration:none; }
</style>
</head>
<body>
<h1>Apache Static Host</h1>
<p>This is the static landing page container.</p>
<p><a href="http://localhost:8081/wp-admin" target="_blank">Open WordPress setup (wp-admin)</a></p>
</body>
</html>
-30
View File
@@ -1,30 +0,0 @@
FROM php:8.2-apache
# Install required PHP extensions for WordPress
RUN apt-get update && apt-get install -y \
libpng-dev \
libjpeg-dev \
libfreetype6-dev \
libzip-dev \
libicu-dev \
&& docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-install -j$(nproc) \
gd \
mysqli \
pdo_mysql \
zip \
intl \
opcache \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Enable Apache modules
RUN a2enmod rewrite headers expires
# Copy custom Apache configuration
COPY conf/httpd.conf /etc/apache2/sites-available/000-default.conf
# Set working directory
WORKDIR /var/www
EXPOSE 80
-22
View File
@@ -1,22 +0,0 @@
# Main Apache configuration for multi-user WordPress hosting
<VirtualHost *:80>
ServerAdmin admin@localhost
DocumentRoot /var/www
<Directory /var/www>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
<FilesMatch \.php$>
SetHandler application/x-httpd-php
</FilesMatch>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
# Include user site configs from each user volume
IncludeOptional /var/www/*/site_conf/site.conf
@@ -1,13 +0,0 @@
<VirtualHost *:80>
ServerName {USER_DOMAIN}
ServerAlias www.{USER_DOMAIN}
DocumentRoot /var/www/{USER_VOLUME}/wordpress_content
<Directory "/var/www/{USER_VOLUME}/wordpress_content">
AllowOverride All
Require all granted
</Directory>
ErrorLog /var/www/{USER_VOLUME}/site_conf/error.log
CustomLog /var/www/{USER_VOLUME}/site_conf/access.log combined
</VirtualHost>
-58
View File
@@ -1,58 +0,0 @@
version: "3.8"
services:
apache:
build:
context: ./apache
dockerfile: Dockerfile
ports:
- "80:80"
- "443:443"
volumes:
- wordpress_master:/var/www/master
# - ./volumes/data1-volume:/var/www/data1
# - ./volumes/data2-volume:/var/www/data2
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wp_user
WORDPRESS_DB_PASSWORD: wp_password
WORDPRESS_DB_NAME: wp_master
depends_on:
- db
restart: unless-stopped
networks:
- wordpress_network
db:
image: mariadb:latest
volumes:
- db_data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: root_password
MYSQL_DATABASE: wp_master
MYSQL_USER: wp_user
MYSQL_PASSWORD: wp_password
restart: unless-stopped
networks:
- wordpress_network
phpmyadmin:
image: phpmyadmin:latest
ports:
- "8080:80"
environment:
PMA_HOST: db
MYSQL_ROOT_PASSWORD: root_password
depends_on:
- db
restart: unless-stopped
networks:
- wordpress_network
volumes:
db_data:
wordpress_master:
networks:
wordpress_network:
driver: bridge
-371
View File
@@ -1,371 +0,0 @@
#!/usr/bin/env bash
# Helper script for managing the OCF-style WordPress hosting platform
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
print_header() {
echo -e "${BLUE}=========================================${NC}"
echo -e "${BLUE}$1${NC}"
echo -e "${BLUE}=========================================${NC}"
}
print_success() {
echo -e "${GREEN}✓ $1${NC}"
}
print_warning() {
echo -e "${YELLOW}⚠ $1${NC}"
}
print_error() {
echo -e "${RED}✗ $1${NC}"
}
# Help function
show_help() {
cat << EOF
OCF WordPress Hosting Manager
Usage: ./manage.sh [command]
Commands:
start Build and start all services
stop Stop all services
restart Restart all services
status Show status of all services
logs [service] Show logs (optionally for specific service)
user-add Register a new user
user-list List all registered users
user-remove Remove a user (with backup)
db-backup Backup the database
db-restore Restore database from backup
db-shell Open database shell
test-php Test PHP functionality
test-db Test database connectivity
clean Stop and remove all containers, volumes, and networks
clean-all Clean everything including user data (DANGEROUS!)
help Show this help message
Examples:
./manage.sh start
./manage.sh user-add
./manage.sh logs apache
./manage.sh db-backup
EOF
}
# Start services
cmd_start() {
print_header "Starting Services"
docker-compose up -d --build
print_success "Services started"
echo ""
cmd_status
}
# Stop services
cmd_stop() {
print_header "Stopping Services"
docker-compose down
print_success "Services stopped"
}
# Restart services
cmd_restart() {
print_header "Restarting Services"
docker-compose restart
print_success "Services restarted"
}
# Show status
cmd_status() {
print_header "Service Status"
docker-compose ps
echo ""
echo "Access URLs:"
echo " • Test Site: http://localhost"
echo " • phpMyAdmin: http://localhost:8080"
}
# Show logs
cmd_logs() {
local service=${1:-""}
if [ -n "$service" ]; then
docker-compose logs -f "$service"
else
docker-compose logs -f
fi
}
# Add new user
cmd_user_add() {
print_header "Register New User"
read -p "Enter username: " username
read -p "Enter domain (e.g., alice.local): " domain
if [ -z "$username" ] || [ -z "$domain" ]; then
print_error "Username and domain are required"
exit 1
fi
./register_user.sh "$username" "$domain"
echo ""
print_warning "Don't forget to:"
echo " 1. Add volume to docker-compose.yml"
echo " 2. Run: ./manage.sh restart"
echo " 3. Add '$domain' to /etc/hosts pointing to 127.0.0.1"
}
# List users
cmd_user_list() {
print_header "Registered Users"
if [ ! -d "./volumes" ] || [ -z "$(ls -A ./volumes 2>/dev/null)" ]; then
print_warning "No users registered yet"
return
fi
echo -e "${BLUE}Volume\t\t\tDomain${NC}"
echo "----------------------------------------"
for vol_dir in ./volumes/*/; do
if [ -d "$vol_dir" ]; then
vol_name=$(basename "$vol_dir")
conf_file="${vol_dir}site_conf/site.conf"
if [ -f "$conf_file" ]; then
domain=$(grep "ServerName" "$conf_file" | awk '{print $2}')
echo -e "${vol_name}\t\t${domain}"
fi
fi
done
}
# Remove user
cmd_user_remove() {
print_header "Remove User"
cmd_user_list
echo ""
read -p "Enter volume name to remove (e.g., data1-volume): " vol_name
if [ -z "$vol_name" ]; then
print_error "Volume name required"
exit 1
fi
vol_path="./volumes/${vol_name}"
if [ ! -d "$vol_path" ]; then
print_error "Volume not found: $vol_path"
exit 1
fi
print_warning "This will backup and remove: $vol_path"
read -p "Are you sure? (yes/no): " confirm
if [ "$confirm" != "yes" ]; then
print_warning "Cancelled"
exit 0
fi
# Create backup
backup_name="backup_${vol_name}_$(date +%Y%m%d_%H%M%S).tar.gz"
tar -czf "$backup_name" "$vol_path"
print_success "Backup created: $backup_name"
# Remove volume
rm -rf "$vol_path"
print_success "Volume removed: $vol_path"
print_warning "Remember to remove the volume mount from docker-compose.yml"
}
# Database backup
cmd_db_backup() {
print_header "Database Backup"
backup_file="db_backup_$(date +%Y%m%d_%H%M%S).sql"
docker-compose exec -T db mysqldump -u wp_user -pwp_password wp_master > "$backup_file"
print_success "Database backed up to: $backup_file"
}
# Database restore
cmd_db_restore() {
print_header "Database Restore"
# List available backups
echo "Available backups:"
ls -1 db_backup_*.sql 2>/dev/null || print_warning "No backups found"
echo ""
read -p "Enter backup file name: " backup_file
if [ ! -f "$backup_file" ]; then
print_error "Backup file not found: $backup_file"
exit 1
fi
print_warning "This will restore database from: $backup_file"
read -p "Are you sure? (yes/no): " confirm
if [ "$confirm" != "yes" ]; then
print_warning "Cancelled"
exit 0
fi
docker-compose exec -T db mysql -u wp_user -pwp_password wp_master < "$backup_file"
print_success "Database restored from: $backup_file"
}
# Database shell
cmd_db_shell() {
print_header "Database Shell"
echo "Connecting to MariaDB..."
docker-compose exec db mysql -u wp_user -pwp_password wp_master
}
# Test PHP
cmd_test_php() {
print_header "Testing PHP"
if ! docker-compose ps | grep -q apache.*Up; then
print_error "Apache container is not running"
exit 1
fi
echo "Testing PHP version..."
docker-compose exec apache php -v
echo ""
echo "Testing PHP extensions..."
docker-compose exec apache php -m | grep -E "(mysqli|gd|zip)"
echo ""
print_success "PHP is working correctly"
}
# Test database
cmd_test_db() {
print_header "Testing Database Connection"
if ! docker-compose ps | grep -q db.*Up; then
print_error "Database container is not running"
exit 1
fi
result=$(docker-compose exec -T apache php -r "echo mysqli_connect('db', 'wp_user', 'wp_password', 'wp_master') ? 'success' : 'failed';")
if [ "$result" = "success" ]; then
print_success "Database connection successful"
else
print_error "Database connection failed"
exit 1
fi
}
# Clean containers
cmd_clean() {
print_header "Cleaning Containers"
print_warning "This will stop and remove containers, networks, and anonymous volumes"
read -p "Are you sure? (yes/no): " confirm
if [ "$confirm" != "yes" ]; then
print_warning "Cancelled"
exit 0
fi
docker-compose down -v
print_success "Cleaned up containers and volumes"
}
# Clean everything
cmd_clean_all() {
print_header "DANGER: Clean Everything"
print_error "This will remove ALL containers, volumes, AND user data"
print_error "This action CANNOT be undone!"
read -p "Type 'DELETE EVERYTHING' to confirm: " confirm
if [ "$confirm" != "DELETE EVERYTHING" ]; then
print_warning "Cancelled"
exit 0
fi
docker-compose down -v
rm -rf ./volumes/*
print_success "Everything cleaned"
}
# Main command router
case "${1:-help}" in
start)
cmd_start
;;
stop)
cmd_stop
;;
restart)
cmd_restart
;;
status)
cmd_status
;;
logs)
cmd_logs "$2"
;;
user-add)
cmd_user_add
;;
user-list)
cmd_user_list
;;
user-remove)
cmd_user_remove
;;
db-backup)
cmd_db_backup
;;
db-restore)
cmd_db_restore
;;
db-shell)
cmd_db_shell
;;
test-php)
cmd_test_php
;;
test-db)
cmd_test_db
;;
clean)
cmd_clean
;;
clean-all)
cmd_clean_all
;;
help|--help|-h)
show_help
;;
*)
print_error "Unknown command: $1"
echo ""
show_help
exit 1
;;
esac
-134
View File
@@ -1,134 +0,0 @@
#!/usr/bin/env bash
# Usage: ./register_user.sh USER_NAME USER_DOMAIN
# Example: ./register_user.sh alice alice.example.com
set -e
USER_NAME="$1"
USER_DOMAIN="$2"
if [ -z "$USER_NAME" ] || [ -z "$USER_DOMAIN" ]; then
echo "Usage: $0 USER_NAME USER_DOMAIN"
echo "Example: $0 alice alice.example.com"
exit 1
fi
# Get script directory
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"
# Create volumes directory if it doesn't exist
mkdir -p ./volumes
# Decide next data folder number
if [ -d "./volumes" ] && [ "$(ls -A ./volumes)" ]; then
NEXT_INDEX=$(ls -1d volumes/data* 2>/dev/null | wc -l)
NEXT_INDEX=$((NEXT_INDEX + 1))
else
NEXT_INDEX=1
fi
USER_VOLUME="data${NEXT_INDEX}"
VOLUME_DIR="./volumes/${USER_VOLUME}-volume"
echo "========================================="
echo "Creating new user site:"
echo " User: ${USER_NAME}"
echo " Domain: ${USER_DOMAIN}"
echo " Volume: ${USER_VOLUME}"
echo "========================================="
# Create volume directory structure
mkdir -p "${VOLUME_DIR}/site_conf"
mkdir -p "${VOLUME_DIR}/wordpress_content"
mkdir -p "${VOLUME_DIR}/database"
# Copy vhost template and replace placeholders
TEMPLATE_FILE="./apache/vhost-templates/user_vhost.template"
TARGET_CONF="${VOLUME_DIR}/site_conf/site.conf"
if [ ! -f "$TEMPLATE_FILE" ]; then
echo "ERROR: Template file not found: $TEMPLATE_FILE"
exit 1
fi
sed \
-e "s/{USER_DOMAIN}/${USER_DOMAIN}/g" \
-e "s/{USER_VOLUME}/${USER_VOLUME}/g" \
"${TEMPLATE_FILE}" > "${TARGET_CONF}"
echo "✓ Created site configuration at ${TARGET_CONF}"
# Download WordPress into the user's content directory
echo "Downloading WordPress..."
cd "${VOLUME_DIR}/wordpress_content"
curl -O https://wordpress.org/latest.tar.gz
tar -xzf latest.tar.gz --strip-components=1
rm latest.tar.gz
# Create wp-config.php with database connection
cat > wp-config.php << 'EOF'
<?php
define('DB_NAME', getenv('WORDPRESS_DB_NAME') ?: 'wp_master');
define('DB_USER', getenv('WORDPRESS_DB_USER') ?: 'wp_user');
define('DB_PASSWORD', getenv('WORDPRESS_DB_PASSWORD') ?: 'wp_password');
define('DB_HOST', getenv('WORDPRESS_DB_HOST') ?: 'db:3306');
define('DB_CHARSET', 'utf8mb4');
define('DB_COLLATE', '');
// Unique keys and salts (generate from https://api.wordpress.org/secret-key/1.1/salt/)
define('AUTH_KEY', 'put your unique phrase here');
define('SECURE_AUTH_KEY', 'put your unique phrase here');
define('LOGGED_IN_KEY', 'put your unique phrase here');
define('NONCE_KEY', 'put your unique phrase here');
define('AUTH_SALT', 'put your unique phrase here');
define('SECURE_AUTH_SALT', 'put your unique phrase here');
define('LOGGED_IN_SALT', 'put your unique phrase here');
define('NONCE_SALT', 'put your unique phrase here');
$table_prefix = 'wp_';
define('WP_DEBUG', false);
if ( !defined('ABSPATH') )
define('ABSPATH', dirname(__FILE__) . '/');
require_once(ABSPATH . 'wp-settings.php');
EOF
cd "$SCRIPT_DIR"
echo "✓ WordPress installed to ${VOLUME_DIR}/wordpress_content"
# Create initial database dump placeholder
cat > "${VOLUME_DIR}/database/README.md" << EOF
# Database Directory for ${USER_NAME}
This directory can contain:
- SQL dump files for backup/restore
- Database migration scripts
- User-specific database notes
The WordPress installation uses the shared database defined in docker-compose.yml.
Each user site should use a unique table prefix in wp-config.php.
EOF
echo "✓ Created database directory with README"
echo ""
echo "========================================="
echo "✓ User ${USER_NAME} registered successfully!"
echo "========================================="
echo ""
echo "Next steps:"
echo "1. Add this volume mount to docker-compose.yml:"
echo " - ./volumes/${USER_VOLUME}-volume:/var/www/${USER_VOLUME}"
echo ""
echo "2. Restart the Apache container:"
echo " docker-compose restart apache"
echo ""
echo "3. Add DNS/hosts entry for ${USER_DOMAIN} pointing to your server"
echo ""
echo "4. Visit http://${USER_DOMAIN} to complete WordPress setup"
echo ""
-3
View File
@@ -1,3 +0,0 @@
FROM wordpress:latest
# You can add themes/plugins or custom setup here
-18
View File
@@ -1,18 +0,0 @@
<?php
// Basic WordPress config example
define('DB_NAME', getenv('WORDPRESS_DB_NAME'));
define('DB_USER', getenv('WORDPRESS_DB_USER'));
define('DB_PASSWORD', getenv('WORDPRESS_DB_PASSWORD'));
define('DB_HOST', getenv('WORDPRESS_DB_HOST'));
define('DB_CHARSET', 'utf8');
define('DB_COLLATE', '');
$table_prefix = 'wp_';
define('WP_DEBUG', false);
if ( !defined('ABSPATH') )
define('ABSPATH', dirname(__FILE__) . '/');
require_once(ABSPATH . 'wp-settings.php');