데브포일 홈
WordPress 자동화
Guest
STAGE 15 · Lv.77

멀티 사이트 동시 관리

Make.com을 활용하여 여러 WordPress 사이트를 중앙에서 관리합니다. 콘텐츠 동시 배포, 통합 리포팅, 플러그인/테마 일괄 관리를 구현합니다.

멀티 사이트 관리의 도전과 솔루션

왜 멀티 사이트 관리 자동화가 필요한가?

현대 디지털 비즈니스 환경에서 하나의 조직이 운영하는 WordPress 사이트 수는 꾸준히 증가하고 있습니다. 웹 에이전시는 수십에서 수백 개의 클라이언트 사이트를 관리하고, 글로벌 기업은 국가별/브랜드별로 독립적인 사이트를 운영합니다. 프랜차이즈 비즈니스는 각 지점마다 별도의 웹사이트가 필요하며, 미디어 회사는 주제별로 여러 사이트를 운영합니다.


이런 상황에서 각 사이트에 개별적으로 접속하여 콘텐츠를 발행하고, 플러그인을 업데이트하고, 보안을 점검하는 것은 시간과 인력의 엄청난 낭비입니다. 사이트가 5개만 넘어가도 수동 관리는 실질적으로 불가능해집니다. 하나의 사이트에서 플러그인 업데이트에 5분이 걸린다면, 50개 사이트에서는 250분(약 4시간)이 소요됩니다. 여기에 콘텐츠 배포, 백업 확인, 보안 스캔까지 더하면 하루 8시간 근무로는 턱없이 부족합니다.


Make.com은 이 문제를 근본적으로 해결합니다. 하나의 자동화 시나리오에서 수십, 수백 개의 WordPress 사이트를 동시에 관리할 수 있으며, 사람이 개입하지 않아도 24시간 365일 모든 사이트가 최신 상태로 유지됩니다. Make.com의 Iterator(반복 처리), Router(조건 분기), Error Handler(오류 처리) 기능을 조합하면 엔터프라이즈급 멀티 사이트 관리 시스템을 코딩 없이 구축할 수 있습니다.

🌐
50+ 사이트
하나의 시나리오로 동시 관리
⏱️
95% 절감
관리 시간 대폭 감소
🔄
24/7 자동
중단 없는 모니터링 및 관리
💰
ROI 300%+
인건비 대비 자동화 효율

수동 관리 vs 자동화 관리: 현실적 비교

사이트 수가 늘어날수록 수동 관리와 자동화 관리의 효율 차이는 기하급수적으로 벌어집니다. 아래 표에서 실제 작업별 소요 시간을 비교해 보겠습니다. 수동 관리의 경우 사이트 수에 비례하여 시간이 증가하지만, Make.com 자동화는 사이트 수와 거의 무관하게 일정한 시간에 모든 작업을 처리합니다.

관리 작업 수동 관리 (10개 사이트) 수동 관리 (50개 사이트) Make.com 자동화
콘텐츠 동시 배포 (1개 글) 50분 (사이트당 5분) 250분 (4시간+) 2분 (자동 완료)
플러그인 업데이트 확인 30분 150분 (2.5시간) 3분 (자동 스캔)
보안 스캔 실행 40분 200분 (3.3시간) 5분 (병렬 스캔)
백업 상태 확인 20분 100분 (1.6시간) 1분 (자동 확인)
통합 리포트 생성 60분 (수동 취합) 300분 (5시간) 5분 (자동 생성)
일일 총 소요시간 200분 (3.3시간) 1,000분 (16.7시간) 16분 (자동)
멀티 사이트 관리 아키텍처 핵심
성공적인 멀티 사이트 자동화 관리의 핵심은 중앙 허브(Make.com) + 표준화된 엔드포인트(WordPress REST API) 구조입니다. 모든 관리 대상 사이트에 동일한 커스텀 REST API 플러그인을 설치하고, Make.com에서 사이트 목록을 관리하는 데이터 소스(Google Sheets, Airtable 등)를 연결합니다. 이렇게 하면 사이트를 추가하거나 제거할 때 시나리오를 수정할 필요 없이 데이터 소스만 업데이트하면 됩니다. 확장성과 유지보수성을 동시에 확보하는 핵심 전략입니다.

멀티 사이트 관리 자동화의 전체 아키텍처

Make.com 기반 멀티 사이트 관리 시스템은 크게 4개의 레이어로 구성됩니다:


