Files
Gnuboard7/docs/requirements.md
T
HeuJung 2ae1972a3b perf(core): 대용량 목록 상한 총 건수·커서 계약 신설 및 요청당 반복 실행 비용 정리
공개 이슈 gnuboard/g7 이 지목한 병목은 "같은 일을 반복 실행한다" 축이다.
응답·행의 무게를 다룬 · 과 겹치지 않는다.

공통 계약 — 총 건수 상한과 페이지 이동 범위는 별개 결정이다. 묶으면 필요 없이
기능이 깎인다. 총 건수만 상한을 받고(파생 테이블 COUNT), "다음" 이동은
per_page + 1 실측으로 끝까지 열어 둔다. 계산이 불가능해지는 것은 마지막 페이지
번호 하나뿐이며 그 사실은 last_page: null 이 알린다. 최신순처럼 실제 컬럼으로
정렬하는 목록은 커서로 전환해 깊이와 무관하게 일정 속도로 이동한다. 관련도순은
계산값 정렬이라 커서 키로 쓸 수 없어 offset 을 유지한다.

계약의 입구는 표준 paginate 와 같은 폭이어야 한다. 관계·쿼리 빌더를 받지 못하면
그 좁은 만큼이 그대로 운영 500 이 되고, 실제로 관리자 알림 목록에서 그렇게 터졌다.
응답 조립도 컬렉션마다 손으로 하면 형태가 늘어나는 순간 없는 값을 부르거나 새
필드를 흘리므로, 형태 판정을 paginationMeta 한 곳에 모았다. 표준 paginate
응답은 필드 단위로 이전과 동일하다.

요청당 반복 비용 — 훅 구독마다 남기던 로그 400줄, 요청당 스무 번 넘던 설정 파일
재읽기, 이미 캐시된 목록의 DB 재조회를 없앴다. 권한 판정은 요청 스코프 메모를 두어
화면 요소마다 나가던 조회를 한 번으로 줄였고, 크로스 요청 캐시는 두지 않아 권한
변경이 종전처럼 다음 요청에 반영된다.

검색 질의는 활성 엔진이 만든다. 저장소가 구체 엔진을 지목하면 플러그인이 등록한
엔진은 호출될 기회 자체를 잃고 오류 없이 다른 방식으로 동작한다. 해석기를 두어
활성 엔진에 위임하고, 전문검색이 없는 DBMS 의 부분일치 폴백도 드라이버명 하드코딩
대신 선언형 config 로 옮겼다.

총 건수가 잘린 목록에서 순번을 역산하면 0 과 음수가 나온다. 지어내지 않고 null 을
돌려주며, 그 원칙을 last_page 와 동일하게 적용했다.
2026-08-06 11:13:51 +09:00

13 KiB
Raw Permalink Blame History

그누보드7 시스템 요구사항 (System Requirements)

그누보드7 설치 및 운영을 위한 서버/클라이언트 요구사항 문서

TL;DR (5초 요약)

1. PHP 8.2+ 필수
2. MySQL 8.0+ 또는 MariaDB 10.3+ (utf8mb4, utf8mb4_unicode_ci)
3. PHP 필수 모듈 30개 (ctype, curl, gd, intl, redis, imagick 등)
4. 하드웨어: 최소 2 vCPU·2GB / 권장 4 vCPU·8GB, 디스크 최소 700MB / 권장 2GB+
5. 프로덕션: HTTPS 필수, Redis 권장, 큐 워커/스케줄러/Reverb 데몬 필요

1. 서버 요구사항

1.1 운영체제

OS 지원 수준 비고
Linux (Ubuntu 22.04+, CentOS/RHEL 8+) 프로덕션 권장 가장 안정적

1.2 웹서버

웹서버 버전 비고
Nginx 1.18+ 프로덕션 권장
Apache 2.4+ mod_rewrite 활성화 필수
  • Laravel은 public/index.php를 진입점으로 사용
  • Apache 사용 시 .htaccess 파일이 URL 리라이팅 처리

1.3 PHP

항목 요구사항
버전 8.2 이상 (^8.2)
SAPI FPM (권장) 또는 mod_php (Apache + mod_fcgid 환경은 §1.3.1)

1.3.1 Apache + mod_fcgid 환경 추가 설정 (권장)

