v0.0.3 published

This commit is contained in:
2025-06-02 11:27:10 +08:00
commit dca4f11e0d
61 changed files with 16453 additions and 0 deletions

650
dev/Dockerfile_v0.0.4 Normal file
View File

@@ -0,0 +1,650 @@
# Hexo Blog Container v0.0.4 - Enhanced Production Version
#
# This version includes optimizations based on v0.0.3-fixed testing results:
# - Improved layer caching for faster rebuilds
# - Enhanced security configurations
# - Better resource management
# - Optional SSL support preparation
# - Monitoring improvements
#
# Author: AI Assistant
# Version: 0.0.4
# Date: 2025-05-29
# ---- Build Arguments ----
ARG UBUNTU_VERSION=22.04
ARG TZ=Asia/Shanghai
ARG PUID=1000
ARG PGID=1000
ARG NGINX_VERSION=1.18.0
# ---- Stage 1: Base Dependencies ----
FROM ubuntu:${UBUNTU_VERSION} AS base
ARG TZ
ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=${TZ}
ENV LANG=zh_CN.UTF-8
# Configure timezone first (improves caching)
RUN ln -sf /usr/share/zoneinfo/$TZ /etc/localtime && \
echo $TZ > /etc/timezone
# Configure optimized Chinese mirrors for enhanced reliability
RUN cp /etc/apt/sources.list /etc/apt/sources.list.backup && \
printf '%s\n' \
'# Optimized Tsinghua University mirror sources with fallback' \
'deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy main restricted universe multiverse' \
'deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-updates main restricted universe multiverse' \
'deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-backports main restricted universe multiverse' \
'deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-security main restricted universe multiverse' \
'# Fallback to official sources' \
'# deb http://archive.ubuntu.com/ubuntu/ jammy main restricted universe multiverse' \
> /etc/apt/sources.list
# Install base system packages with enhanced retry mechanism
RUN for i in 1 2 3; do \
echo "Base packages attempt $i..." && \
apt-get clean && \
apt-get update --fix-missing && \
apt-get install -y --no-install-recommends --fix-missing \
ca-certificates \
curl \
wget \
gnupg \
lsb-release && \
echo "Base packages installation successful" && \
break || { \
echo "Attempt $i failed, waiting 10 seconds..."; \
sleep 10; \
}; \
done
# ---- Stage 2: Runtime Dependencies ----
FROM base AS runtime-deps
# Install runtime packages in optimized order (most stable first)
RUN for i in 1 2 3; do \
echo "Runtime packages attempt $i..." && \
apt-get update --fix-missing && \
apt-get install -y --no-install-recommends --fix-missing \
# Core system
locales \
tzdata \
# Git and SSH
git \
openssh-server \
# Web server
nginx-full \
# Utilities
gettext-base \
supervisor \
logrotate \
# Monitoring tools
htop \
iotop \
# Security tools
fail2ban && \
echo "Runtime packages installation successful" && \
break || { \
echo "Runtime attempt $i failed, waiting 15 seconds..."; \
sleep 15; \
}; \
done && \
# Configure locale
sed -i 's/# zh_CN.UTF-8 UTF-8/zh_CN.UTF-8 UTF-8/' /etc/locale.gen && \
locale-gen && \
update-locale LANG=zh_CN.UTF-8 && \
# Clean up
apt-get autoremove -y && \
apt-get autoclean && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
# ---- Stage 3: Configuration Builder ----
FROM runtime-deps AS config-builder
# Create directory structure
RUN mkdir -p /etc/container/{templates,ssl,monitoring} && \
mkdir -p /app/scripts && \
mkdir -p /home/hexo && \
mkdir -p /var/log/container && \
mkdir -p /backup
# Create enhanced Git repository with improved hooks
RUN git init --bare /home/hexo/hexo.git && \
git config --global init.defaultBranch main
# Create enhanced post-receive hook with better error handling and monitoring
RUN printf '%s\n' \
'#!/bin/bash' \
'set -euo pipefail' \
'' \
'# Enhanced post-receive hook with monitoring and error recovery' \
'# Version: 0.0.4 - Production ready with enhanced logging' \
'' \
'readonly LOG_FILE="/var/log/container/deployment.log"' \
'readonly DEPLOY_TIME=$(date "+%%Y-%%m-%%d %%H:%%M:%%S")' \
'readonly TARGET_DIR="/home/www/hexo"' \
'readonly BACKUP_DIR="/backup/auto"' \
'' \
'log_deploy() {' \
' local message="[$DEPLOY_TIME] $*"' \
' echo "$message"' \
' if [[ -w "/var/log/container" ]] || [[ -w "$LOG_FILE" ]]; then' \
' echo "$message" >> "$LOG_FILE"' \
' fi' \
' # Send to syslog for monitoring' \
' logger -t "hexo-deploy" "$message"' \
'}' \
'' \
'create_backup() {' \
' if [[ -d "$TARGET_DIR" ]] && [[ "$(ls -A "$TARGET_DIR")" ]]; then' \
' mkdir -p "$BACKUP_DIR"' \
' local backup_name="backup-$(date +%%Y%%m%%d-%%H%%M%%S)"' \
' tar -czf "$BACKUP_DIR/$backup_name.tar.gz" -C "$TARGET_DIR" . 2>/dev/null || true' \
' # Keep only last 5 backups' \
' ls -t "$BACKUP_DIR"/backup-*.tar.gz 2>/dev/null | tail -n +6 | xargs -r rm -f' \
' log_deploy "[BACKUP] Created: $backup_name.tar.gz"' \
' fi' \
'}' \
'' \
'rollback_on_error() {' \
' log_deploy "[ERROR] Deployment failed, attempting rollback..."' \
' local latest_backup=$(ls -t "$BACKUP_DIR"/backup-*.tar.gz 2>/dev/null | head -n1)' \
' if [[ -n "$latest_backup" ]]; then' \
' rm -rf "$TARGET_DIR"/* 2>/dev/null || true' \
' tar -xzf "$latest_backup" -C "$TARGET_DIR" 2>/dev/null && \
' log_deploy "[ROLLBACK] Restored from: $(basename "$latest_backup")" || \
' log_deploy "[ROLLBACK] Failed to restore backup"' \
' fi' \
'}' \
'' \
'# Main deployment process' \
'trap rollback_on_error ERR' \
'' \
'log_deploy "=== Git Push Deployment Started ==="' \
'' \
'# Create backup before deployment' \
'create_backup' \
'' \
'# Ensure target directory exists' \
'mkdir -p "$TARGET_DIR"' \
'log_deploy "Target directory prepared: $TARGET_DIR"' \
'' \
'# Checkout files' \
'if git --git-dir=/home/hexo/hexo.git --work-tree="$TARGET_DIR" checkout -f; then' \
' log_deploy "[SUCCESS] Files checked out successfully"' \
'else' \
' log_deploy "[FAIL] Failed to checkout files"' \
' exit 1' \
'fi' \
'' \
'# Set proper ownership and permissions' \
'chown -R hexo:hexo "$TARGET_DIR" 2>/dev/null || true' \
'find "$TARGET_DIR" -type f -exec chmod 644 {} \\;' \
'find "$TARGET_DIR" -type d -exec chmod 755 {} \\;' \
'log_deploy "[SUCCESS] Permissions updated"' \
'' \
'# Check for special files and handle them' \
'if [[ -f "$TARGET_DIR/nginx.conf" ]]; then' \
' log_deploy "[CONFIG] Custom nginx.conf detected - reload required"' \
' touch /tmp/nginx-reload-required' \
'fi' \
'' \
'if [[ -f "$TARGET_DIR/.env" ]]; then' \
' log_deploy "[CONFIG] Environment file detected"' \
' chmod 600 "$TARGET_DIR/.env"' \
'fi' \
'' \
'# Update deployment timestamp' \
'echo "$DEPLOY_TIME" > "$TARGET_DIR/.deployment-timestamp"' \
'' \
'log_deploy "=== Git Push Deployment Completed Successfully ==="' \
'log_deploy "Files deployed: $(find "$TARGET_DIR" -type f | wc -l)"' \
'log_deploy ""' > /home/hexo/hexo.git/hooks/post-receive
RUN chmod +x /home/hexo/hexo.git/hooks/post-receive
# Create enhanced SSH configuration with fail2ban integration
RUN printf '%s\n' \
'# Enhanced SSH Configuration for Hexo Blog Container v0.0.4' \
'# Production-ready with security hardening and monitoring' \
'Port 22' \
'ListenAddress 0.0.0.0' \
'ListenAddress ::' \
'' \
'# Protocol and Authentication' \
'Protocol 2' \
'PermitRootLogin no' \
'PasswordAuthentication no' \
'PubkeyAuthentication yes' \
'AuthorizedKeysFile .ssh/authorized_keys' \
'PermitEmptyPasswords no' \
'ChallengeResponseAuthentication no' \
'' \
'# Security Settings' \
'MaxAuthTries 3' \
'MaxSessions 5' \
'MaxStartups 2:30:10' \
'LoginGraceTime 30' \
'ClientAliveInterval 300' \
'ClientAliveCountMax 2' \
'' \
'# Access Control' \
'AllowUsers hexo' \
'DenyUsers root' \
'DenyGroups root' \
'' \
'# Features' \
'X11Forwarding no' \
'AllowTcpForwarding yes' \
'GatewayPorts no' \
'PermitTunnel no' \
'UsePAM yes' \
'PrintMotd no' \
'TCPKeepAlive yes' \
'' \
'# Logging and Monitoring' \
'SyslogFacility AUTH' \
'LogLevel VERBOSE' \
'' \
'# File transfer' \
'Subsystem sftp internal-sftp' \
'' \
'# Banner' \
'Banner /etc/ssh/banner.txt' > /etc/container/templates/sshd_config.template
# Create SSH banner
RUN printf '%s\n' \
'*****************************************************' \
'* Hexo Blog Docker Container - Authorized Access *' \
'* Version: 0.0.4 - Production Environment *' \
'* Monitoring: Active | Logging: Enabled *' \
'*****************************************************' \
'' > /etc/container/templates/banner.txt
# Create enhanced Nginx configuration with performance optimizations
RUN printf '%s\n' \
'# Enhanced Nginx Configuration for Hexo Blog Container v0.0.4' \
'# Optimized for performance, security, and monitoring' \
'' \
'user hexo;' \
'worker_processes auto;' \
'worker_rlimit_nofile 65535;' \
'pid /var/run/nginx.pid;' \
'' \
'events {' \
' worker_connections 4096;' \
' use epoll;' \
' multi_accept on;' \
' accept_mutex off;' \
'}' \
'' \
'http {' \
' # Basic Settings' \
' sendfile on;' \
' tcp_nopush on;' \
' tcp_nodelay on;' \
' keepalive_timeout 65;' \
' keepalive_requests 1000;' \
' reset_timedout_connection on;' \
' types_hash_max_size 2048;' \
' server_tokens off;' \
' client_max_body_size 10m;' \
' client_body_buffer_size 128k;' \
' client_header_buffer_size 1k;' \
' large_client_header_buffers 4 8k;' \
' client_body_timeout 12;' \
' client_header_timeout 12;' \
' send_timeout 10;' \
' ' \
' # MIME' \
' include /etc/nginx/mime.types;' \
' default_type application/octet-stream;' \
' ' \
' # Logging Format' \
' log_format main '\''$remote_addr - $remote_user [$time_local] "$request" '\'' \
' '\''$status $body_bytes_sent "$http_referer" '\'' \
' '\''"$http_user_agent" "$http_x_forwarded_for"'\'';' \
' ' \
' log_format detailed '\''$remote_addr - $remote_user [$time_local] '\'' \
' '\''"$request" $status $body_bytes_sent '\'' \
' '\''"$http_referer" "$http_user_agent" '\'' \
' '\''rt=$request_time uct="$upstream_connect_time" '\'' \
' '\''uht="$upstream_header_time" urt="$upstream_response_time"'\'';' \
' ' \
' access_log /var/log/nginx/access.log main;' \
' error_log /var/log/nginx/error.log warn;' \
' ' \
' # Gzip Compression' \
' gzip on;' \
' gzip_vary on;' \
' gzip_min_length 1000;' \
' gzip_proxied any;' \
' gzip_comp_level 6;' \
' gzip_types' \
' application/atom+xml' \
' application/geo+json' \
' application/javascript' \
' application/x-javascript' \
' application/json' \
' application/ld+json' \
' application/manifest+json' \
' application/rdf+xml' \
' application/rss+xml' \
' application/xhtml+xml' \
' application/xml' \
' font/eot' \
' font/otf' \
' font/ttf' \
' image/svg+xml' \
' text/css' \
' text/javascript' \
' text/plain' \
' text/xml;' \
' ' \
' # Security Headers' \
' add_header X-Frame-Options "SAMEORIGIN" always;' \
' add_header X-Content-Type-Options "nosniff" always;' \
' add_header X-XSS-Protection "1; mode=block" always;' \
' add_header Referrer-Policy "strict-origin-when-cross-origin" always;' \
' add_header Content-Security-Policy "default-src '\''self'\''; script-src '\''self'\''; style-src '\''self'\'' '\''unsafe-inline'\''; img-src '\''self'\'' data: https:; font-src '\''self'\''; connect-src '\''self'\''; frame-ancestors '\''self'\''" always;' \
' ' \
' # Rate Limiting' \
' limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;' \
' limit_req_zone $binary_remote_addr zone=strict:10m rate=2r/s;' \
' ' \
' # Cache for static assets' \
' map $sent_http_content_type $expires {' \
' default off;' \
' text/html 1h;' \
' text/css 1y;' \
' application/javascript 1y;' \
' ~image/ 1y;' \
' ~font/ 1y;' \
' }' \
' ' \
' expires $expires;' \
' ' \
' # Main server block' \
' server {' \
' listen 80 default_server;' \
' listen [::]:80 default_server;' \
' server_name _;' \
' root /home/www/hexo;' \
' index index.html index.htm;' \
' ' \
' # Rate limiting for general requests' \
' limit_req zone=general burst=20 nodelay;' \
' ' \
' # Health check endpoint (no rate limiting)' \
' location = /health {' \
' access_log off;' \
' return 200 "healthy\\n";' \
' add_header Content-Type text/plain;' \
' add_header X-Health-Check "ok";' \
' }' \
' ' \
' # Monitoring endpoint (restricted)' \
' location = /status {' \
' limit_req zone=strict burst=5;' \
' access_log off;' \
' return 200 "{\\"status\\":\\"ok\\",\\"version\\":\\"0.0.4\\",\\"timestamp\\":\\"$(date -Iseconds)\\"}\\n";' \
' add_header Content-Type application/json;' \
' }' \
' ' \
' # Main content location' \
' location / {' \
' try_files $uri $uri/ /index.html;' \
' ' \
' # Cache control for HTML files' \
' location ~* \\.html$ {' \
' add_header Cache-Control "public, no-cache, must-revalidate";' \
' }' \
' }' \
' ' \
' # Static assets with aggressive caching' \
' location ~* \\.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {' \
' expires 1y;' \
' add_header Cache-Control "public, immutable";' \
' add_header Vary "Accept-Encoding";' \
' ' \
' # Optional: serve pre-compressed files' \
' location ~* \\.(css|js)$ {' \
' gzip_static on;' \
' }' \
' }' \
' ' \
' # Security - Block hidden files and sensitive files' \
' location ~ /\\. {' \
' deny all;' \
' access_log off;' \
' log_not_found off;' \
' }' \
' ' \
' location ~* \\.(sql|log|env|config)$ {' \
' deny all;' \
' access_log off;' \
' log_not_found off;' \
' }' \
' ' \
' # Block unwanted bots' \
' location ~* (wp-admin|wp-login|xmlrpc|admin|login) {' \
' deny all;' \
' access_log off;' \
' log_not_found off;' \
' }' \
' ' \
' # Custom error pages' \
' error_page 404 /404.html;' \
' error_page 500 502 503 504 /50x.html;' \
' ' \
' location = /404.html {' \
' internal;' \
' }' \
' ' \
' location = /50x.html {' \
' internal;' \
' }' \
' }' \
'}' > /etc/container/templates/nginx.conf.template
# Create Supervisor configuration for process management
RUN printf '%s\n' \
'[supervisord]' \
'nodaemon=true' \
'pidfile=/var/run/supervisord.pid' \
'logfile=/var/log/container/supervisord.log' \
'logfile_maxbytes=50MB' \
'logfile_backups=10' \
'loglevel=info' \
'' \
'[program:sshd]' \
'command=/usr/sbin/sshd -D' \
'autostart=true' \
'autorestart=true' \
'stderr_logfile=/var/log/container/sshd.err.log' \
'stdout_logfile=/var/log/container/sshd.out.log' \
'user=root' \
'' \
'[program:nginx]' \
'command=nginx -g "daemon off;"' \
'autostart=true' \
'autorestart=true' \
'stderr_logfile=/var/log/container/nginx.err.log' \
'stdout_logfile=/var/log/container/nginx.out.log' \
'user=root' \
'' \
'[program:log-rotator]' \
'command=/app/scripts/log-rotator.sh' \
'autostart=true' \
'autorestart=true' \
'stderr_logfile=/var/log/container/log-rotator.err.log' \
'stdout_logfile=/var/log/container/log-rotator.out.log' \
'user=root' > /etc/container/templates/supervisord.conf.template
# Copy start script
COPY start.sh /app/start.sh
# ---- Stage 4: Production Runtime ----
FROM config-builder AS production
ARG PUID
ARG PGID
ENV PUID=${PUID}
ENV PGID=${PGID}
ENV SUPERVISOR_ENABLED=true
# Copy configuration templates and scripts
COPY --from=config-builder /etc/container/templates /etc/container/templates/
COPY --from=config-builder /home/hexo/hexo.git /home/hexo/hexo.git
# Create enhanced startup scripts
RUN printf '%s\n' \
'#!/bin/bash' \
'# Log rotation script for Hexo Blog Container' \
'set -euo pipefail' \
'' \
'while true; do' \
' # Rotate deployment logs' \
' if [[ -f "/var/log/container/deployment.log" ]] && [[ $(stat -f "%%z" "/var/log/container/deployment.log" 2>/dev/null || stat -c "%%s" "/var/log/container/deployment.log") -gt 10485760 ]]; then' \
' mv "/var/log/container/deployment.log" "/var/log/container/deployment.log.$(date +%%Y%%m%%d-%%H%%M%%S)"' \
' touch "/var/log/container/deployment.log"' \
' chown hexo:hexo "/var/log/container/deployment.log"' \
' # Keep only last 5 log files' \
' ls -t /var/log/container/deployment.log.* 2>/dev/null | tail -n +6 | xargs -r rm -f' \
' fi' \
' ' \
' # Sleep for 1 hour' \
' sleep 3600' \
'done' > /app/scripts/log-rotator.sh
RUN chmod +x /app/scripts/log-rotator.sh
# Create hexo user with proper UID/GID
RUN groupadd -g ${PGID} hexo && \
useradd -r -u ${PUID} -g hexo -d /home/hexo -s /bin/bash hexo && \
mkdir -p /home/hexo/.ssh && \
mkdir -p /home/www/hexo && \
chown -R hexo:hexo /home/hexo && \
chown -R hexo:hexo /home/www/hexo
# Set up logging and permissions
RUN mkdir -p /var/run/sshd && \
chmod +x /app/start.sh && \
chmod +x /home/hexo/hexo.git/hooks/post-receive && \
mkdir -p /var/log/container && \
chown hexo:hexo /var/log/container && \
chmod 755 /var/log/container && \
mkdir -p /backup/auto && \
chown hexo:hexo /backup && \
chmod 755 /backup
# Configure SSH with enhanced security
RUN mkdir -p /root/.ssh && \
chmod 700 /root/.ssh
# Remove default nginx configurations to prevent conflicts
RUN rm -f /etc/nginx/sites-enabled/default && \
rm -f /etc/nginx/sites-available/default && \
rm -f /etc/nginx/conf.d/default.conf
# Configure fail2ban for SSH protection
RUN printf '%s\n' \
'[sshd]' \
'enabled = true' \
'port = ssh' \
'filter = sshd' \
'logpath = /var/log/auth.log' \
'maxretry = 3' \
'bantime = 3600' \
'findtime = 600' > /etc/fail2ban/jail.local
# Create default index page with version info
RUN printf '%s\n' \
'<!DOCTYPE html>' \
'<html lang="zh-CN">' \
'<head>' \
' <meta charset="UTF-8">' \
' <meta name="viewport" content="width=device-width, initial-scale=1.0">' \
' <title>Hexo Blog Docker v0.0.4</title>' \
' <style>' \
' body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; margin: 0; padding: 40px; background: linear-gradient(135deg, #667eea 0%%, #764ba2 100%%); color: white; }' \
' .container { max-width: 800px; margin: 0 auto; text-align: center; }' \
' .header { margin-bottom: 40px; }' \
' .version { background: rgba(255,255,255,0.1); padding: 20px; border-radius: 10px; margin: 20px 0; }' \
' .features { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 20px; margin: 40px 0; }' \
' .feature { background: rgba(255,255,255,0.1); padding: 20px; border-radius: 10px; }' \
' .footer { margin-top: 40px; opacity: 0.8; }' \
' a { color: #ffeb3b; text-decoration: none; }' \
' a:hover { text-decoration: underline; }' \
' </style>' \
'</head>' \
'<body>' \
' <div class="container">' \
' <div class="header">' \
' <h1>🚀 Hexo Blog Docker</h1>' \
' <p>高性能博客容器 - 生产就绪版本</p>' \
' </div>' \
' ' \
' <div class="version">' \
' <h2>版本信息</h2>' \
' <p><strong>Version:</strong> 0.0.4-enhanced</p>' \
' <p><strong>Status:</strong> 🟢 Running</p>' \
' <p><strong>Build Date:</strong> 2025-05-29</p>' \
' </div>' \
' ' \
' <div class="features">' \
' <div class="feature">' \
' <h3>🌐 Web Server</h3>' \
' <p>Nginx with performance optimizations</p>' \
' </div>' \
' <div class="feature">' \
' <h3>🔐 SSH Access</h3>' \
' <p>Secure key-based authentication</p>' \
' </div>' \
' <div class="feature">' \
' <h3>📦 Git Deploy</h3>' \
' <p>Automated deployment with backup</p>' \
' </div>' \
' <div class="feature">' \
' <h3>📊 Monitoring</h3>' \
' <p>Health checks and logging</p>' \
' </div>' \
' </div>' \
' ' \
' <div class="footer">' \
' <p>Ready for your content! Deploy via Git push to get started.</p>' \
' <p><a href="/health">Health Check</a> | <a href="/status">Status API</a></p>' \
' </div>' \
' </div>' \
'</body>' \
'</html>' > /home/www/hexo/index.html
# Expose ports
EXPOSE 80 22
# Enhanced health check with multiple endpoints
HEALTHCHECK --interval=30s --timeout=10s --start-period=15s --retries=3 \
CMD curl -f http://localhost/health && \
curl -f http://localhost/status && \
pgrep nginx > /dev/null && \
pgrep sshd > /dev/null || exit 1
# Set proper ownership for all files
RUN chown -R hexo:hexo /home/www/hexo /home/hexo
# Start with enhanced process management
CMD ["/app/start.sh"]
# Labels for metadata
LABEL maintainer="AI Assistant" \
version="0.0.4" \
description="Enhanced Hexo Blog Docker Container with monitoring and security" \
org.opencontainers.image.title="Hexo Blog Docker" \
org.opencontainers.image.description="Production-ready Hexo blog container with Nginx, SSH, and Git deployment" \
org.opencontainers.image.version="0.0.4" \
org.opencontainers.image.created="2025-05-29" \
org.opencontainers.image.vendor="AI Assistant" \
org.opencontainers.image.licenses="MIT"