20 changed files with 850 additions and 290 deletions
+24
View File
@@ -0,0 +1,24 @@
# 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
@@ -0,0 +1,26 @@
# 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
*~
+151 -1
View File
@@ -1,2 +1,152 @@
# Secure-OCF-Web-Hosting
# 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/)
BIN
View File
Binary file not shown.
-95
View File
@@ -1,95 +0,0 @@
# 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
@@ -1,28 +0,0 @@
# 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
@@ -1,20 +0,0 @@
# 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
@@ -1,96 +0,0 @@
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
@@ -1,2 +0,0 @@
Username: admin
Password: wp_graf_pass
@@ -1,29 +0,0 @@
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
@@ -1,19 +0,0 @@
<!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
@@ -0,0 +1,30 @@
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
@@ -0,0 +1,22 @@
# 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
@@ -0,0 +1,13 @@
<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
@@ -0,0 +1,58 @@
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
Executable
+371
View File
@@ -0,0 +1,371 @@
#!/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
@@ -0,0 +1,134 @@
#!/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
@@ -0,0 +1,3 @@
FROM wordpress:latest
# You can add themes/plugins or custom setup here
+18
View File
@@ -0,0 +1,18 @@
<?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');