v0.0.3 published
This commit is contained in:
352
arch/origin/Dockerfile
Normal file
352
arch/origin/Dockerfile
Normal file
@@ -0,0 +1,352 @@
|
||||
# ---- Stage 1: Builder/Base ----
|
||||
# This stage sets up the base environment, installs build tools, creates scripts and templates
|
||||
FROM ubuntu:22.04 AS builder
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
ENV TZ=Asia/Shanghai
|
||||
|
||||
# Set the timezone
|
||||
RUN ln -sf /usr/share/zoneinfo/$TZ /etc/localtime && \
|
||||
echo $TZ > /etc/timezone
|
||||
|
||||
# Install all required packages in a single layer
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends \
|
||||
locales \
|
||||
git \
|
||||
nginx-full \
|
||||
gettext-base && \
|
||||
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 && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Create non-root user for security
|
||||
RUN groupadd -r hexo && useradd -r -g hexo -d /home/hexo -s /bin/bash hexo
|
||||
|
||||
# Make essential directories for artifacts
|
||||
RUN mkdir -p /root/hexo.git/hooks && \
|
||||
mkdir -p /etc/container/templates && \
|
||||
mkdir -p /app && \
|
||||
mkdir -p /home/hexo
|
||||
|
||||
# Configure git hook with proper permissions
|
||||
RUN git init --bare /root/hexo.git && \
|
||||
echo "#!/bin/bash" > /root/hexo.git/hooks/post-receive && \
|
||||
echo "git --work-tree=/home/www/hexo --git-dir=/root/hexo.git checkout -f" >> /root/hexo.git/hooks/post-receive && \
|
||||
echo "chown -R hexo:hexo /home/www/hexo" >> /root/hexo.git/hooks/post-receive && \
|
||||
chmod +x /root/hexo.git/hooks/post-receive
|
||||
|
||||
# Backup original nginx.conf
|
||||
RUN cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak
|
||||
|
||||
# Create improved SSH Config Template
|
||||
RUN cat > /etc/container/templates/sshd_config.template << 'EOF'
|
||||
# SSH Configuration Template
|
||||
Port ${SSH_PORT:-22}
|
||||
ListenAddress 0.0.0.0
|
||||
ListenAddress ::
|
||||
PermitRootLogin ${PERMIT_ROOT_LOGIN:-no}
|
||||
PubkeyAuthentication yes
|
||||
AuthorizedKeysFile .ssh/authorized_keys
|
||||
PasswordAuthentication no
|
||||
ChallengeResponseAuthentication no
|
||||
UsePAM yes
|
||||
X11Forwarding no
|
||||
PrintMotd no
|
||||
AcceptEnv LANG LC_*
|
||||
Subsystem sftp /usr/lib/openssh/sftp-server
|
||||
EOF
|
||||
|
||||
# Create Nginx Config Template with security headers
|
||||
RUN cat > /etc/container/templates/nginx.conf.template << 'EOF'
|
||||
# Nginx Configuration Template
|
||||
user ${NGINX_USER:-hexo};
|
||||
worker_processes ${NGINX_WORKERS:-auto};
|
||||
pid /var/run/nginx.pid;
|
||||
|
||||
events {
|
||||
worker_connections ${NGINX_CONNECTIONS:-1024};
|
||||
use epoll;
|
||||
multi_accept on;
|
||||
}
|
||||
|
||||
http {
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
# Logging
|
||||
access_log /var/log/nginx/access.log;
|
||||
error_log /var/log/nginx/error.log;
|
||||
|
||||
# Performance
|
||||
sendfile on;
|
||||
tcp_nopush on;
|
||||
tcp_nodelay on;
|
||||
keepalive_timeout 65;
|
||||
types_hash_max_size 2048;
|
||||
|
||||
# Security headers
|
||||
add_header X-Frame-Options DENY;
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
|
||||
# Gzip compression
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_proxied any;
|
||||
gzip_comp_level 6;
|
||||
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
|
||||
|
||||
server {
|
||||
listen ${HTTP_PORT:-80};
|
||||
server_name ${SERVER_NAME:-localhost};
|
||||
root ${WEB_ROOT:-/home/www/hexo};
|
||||
index index.html index.htm;
|
||||
|
||||
# Security
|
||||
server_tokens off;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ =404;
|
||||
}
|
||||
|
||||
# Static files caching
|
||||
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
# Create improved start script
|
||||
RUN cat > /app/start.sh << 'EOF'
|
||||
#!/bin/bash
|
||||
|
||||
# Color definitions
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Log file and rotation settings
|
||||
LOG_DIR="/var/log/container"
|
||||
LOG_FILE="$LOG_DIR/services.log"
|
||||
MAX_LOG_SIZE=10485760 # 10MB
|
||||
|
||||
# --- Logging functions ---
|
||||
_log() {
|
||||
local level_color=$1
|
||||
local level_name=$2
|
||||
shift 2
|
||||
echo -e "${level_color}[${level_name}]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $@"
|
||||
}
|
||||
log_info() { _log "$BLUE" "INFO" "$@"; }
|
||||
log_success() { _log "$GREEN" "SUCCESS" "$@"; }
|
||||
log_warning() { _log "$YELLOW" "WARNING" "$@"; }
|
||||
log_error() { _log "$RED" "ERROR" "$@"; }
|
||||
|
||||
# --- Setup logging ---
|
||||
setup_logging() {
|
||||
mkdir -p "$LOG_DIR"
|
||||
touch "$LOG_FILE"
|
||||
log_info "Logging to console and $LOG_FILE"
|
||||
exec > >(tee -a "$LOG_FILE") 2> >(tee -a "$LOG_FILE" >&2)
|
||||
}
|
||||
|
||||
# --- Render configuration files ---
|
||||
render_config() {
|
||||
log_info "Rendering configuration templates..."
|
||||
local rendered=0
|
||||
|
||||
if envsubst < /etc/container/templates/sshd_config.template > /etc/ssh/sshd_config; then
|
||||
log_success "SSHD configuration rendered"; ((rendered++))
|
||||
else
|
||||
log_error "Failed to render SSHD configuration";
|
||||
fi
|
||||
|
||||
if envsubst < /etc/container/templates/nginx.conf.template > /etc/nginx/nginx.conf; then
|
||||
log_success "Nginx configuration rendered"; ((rendered++))
|
||||
else
|
||||
log_error "Failed to render Nginx configuration";
|
||||
fi
|
||||
|
||||
if [ "$rendered" -eq 2 ]; then
|
||||
log_success "All configuration files rendered"
|
||||
return 0
|
||||
else
|
||||
log_error "Failed to render some configuration files"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# --- Start services ---
|
||||
start_services() {
|
||||
log_info "Starting SSH service..."
|
||||
if [ ! -f "/etc/ssh/ssh_host_rsa_key" ]; then
|
||||
log_info "Generating SSH host keys..."
|
||||
ssh-keygen -A
|
||||
fi
|
||||
|
||||
/usr/sbin/sshd -D &
|
||||
SSH_PID=$!
|
||||
|
||||
log_info "Starting Nginx service..."
|
||||
nginx -g "daemon off;" &
|
||||
NGINX_PID=$!
|
||||
|
||||
sleep 2
|
||||
|
||||
if kill -0 $SSH_PID 2>/dev/null && kill -0 $NGINX_PID 2>/dev/null; then
|
||||
log_success "All services started successfully"
|
||||
return 0
|
||||
else
|
||||
log_error "Failed to start some services"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# --- Monitor services ---
|
||||
monitor_services() {
|
||||
log_info "Starting service monitoring..."
|
||||
while true; do
|
||||
sleep 30
|
||||
|
||||
if ! kill -0 $SSH_PID 2>/dev/null; then
|
||||
log_error "SSH service stopped, attempting restart..."
|
||||
/usr/sbin/sshd -D &
|
||||
SSH_PID=$!
|
||||
fi
|
||||
|
||||
if ! kill -0 $NGINX_PID 2>/dev/null; then
|
||||
log_error "Nginx service stopped, attempting restart..."
|
||||
nginx -g "daemon off;" &
|
||||
NGINX_PID=$!
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# --- Cleanup function ---
|
||||
cleanup() {
|
||||
log_info "Received shutdown signal, gracefully stopping services..."
|
||||
|
||||
if [ ! -z "$NGINX_PID" ] && kill -0 $NGINX_PID 2>/dev/null; then
|
||||
log_info "Stopping Nginx (PID:$NGINX_PID)"
|
||||
kill -TERM $NGINX_PID
|
||||
wait $NGINX_PID 2>/dev/null
|
||||
log_success "Nginx stopped"
|
||||
fi
|
||||
|
||||
if [ ! -z "$SSH_PID" ] && kill -0 $SSH_PID 2>/dev/null; then
|
||||
log_info "Stopping SSH (PID:$SSH_PID)"
|
||||
kill -TERM $SSH_PID
|
||||
wait $SSH_PID 2>/dev/null
|
||||
log_success "SSH stopped"
|
||||
fi
|
||||
|
||||
log_info "Container shutdown complete"
|
||||
exit 0
|
||||
}
|
||||
|
||||
trap cleanup SIGTERM SIGINT
|
||||
|
||||
# --- Main execution ---
|
||||
main() {
|
||||
setup_logging
|
||||
log_info "===== Container Starting ====="
|
||||
log_info "Time: $(date)"
|
||||
log_info "Timezone: $TZ"
|
||||
log_info "User: $(whoami)"
|
||||
|
||||
if ! render_config; then
|
||||
log_error "Configuration rendering failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! /usr/sbin/sshd -t; then
|
||||
log_error "SSH configuration test failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! nginx -t; then
|
||||
log_error "Nginx configuration test failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! start_services; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_success "===== All services started successfully ====="
|
||||
monitor_services
|
||||
}
|
||||
|
||||
main
|
||||
EOF
|
||||
RUN chmod +x /app/start.sh
|
||||
|
||||
# ---- Stage 2: Production ----
|
||||
# This stage builds the final runtime image with only necessary dependencies
|
||||
FROM ubuntu:22.04 AS production
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
ENV TZ=Asia/Shanghai
|
||||
ENV PUID=1000
|
||||
ENV PGID=1000
|
||||
ENV LANG=zh_CN.UTF-8
|
||||
|
||||
# Copy timezone and locale settings from builder
|
||||
COPY --from=builder /etc/localtime /etc/localtime
|
||||
COPY --from=builder /etc/timezone /etc/timezone
|
||||
COPY --from=builder /usr/lib/locale/zh_CN.utf8 /usr/lib/locale/zh_CN.utf8/
|
||||
COPY --from=builder /etc/default/locale /etc/default/locale
|
||||
|
||||
# Install only runtime dependencies
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends \
|
||||
openssh-server \
|
||||
git \
|
||||
nginx-full \
|
||||
gettext-base \
|
||||
curl && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Create hexo user
|
||||
RUN groupadd -r hexo && \
|
||||
useradd -r -g hexo -d /home/hexo -s /bin/bash hexo
|
||||
|
||||
# Create necessary directories
|
||||
RUN mkdir -p /root/.ssh && \
|
||||
mkdir -p /home/www/hexo && \
|
||||
mkdir -p /home/www/ssl && \
|
||||
mkdir -p /var/run/sshd && \
|
||||
mkdir -p /var/log/container && \
|
||||
mkdir -p /var/log/nginx && \
|
||||
mkdir -p /home/hexo/.ssh
|
||||
|
||||
# Copy artifacts from builder stage
|
||||
COPY --from=builder /root/hexo.git /root/hexo.git
|
||||
COPY --from=builder /etc/container/templates /etc/container/templates/
|
||||
COPY --from=builder /app/start.sh /root/start.sh
|
||||
COPY --from=builder /etc/nginx/nginx.conf.bak /etc/nginx/nginx.conf.bak
|
||||
|
||||
# Set proper permissions
|
||||
RUN chmod +x /root/start.sh && \
|
||||
chmod +x /root/hexo.git/hooks/post-receive && \
|
||||
chown -R hexo:hexo /home/www/hexo && \
|
||||
chown -R hexo:hexo /home/hexo && \
|
||||
chmod -R 755 /home/www/hexo && \
|
||||
chmod 700 /root/.ssh && \
|
||||
chmod 700 /home/hexo/.ssh
|
||||
|
||||
# Health check
|
||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
||||
CMD curl -f http://localhost/ || exit 1
|
||||
|
||||
VOLUME ["/home/www/hexo", "/root/.ssh", "/home/www/ssl", "/root/hexo.git", "/var/log/container", "/var/log/nginx"]
|
||||
|
||||
EXPOSE 22 80 443
|
||||
|
||||
CMD ["/root/start.sh"]
|
||||
Reference in New Issue
Block a user