1. 데이터 레이어 (Data Layer) - Google Sheets 또는 Airtable에 관리 대상 사이트 목록, API 인증 정보, 관리 설정을 저장합니다. 사이트 추가/제거 시 이 레이어만 수정하면 됩니다.


2. 오케스트레이션 레이어 (Orchestration Layer) - Make.com 시나리오가 중앙 제어 역할을 합니다. 스케줄 트리거, Webhook, Iterator, Router 등을 조합하여 전체 워크플로우를 관리합니다.


3. 통신 레이어 (Communication Layer) - WordPress REST API를 통해 각 사이트와 통신합니다. 커스텀 엔드포인트를 통해 표준 REST API로는 불가능한 고급 기능도 지원합니다.


4. 리포팅 레이어 (Reporting Layer) - 수집된 데이터를 Google Sheets 대시보드, Slack 알림, 이메일 리포트 등으로 시각화하고 전달합니다.

📋
사이트 목록
(Google Sheets)
Make.com
오케스트레이션
🔗
REST API
병렬 호출
🌐
N개 WordPress
사이트 처리
📊
통합 대시보드
& 알림

Make.com으로 중앙 콘텐츠 배포 시나리오 구축

콘텐츠 동시 배포의 원리와 설계

중앙 콘텐츠 배포 시스템은 하나의 콘텐츠를 작성하면 지정된 모든 WordPress 사이트에 동시에 발행되는 구조입니다. 이 시스템은 프랜차이즈 본사에서 각 지점 사이트에 공지사항을 배포하거나, 미디어 네트워크에서 동일한 뉴스를 여러 사이트에 동시 게재하거나, 에이전시가 클라이언트 사이트에 정기 콘텐츠를 배포하는 등의 시나리오에 적합합니다.


Make.com 시나리오의 핵심은 Iterator 모듈입니다. Google Sheets에서 사이트 목록을 가져온 후, Iterator가 각 사이트를 순회하면서 WordPress REST API를 통해 콘텐츠를 발행합니다. 에러 핸들러를 추가하면 특정 사이트에서 오류가 발생해도 나머지 사이트의 배포는 계속 진행됩니다.

1
사이트 마스터 시트 생성: Google Sheets에 관리 대상 사이트의 URL, API 사용자명, Application Password, 활성 상태, 카테고리 매핑 정보를 기록합니다. 각 사이트별로 고유한 Application Password를 발급받아 저장합니다. 이 시트가 전체 시스템의 Single Source of Truth(유일한 진실의 원천)가 됩니다.
2
Make.com 시나리오 생성: 새 시나리오를 생성하고 트리거 모듈을 설정합니다. Webhook 트리거(즉시 배포)와 Schedule 트리거(예약 배포)를 모두 준비합니다. Webhook은 외부 시스템에서 즉시 배포를 요청할 때 사용하고, Schedule은 정기 배포에 사용합니다.
3
사이트 목록 로드: Google Sheets 모듈로 사이트 마스터 시트를 읽어옵니다. Active 필드가 "YES"인 사이트만 필터링하여 비활성 사이트는 자동으로 건너뜁니다. 이렇게 하면 특정 사이트를 일시 중지하고 싶을 때 시트에서 Active를 "NO"로만 변경하면 됩니다.
4
Iterator 설정: 사이트 목록 배열을 Iterator에 연결합니다. Iterator는 각 사이트 정보를 하나씩 꺼내어 다음 모듈로 전달합니다. 각 반복(iteration)마다 해당 사이트의 URL, 인증 정보, 카테고리 매핑이 개별적으로 처리됩니다.
5
HTTP 요청 모듈: WordPress REST API에 POST 요청을 보내 콘텐츠를 발행합니다. URL은 Iterator에서 전달받은 사이트 URL + /wp-json/wp/v2/posts로 구성합니다. Basic Auth 헤더에 해당 사이트의 사용자명과 Application Password를 설정합니다.
6
에러 핸들링: HTTP 요청 모듈에 에러 핸들러를 추가합니다. 특정 사이트에서 오류(서버 다운, 인증 실패 등)가 발생해도 시나리오 전체가 중단되지 않도록 합니다. 오류 정보를 별도 배열에 기록하여 최종 리포트에 포함합니다.
7
결과 집계 및 알림: Array Aggregator로 모든 사이트의 배포 결과를 수집하고, 성공/실패 건수를 집계합니다. 결과를 Google Sheets 로그 시트에 기록하고, Slack이나 이메일로 배포 완료 알림을 발송합니다.

사이트 마스터 시트 구조

