Nextcloud 17 설치 가이드: CentOS 8, Nginx, PHP 7.3, MariaDB

Nextcloud 17을 CentOS 8 서버에 Nginx, PHP-FPM 7.3, MariaDB로 설치하고 Let’s Encrypt로 HTTPS를 적용하는 단계별 가이드입니다. 최소 요구사항(2GB RAM, 25GB 디스크, 2 vCPU)에 맞춰 패키지 리포지토리 설정, PHP 최적화, SELinux 설정, Nginx 가상호스트 구성과 문제 해결 팁까지 포함합니다.
중요: 도메인과 이메일, 데이터베이스 비밀번호 등 민감 정보는 반드시 본인 값으로 바꾸세요.
개요
Nextcloud는 오픈소스 개인용 클라우드 소프트웨어로, ownCloud에서 포크되어 개발되었습니다. PHP와 JavaScript로 작성되며 MySQL/MariaDB, PostgreSQL, Oracle, SQLite 등 다양한 데이터베이스를 지원합니다. 이 가이드는 CentOS 8 서버에서 Nginx, PHP-FPM 7.3, MariaDB를 이용해 Nextcloud 17을 설치하고 SSL을 적용해 보안을 강화하는 절차를 설명합니다.
목표
- Nginx 웹서버 설치와 방화벽 설정
- PHP-FPM 7.3 설치와 Nextcloud 권장 설정 적용
- MariaDB 설치 및 Nextcloud용 데이터베이스 설정
- Let’s Encrypt로 SSL 인증서 발급
- Nextcloud 소스 설치 및 권한 설정
- Nginx 가상호스트 구성
- SELinux 설정
- 설치 후 점검과 보안/성능 권장사항
시스템 권장 사양(이 튜토리얼용)
- 메모리: 2GB
- 디스크 여유: 25GB
- CPU: 2 vCPU
- 운영체제: CentOS 8
중요 용어 1줄 정의
- PHP-FPM: PHP 요청을 FastCGI 방식으로 처리하는 데몬
- Nginx: 리버스 프록시와 정적 파일 처리가 뛰어난 웹서버
- SELinux: 커널 레벨 보안 모듈
사전 준비
- 도메인 이름이 있고 DNS에 A 또는 AAAA 레코드가 서버 IP를 가리키도록 설정되어 있어야 합니다.
- root 또는 sudo 권한이 있는 사용자 계정이 필요합니다.
- 방화벽(firewalld)이 활성화되어 있다면 HTTP(80)와 HTTPS(443)를 허용해야 합니다.
1. Nginx 설치 및 방화벽 열기
Nginx는 빠르고 가벼운 웹서버로, Nextcloud에서 정적 파일 제공과 PHP-FPM 프록시 역할을 합니다. CentOS 8의 AppStream 리포지토리에서 설치합니다.
명령:
sudo dnf install nginx
설치가 끝나면 서비스를 시작하고 부팅 시 자동 시작하도록 설정합니다.
systemctl start nginx
systemctl enable nginx
상태 확인:
systemctl status nginx
서비스가 정상이라면 방화벽에 HTTP와 HTTPS를 추가합니다.
firewall-cmd --add-service=http --permanent
firewall-cmd --add-service=https --permanent
firewall-cmd --reload
설치 완료 후 예상 결과: Nginx가 80/443 포트에서 요청을 수신할 준비가 되어 있습니다.
참고: 방화벽 대신 클라우드 제공자의 보안그룹을 사용하는 경우 해당 규칙에서 포트를 열어야 합니다.
2. PHP-FPM 7.3 설치
Nextcloud 17 권장 PHP 버전은 7.2 또는 7.3입니다. CentOS 8 기본은 더 최신/모듈형이므로 REMI 리포지토리의 remi-7.3 모듈을 활성화하여 PHP 7.3을 사용합니다.
리포지토리 준비 및 설치:
sudo dnf config-manager --set-enabled PowerTools
sudo dnf install epel-release
sudo dnf install https://rpms.remirepo.net/enterprise/remi-release-8.rpm
dnf repolist
PHP 모듈 목록 확인 및 remi-7.3 활성화:
dnf module list php
dnf module enable php:remi-7.3
PHP 및 필요한 확장 설치:
sudo dnf install php-fpm php-cli php-devel php-gd php-mysqlnd php-pear php-xml php-mbstring php-pdo php-json php-pecl-apcu php-pecl-apcu-devel php-pecl-imagick-devel php-intl php-opcache php-zip
설치 후 PHP-FPM 서비스는 다음 단계에서 설정 파일을 편집한 뒤 시작합니다.
성능 팁: Nextcloud에서는 opcache와 APCu가 성능에 큰 도움을 줍니다. opcache는 PHP 코드 캐시, APCu는 객체 캐시로 자주 사용됩니다.
3. PHP-FPM 7.3 구성
설정 파일을 편집하여 Nextcloud에 권장되는 PHP 설정을 적용합니다.
php.ini 편집:
vim /etc/php.ini
아래 항목을 찾아 주석을 해제하고 값 변경:
memory_limit = 512M
date.timezone = Asia/Seoul
cgi.fixpathinfo = 0
참고: date.timezone은 서버 위치에 맞게 바꾸세요. 예시는 서울 시간입니다.
opcache 설정:
vim /etc/php.d/10-opcache.ini
다음 설정으로 변경:
opcache.enable=1
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=10000
opcache.memory_consumption=128
opcache.save_comments=1
opcache.revalidate_freq=1
PHP-FPM 풀 설정:
vim /etc/php-fpm.d/www.conf
다음 사항을 적용합니다:
- user와 group을 nginx로 변경
- listen을 소켓으로 변경
- 환경 변수와 opcache 파일 캐시 경로 주석 해제
예시 변경:
user = nginx
group = nginx
listen = /run/php-fpm/www.sock
env[HOSTNAME] = $HOSTNAME
env[PATH] = /usr/local/bin:/usr/bin:/bin
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp
php_value[opcache.file_cache] = /var/lib/php/opcache
세션과 opcache용 디렉터리를 만들고 소유권 설정:
mkdir -p /var/lib/php/{session,opcache}
chown -R nginx:nginx /var/lib/php/{session,opcache}
서비스 시작 및 자동 시작 등록:
systemctl enable php-fpm
systemctl start php-fpm
상태 확인 및 소켓 존재 확인:
netstat -pl | grep php
systemctl status php-fpm
운영 팁: 소켓 기반 통신은 localhost TCP보다 약간 빠르고 권한 관리가 편리합니다. 그러나 컨테이너화나 분산 환경에서는 TCP를 고려하세요.
4. MariaDB 설치 및 Nextcloud용 데이터베이스 구성
Nextcloud는 데이터베이스를 사용해 사용자와 메타데이터를 저장합니다. 이 가이드에서는 MariaDB를 사용합니다.
설치:
sudo dnf install mariadb mariadb-server
서비스 시작 및 자동 시작 등록:
systemctl start mariadb
systemctl enable mariadb
루트 계정 보안 설정:
mysql_secure_installation
대화형 질문 예시에는 대부분 Y로 응답하여 익명 사용자 제거, 테스트 DB 제거, 권한 테이블 재로드를 수행합니다.
MySQL 셸에서 데이터베이스와 사용자 생성:
mysql -u root -p
create database nextcloud_db;
create user nextclouduser@localhost identified by 'nextcloudpassdb';
grant all privileges on nextcloud_db.* to nextclouduser@localhost identified by 'nextcloudpassdb';
flush privileges;
중요: 실제 환경에서는 암호를 더 강하게 설정하고 호스트 범위를 필요 최소한으로 제한하세요. 또한 비밀번호는 안전한 비밀 관리 시스템(예: Vault)에 저장하는 것을 권장합니다.
백업 팁: 데이터베이스 백업은 정기적으로 수행하고 백업 파일은 암호화하여 다른 물리적 위치에 보관하세요.
5. Let’s Encrypt SSL 인증서 발급
공개 도메인에 대해 HTTPS를 적용하려면 certbot을 사용해 무료 TLS 인증서를 발급받습니다. 이 가이드는 webroot 플러그인을 사용합니다.
certbot 설치:
sudo dnf install certbot
인증서 발급(도메인과 이메일을 본인 값으로 변경):
certbot certonly --webroot --webroot-path /usr/share/nginx/html --agree-tos -m [email protected] -d cloud.hakase-labs.io
발급된 인증서는 다음 경로에 저장됩니다:
/etc/letsencrypt/live/cloud.hakase-labs.io/
확인:
ls -lah /etc/letsencrypt/live/cloud.hakase-labs.io/
자동 갱신 크론은 certbot이 설치될 때 자동으로 설정되기도 하지만, 아래 명령으로 테스트 갱신을 권장합니다.
certbot renew --dry-run
권장: 인증서 사용 경로를 Nginx 구성에서 정확히 지정하고, privkey와 fullchain 권한을 적절히 제한하세요.
6. Nextcloud 다운로드 및 설치 파일 준비
Nextcloud 소스 코드를 /var/www에 다운로드합니다.
필수 패키지 설치:
sudo dnf install unzip wget
다운로드 및 압축 해제:
cd /var/www/
wget https://download.nextcloud.com/server/releases/nextcloud-17.0.2.zip
unzip nextcloud-17.0.2.zip
데이터 디렉터리 생성 및 권한 설정:
mkdir -p /var/www/nextcloud/data/
sudo chown -R nginx:nginx /var/www/nextcloud
Nextcloud의 data 디렉터리는 웹서버가 읽고 쓸 수 있어야 하므로 SELinux와 파일권한 설정이 필요합니다. 아래 SELinux 섹션을 참고하세요.
보안 팁: data 디렉터리를 웹 루트와 분리된 볼륨에 두고 정기적으로 백업합니다.
7. Nginx 가상호스트 설정
/etc/nginx/conf.d에 Nextcloud용 설정 파일을 만듭니다.
cd /etc/nginx/conf.d/
vim nextcloud.conf
아래 구성은 Nextcloud의 권장 Nginx 설정을 기반으로 하며, 도메인명과 SSL 인증서 경로는 본인 환경에 맞춰 변경하세요.
upstream php-handler {
#server 127.0.0.1:9000;
server unix:/run/php-fpm/www.sock;
}
server {
listen 80;
listen [::]:80;
server_name cloud.hakase-labs.io;
# enforce https
return 301 https://$server_name:443$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name cloud.hakase-labs.io;
ssl_certificate /etc/ssl/nginx/fullchain.pem;
ssl_certificate_key /etc/ssl/nginx/privkey.pem;
add_header Referrer-Policy "no-referrer" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Download-Options "noopen" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Permitted-Cross-Domain-Policies "none" always;
add_header X-Robots-Tag "none" always;
add_header X-XSS-Protection "1; mode=block" always;
fastcgi_hide_header X-Powered-By;
root /var/www/nextcloud;
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location = /.well-known/carddav {
return 301 $scheme://$host:$server_port/remote.php/dav;
}
location = /.well-known/caldav {
return 301 $scheme://$host:$server_port/remote.php/dav;
}
client_max_body_size 512M;
fastcgi_buffers 64 4K;
gzip on;
gzip_vary on;
gzip_comp_level 4;
gzip_min_length 256;
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
location / {
rewrite ^ /index.php;
}
location ~ ^\/(?:build|tests|config|lib|3rdparty|templates|data)\/ {
deny all;
}
location ~ ^\/(?:\.|autotest|occ|issue|indie|db_|console) {
deny all;
}
location ~ ^\/(?:index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+)\.php(?:$|\/) {
fastcgi_split_path_info ^(.+?\.php)(\/.*|)$;
set $path_info $fastcgi_path_info;
try_files $fastcgi_script_name =404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $path_info;
fastcgi_param HTTPS on;
fastcgi_param modHeadersAvailable true;
fastcgi_param front_controller_active true;
fastcgi_pass php-handler;
fastcgi_intercept_errors on;
fastcgi_request_buffering off;
}
location ~ ^\/(?:updater|oc[ms]-provider)(?:$|\/) {
try_files $uri/ =404;
index index.php;
}
location ~ \.(?:css|js|woff2?|svg|gif|map)$ {
try_files $uri /index.php$request_uri;
add_header Cache-Control "public, max-age=15778463";
add_header Referrer-Policy "no-referrer" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Download-Options "noopen" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Permitted-Cross-Domain-Policies "none" always;
add_header X-Robots-Tag "none" always;
add_header X-XSS-Protection "1; mode=block" always;
access_log off;
}
location ~ \.(?:png|html|ttf|ico|jpg|jpeg|bcmap)$ {
try_files $uri /index.php$request_uri;
access_log off;
}
}
구성 테스트 및 Nginx 재시작:
nginx -t
systemctl restart nginx
포트 확인:
netstat -plntu
주의 사항: 위 구성에서 ssl_certificate 경로는 certbot으로 발급한 경로 또는 시스템별 경로로 바꿔야 합니다. 본 예시는 /etc/ssl/nginx를 사용한 가상 경로입니다.
8. SELinux 설정
서버에서 SELinux를 Enforcing 모드로 유지하면서 Nextcloud가 정상 동작하도록 컨텍스트를 설정합니다.
관리 도구 설치:
sudo dnf install policycoreutils-python-utils
다음 명령으로 웹서버가 쓰기 권한이 필요한 디렉터리에 올바른 SELinux 유형을 할당합니다.
semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/nextcloud/data(/.*)?'
semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/nextcloud/config(/.*)?'
semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/nextcloud/apps(/.*)?'
semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/nextcloud/assets(/.*)?'
semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/nextcloud/.htaccess'
semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/nextcloud/.user.ini'
restorecon -Rv '/var/www/nextcloud/'
검증: restorecon이 에러 없이 완료되면 파일 컨텍스트가 적용됩니다. 필요 시 ls -laZ /var/www/nextcloud
로 컨텍스트를 확인하세요.
SELinux 팁: SELinux 로그(/var/log/audit/audit.log)를 확인하여 denied 항목이 있으면 audit2allow로 정책을 생성하거나, 필요한 경우만 예외를 만드세요.
9. 웹 설치 마법사로 최종 설정
브라우저를 열고 도메인으로 접속합니다. 예:
설치 페이지에서 관리 계정과 비밀번호를 입력하고 데이터베이스는 MySQL/MariaDB를 선택하여 앞서 만든 데이터베이스 정보를 입력합니다.
관리자 계정 예시 입력:
- 관리자 사용자: admin
- 비밀번호: 안전한 비밀번호
- 데이터베이스: MySQL/MariaDB
- 데이터베이스 이름: nextcloud_db
- 데이터베이스 사용자: nextclouduser
- 데이터베이스 비밀번호: nextcloudpassdb
Finish Setup을 클릭하면 Nextcloud 설치가 진행됩니다. 설치가 완료되면 대시보드로 이동합니다.
설치 후 점검 목록:
- 로그인 가능한지 확인
- 파일 업로드/다운로드 테스트
- 캘린더/CardDAV 동기화 테스트(필요한 경우)
- 인증서 경고가 없는지 확인
운영 및 보안 권장사항
- 정기 업데이트
- OS와 패키지, Nextcloud를 정기적으로 업데이트하세요. 보안 패치를 우선 적용합니다.
- 백업 전략
- 데이터베이스와 Nextcloud의 data 디렉터리를 정기적으로 백업하세요. 스냅샷과 원격 복제를 병행하면 안전합니다.
- 모니터링
- 서비스(nginx, php-fpm, mariadb) 상태와 로그를 모니터링하고, 디스크 사용량과 메모리 사용량 임계값을 설정하세요.
- TLS 강화
- 불필요한 TLS 버전과 취약한 사이퍼를 비활성화하고 HSTS를 적용하되 preload는 신중히 사용하세요.
- 브루트 포스 방지
- fail2ban 같은 도구를 사용해 로그인 시도 과다 IP를 차단하세요.
- 앱 관리
- Nextcloud 앱은 신뢰할 수 있는 소스만 설치하고, 사용하지 않는 앱은 비활성화하세요.
성능 최적화 팁
- PHP 메모리 제한을 필요에 따라 조정하세요(예: 512M). 사용량이 많으면 늘립니다.
- opcache 및 APCu를 사용하여 PHP와 객체 캐시를 활성화하세요.
- 외부 저장소를 사용하는 경우 지연 시간을 고려하세요.
- 파일 업로드 제한(client_max_body_size)은 필요에 따라 조정하세요.
대안과 확장 옵션
- 웹서버 대안: Apache + mod_php 또는 Apache + php-fpm. 일부 환경에서 .htaccess가 유리합니다.
- 데이터베이스 대안: PostgreSQL은 높은 동시성 처리에서 장점이 있으며 대규모 환경에서 추천됩니다.
- 간단한 테스트 환경: SQLite 사용 가능하지만 다중 사용자 또는 대규모 배포에는 권장되지 않습니다.
역할별 체크리스트
시스템 관리자
- 도메인 DNS 설정 확인
- 방화벽 규칙 적용
- 정기 백업 및 복구 테스트
- 운영체제와 패키지 업데이트
Dev/Ops
- CI/CD로 업그레이드 테스트 자동화
- 모니터링 경보 설정
- 성능 테스트 및 튜닝
엔드유저
- 클라이언트 앱(Windows/Mac/Linux/Android/iOS) 설치
- 동기화 폴더 설정 및 테스트
- 2단계 인증 활성화(관리자가 허용할 경우)
문제 해결 가이드
문제: Nginx가 502 Bad Gateway 반환
원인과 해결책:
- PHP-FPM이 실행 중인지 확인
systemctl status php-fpm
- 소켓 권한 문제 체크
ls -la /run/php-fpm/www.sock
- 소유자가 nginx인지 확인하고 필요 시 재시작
- php-fpm 로그 확인
/var/log/php-fpm/error.log
또는 시스템 저널
문제: 업로드 파일이 0바이트로 저장됨
원인과 해결책:
- Nginx 설정의 client_max_body_size가 충분한지 확인
- PHP의 upload_max_filesize와 post_max_size 확인
- SELinux가 파일 쓰기를 차단하는지 확인
ausearch -m avc -ts recent
또는/var/log/audit/audit.log
문제: 인증서 관련 경고
원인과 해결책:
- 브라우저가 인증서를 신뢰하지 않음: 올바른 도메인으로 발급했는지 확인
- 인증서 만료:
certbot renew --dry-run
로 갱신 테스트
추가 디버깅 명령
journalctl -u nginx -e
journalctl -u php-fpm -e
journalctl -u mariadb -e
tail -n 200 /var/log/letsencrypt/letsencrypt.log
마이그레이션과 업그레이드 팁
- 메이저 업그레이드 전에 전체 백업을 수행하세요.
- Nextcloud의 앱 호환성 체크리스트를 확인하고 비호환 앱은 비활성화하세요.
- 테스트 환경에서 업그레이드를 검증한 뒤 프로덕션에 적용하세요.
점검표: 설치 완료 후 확인할 항목
- 웹으로 접속하여 로그인 성공
- SSL이 적용되어 브라우저 경고 없음
- 파일 업로드 및 다운로드 정상
- 데이터베이스 연결 확인
- SELinux 컨텍스트 적용 확인
- 백업 스케줄이 설정되어 있음
- 모니터링이 설정되어 있음
요약
이 가이드에서는 CentOS 8에 Nginx, PHP-FPM 7.3, MariaDB 기반으로 Nextcloud 17을 설치하는 전체 절차를 다뤘습니다. 리포지토리 설정, PHP 최적화, SELinux와 파일권한, Let’s Encrypt로 TLS 적용, Nginx 가상호스트 구성까지 포함되어 있어 실무 환경에 바로 적용할 수 있습니다.
핵심 권장 사항
- 보안 패치와 인증서 갱신을 자동화하세요.
- 정기 백업과 복구 테스트를 수행하세요.
- SELinux를 비활성화하기보다는 필요한 예외만 추가하세요.
참고 자료
감사의 말
이 문서는 실습 환경에서 테스트된 절차를 기준으로 작성되었습니다. 실제 운영 환경에서는 인프라 정책과 보안 규정을 우선 적용하세요.