PHP 8.5 NTS(Windows) 등 mod_php DLL 이 제공되지 않는 빌드를 Apache 와 결합할 때 PHP 가 php-cgi.exe 기반 mod_fcgid 로 구동된다. 이 SAPI 의 default 출력 버퍼(FcgidOutputBufferSize 64KB) 가 인스톨러 SSE 스트림과 폴링 응답을 스크립트 종료 시점까지 보관하여 진행 상황이 화면에 실시간 반영되지 않는다.

Apache fcgid.conf 에 다음 1줄을 추가 후 Apache 재시작:

FcgidOutputBufferSize 0

미설정 시:

  • 인스톨러 SSE 호환성 사전 체크가 buffered 환경으로 자동 판정되어 폴링 모드로 fallback
  • 폴링 모드 응답은 코드 레벨 64KB padding 워크어라운드로 동작은 보장되나, SSE 모드가 아닌 1초 간격 폴링으로 진행 상황이 표시됨

1.4 PHP 필수 확장 모듈

모듈 용도
bcmath 정밀 수학 연산 (가격 계산 등)
ctype 문자 타입 검사
curl HTTP 클라이언트
dom XML/HTML DOM 처리
exif 이미지 메타데이터 읽기
fileinfo MIME 타입 감지
filter 데이터 필터링/검증
gd 이미지 처리 (썸네일, 리사이징)
hash 해시 함수
imagick 고급 이미지 처리 (ImageMagick)
intl 국제화 (다국어, 날짜/숫자 포맷)
json JSON 인코딩/디코딩
ldap LDAP 인증 연동
libxml XML 파싱 기반 라이브러리
maxminddb GeoIP 데이터베이스 조회
mbstring 멀티바이트 문자열 처리
memcached Memcached 캐시 드라이버
openssl 암호화/복호화 (AES-256-CBC)
pcntl 프로세스 제어 (큐 워커)
pcre 정규 표현식
pdo 데이터베이스 추상화
pdo_mysql MySQL/MariaDB PDO 드라이버
phar Phar 아카이브 (Composer)
posix POSIX 함수 (프로세스 관리)
redis Redis 캐시/세션/큐 드라이버
session 세션 관리
simplexml 간편 XML 파싱
sodium 최신 암호화 라이브러리
tokenizer PHP 토큰 파싱
xml XML 파서
xmlwriter XML 문서 생성
zip ZIP 압축/해제
zlib 데이터 압축

1.5 PHP 설정 권장값 (php.ini)

설정 최소값 권장값 비고
memory_limit 128M 256M+ 이미지 처리 시 높은 메모리 필요
upload_max_filesize 10M 20M+ 첨부파일 업로드 크기
post_max_size 12M 25M+ upload_max_filesize보다 커야 함
max_execution_time 60 120+ 대량 데이터 처리 시
max_input_vars 1000 5000+ 복잡한 폼 데이터 처리

1.6 파일 권한 및 umask 운영 방식

G7 은 배포 환경에 따라 세 가지 대표 운영 방식을 지원한다. 본 섹션은 각 방식에서 storage/ 등 런타임 쓰기 대상 디렉토리의 권한 설정과 umask 권장값을 정리한다.

운영 방식 분류

운영 방식 소유자 : 그룹 권장 퍼미션 전형적 환경
A. 그룹 공유 사용자 : www-data (서로 다른 UID) drwxrwxr-x (0775) + g+w SSH 로그인 사용자와 php-fpm 프로세스가 UID 가 다르고 www-data 같은 공용 그룹으로 파일 쓰기 권한을 공유하는 일반적인 Ubuntu/Debian 구성
B. 단일 소유자 사용자 : 사용자 또는 www-data : www-data (동일 UID) drwxr-xr-x (0755) suexec / mod_userdir / 단순 Apache 환경에서 파일 소유자·웹서버 프로세스가 같은 UID
C. suexec / cPanel 계정별 UID 격리 drwxr-xr-x (0755) 공유 호스팅, 계정마다 독립 UID/GID

storage/ 디렉토리의 실제 퍼미션을 확인:

stat -c '%a %U:%G' storage

권장 설정

방식 A (그룹 공유):

# 인스톨러 완료 후 운영자가 1회 실행
sudo chown -R $USER:www-data storage bootstrap/cache vendor modules plugins templates
sudo chmod -R 775 storage bootstrap/cache vendor modules plugins templates

