CentOS 8 환경에서 OnlyOffice 구축하기
기업 내부에서 문서 협업 환경을 구축할 때 OnlyOffice는 Microsoft Office Online과 유사한 기능을 오픈소스로 제공하는 대안이다. 이번 가이드에서는 Docker 기반으로 안정적인 문서 서버를 구축하고 Nextcloud와 연동하는 과정을 다룬다.
1. 시스템 환경 구성
먼저 서버 기본 설정을 완료한다. CentOS 8 Stream 기준으로 작성되었으며, 실제 운영 환경에 맞게 경로와 사용자명은 적절히 수정해야 한다.
# 시스템 업데이트
sudo dnf update -y
# 필수 저장소 추가
sudo dnf install -y epel-release
sudo dnf config-manager --set-enabled powertools
# 컨테이너 관련 의존성 설치
sudo dnf install -y yum-utils device-mapper-persistent-data lvm2
# 방화벽 규칙 설정 (firewalld 사용 시)
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --permanent --add-port=8000/tcp
sudo firewall-cmd --reload
# SELinux 컨텍스트 조정 (Docker 볼륨 마운트 이슈 방지)
sudo setsebool -P container_manage_cgroup on
2. 컨테이너 런타임 설치
Docker 대신 Podman을 사용할 수도 있지만, OnlyOffice 공식 이미지와의 호환성을 위해 Docker CE를 설치한다.
# 기존 Docker 패키지 제거
sudo dnf remove -y docker docker-client docker-client-latest docker-common \
docker-latest docker-latest-logrotate docker-logrotate docker-engine
# Docker 저장소 등록
sudo yum-config-manager --add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
# Docker 설치 및 서비스 활성화
sudo dnf install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
sudo systemctl enable --now docker
# 관리 사용자를 docker 그룹에 추가
sudo usermod -aG docker $USER
# 이미지 풀 가속 설정 (선택사항)
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json > /dev/null <<'EOF'
{
"registry-mirrors": [
"https://mirror.gcr.io",
"https://docker.mirrors.ustc.edu.cn"
],
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
EOF
sudo systemctl restart docker
3. OnlyOffice 문서 서버 배포
docker-compose를 활용하여 문서 서버를 정의한다. JWT 토큰을 설정하여 무단 접근을 방지하고, 문서 변환 워커 수는 서버 사양에 따라 조정한다.
mkdir -p ~/onlyoffice-deploy && cd ~/onlyoffice-deploy
cat > compose.yml <<'EOF'
services:
docs:
image: onlyoffice/documentserver:latest
container_name: office-docs
restart: unless-stopped
ports:
- "127.0.0.1:8088:80"
environment:
- JWT_ENABLED=true
- JWT_SECRET=${JWT_SECRET_KEY:?JWT_SECRET_KEY is required}
- JWT_HEADER=Authorization
- JWT_IN_BODY=false
- WOPI_ENABLED=true
volumes:
- doc_data:/var/www/onlyoffice/Data
- doc_logs:/var/log/onlyoffice
- doc_cache:/var/lib/onlyoffice/documentserver/App_Data/cache/files
deploy:
resources:
limits:
cpus: '4.00'
memory: 8G
volumes:
doc_data:
doc_logs:
doc_cache:
EOF
# 환경 변수 파일 생성
read -s -p "JWT 비밀키 입력 (32자 이상 권장): " jwt_key
echo "JWT_SECRET_KEY=${jwt_key}" > .env
docker compose up -d
배포 후 내부 헬스체크 엔드포인트로 상태를 확인한다.
curl -f http://localhost:8088/healthcheck || echo "서비스 점검 필요"
4. Nginx 리버스 프록시 구성
외부 접근을 위해 Nginx를 프론트엔드로 배치한다. WebSocket 지원이 필수적이며, 대용량 파일 업로드를 고려한 버퍼 설정이 필요하다.
sudo dnf install -y nginx
sudo tee /etc/nginx/conf.d/onlyoffice.conf > /dev/null <<'EOF'
upstream doc_backend {
server 127.0.0.1:8088;
keepalive 32;
}
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
server_name docs.company.internal;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl http2;
server_name docs.company.internal;
# SSL 인증서 경로 (certbot 발급 후 수정)
ssl_certificate /etc/letsencrypt/live/docs.company.internal/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/docs.company.internal/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256';
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
# HSTS (운영 환경에서만 활성화)
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
client_max_body_size 512M;
client_body_buffer_size 16k;
location / {
proxy_pass http://doc_backend;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
proxy_buffering off;
}
location ~ /\. {
deny all;
}
}
EOF
sudo nginx -t && sudo systemctl reload nginx
5. TLS 인증서 자동화
Let's Encrypt를 통해 무료 인증서를 발급받고 자동 신을 설정한다. 내부망 환경이라면 기업 PKI나 사설 CA 인증서를 대신 사용할 수 있다.
# certbot 설치
sudo dnf install -y certbot python3-certbot-nginx
# 인증서 발급 (DNS 검증이 필요한 경우 --preferred-challenges dns 추가)
sudo certbot --nginx -d docs.company.internal --agree-tos --non-interactive \
--email admin@company.internal --redirect
# 자동 갱신 테스트
sudo certbot renew --dry-run
# 크론탭에 갱신 작업 등록
echo "0 3 * * * root certbot renew --quiet --deploy-hook 'systemctl reload nginx'" | \
sudo tee /etc/cron.d/certbot-renewal > /dev/null
6. Nextcloud 연동 설정
Nextcloud 관리자 페이지에서 OnlyOffice 플리케이션을 활성화한 후, 다음과 같이 설정한다.
| 설정 항목 | 값 |
|---|---|
| 문서 서버 주소 | https://docs.company.internal |
| 비밀 키 (JWT) | compose.yml에 정의한 JWT_SECRET_KEY 값 |
| 헤더 | Authorization |
| 편집 권한 | 문서, 스프레드시트, 프레젠테이션, 양식 |
고급 설정에서 강제 저장과 공동 편집 모드를 활성화하면 실시간 협업이 원활해진다. 모바일 클라이언트에서도 정상 작동하려면 문서 서버 주소가 외부에서 접근 가능한 도메인이어야 한다.
7. 운영 자동화 스크립트
지속적인 운영을 위해 다음 스크립트를 /opt/onlyoffice-maintain에 배치한다.
#!/bin/bash
# /opt/onlyoffice-maintain/backup.sh
BACKUP_ROOT="/backup/onlyoffice"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
RETENTION_DAYS=30
mkdir -p "${BACKUP_ROOT}"
# 문서 데이터 백업
tar czf "${BACKUP_ROOT}/docs_${TIMESTAMP}.tar.gz" \
-C /var/lib/docker/volumes/onlyoffice-deploy_doc_data/_data .
# 설정 백업
tar czf "${BACKUP_ROOT}/config_${TIMESTAMP}.tar.gz" \
~/onlyoffice-deploy/
# 오래된 백업 삭제
find "${BACKUP_ROOT}" -name "*.tar.gz" -mtime +${RETENTION_DAYS} -delete
# 백업 결과 알림 (메일 또는 웹훅)
echo "OnlyOffice 백업 완료: ${TIMESTAMP}" >> /var/log/onlyoffice-backup.log
#!/bin/bash
# /opt/onlyoffice-maintain/healthcheck.sh
STATUS=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:8088/healthcheck)
if [ "$STATUS" != "200" ]; then
systemctl restart docker
echo "$(date): 문서 서버 재시작" >> /var/log/onlyoffice-monitor.log
fi
크론탭에 다음 항목을 등록한다.
# 매일 2시 백업
0 2 * * * /opt/onlyoffice-maintain/backup.sh
# 5분마다 상태 점
*/5 * * * * /opt/onlyoffice-maintain/healthcheck.sh
문제 해결 참고사항
- 변환 서비스 장애:
documentserver-converter프로세스 메모리 부족 시lib/v8힙 크기를 늘린다. - 한글 폰트 깨짐: 테이너 내부
/usr/share/fonts에 나눔폰트나 마인드폰트를 마운트한다. - 協同 편집 지연: WebSocket 프록시 버퍼링 해제 확인,
proxy_buffering off설정 누락 여부 점검. - Nextcloud 연동 실패: JWT 토큰 불일치가 가장 흔한 원인. 양쪽 설정의 대소문자와 공백을 확인한다.