Google Sheets에 아래와 같은 구조로 사이트 정보를 관리합니다. 각 사이트별로 고유한 인증 정보와 설정을 저장하여 Make.com 시나리오에서 동적으로 참조합니다.

// Google Sheets: 사이트 마스터 시트 구조 // ┌──────────────────────────────────────────────────────────────────────────────────┐ // │ Site ID │ Site URL │ API User │ App Password │ Active │ Category │ // ├──────────────────────────────────────────────────────────────────────────────────┤ // │ site_01 │ https://brand-a.com │ api_admin│ xxxx xxxx .. │ YES │ 뉴스 │ // │ site_02 │ https://brand-b.co.kr │ api_admin│ yyyy yyyy .. │ YES │ 블로그 │ // │ site_03 │ https://shop-c.com │ editor │ zzzz zzzz .. │ YES │ 제품 │ // │ site_04 │ https://media-d.co.kr │ api_admin│ wwww wwww .. │ NO │ 뉴스 │ // │ site_05 │ https://franchise-e.com │ manager │ vvvv vvvv .. │ YES │ 공지 │ // │ ... │ ... │ ... │ ... │ ... │ ... │ // └──────────────────────────────────────────────────────────────────────────────────┘ // Make.com 시나리오 구성: // [Webhook/Schedule] → [Google Sheets: 사이트 목록] → [Filter: Active=YES] // → [Iterator] → [HTTP: POST /wp-json/wp/v2/posts] → [Error Handler] // → [Array Aggregator] → [Google Sheets: 로그 기록] → [Slack: 알림] // Make.com HTTP 모듈 설정 예시: // URL: {{iterator.site_url}}/wp-json/wp/v2/posts // Method: POST // Headers: // Authorization: Basic {{base64(iterator.api_user + ":" + iterator.app_password)}} // Content-Type: application/json // Body: { "title": "{{webhook.post_title}}", "content": "{{webhook.post_content}}", "status": "{{webhook.post_status}}", "categories": ["{{iterator.category_id}}"], "meta": { "_source_site": "central-hub", "_distribution_id": "{{webhook.distribution_id}}", "_deployed_at": "{{now}}" } }

WordPress 측: 원격 관리용 커스텀 플러그인

모든 관리 대상 사이트에 동일한 커스텀 플러그인을 설치합니다. 이 플러그인은 Make.com에서 호출할 수 있는 REST API 엔드포인트를 제공하며, 사이트 상태 조회, 콘텐츠 일괄 발행, 플러그인 관리, 보안 스캔 등의 기능을 포함합니다. 표준 WordPress REST API만으로는 제공되지 않는 관리 기능을 커스텀 엔드포인트를 통해 확장합니다.