추가로 php-fpm / systemd 의 umask 를 002 로 설정하면 cron·composer·수동 SSH artisan 등 외부 프로세스도 동일 권한으로 파일을 만든다.

설정 지점 값 위치 예시
php-fpm pool umask = 002 /etc/php/8.x/fpm/pool.d/www.conf
systemd unit UMask=0002 /lib/systemd/system/php8.x-fpm.service [Service] 섹션

시스템 레벨 설정이 없어도 코어 부팅 시 storage/ 의 g+w 여부를 감지하여 프로세스 umask 를 자동으로 0002 로 동조하므로 Laravel 부팅 경로를 거치는 파일 생성은 정상 동작한다 (public/index.php, artisan, queue worker, scheduler 등). 시스템 레벨 설정은 부팅 경로를 거치지 않는 외부 프로세스 대응용 권장 사항.

방식 B/C (단일 소유자):

sudo chmod -R 755 storage bootstrap/cache vendor modules plugins templates

그룹 쓰기 비트가 없으므로 코어 자동 umask 동조는 발동하지 않는다 (운영자 의도 존중). 추가 설정 불필요.

인스톨러가 안내하는 기본 권한

인스톨러의 기본 안내 명령은 보수적으로 chmod -R 755 를 제시한다. 방식 A 로 운영하려면 인스톨 완료 후 775 로 재조정 + 소유자/그룹을 본인 계정 + www-data 로 변경. 인스톨러는 chmod 를 직접 호출하지 않으므로 운영자가 쉘에서 1회 실행.


2. 데이터베이스

2.1 지원 DBMS

DBMS 최소 버전 비고
MySQL 8.0 이상 프로덕션 권장
MariaDB 10.3 이상 MySQL 호환 대안

2.2 설정 요구사항

항목 값 비고
charset utf8mb4 이모지 등 4바이트 문자 지원
collation utf8mb4_unicode_ci 유니코드 정렬
테이블 접두어 g7_ (기본값) .env에서 DB_PREFIX로 변경 가능

선택 기능:

  • Write/Read 분리: Master-Replica 구성 지원 (DB_WRITE_* / DB_READ_* 환경 변수)

3. 하드웨어 사양

3.1 CPU · 메모리

수준 CPU 메모리 상정 환경
최소 2 vCPU 2GB 설치·기능 확인용. 동시 접속이 거의 없는 개발/검토 환경
권장 4 vCPU 8GB 웹서버 + PHP-FPM + MySQL + Redis 를 한 대에 올린 소규모 운영
분리 구성 웹 2 vCPU / DB 2 vCPU 각 4GB 이상 트래픽이 늘면 DB 를 먼저 분리

메모리 배분은 어떤 구성 요소를 같은 서버에 올렸는지에 따라 달라진다. 한 대에 모두 올린 경우 MySQL 의 innodb_buffer_pool_size 가 전체 메모리의 절반을 넘지 않도록 두고, PHP-FPM 자식 프로세스 수 × memory_limit 가 남은 메모리를 넘지 않는지 확인한다.

위 수치는 코어와 번들 확장을 기본 설정으로 운영할 때의 출발점이다. 실제 필요량은 데이터 규모·동시 접속·설치한 확장에 따라 달라지므로, 운영 전 대상 트래픽으로 직접 측정할 것을 권한다(php artisan g7:bench 로 목록·화면·쓰기·배치 4축을 잰다).

