개요
OpenProject는 독일에서 개발된 선도적인 오픈소스 프로젝트 관리 소프트웨어로, GNU GPL v3 라이선스로 배포됩니다. 클래식, 애자일, 하이브리드 프로젝트 관리를 모두 지원하며, Gantt 차트, 작업 관리, 팀 협업, 시간/비용 추적 기능을 제공합니다. 유럽의 데이터 보호 기준을 충족하며, 데이터 주권이 중요한 조직에 적합합니다.
OpenProject의 핵심 철학
OpenProject는 “데이터 보호와 정보 보안”을 최우선으로, 오픈소스의 투명성과 엔터프라이즈급 기능을 결합했습니다. 독일 베를린에 본사를 둔 회사가 개발하여 EU 데이터 보호 규정을 완벽히 준수합니다.
주요 특징
| 기능 | 설명 |
|---|---|
| Gantt 차트 | 프로젝트 타임라인 시각화, 의존성 관리 |
| 애자일 보드 | Scrum/Kanban 지원, 스프린트 관리 |
| 작업 패키지 | 이슈/태스크/버그 통합 관리 |
| 팀 플래너 | 주간/격주 캘린더로 리소스 할당 |
| 시간 추적 | 작업별 시간 기록 및 보고서 |
| 비용 관리 | 예산 설정 및 비용 추적 |
| 위키 | 프로젝트 문서화 |
| 포럼 | 팀 토론 공간 |
| 미팅 관리 | 회의록 및 일정 관리 |
| 뉴스 | 프로젝트 공지사항 |
| BIM 지원 | 건설/건축 프로젝트 지원 (Enterprise) |
프로젝트 관리 도구 비교
| 기능 | OpenProject | Jira | MS Project | Plane |
|---|---|---|---|---|
| 오픈소스 | ✅ | ❌ | ❌ | ✅ |
| 셀프호스팅 | ✅ | 제한적 | ❌ | ✅ |
| Gantt 차트 | ✅ | 제한적 | ✅ | ✅ |
| 애자일 보드 | ✅ | ✅ | ❌ | ✅ |
| 시간 추적 | ✅ | 플러그인 | ❌ | ❌ |
| 비용 관리 | ✅ | 플러그인 | ✅ | ❌ |
| 위키 | ✅ | Confluence | ❌ | ✅ |
| EU 데이터 준수 | ✅ | ❌ | ❌ | – |
| 무제한 사용자 | ✅ | ❌ | ❌ | 제한적 |
에디션 비교
| 기능 | Community (무료) | Enterprise |
|---|---|---|
| 기본 프로젝트 관리 | ✅ | ✅ |
| Gantt 차트 | ✅ | ✅ |
| 애자일 보드 | ✅ | ✅ |
| 시간/비용 추적 | ✅ | ✅ |
| 위키/포럼 | ✅ | ✅ |
| 고급 보고서 | ❌ | ✅ |
| LDAP/SAML SSO | ❌ | ✅ |
| 2FA | ❌ | ✅ |
| 문서 관리 (실시간 협업) | ❌ | ✅ |
| 전문 지원 | ❌ | ✅ |
시스템 요구 사항
| 항목 | 최소 사양 | 권장 사양 (200+ 사용자) |
|---|---|---|
| RAM | 4GB | 8GB+ (더 많은 워커 필요) |
| CPU | 2 코어 | 4+ 코어 |
| 저장소 | 20GB | 50GB+ |
| PostgreSQL | 13+ | 16+ 권장 |
| Docker | 20.10+ | 최신 버전 |
Docker Compose 설치
방법 1: All-in-One 컨테이너 (간단한 설치)
mkdir -p ~/openproject && cd ~/openproject
# 단일 컨테이너 실행
docker run -d \
--name openproject \
-p 8080:80 \
-e OPENPROJECT_SECRET_KEY_BASE=your-secret-key-here \
-e OPENPROJECT_HOST__NAME=openproject.yourdomain.com \
-v openproject-pgdata:/var/openproject/pgdata \
-v openproject-assets:/var/openproject/assets \
openproject/openproject:15
방법 2: Docker Compose (프로덕션 권장)
1) 디렉토리 및 환경 변수 설정
mkdir -p ~/openproject && cd ~/openproject
.env 파일 생성:
# 도메인 설정
OPENPROJECT_HOST__NAME=openproject.yourdomain.com
OPENPROJECT_HTTPS=true
# Secret Key (필수 - 랜덤 문자열 생성)
OPENPROJECT_SECRET_KEY_BASE=your-very-long-random-secret-key-here-at-least-64-chars
# 데이터베이스
POSTGRES_USER=openproject
POSTGRES_PASSWORD=your_secure_db_password
POSTGRES_DB=openproject
DATABASE_URL=postgres://openproject:your_secure_db_password@db:5432/openproject
# 이메일 설정 (선택사항)
OPENPROJECT_EMAIL__DELIVERY__METHOD=smtp
OPENPROJECT_SMTP__ADDRESS=smtp.example.com
OPENPROJECT_SMTP__PORT=587
OPENPROJECT_SMTP__USER__NAME=your-email@example.com
OPENPROJECT_SMTP__PASSWORD=your-email-password
OPENPROJECT_SMTP__ENABLE__STARTTLS__AUTO=true
OPENPROJECT_MAIL__FROM=openproject@example.com
# 기타 설정
OPENPROJECT_DEFAULT__LANGUAGE=ko
OPENPROJECT_LOG__LEVEL=info
2) docker-compose.yml
version: "3.8"
x-op-app: &app
image: openproject/openproject:15
restart: unless-stopped
environment:
OPENPROJECT_HOST__NAME: ${OPENPROJECT_HOST__NAME}
OPENPROJECT_HTTPS: ${OPENPROJECT_HTTPS:-false}
OPENPROJECT_SECRET_KEY_BASE: ${OPENPROJECT_SECRET_KEY_BASE}
DATABASE_URL: ${DATABASE_URL}
OPENPROJECT_EMAIL__DELIVERY__METHOD: ${OPENPROJECT_EMAIL__DELIVERY__METHOD:-}
OPENPROJECT_SMTP__ADDRESS: ${OPENPROJECT_SMTP__ADDRESS:-}
OPENPROJECT_SMTP__PORT: ${OPENPROJECT_SMTP__PORT:-}
OPENPROJECT_SMTP__USER__NAME: ${OPENPROJECT_SMTP__USER__NAME:-}
OPENPROJECT_SMTP__PASSWORD: ${OPENPROJECT_SMTP__PASSWORD:-}
OPENPROJECT_SMTP__ENABLE__STARTTLS__AUTO: ${OPENPROJECT_SMTP__ENABLE__STARTTLS__AUTO:-}
OPENPROJECT_MAIL__FROM: ${OPENPROJECT_MAIL__FROM:-}
OPENPROJECT_DEFAULT__LANGUAGE: ${OPENPROJECT_DEFAULT__LANGUAGE:-en}
volumes:
- openproject-assets:/var/openproject/assets
services:
db:
image: postgres:15-alpine
container_name: openproject-db
restart: unless-stopped
stop_grace_period: "3s"
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
volumes:
- openproject-pgdata:/var/lib/postgresql/data
networks:
- openproject-network
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
interval: 10s
timeout: 5s
retries: 5
cache:
image: memcached:alpine
container_name: openproject-cache
restart: unless-stopped
networks:
- openproject-network
web:
<<: *app
container_name: openproject-web
command: "./docker/prod/web"
depends_on:
db:
condition: service_healthy
cache:
condition: service_started
seeder:
condition: service_completed_successfully
networks:
- openproject-network
labels:
- autoheal=true
worker:
<<: *app
container_name: openproject-worker
command: "./docker/prod/worker"
depends_on:
db:
condition: service_healthy
cache:
condition: service_started
seeder:
condition: service_completed_successfully
networks:
- openproject-network
cron:
<<: *app
container_name: openproject-cron
command: "./docker/prod/cron"
depends_on:
db:
condition: service_healthy
cache:
condition: service_started
seeder:
condition: service_completed_successfully
networks:
- openproject-network
seeder:
<<: *app
container_name: openproject-seeder
command: "./docker/prod/seeder"
restart: on-failure
depends_on:
db:
condition: service_healthy
cache:
condition: service_started
networks:
- openproject-network
proxy:
image: nginx:alpine
container_name: openproject-proxy
restart: unless-stopped
ports:
- "8080:80"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
- openproject-assets:/var/openproject/assets:ro
depends_on:
- web
networks:
- openproject-network
volumes:
openproject-pgdata:
openproject-assets:
networks:
openproject-network:
driver: bridge
3) Nginx 설정 파일 (nginx.conf)
upstream openproject {
server openproject-web:8080;
}
server {
listen 80;
server_name _;
client_max_body_size 100M;
location / {
proxy_pass http://openproject;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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_read_timeout 300;
proxy_connect_timeout 300;
}
location /assets {
alias /var/openproject/assets;
expires max;
add_header Cache-Control public;
}
}
4) 실행
docker-compose up -d
# 로그 확인
docker-compose logs -f
# 초기화 완료 확인 (seeder 완료까지 대기)
docker-compose logs seeder
Traefik 리버스 프록시 설정
services:
proxy:
image: nginx:alpine
container_name: openproject-proxy
restart: unless-stopped
labels:
- "traefik.enable=true"
- "traefik.http.routers.openproject.rule=Host(`openproject.yourdomain.com`)"
- "traefik.http.routers.openproject.entrypoints=websecure"
- "traefik.http.routers.openproject.tls.certresolver=myresolver"
- "traefik.http.services.openproject.loadbalancer.server.port=80"
networks:
- openproject-network
- traefik-network
초기 설정
1) 웹 접속
브라우저에서 http://localhost:8080 또는 설정한 도메인으로 접속합니다.
2) 기본 관리자 계정
- 사용자명: admin
- 비밀번호: admin
첫 로그인 시 비밀번호 변경이 요구됩니다.
3) 시스템 설정
관리자로 로그인 후 Administration 메뉴에서:
- General settings: 언어, 시간대 설정
- Email settings: SMTP 설정 확인
- Users: 사용자 추가 및 권한 설정
- Roles and permissions: 역할별 권한 정의
주요 기능 활용
Gantt 차트 사용법
- 프로젝트 > Gantt charts 모듈 선택
- 작업 패키지 생성 및 시작/종료일 설정
- 드래그 앤 드롭으로 일정 조정
- 의존성 설정: 선행/후행 작업 연결
- PDF 내보내기 가능
애자일 보드 설정
- 프로젝트 > Boards 모듈 선택
- Action board 또는 Basic board 생성
- 컬럼 추가/수정 (To Do, In Progress, Done 등)
- 작업 패키지를 카드로 드래그 앤 드롭
팀 플래너
- 프로젝트 > Team planner 선택
- 팀원별 주간/격주 캘린더 뷰
- 작업 할당 및 일정 시각화
- 리소스 충돌 확인
작업 패키지 유형
| 유형 | 용도 |
|---|---|
| Task | 일반 작업 |
| Feature | 새 기능 개발 |
| Bug | 버그 수정 |
| User Story | 사용자 스토리 |
| Epic | 대규모 작업 그룹 |
| Milestone | 주요 이정표 |
| Phase | 프로젝트 단계 |
트러블슈팅
seeder 실패
# seeder 로그 확인
docker-compose logs seeder
# seeder 재실행
docker-compose restart seeder
데이터베이스 연결 오류
# DB 상태 확인
docker-compose exec db psql -U openproject -d openproject -c "SELECT 1"
# 마이그레이션 실행
docker-compose exec web bundle exec rails db:migrate
파일 업로드 실패
# assets 볼륨 권한 확인
docker-compose exec web ls -la /var/openproject/assets
# 권한 수정
docker-compose exec web chown -R app:app /var/openproject/assets
성능 최적화
# docker-compose.yml에서 워커 수 조정
environment:
OPENPROJECT_WEB__WORKERS: 4
OPENPROJECT_WEB__TIMEOUT: 300
백업 및 복원
데이터베이스 백업
# PostgreSQL 백업
docker-compose exec db pg_dump -U openproject openproject > openproject_backup_$(date +%Y%m%d).sql
# 복원
cat openproject_backup.sql | docker-compose exec -T db psql -U openproject openproject
Assets 백업
# assets 볼륨 백업
docker run --rm -v openproject_openproject-assets:/data -v $(pwd):/backup alpine tar czf /backup/assets_$(date +%Y%m%d).tar.gz /data
전체 백업 스크립트
#!/bin/bash
BACKUP_DIR="/backups/openproject/$(date +%Y%m%d)"
mkdir -p $BACKUP_DIR
# 데이터베이스
docker-compose exec -T db pg_dump -U openproject openproject > $BACKUP_DIR/database.sql
# Assets
docker run --rm -v openproject_openproject-assets:/data -v $BACKUP_DIR:/backup alpine tar czf /backup/assets.tar.gz /data
# 환경 변수
cp .env $BACKUP_DIR/
echo "Backup completed: $BACKUP_DIR"
업그레이드
# 백업 먼저 수행
./backup.sh
# 이미지 업데이트
docker-compose pull
# 서비스 재시작
docker-compose down
docker-compose up -d
# 마이그레이션 (자동 실행되지만 확인)
docker-compose logs seeder
Nextcloud 연동
OpenProject는 Nextcloud와 통합하여 파일 관리 기능을 확장할 수 있습니다:
- Nextcloud에 Team folders 앱 설치
- OpenProject 관리 > File storages에서 Nextcloud 연결
- 프로젝트별 자동 폴더 관리 가능 (Enterprise)