/** * Plugin Name: MAP Remote Manager * Description: Make.com Automation Platform 원격 관리 엔드포인트 * Version: 2.0.0 * Author: WordPress Automation Team */ // 보안 체크 defined('ABSPATH') || exit; class MAP_Remote_Manager { private static $instance = null; public static function get_instance() { if (null === self::$instance) { self::$instance = new self(); } return self::$instance; } private function __construct() { add_action('rest_api_init', [$this, 'register_endpoints']); } public function register_endpoints() { // 사이트 종합 상태 조회 register_rest_route('map-remote/v1', '/status', [ 'methods' => 'GET', 'callback' => [$this, 'get_site_status'], 'permission_callback' => [$this, 'check_admin_permission'], ]); // 일괄 콘텐츠 발행 register_rest_route('map-remote/v1', '/bulk-publish', [ 'methods' => 'POST', 'callback' => [$this, 'bulk_publish'], 'permission_callback' => [$this, 'check_publish_permission'], ]); // 플러그인 목록 및 업데이트 현황 register_rest_route('map-remote/v1', '/plugins', [ 'methods' => 'GET', 'callback' => [$this, 'get_plugins_status'], 'permission_callback' => [$this, 'check_admin_permission'], ]); // 플러그인 일괄 업데이트 실행 register_rest_route('map-remote/v1', '/plugins/update', [ 'methods' => 'POST', 'callback' => [$this, 'update_plugins'], 'permission_callback' => [$this, 'check_admin_permission'], ]); // 보안 스캔 엔드포인트 register_rest_route('map-remote/v1', '/security-scan', [ 'methods' => 'GET', 'callback' => [$this, 'run_security_scan'], 'permission_callback' => [$this, 'check_admin_permission'], ]); // 백업 상태 확인 register_rest_route('map-remote/v1', '/backup-status', [ 'methods' => 'GET', 'callback' => [$this, 'get_backup_status'], 'permission_callback' => [$this, 'check_admin_permission'], ]); } // ===== 사이트 종합 상태 ===== public function get_site_status() { global $wp_version; $theme = wp_get_theme(); return [ 'site_name' => get_bloginfo('name'), 'site_url' => home_url(), 'wp_version' => $wp_version, 'php_version' => PHP_VERSION, 'mysql_version' => $GLOBALS['wpdb']->db_version(), 'theme_name' => $theme->get('Name'), 'theme_version' => $theme->get('Version'), 'post_count' => wp_count_posts()->publish, 'page_count' => wp_count_posts('page')->publish, 'user_count' => count_users()['total_users'], 'active_plugins' => count(get_option('active_plugins')), 'disk_usage' => size_format($this->get_upload_size()), 'last_post_date' => get_lastpostdate('blog', 'post'), 'updates_plugins' => $this->count_plugin_updates(), 'updates_themes' => $this->count_theme_updates(), 'ssl_valid' => is_ssl(), 'memory_limit' => WP_MEMORY_LIMIT, 'debug_mode' => WP_DEBUG, 'timestamp' => current_time('mysql'), ]; } // ===== 일괄 콘텐츠 발행 ===== public function bulk_publish($request) { $params = $request->get_json_params(); $results = []; foreach ($params['posts'] as $post_data) { $post_id = wp_insert_post([ 'post_title' => sanitize_text_field($post_data['title']), 'post_content' => wp_kses_post($post_data['content']), 'post_status' => $post_data['status'] ?? 'draft', 'post_author' => get_current_user_id(), 'post_category' => $post_data['categories'] ?? [], 'meta_input' => $post_data['meta'] ?? [], ]); if (!is_wp_error($post_id)) { // 피처 이미지 설정 if (!empty($post_data['featured_image_url'])) { $this->set_featured_image($post_id, $post_data['featured_image_url']); } $results[] = [ 'status' => 'success', 'post_id' => $post_id, 'url' => get_permalink($post_id), ]; } else { $results[] = [ 'status' => 'error', 'error' => $post_id->get_error_message(), ]; } } return [ 'total' => count($results), 'success' => count(array_filter($results, fn($r) => $r['status'] === 'success')), 'results' => $results, 'timestamp' => current_time('mysql'), ]; } // ===== 퍼미션 체크 ===== public function check_admin_permission() { return current_user_can('manage_options'); } public function check_publish_permission() { return current_user_can('publish_posts'); } // ===== 헬퍼 메서드 ===== private function get_upload_size() { $upload_dir = wp_upload_dir(); $size = 0; $path = $upload_dir['basedir']; if (is_dir($path)) { foreach (new RecursiveIteratorIterator( new RecursiveDirectoryIterator($path) ) as $file) { $size += $file->getSize(); } } return $size; } private function count_plugin_updates() { $updates = get_site_transient('update_plugins'); return isset($updates->response) ? count($updates->response) : 0; } private function count_theme_updates() { $updates = get_site_transient('update_themes'); return isset($updates->response) ? count($updates->response) : 0; } private function set_featured_image($post_id, $image_url) { require_once ABSPATH . 'wp-admin/includes/media.php'; require_once ABSPATH . 'wp-admin/includes/file.php'; require_once ABSPATH . 'wp-admin/includes/image.php'; $attach_id = media_sideload_image($image_url, $post_id, null, 'id'); if (!is_wp_error($attach_id)) { set_post_thumbnail($post_id, $attach_id); } } } MAP_Remote_Manager::get_instance();
Application Password 관리 팁
WordPress 5.6부터 Application Password 기능이 기본 내장되어 있습니다. 각 사이트에서 사용자 프로필 > Application Passwords에서 Make.com 전용 비밀번호를 발급하세요. 일반 로그인 비밀번호와 분리되어 있어 보안적으로 안전하며, 문제 발생 시 해당 Application Password만 삭제하면 됩니다. 중요: Application Password는 발급 시 한 번만 표시되므로 즉시 Google Sheets에 기록해야 합니다. 또한 각 사이트마다 고유한 Application Password를 사용하여, 하나의 사이트 인증이 유출되어도 다른 사이트에 영향이 없도록 관리하세요.
🔒
여기까지는 미리보기입니다
멀티 사이트 동시 관리
무료 가입하면 이어서 볼 수 있고, 강의를 완료할 때마다 XP와 레벨이 쌓입니다.
Google로 3초 만에 시작 →🧵 Threads로 시작무료 공개 강의 둘러보기 (Lv.1~3)