이 수치의 근거

  • 권장 4 vCPU · 8GB — 사용자가 4 vCPU · 8GB 가상머신에서 수행한 운영 환경 측정 보고 (gnuboard/g7#82)에서 코어와 번들 확장을 함께 올린 구성이 동작한 사양이다. 같은 보고에서 대량 데이터의 검색·목록 조회는 이 사양에서도 메모리 압박이 관측되었으므로, "이 사양이면 어떤 규모든 충분하다" 는 뜻이 아니라 한 대 구성의 하한선으로 읽어야 한다.
  • 최소 2 vCPU · 2GB — 설치와 기능 확인이 가능한 수준으로, 위 보고의 측정 대상이 아니다. 동시 접속이 있는 운영에는 적합하지 않다.
  • 분리 구성 — 위 보고에서 부하가 먼저 걸린 지점이 데이터베이스였다는 관측에 따른 순서 제안이다. 분리 시점의 트래픽 임계값은 측정하지 않았다.

우리가 직접 측정한 범위는 쿼리 실행 횟수와 조회 구조이며, 특정 사양에서의 동시 접속 한계나 응답 시간은 측정하지 않았다. 그 값이 필요하면 대상 환경에서 직접 재야 한다.

3.2 디스크 용량

수준 용량 포함 범위
최소 700MB 코어 + 기본 확장
권장 2GB 이상 코어 + 확장 + 첨부파일 + 캐시 + 로그
  • 사용자 업로드 파일, 로그, 캐시 등은 별도 용량 산정 필요
  • storage/ 디렉토리에 쓰기 권한 필수

4. 선택적 서비스 (프로덕션 권장)

4.1 Redis

항목 요구사항 비고
Redis 6.0 이상 캐시, 세션, 큐 드라이버로 사용 가능
  • 프로덕션 환경에서 캐시/세션/큐 성능 향상을 위해 권장
  • PHP redis 확장 필요 (phpredis)

4.2 클라우드 서비스 (AWS)

서비스 용도 필수 여부
AWS S3 파일 스토리지 (클라우드) 선택
AWS SES 이메일 발송 선택
AWS SQS 큐 처리 (대규모 트래픽) 선택
  • aws/aws-sdk-php 패키지 포함됨

4.3 메일 서비스

서비스 비고
Mailgun symfony/mailgun-mailer 패키지 포함됨
AWS SES 위 AWS 서비스 참조
SMTP 자체 SMTP 서버 사용 가능
  • 이메일 발송이 필요 없는 경우 MAIL_MAILER=log로 설정

4.4 WebSocket (Laravel Reverb)

항목 요구사항 비고
Laravel Reverb 포함됨 (laravel/reverb ^1.6) 자체 호스팅 WebSocket 서버
기본 포트 8080 REVERB_PORT로 변경 가능
  • 실시간 알림, 브로드캐스팅 기능 사용 시 필요
  • 대안: Pusher 서비스 (pusher-js 클라이언트 포함됨)

5. 보안

5.1 SSL/TLS

환경 요구사항
프로덕션 HTTPS 필수
  • Laravel Reverb WebSocket도 wss:// 프로토콜 사용 (REVERB_SCHEME=https)
  • Sanctum 세션 인증 시 SESSION_SECURE_COOKIE=true 설정 권장

6. 프로덕션 데몬 프로세스

프로덕션 환경에서 상시 실행해야 하는 프로세스:

프로세스 명령어 관리 도구
큐 워커 php artisan queue:work Supervisor 등
스케줄러 php artisan schedule:run cron (매분 실행)
WebSocket php artisan reverb:start Supervisor 등
# cron 예시 (스케줄러)
* * * * * cd /path/to/g7 && php artisan schedule:run >> /dev/null 2>&1

7. 지원 브라우저

브라우저 지원 범위
Chrome / Edge 최신 2개 버전
Firefox 최신 2개 버전
Safari 최신 2개 버전
  • React 19 + Tailwind CSS 4 호환 범위 기준
  • Internet Explorer 미지원

8. 호스팅 환경별 제한사항

8.1 공유 호스팅 (Shared Hosting)

공유 호스팅에서도 그누보드7 설치는 가능하지만, 호스팅 업체에 따라 아래 기능이 제한될 수 있습니다.

제한될 수 있는 기능:

제한 항목 영향받는 기능 대안
데몬 프로세스 (Supervisor) 큐 워커 상시 실행 불가 QUEUE_CONNECTION=sync (동기 처리)
cron 최소 간격 스케줄러 분 단위 실행 제한 호스팅 cPanel cron (지원 간격 확인)
PHP 확장 제한 (pcntl, posix, redis, imagick 등) 큐 워커, 프로세스 관리, Redis 캐시, 이미지 처리 파일/DB 캐시, GD 라이브러리
PHP 설정 변경 (memory_limit, max_execution_time 등) 대용량 파일 업로드, 이미지 처리 호스팅 관리자에게 변경 요청
커스텀 포트 (80/443 외) Reverb WebSocket (기본 8080 포트) Pusher 등 외부 WebSocket 서비스
파일 권한 (symlink 등) storage/ 심볼릭 링크 php artisan storage:link 대체 방식 확인
디스크 용량 첨부파일, 로그, 캐시 누적 플랜별 용량 확인, 정기 정리