Maintenance
Backup and Recovery
Database Backup
bash
#!/bin/bash
# backup-database.sh
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/var/backups/openproject"
DB_NAME="openproject"
DB_USER="openproject"
# Create backup directory
mkdir -p $BACKUP_DIR
# Database backup
pg_dump -h localhost -U $DB_USER -d $DB_NAME > $BACKUP_DIR/openproject_db_$DATE.sql
# Compress backup
gzip $BACKUP_DIR/openproject_db_$DATE.sql
# Remove old backups (keep 30 days)
find $BACKUP_DIR -name "*.gz" -mtime +30 -delete
# Upload to S3 (optional)
aws s3 cp $BACKUP_DIR/openproject_db_$DATE.sql.gz s3://company-backups/openproject/
File System Backup
bash
#!/bin/bash
# backup-files.sh
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/var/backups/openproject"
FILES_DIR="/var/openproject"
# Create backup directory
mkdir -p $BACKUP_DIR
# Files backup
tar -czf $BACKUP_DIR/openproject_files_$DATE.tar.gz -C $FILES_DIR .
# Configuration backup
tar -czf $BACKUP_DIR/openproject_config_$DATE.tar.gz -C /etc/openproject .
# Remove old backups
find $BACKUP_DIR -name "*.tar.gz" -mtime +30 -delete
Automated Backup Script
bash
#!/bin/bash
# automated-backup.sh
# Set variables
BACKUP_DIR="/var/backups/openproject"
DATE=$(date +%Y%m%d_%H%M%S)
LOG_FILE="/var/log/openproject/backup.log"
# Function to log messages
log_message() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> $LOG_FILE
}
# Start backup
log_message "Starting OpenProject backup"
# Stop services (optional, for consistent backup)
# systemctl stop openproject
# Database backup
log_message "Starting database backup"
pg_dump -h localhost -U openproject openproject | gzip > $BACKUP_DIR/db_$DATE.sql.gz
# Files backup
log_message "Starting files backup"
tar -czf $BACKUP_DIR/files_$DATE.tar.gz -C /var/openproject .
# Configuration backup
log_message "Starting configuration backup"
tar -czf $BACKUP_DIR/config_$DATE.tar.gz -C /etc/openproject .
# Restart services
# systemctl start openproject
# Cleanup old backups
log_message "Cleaning up old backups"
find $BACKUP_DIR -name "*.gz" -mtime +30 -delete
log_message "Backup completed successfully"
System Maintenance
Log Cleanup
bash
#!/bin/bash
# log-cleanup.sh
# OpenProject logs
find /var/log/openproject -name "*.log" -mtime +30 -delete
find /var/log/openproject -name "*.log.*" -mtime +30 -delete
# System logs
journalctl --vacuum-time=30d
# Nginx logs
find /var/log/nginx -name "*.log" -mtime +30 -delete
Database Maintenance
bash
#!/bin/bash
# database-maintenance.sh
# Vacuum and analyze database
sudo -u postgres psql -d openproject -c "VACUUM ANALYZE;"
# Reindex database
sudo -u postgres psql -d openproject -c "REINDEX DATABASE openproject;"
# Update statistics
sudo -u postgres psql -d openproject -c "ANALYZE;"
Performance Optimization
bash
#!/bin/bash
# performance-optimization.sh
# Clear Rails cache
sudo -u openproject bash -c "cd /opt/openproject && RAILS_ENV=production bundle exec rake tmp:cache:clear"
# Restart services
systemctl restart openproject
systemctl restart nginx
systemctl restart redis
# Clear system cache
echo 3 > /proc/sys/vm/drop_caches
Security Maintenance
Security Updates
bash
#!/bin/bash
# security-updates.sh
# Update system packages
apt update && apt upgrade -y
# Update OpenProject
apt update && apt install --only-upgrade openproject
# Update Ruby gems
sudo -u openproject bash -c "cd /opt/openproject && bundle update"
# Restart services
systemctl restart openproject
Access Control Audit
ruby
# lib/security_audit.rb
class SecurityAudit
def self.audit_user_permissions
users_with_admin = User.where(admin: true)
inactive_admins = users_with_admin.where('last_login_on < ?', 90.days.ago)
report = {
total_users: User.count,
admin_users: users_with_admin.count,
inactive_admins: inactive_admins.count,
users_without_recent_login: User.where('last_login_on < ?', 180.days.ago).count
}
Rails.logger.info "Security audit report: #{report}"
report
end
def self.audit_project_permissions
projects_with_public_access = Project.where(is_public: true)
report = {
total_projects: Project.count,
public_projects: projects_with_public_access.count,
projects_without_members: Project.joins(:members).group('projects.id').having(