목차
Toggle이 글은 Oracle Cloud ARM 서버로 워드프레스를 구성한 사례와 설정 예시를 다룹니다. 무료 대상 여부, 가용 용량과 실제 성능은 현재 계정과 워크로드에서 따로 확인해야 합니다.
1. Oracle Cloud ARM 서버로 워드프레스 구축하기
OCI Always Free 리소스를 사용하려면 서비스별 무료 한도와 계정 조건을 먼저 확인해야 합니다. ARM 인스턴스도 지원되는 shape와 리전의 가용 용량을 확인한 뒤 선택합니다.
무료 티어 리소스 구성
ARM은 서버의 프로세서 아키텍처입니다. 필요한 패키지와 확장 기능의 ARM 지원 여부를 먼저 확인하고, 지원되는 배포본이 없다면 다른 실행 환경을 검토해야 합니다.
Oracle Cloud의 Always Free는 계정·리전·리소스별 무료 한도 내에서 사용할 수 있는 서비스입니다. 모든 블로그의 평생 무과금이나 자원 확보를 보장하지 않습니다. 무료 대상 shape, 현재 월간 한도, 용량 가용성과 유휴 인스턴스 회수 조건은 공식 Always Free 문서에서 확인하세요. 이 글의 과거 구성과 현재 계정의 이용 한도는 구분해야 합니다.
컴퓨팅·스토리지·전송량의 무료 한도를 각각 확인하세요:
2026-10-05 공식 문서 재확인: 무료 자원은 서비스별 한도와 계정 조건이 적용됩니다. 이 글의 ARM 24GB·월 3,000 OCPU 시간은 과거 예시이며 현재 보장량으로 사용하지 마세요. Compute의 shape·월간 OCPU/메모리 사용량, 부트 볼륨을 포함한 Block Volume 합계, 계정 유형별 Object Storage 한도와 아웃바운드 전송량을 현재 공식 한도표에서 각각 확인해야 합니다. 실제 계정의 한도·과금·가용성을 이 글에서 검증한 것은 아닙니다.
운영에 필요한 용량은 PHP 워커 메모리, 데이터베이스 부하와 피크 요청을 측정해 판단합니다. ARM 아키텍처나 사양표만으로 워드프레스 성능을 보장할 수는 없습니다.
부트 볼륨과 데이터 볼륨의 사용량을 함께 계산해 Block Volume 한도를 확인합니다. 시스템과 데이터를 별도 볼륨에 둘 경우에도 백업과 복원, 각 볼륨의 용량을 검토해야 합니다. 이 글의 200GB는 과거 구성 예시입니다.
이미지와 문서는 Object Storage에 둘 수 있습니다. 저장 계층, 계정 유형별 한도와 요청·전송 비용을 확인하고, 워드프레스 미디어의 URL과 접근 권한을 따로 점검하세요. 과거의 10GB 수치를 현재 모든 계정의 한도로 사용하지 마세요.
아웃바운드 전송량은 페이지, 이미지와 백업 트래픽을 함께 예상합니다. 과거 예시의 월 10TB를 현재 한도로 가정하거나 이미지가 많아도 비용 걱정이 없다고 판단하지 말고, 사용할 서비스의 현재 한도와 과금 조건을 확인하세요.
기본 시스템 구성
이 글에서 다루는 워드프레스 구성은 다음과 같습니다:
웹 애플리케이션 구성:
- ARM 기반 컴퓨트 인스턴스
- Oracle Linux OS에 워드프레스 설치
- Apache 웹 서버 활용
데이터베이스·캐시·미디어 저장:
- MySQL HeatWave 데이터베이스
- Redis 캐시 서버
- 객체 스토리지 연동
시스템 초기 설정 및 웹 서버 구성 스크립트
#!/bin/bash # RHEL/CentOS 웹 서버 설정 스크립트 # root 권한 확인 if [[ $EUID -ne 0 ]]; then echo "root 권한으로 실행하세요." exit 1 fi # 시스템 업데이트 및 기본 패키지 설치 dnf update -y dnf install -y epel-release dnf install -y httpd php php-fpm php-mysqlnd php-json php-gd php-mbstring php-xml php-opcache mod_ssl # PHP 설정 sed -i 's/memory_limit = .*/memory_limit = 256M/' /etc/php.ini sed -i 's/upload_max_filesize = .*/upload_max_filesize = 32M/' /etc/php.ini sed -i 's/post_max_size = .*/post_max_size = 64M/' /etc/php.ini # Apache 보안 설정 cat > /etc/httpd/conf.d/security.conf << 'EOF' ServerTokens Prod ServerSignature Off TraceEnable Off Header set X-Frame-Options "SAMEORIGIN" EOF # SELinux 설정 setsebool -P httpd_can_network_connect 1 # 방화벽 설정 systemctl start firewalld systemctl enable firewalld firewall-cmd --permanent --add-service=http firewall-cmd --permanent --add-service=https firewall-cmd --reload # 서비스 시작 systemctl enable httpd php-fpm systemctl start httpd php-fpm echo "웹 서버 설정이 완료되었습니다."
2. 무료 MySQL HeatWave로 데이터베이스 구성
MySQL DB System의 무료 대상 여부와 가용 용량은 공식 서비스 조건에서 따로 확인하세요. 연결과 쿼리 동작도 먼저 검증해야 합니다. HeatWave의 분석용 가속 기능은 지원 조건과 처리 경로가 별개이며, 워드프레스 쿼리가 자동으로 빨라진다고 가정해서는 안 됩니다.
데이터베이스 초기 설정
/** * WordPress 데이터베이스 초기 설정 스크립트 * * 이 스크립트는 다음 작업을 수행합니다: * 1. WordPress용 새 데이터베이스 생성 * 2. 전용 데이터베이스 사용자 생성 * 3. 사용자에게 필요한 권한 부여 */ -- Step 1: WordPress 전용 데이터베이스 생성 CREATE DATABASE wordpress_db; -- Step 2: WordPress 전용 사용자 생성 (모든 호스트에서 접속 가능) CREATE USER 'wordpress_user'@'%' IDENTIFIED BY 'your_password'; -- Step 3: 생성된 사용자에게 데이터베이스 접근 권한 부여 GRANT ALL PRIVILEGES ON wordpress_db.* TO 'wordpress_user'@'%'; -- Step 4: 권한 변경사항 즉시 적용 FLUSH PRIVILEGES;
워드프레스 데이터베이스 최적화
데이터베이스 성능을 점검할 때는 대표 쿼리와 실행 계획을 먼저 확인합니다. 아래는 진단·설정 항목의 예시입니다.
posts와 postmeta를 함께 조회하는 쿼리는 실행 계획과 실제 선택도를 확인합니다. 인덱스는 워드프레스 기본 인덱스와 중복되는지, 쓰기 비용이 늘어나는지 검토한 뒤 판단하세요.
SHOW CREATE TABLE wp_posts; SHOW INDEX FROM wp_posts; SHOW CREATE TABLE wp_postmeta; SHOW INDEX FROM wp_postmeta; SHOW CREATE TABLE wp_term_relationships; SHOW INDEX FROM wp_term_relationships;
실제 테이블 접두사로 바꾸세요. WordPress 기본 인덱스와 겹치는지 먼저 확인합니다. meta_value는 LONGTEXT이므로 일반 인덱스에 접두사 길이가 필요하지만 임의의 길이를 모든 사이트에 적용하면 안 됩니다. 문자셋·키 길이·선택도·대표 쿼리의 실행 계획과 쓰기 비용을 스테이징에서 검증한 후 개별 DDL을 검토하세요. 위 조회는 인덱스를 생성하거나 삭제하지 않습니다.
성능 모니터링 구성
/** * WordPress 데이터베이스 성능 모니터링 설정 스크립트 * * 이 스크립트는 두 가지 주요 모니터링 메커니즘을 설정합니다: * 1. Slow Query Log: 느린 쿼리를 감지하고 기록 * 2. Performance Schema: 상세한 성능 메트릭스 수집 * * 주의: 이러한 모니터링 설정은 서버 성능에 약간의 영향을 줄 수 있습니다. */ -- Section 1: Slow Query Log 설정 -- 목적: 성능이 좋지 않은 쿼리를 식별하고 최적화하기 위한 로깅 활성화 -- 느린 쿼리 로깅 활성화 SET GLOBAL slow_query_log = 1; -- 느린 쿼리로 간주할 실행 시간 임계값 설정 (초 단위) -- 2초 이상 걸리는 모든 쿼리가 로그에 기록됨 SET GLOBAL long_query_time = 2; -- 로그 파일 경로 설정 -- 주의: 해당 경로에 MySQL이 쓰기 권한을 가지고 있어야 함 SET GLOBAL slow_query_log_file = '/var/log/mysql/slow-query.log'; -- Section 2: Performance Schema 설정 -- 목적: SQL 문장 수준의 상세한 성능 메트릭스 수집 -- SQL 문장 모니터링 도구 활성화 -- NAME LIKE 'statement/%': 모든 종류의 SQL 문장을 모니터링 UPDATE performance_schema.setup_instruments SET ENABLED = 'YES', -- 모니터링 활성화 TIMED = 'YES' -- 시간 측정 활성화 WHERE NAME LIKE 'statement/%';
Slow Query Log 설정값 2초는 이 글의 설정 예시입니다. 기록할 쿼리의 범위, 로그량과 조사 목적을 기준으로 임계값을 정하고, 실제 응답 시간과 함께 해석하세요.
Performance Schema는 Slow Query Log보다 더 상세한 정보를 제공합니다. SQL 문장의 실행 시간뿐만 아니라, 리소스 사용량, 대기 시간, 락 경합 등 다양한 성능 지표를 수집합니다. 다음과 같은 상황에서 특히 유용합니다:
- 특정 쿼리가 왜 느린지 파악할 때
- 데이터베이스 서버의 전반적인 성능 상태를 모니터링할 때
- 성능 병목 현상의 원인을 찾을 때
ARM 환경에서 워드프레스 성능 최적화
PHP-FPM과 OPcache 설정을 각각 확인합니다. 아래 값은 측정 없이 모든 ARM 환경에 적용할 기본값으로 사용하지 마세요.
- 실행 환경에 맞는 프로세스 관리 방식 확인
- 측정한 메모리 사용량을 기준으로 워커 수 검토
- OPcache 활성화와 메모리 사용량 점검
PHP-FPM 성능 최적화
dynamic 모드에서는 PHP-FPM이 설정된 범위 안에서 워커 수를 조절합니다. 안전한 범위가 자동으로 정해지는 것은 아니므로, 워커별 메모리와 동시 요청을 측정해 한도를 검토해야 합니다.
PHP의 요청별 메모리 한도와 FPM 워커 수를 함께 검토하세요. 다른 서비스가 사용하는 메모리도 남겨 두어야 합니다.
upload_max_filesize는 파일 하나의 크기를, post_max_size는 파일을 포함한 POST 요청 전체의 크기를 제한합니다. post_max_size를 upload_max_filesize보다 크게 설정하는 이유는 파일 업로드 시 발생하는 추가 POST 데이터(예: 파일 메타데이터)를 고려하기 위함입니다.
max_execution_time은 스크립트 실행 시간, max_input_time은 업로드를 포함한 입력 수신 시간과 관련된 제한입니다. 적용 범위와 환경 차이를 PHP 공식 문서에서 확인하세요. 300초는 기존 예시이며 다음 작업의 성공이나 안전성을 보장하지 않습니다:
- 대량의 데이터 가져오기/내보내기
- 복잡한 데이터베이스 쿼리 실행
- 대용량 미디어 파일 처리
이 블록은 기존 FPM pool의 일부 설정입니다. www.conf 전체를 덮어쓰지 마세요.
실제 서비스가 읽는 php-fpm.conf/include 경로와 [www] pool, 실행 계정·listen 설정을 먼저 확인하고 원본을 보관합니다.
pm.*는 pool 지시어이고 PHP ini 값은 여기서 php_admin_value[…]로 지정합니다. php.ini의 bare 지시어와 혼합하지 마세요. 이 관리 값은 ini_set()으로 덮어쓸 수 없습니다. php –ini는 CLI 환경만 보여주므로 FPM 경로 증거로 사용하지 마세요.
설치된 FPM 실행 파일로 php-fpm -t 검사를 통과한 뒤에만 확인한 서비스의 reload를 검토하고, 실패하면 중단하여 원본을 복구합니다. 숫자는 기존 예시이며 실제 환경 적합성은 별도 검증해야 합니다.
;-----------------------------------------------------------------------------
; PHP-FPM 프로세스 관리자 설정
; 파일 위치: /etc/php-fpm.d/www.conf
;
; 다음 값은 설명용 예시이며 4GB RAM/4 코어에서 검증된 최적값이 아닙니다.
; 실제 프로세스 메모리, 가용 RAM과 부하를 측정한 후 각 한도를 정합니다.
;-----------------------------------------------------------------------------
; 프로세스 관리 방식 설정
; dynamic: 서버 부하에 따라 프로세스 수를 자동으로 조절
pm = dynamic
; 최대 자식 프로세스 수
; 공식: (서버 총 RAM - 예약 RAM) / 평균 프로세스 RAM 사용량
; 예: (4GB - 1GB) / 60MB = ~50
pm.max_children = 50
; 서버 시작 시 생성할 프로세스 수
; 시작 프로세스 수 예시: 초기 부하에 맞춰 검증
pm.start_servers = 5
; 최소 유지 대기 프로세스 수
; 최소 대기 프로세스 수 예시: 실제 요청 패턴으로 검증
pm.min_spare_servers = 5
; 최대 유지 대기 프로세스 수
; 최대 대기 프로세스 수 예시: 메모리 여유와 부하로 검증
pm.max_spare_servers = 35
; 프로세스당 최대 요청 처리 수
; 메모리 누수 방지를 위해 주기적으로 프로세스 재시작
pm.max_requests = 500
;-----------------------------------------------------------------------------
; PHP 메모리 및 실행 시간 제한 설정
;
; 플러그인과 미디어 처리량에 따라 별도 검증해야 하는 예시 값입니다.
;-----------------------------------------------------------------------------
; PHP 스크립트당 최대 메모리 할당량
; 256MB는 이 예시 값이며 WordPress의 보편적 최소 요구량이 아닙니다.
php_admin_value[memory_limit] = 256M
; PHP 스크립트 최대 실행 시간 (초)
; 대용량 파일 업로드, 백업 처리 등을 위한 설정
php_admin_value[max_execution_time] = 300
; POST 데이터 파싱 최대 허용 시간 (초)
; max_execution_time과 동일하게 설정
php_admin_value[max_input_time] = 300
; POST 요청 최대 크기
; 여러 파일 동시 업로드 고려
php_admin_value[post_max_size] = 64M
; 단일 파일 업로드 최대 크기
; post_max_size보다 작게 설정
php_admin_value[upload_max_filesize] = 32M
캐싱 시스템 구축:
페이지 캐시, 워드프레스 객체 캐시와 OPcache는 저장하는 데이터와 유효기간이 다릅니다. 각 계층의 적중 여부와 무효화 범위를 따로 확인하고 응답 시간에 미치는 영향을 측정합니다.
- WP Super Cache (페이지 레벨 캐시) 동적으로 생성한 페이지를 정적 HTML로 저장합니다. 전달 방식과 캐시 대상에 따라 처리 경로가 달라지므로, 현재 모드와 제외 조건을 확인하고 실제 캐시 적중을 점검해야 합니다.
- Redis 객체 캐시 워드프레스 영구 객체 캐시와 연결하면 재계산 비용이 큰 데이터와 조회 결과를 요청 사이에 재사용할 수 있습니다. PHP 세션이 자동으로 저장된다고 가정하지 말고, 사용하는 플러그인과 데이터베이스·키 범위를 확인하세요.
- OPcache (코드 레벨 캐시) 컴파일된 PHP 바이트코드를 재사용합니다. 워드프레스의 페이지 내용이나 데이터베이스 조회 결과를 저장하는 캐시와 구분해서 설정과 사용량을 확인합니다.
/** * WordPress 고성능 다층 캐시 시스템 설정 * * 이 설정은 세 가지 레벨의 캐시를 구성합니다: * 1. WP Super Cache: 페이지 레벨 캐시 * 2. Redis: 객체 레벨 캐시 * 3. OPcache: PHP 코드 레벨 캐시 */ //----------------------------------------------------------------------------- // 레벨 1: WP Super Cache 설정 // 목적: 전체 페이지 캐싱으로 데이터베이스 쿼리와 PHP 실행을 완전히 건너뛰기 //----------------------------------------------------------------------------- // 워드프레스 캐시 기능 활성화 define('WP_CACHE', true); // WP Super Cache 플러그인 경로 설정 define('WPCACHEHOME', '/var/www/html/wp-content/plugins/wp-super-cache/'); //----------------------------------------------------------------------------- // 레벨 2: Redis 객체 캐시 설정 // 목적: 데이터베이스 쿼리 결과와 객체를 메모리에 저장하여 빠른 접근 제공 //----------------------------------------------------------------------------- // Redis 서버 호스트 설정 (도커 컨테이너 이름 또는 IP 주소) define('WP_REDIS_HOST', 'redis'); // Redis 서버 포트 설정 (기본값: 6379) define('WP_REDIS_PORT', 6379); // Redis 연결 타임아웃 설정 (초 단위) define('WP_REDIS_TIMEOUT', 1); // Redis 읽기 작업 타임아웃 설정 (초 단위) define('WP_REDIS_READ_TIMEOUT', 1); // Redis 데이터베이스 번호 (0-15 사이의 값) define('WP_REDIS_DATABASE', 0); //----------------------------------------------------------------------------- // 레벨 3: OPcache 설정 // 목적: PHP 코드를 컴파일된 상태로 메모리에 저장하여 실행 속도 향상 //----------------------------------------------------------------------------- // OPcache가 사용할 메모리 크기 (MB) opcache.memory_consumption=128 // 문자열을 위한 메모리 버퍼 크기 (MB) opcache.interned_strings_buffer=8 // 캐시할 수 있는 최대 파일 수 opcache.max_accelerated_files=4000 // 캐시된 파일의 유효성을 검사하는 주기 (초) opcache.revalidate_freq=60 // 빠른 종료 기능 활성화 opcache.fast_shutdown=1 // CLI 환경에서도 OPcache 사용 opcache.enable_cli=1
4. 보안 설정과 모니터링 시스템 구축
보안 기본 설정
무료 티어라고 해서 보안을 소홀히 할 수는 없습니다.
Oracle Cloud의 Security List를 활용한 방화벽 설정:
SSH 접속 제한은 복구 경로를 준비한 별도 변경으로 진행하세요.
기존 세션을 유지하고 비-root 관리 계정의 키 로그인·sudo를 두 번째 새 세션에서 먼저 시험합니다. OCI 콘솔 복구 접근과 설정/방화벽 원본을 확보하세요.
sshd_config와 Include/Match의 실제 적용값을 확인하고 무조건 sed 치환하지 마세요. 변경 후 sshd -t 및 해당 사용자·주소를 지정한 sshd -T -C 검사를 통과해야 하며 실패 시 적용을 중단합니다. 검증한 서비스만 reload한 뒤 새 접속과 sudo를 재검증하고 기존 세션은 유지합니다. 실패 시 보관한 설정을 기존 세션/콘솔에서 복원하고 재검사 후 reload합니다.
firewalld와 직접 iptables 변경을 섞지 마세요. 실제 관리 방식, IPv4/IPv6, OCI 네트워크 규칙, 체인 순서와 접속 원본 CIDR을 확인한 후 별도 계획을 세우세요.
허용 규칙 실패 후 차단을 계속하지 않으며, 사전에 시험한 시간 제한 자동 복구 또는 콘솔 복구 없이는 원격 SSH 차단을 적용하지 않습니다. 아래는 조회·검사만 수행합니다.
# 읽기 전용 사전 점검. 설치된 서비스 확인 후 실제 경로를 사용하세요.
sudo /usr/sbin/sshd -t
sudo /usr/sbin/sshd -T
# Match 조건 예시. 모든 placeholder를 실제 값으로 바꾼 뒤 사용하세요:
# sudo /usr/sbin/sshd -T -C user=ADMIN,addr=CLIENT_IP,host=CLIENT_HOST
# 이 서버에서 실제로 사용하는 방화벽 관리자만 조회하세요:
# sudo firewall-cmd --list-all
# sudo iptables-save
# sudo ip6tables-save
SSL/TLS 설정
이 예시는 Let’s Encrypt를 사용한 HTTPS 구성입니다. 인증서 발급, 갱신 필요 여부 확인, 실제 갱신과 Apache 재적용은 구분해서 검증하세요:
기존 Certbot timer와 cron의 등록·최근 실행 결과를 확인한 뒤 한 가지 예약 방식만 사용하세요. 바이너리 경로·패키지 버전·실행 계정과 Apache authenticator/installer 구성을 먼저 검증합니다.
시스템 /etc/crontab·/etc/cron.d에는 사용자 필드가 필요하지만 crontab -e에는 넣지 않습니다. 하루 두 번 예시는 실패 재시도 여유를 위한 것이며 실제 주기는 관리 정책에 맞춥니다.
post-hook은 성공한 갱신 전용이 아닙니다. 성공 후 추가 동작이 필요하면 검증된 deploy-hook을 사용하고 Apache 구성 검사 성공 뒤에만 reload하도록 하세요. Apache 플러그인이 이미 처리하는 동작을 중복 추가하지 마세요.
dry-run과 hook 동작을 비운영 환경에서 확인하고 실행 오류·인증서 만료를 별도로 감시합니다. 실패 시 기존 예약과 정상 설정을 복원하세요.
이것은 인증서 예약이며 WP-Cron 대체가 아닙니다. 이 글에는 DISABLE_WP_CRON이 없으므로 방문 기반 작업을 유지하고, 별도 대체 스케줄러의 실제 실행 검증 전에는 비활성화하지 마세요.
#!/bin/bash
#-----------------------------------------------------------------------------
# Let's Encrypt SSL 인증서 설정 및 자동 갱신 스크립트
#
# 이 스크립트는 다음 작업을 수행합니다:
# 1. 메인 도메인과 www 서브도메인에 대한 SSL 인증서 발급
# 2. Apache 웹 서버 설정 자동 구성
# 3. 인증서 자동 갱신 작업 예약
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# 섹션 1: SSL 인증서 발급
# certbot은 Let's Encrypt의 공식 클라이언트입니다.
# --apache 옵션은 Apache 설정을 자동으로 업데이트합니다.
#-----------------------------------------------------------------------------
# 메인 도메인에 대한 인증서 발급
# 이 과정에서 다음 작업이 자동으로 수행됩니다:
# - 도메인 소유권 확인
# - 인증서 발급
# - Apache 가상 호스트 설정 업데이트
sudo certbot --apache -d yourdomain.com
# www 서브도메인에 대한 인증서 발급
# 대부분의 사이트는 www와 non-www 버전 모두 지원해야 합니다
sudo certbot --apache -d www.yourdomain.com
# 갱신 예약: 기존 timer/cron을 먼저 확인하고 중복 설치하지 않습니다.
systemctl list-timers --all
# 확인한 Certbot 바이너리로 비운영 환경에서 먼저 시험:
# sudo /usr/bin/certbot renew --dry-run
# 기존 예약이 없을 때만 /etc/cron.d/certbot 예시를 검토합니다.
# 시스템 crontab은 시간 필드 다음에 root 사용자 필드가 필요합니다.
# 17 2,14 * * * root /usr/bin/certbot renew --quiet
# 위 행은 shell 명령이 아니며 검증 후 한 곳에만 설치합니다.
종합 모니터링 시스템
아래 모니터링 예시는 디스크 공간, 메모리 상태와 웹사이트 접근성을 확인하고 하루 한 번 실행하도록 구성했습니다. 필요한 감시 주기는 장애 탐지 목표에 따라 정하고, 오류 처리와 알림 전달은 별도로 검증해야 합니다.
#!/bin/bash # simple_monitor.sh # 기본적인 시스템 상태만 체크 LOG_FILE="/var/log/wp_simple_monitor.log" # 하루에 한 번만 실행 echo "=== Daily Check: $(date) ===" >> $LOG_FILE df -h | grep '/var/www' >> $LOG_FILE free -m | grep 'Mem:' >> $LOG_FILE curl -sL http://yourdomain.com -o /dev/null -w "%{http_code}\n" >> $LOG_FILE
5. 워드프레스 백업 및 자동화 구현 방안
백업 스크립트 작성
생성 전용 예시입니다. BACKUP_DIR은 웹 루트·WP_DIR 밖의 비공개 전용 디렉터리로, 경로에는 줄바꿈을 쓰지 않습니다. 실행 계정에 필요한 최소 읽기/쓰기 권한과 보호된 MySQL login-path를 먼저 준비하세요. 비밀번호를 스크립트에 넣지 않습니다.
single-transaction은 InnoDB용이며 DDL·파일 쓰기를 조정하여 DB/파일 일관성을 확보해야 합니다.
SQL 생성·압축·구조 검사 중 하나라도 실패하면 비정상 종료하고 CREATED 표시를 만들지 않습니다. 실패 산출물은 조사용으로 남고 기존 백업은 삭제하지 않습니다. 결과는 각 run 디렉터리의 database.sql.gz, wordpress.tar.gz, CREATED입니다.
암호화·원격 복제는 구현하지 않습니다.
CREATED는 복원 성공을 뜻하지 않습니다. 격리 복원, DB/파일/사이트 동작 확인, 별도 장애 영역의 보호된 사본과 보존 정책을 검증해야 실제 복구 체계로 인정할 수 있습니다. 추가 –type 인자는 사용하지 않습니다.
#!/bin/bash
# backup_and_maintenance.sh — 백업 생성만 수행, 삭제/유지보수 없음
set -Eeuo pipefail
umask 077
: "${BACKUP_DIR:?웹 루트 밖의 전용 백업 디렉터리를 지정하세요}"
: "${WP_DIR:?확인한 WordPress 설치 경로를 지정하세요}"
: "${DB_NAME:?백업 대상 DB 이름을 지정하세요}"
[ -d "$BACKUP_DIR" ] && [ -w "$BACKUP_DIR" ]
[ -f "$WP_DIR/wp-config.php" ]
stage=$(mktemp -d "$BACKUP_DIR/run-$(date -u +%Y%m%dT%H%M%SZ)-XXXXXX")
trap 'rc=$?; printf "FAILED rc=%s stage=%s\n" "$rc" "$stage" >&2; exit "$rc"' ERR
# 실행 계정의 보호된 login-path를 미리 구성/시험해야 합니다.
mysqldump --login-path=wordpress-backup --single-transaction --quick "$DB_NAME" > "$stage/database.sql"
test -s "$stage/database.sql"
gzip "$stage/database.sql"
gzip -t "$stage/database.sql.gz"
# wp-config.php를 포함하므로 백업은 비공개로 보관합니다.
tar -czf "$stage/wordpress.tar.gz" -C "$WP_DIR" .
tar -tzf "$stage/wordpress.tar.gz" > /dev/null
printf 'created_utc=%s\nrestore_verified=no\n' "$(date -u +%FT%TZ)" > "$stage/CREATED"
printf 'CREATED (복원 미검증): %s\n' "$stage"
백업 자동화
실제 경로·DB·실행 계정을 확인하고 스크립트 두 개를 해당 경로에 설치한 뒤, 예약과 동일한 계정/환경으로 먼저 수동 검증하세요. 스크립트와 설정은 관리자가 소유하고 실행 계정이 수정할 수 없도록, 백업·로그 디렉터리는 지정 계정만 필요한 권한을 갖도록 준비합니다.
로그는 /var/log/wordpress/backup.log 한 경로로 통일하고 별도 logrotate 정책도 같은 소유자/경로에 맞춥니다. 매일 DB+파일을 생성하므로 아래 점검도 두 파일과 CREATED를 함께 확인합니다. 압축일 뿐 암호화된 .enc 파일은 없습니다.
실패·오래된 백업·스케줄러 미실행에 대한 독립 알림 전달과 수신을 시험하세요. 아래 점검의 성공만으로 복원·원격 사본·보존 정책을 검증했다고 주장하지 마세요. 예약 중복을 피하고 변경 전 cron/스크립트를 보관하여 실패 시 복원합니다.
# /etc/cron.d/wordpress-backup 구성 예시 — shell에 붙여넣지 마세요.
# 검증한 전용 실행 계정으로 BACKUP_ACCOUNT를 바꾸기 전에는 활성화하지 않습니다.
# Oracle Linux에서 www-data 또는 apache를 임의로 가정하지 마세요.
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
BACKUP_DIR=/backup/wordpress
WP_DIR=/var/www/html/wordpress
DB_NAME=wordpress_db
# 매일 DB와 파일을 한 번에 생성; --type/maintenance 모드 없음.
# 0 3 * * * BACKUP_ACCOUNT /opt/wordpress/scripts/backup_and_maintenance.sh >> /var/log/wordpress/backup.log 2>&1
# 생성 여부 점검; 26시간 기준, 실패 알림 전달은 별도로 구성/시험.
# 30 4 * * * BACKUP_ACCOUNT /opt/wordpress/scripts/check_backup.sh >> /var/log/wordpress/backup.log 2>&1
아래 내용을 별도 check_backup.sh 파일에 저장합니다. 생성 스크립트와 같은 BACKUP_DIR을 사용하세요.
#!/bin/bash
# check_backup.sh — 생성 여부/압축 구조 점검, 복원 검증 아님
set -Eeuo pipefail
: "${BACKUP_DIR:?백업 생성 스크립트와 같은 디렉터리를 지정하세요}"
test -d "$BACKUP_DIR"
markers=$(find "$BACKUP_DIR" -mindepth 2 -maxdepth 2 -type f -name CREATED -mmin -1560 -print)
test -n "$markers" || { echo 'ALERT: 최근 26시간 내 생성 완료 기록 없음' >&2; exit 1; }
while IFS= read -r marker; do
folder=${marker%/CREATED}
test -s "$folder/database.sql.gz"
gzip -t "$folder/database.sql.gz"
test -s "$folder/wordpress.tar.gz"
tar -tzf "$folder/wordpress.tar.gz" > /dev/null
done <<< "$markers"
echo '생성/압축 점검 통과. 격리 복원·독립 사본·복구 목표 달성 여부는 별도 검증 필요.'
🌟 결론
이 글의 구성 예시를 사용하기 전에 다음 항목을 각각 확인하세요:
- ARM shape의 가용 용량과 실제 워크로드
- MySQL 접속·쿼리 동작과 HeatWave 기능의 적용 조건
- PHP-FPM과 캐시 계층별 측정·검증
- 원격 접근, 인증서와 복구 경로
- 데이터 증가량, 비용과 백업·복원 조건
각 설정 예시의 지원 조건과 현재 환경을 대조한 뒤 적용 여부를 판단하세요. 서비스 생성, 접속 성공이나 파일 생성만으로 성능·보안·복원까지 검증됐다고 보아서는 안 됩니다.
📝 참고 자료
2025년 1월은 원래 구성 사례의 작성 시점입니다. 이후 보완한 설명과 당시 화면·코드 예시를 구분해서 읽으세요. 현재 무료 한도, 지원 버전과 서비스 조건은 공식 문서에서 확인해야 합니다.
관련 글: 워드프레스 성능 최적화 가이드 | MySQL HeatWave Autopilot Indexing
#OracleCloud #FreeTier #클라우드컴퓨팅 #워드프레스 #ARM #MySQL #DevOps #테크블로그
