Fast Byte - Thuê VPS Giá Rẻ
Hướng dẫn chung

Cách Cài OpenProject trên VPS Ubuntu 24.04 Tự Host Quản Lý Dự Án A–Z

Cài OpenProject trên VPS Ubuntu 24.04 là con đường nhiều team chọn để sở hữu hệ thống quản lý dự án mạnh như Jira mà không phải trả phí SaaS hàng tháng. Thế nhưng OpenProject là ứng dụng Ruby on Rails “nặng ký”, cài sai cách rất dễ gặp lỗi OOM, SSL hay seeder treo […]

Ảnh đại diện Thanh Lam NguyễnThanh Lam Nguyễn28 phút đọc

Cài OpenProject trên VPS Ubuntu 24.04 là con đường nhiều team chọn để sở hữu hệ thống quản lý dự án mạnh như Jira mà không phải trả phí SaaS hàng tháng. Thế nhưng OpenProject là ứng dụng Ruby on Rails “nặng ký”, cài sai cách rất dễ gặp lỗi OOM, SSL hay seeder treo giữa chừng. Bài viết này sẽ đi cùng bạn từng bước — từ chọn VPS, chạy Docker Compose, đấu Nginx với SSL cho đến backup — bắt đầu bằng một chiếc VPS giá rẻ đủ tài nguyên.

1. Tổng Quan Về OpenProject & Các Tính Năng Cốt Lõi

OpenProject là ứng dụng nền tảng Ruby on Rails mã nguồn mở phục vụ quản trị dự án chuyên sâu, tích hợp phương pháp truyền thống kết hợp Agile linh hoạt. Đây là giải pháp có khối lượng tài nguyên lớn nhất trong số các phần mềm quản lý dự án mã nguồn mở hiện nay, do đó cần được vận hành chuẩn mực như một hệ thống Rails production thực thụ.

OpenProject là gì
OpenProject là gì?

Các tính năng trung tâm của hệ thống

  • Lập kế hoạch dự án: Quản lý cây công việc (Work Packages) phân cấp, xác định mốc quan trọng (milestones), sản phẩm bàn giao, mối quan hệ phụ thuộc, phân rã dự án con và sử dụng kho mẫu dự án sẵn có. Các dự án có thể nhóm thành danh mục (portfolio) để theo dõi tổng thể.
  • Gói công việc (Work Packages): Linh hồn của OpenProject với khả năng biểu diễn đa dạng từ task, bug, feature, user story đến risk, change request hay ticket hỗ trợ. Hỗ trợ theo dõi tiến độ, phân bổ người nhận, ngày bắt đầu/kết thúc, ước tính giờ làm, trường tùy biến, đính kèm tệp và người theo dõi.
  • Biểu đồ Gantt tương tác: Trực quan hóa tiến độ theo dòng thời gian thực, hỗ trợ kéo thả ngày thực hiện, thiết lập đường gantt găng (critical path) và phát hiện điểm nghẽn dự án.
  • Bảng Agile linh hoạt: Tích hợp đầy đủ mô hình Scrum (Backlog sản phẩm, Backlog sprint, biểu đồ Burndown) và Kanban (tùy biến cột, swimlanes, giới hạn WIP, thẻ kéo thả).
  • Theo dõi thời gian & Chi phí: Ghi nhận giờ làm việc thực tế, phân loại hoạt động tính phí và không tính phí, kiểm soát chi phí nhân sự, vật tư, ngân sách và dự báo dòng tiền.
  • Hợp tác & Tài liệu nội bộ: Tích hợp Wiki cho từng dự án, trao đổi thảo luận, thông báo mentions, quản trị tài liệu PDF/Office/bản vẽ có kiểm soát lịch sử phiên bản.
  • Quản lý người dùng & Xác thực: Không giới hạn số lượng tài khoản trên bản Community Edition; phân quyền chi tiết theo vai trò; hỗ trợ xác thực LDAP, Active Directory, OIDC, SAML.
  • Hệ sinh thái tích hợp & REST API: Tương thích tốt với GitHub, GitLab, Nextcloud, Jenkins, Azure DevOps, Slack thông qua Webhooks và REST API mạnh mẽ để tự động hóa quy trình.

VPS Cloud Giá Rẻ

CPU Intel Gold, SSD NVMe U.2, giá từ 50K/tháng

Nền tảng máy chủ ảo tối ưu cho dự án Rails nặng

OpenProject tiêu thụ tài nguyên liên tục cho các tác vụ nền, worker và cơ sở dữ liệu PostgreSQL. Hạ tầng máy chủ của Fast Byte với ổ cứng NVMe tốc độ cao cùng RAM thật dồi dào sẽ đảm bảo quy trình compile asset và seeder diễn ra suôn sẻ, tránh hiện tượng nghẽn I/O hay OOM crash.

Tham khảo VPS giá rẻ

Ưu điểm khi tự host OpenProject

  • Miễn phí và open source (Community Edition).
  • Self-hosted, sở hữu dữ liệu hoàn toàn.
  • Bộ tính năng giàu có mà không tốn phí SaaS định kỳ.
  • Workflow tùy biến sâu.
  • Hỗ trợ mạnh cả Agile lẫn quản lý dự án truyền thống.
  • Phát triển tích cực, cập nhật đều đặn.
  • REST API toàn diện, tài liệu xuất sắc.
  • Phù hợp tổ chức ở mọi quy mô.

Hạn chế khi tự host OpenProject

  • Phức tạp hơn để quản trị so với các tool nhẹ như Trello.
  • Cấu hình ban đầu cần nhiều công đoạn lập kế hoạch hơn các nền tảng SaaS.
  • Một số tính năng nâng cao (SSO mở rộng, custom branding, module chuyên biệt) thuộc về bản Enterprise.
  • Giao diện “đặc ruột” tính năng có thể khiến team thích trình quản lý task tối giản thấy rối.

OpenProject có phù hợp với bạn?

OpenProject là lựa chọn xuất sắc nếu bạn cần một giải pháp self-host thay cho Jira hay Microsoft Project, muốn sở hữu và kiểm soát toàn bộ dữ liệu dự án, cần hỗ trợ cả Agile lẫn PM truyền thống, đòi hỏi tùy biến và automation sâu, muốn tích hợp với công cụ phát triển và hệ thống xác thực doanh nghiệp, hoặc cần nền tảng scale từ team nhỏ lên tổ chức lớn.

Với nhà cung cấp hosting, phòng IT, MSP, team phần mềm hay firm kỹ thuật, OpenProject mang lại một nền tảng trưởng thành, dễ mở rộng, cân bằng giữa tính năng quản lý dự án toàn diện và sự linh hoạt của mã nguồn mở.

OpenProject được dùng rộng rãi trong phát triển phần mềm, IT operations, MSP, kỹ thuật – xây dựng, chính phủ, sản xuất, y tế, giáo dục, pháp lý và nonprofit; quản lý tốt cả sprint phần mềm, triển khai hạ tầng, chiến dịch marketing, dự án compliance lẫn phát triển sản phẩm.

2. Yêu Cầu Phần Cứng VPS & Chuẩn Bị Môi Trường

Một kiến trúc OpenProject đầy đủ sẽ bao gồm Puma web server, tiến trình worker nền, container cron kiểu Sidekiq, cơ sở dữ liệu PostgreSQL, memcached, internal proxy Caddy và máy chủ biên tập cộng tác theo thời gian thực (collaborative editing server). Đừng bao giờ triển khai trên gói máy chủ 2GB RAM vì bước nén tài nguyên giao diện (asset precompile) và nạp dữ liệu mẫu ban đầu (seeder) sẽ lập tức làm cạn bộ nhớ.

Ưu tiên lựa chọn hạ tầng triển khai dựa trên công nghệ ảo hóa KVM độc lập thay vì OpenVZ để đảm bảo tương thích hoàn toàn nhân Linux thực tế, quản lý tài nguyên cgroups và chạy Docker ổn định.

Quy mô người dùng vCPU RAM Ổ cứng Ghi chú kỹ thuật
Thử nghiệm / 1 – 5 người 2 vCPU 4 GB 40 GB Chạy được nhưng tải giao diện lần đầu sẽ chậm. Bắt buộc kích hoạt Swap.
10 – 30 thành viên thường trực 4 vCPU 8 GB 80 GB Mức cấu hình tiêu chuẩn đề xuất cho môi trường doanh nghiệp vừa.
Từ 50 người trở lên (nhiều tệp đính kèm) 4 – 6 vCPU 16 GB 160 GB+ Khuyến nghị chuyển phân vùng lưu tệp đính kèm sang giải pháp đám mây chuyên dụng.

Lưu ý về dung lượng ổ đĩa: Volume của cơ sở dữ liệu PostgreSQL và thư mục chứa file đính kèm (attachments) sẽ tăng dung lượng hoàn toàn độc lập. Thư mục file đính kèm thường là nguyên nhân gây đầy đĩa bất ngờ. Với đội ngũ khoảng 20 người thường xuyên upload tài liệu vào gói công việc, hãy dự trù thêm 5 đến 10 GB lưu trữ mỗi năm.

Thuê VPS giá rẻ

CPU Intel Gold, SSD NVMe U.2, giá từ 50K/tháng

VPS KVM đủ RAM để OpenProject chạy mượt

OpenProject cần kernel thật (KVM) và tối thiểu 4 GB RAM kèm swap. Một VPS KVM giá rẻ tại Fast Byte với CPU Intel Gold và SSD NVMe U.2 giúp bạn có môi trường test riêng tư, chủ động nâng cấu hình khi team lớn dần mà không phụ thuộc SaaS.

Tham khảo VPS giá rẻ

Thiết lập tên máy và múi giờ

Đăng nhập SSH vào máy chủ Ubuntu 24.04 LTS dưới tài khoản có quyền sudo và thực thi các lệnh chuẩn bị:

sudo hostnamectl set-hostname projects
sudo timedatectl set-timezone UTC
sudo apt update && sudo apt -y upgrade
sudo apt -y install curl ca-certificates git ufw nginx
Thiết lập tên máy và múi giờ
Thiết lập tên máy và múi giờ

Kích hoạt bộ nhớ ảo (Swap File)

Kể cả trên các gói VPS 8 GB RAM, bạn vẫn nên cấu hình thêm bộ nhớ ảo Swap tối thiểu 4GB. Rails thường yêu cầu cấp phát bộ nhớ rất dồn dập trong quá trình nạp hệ thống và build tài nguyên. Bộ nhớ Swap sẽ biến một lỗi sập cứng do tràn RAM (Out-Of-Memory) thành một vài phút xử lý hơi chậm nhưng không ngắt quãng dịch vụ.

sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
sudo sysctl -w vm.swappiness=10
echo 'vm.swappiness=10' | sudo tee /etc/sysctl.d/99-swappiness.conf
Kích hoạt bộ nhớ ảo
Kích hoạt bộ nhớ ảo

Cấu hình tường lửa mạng

Chủ động thiết lập tường lửa UFW để đảm bảo chỉ những cổng dịch vụ thiết yếu mới được phép truy cập từ Internet:

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable

Lưu ý kỹ thuật: Docker mặc định xuất bản cổng trực tiếp thông qua chuỗi iptables mang tên DOCKER-USER, điều này có thể bỏ qua các quy tắc của UFW. Hướng dẫn này sẽ ràng buộc cổng dịch vụ nội bộ của OpenProject về địa chỉ loopback cục bộ 127.0.0.1 để cô lập hoàn toàn trước thế giới bên ngoài.

Sau khi chạy, bạn có thể kiểm tra bằng lệnh sudo ss -tlnp để chắc chắn chỉ có sshd và nginx đang lắng nghe trên IP công cộng.

Cấu hình tường lửa mạng
Cấu hình tường lửa mạng

Trong ảnh đầu tiên có cảnh báo:

sudo: unable to resolve host projects: Name or service not known

Đây là lỗi hostname projects chưa được phân giải, không phải lỗi UFW. Kiểm tra bằng:

hostname
cat /etc/hostname
cat /etc/hosts

Nếu hostname trả về projects, hãy mở file:

nano /etc/hosts

Đảm bảo có dòng:

127.0.0.1 localhost
127.0.1.1 projects

Lưu file bằng Ctrl + O → Enter → Ctrl + X.

Nếu hostname thực tế không phải projects, hãy thay projects bằng đúng kết quả của lệnh hostname.

3. Cài Đặt Docker Engine Chuẩn Bản Quyền

Hãy luôn sử dụng kho lưu trữ chính thức từ Docker thay vì gói cài docker.io mặc định của bản phân phối Ubuntu nhằm đảm bảo khả năng tương thích cao nhất với các tiện ích mở rộng Compose v2.

# Cài đặt các gói cần thiết
apt update && apt install -y ca-certificates curl

# Thêm khóa GPG chính thức của Docker
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# Thêm kho Docker
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] \
https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" \
| sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# Cài Docker Engine và Compose Plugin
sudo apt update
sudo apt -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# Chạy từng lệnh:
sudo usermod -aG docker "$USER"
newgrp docker

Kiểm tra phiên bản để xác nhận quá trình cài đặt và vận hành Docker Compose diễn ra chính xác:

docker compose version
Cài Đặt Docker Engine
Cài Đặt Docker Engine

4. Tải Mã Nguồn Docker Compose & Thiết Lập Thư Mục Lưu Trữ

OpenProject quản lý cấu trúc compose tại kho opf/openproject-docker-compose (trước đây được gọi là opf/openproject-deploy). Bạn cần neo repo vào nhánh phát hành ổn định (stable branch) thay vì dùng nhánh phát triển main.

sudo mkdir -p /opt/openproject
sudo chown "$USER":"$USER" /opt/openproject
cd /opt

# Kiểm tra nhánh stable mới nhất đang phát hành
git ls-remote --heads https://github.com/opf/openproject-docker-compose.git 'stable/*'

# Clone nhánh stable hiện tại (ví dụ: stable/17)
git clone https://github.com/opf/openproject-docker-compose.git \
  --depth=1 --branch=stable/17 openproject

cd /opt/openproject
OpenProject quản lý cấu trúc compose
OpenProject quản lý cấu trúc compose

Khởi tạo thư mục chứa tài nguyên tệp (assets)

File docker-compose sẽ gắn kết thư mục dữ liệu trên máy chủ thông qua biến OPDATA. Hãy tạo thư mục này và gán quyền chính xác cho UID 1000 (đây là user nội bộ bên trong container OpenProject):

sudo mkdir -p /var/openproject/assets
sudo chown -R 1000:1000 /var/openproject/assets

5. Cấu Hình Biến Môi Trường (.env) An Toàn

Sao chép tệp mẫu và tiến hành tạo chuỗi mã hóa bảo mật ngẫu nhiên cho hệ thống trước khi chỉnh sửa chi tiết:

cd /opt/openproject
cp .env.example .env

# Tạo các khóa bí mật
openssl rand -hex 64   # SECRET_KEY_BASE
openssl rand -hex 32   # COLLABORATIVE_SERVER_SECRET
openssl rand -base64 24 | tr -d '/+=' # Mật khẩu cơ sở dữ liệu PostgreSQL
tạo chuỗi mã hóa bảo mật ngẫu nhiên
Tạo chuỗi mã hóa bảo mật ngẫu nhiên

Mở tệp .env bằng lệnh nano .env và khai báo các giá trị chuẩn sau:

# Khớp với phiên bản nhánh stable bạn đã clone
TAG=17

# Ràng buộc proxy của stack về cổng loopback cục bộ
PORT=127.0.0.1:8080

# Tên miền chính thức của hệ thống
OPENPROJECT_HOST__NAME=projects.example.com

# Bắt buộc nhận diện giao thức HTTPS qua proxy bên ngoài
OPENPROJECT_HTTPS=true

# Khóa bí mật của Rails (lưu ý sao lưu cẩn thận)
SECRET_KEY_BASE=<Chuỗi openssl rand -hex 64>

# Khóa máy chủ biên tập cộng tác (hocuspocus)
COLLABORATIVE_SERVER_SECRET=<Chuỗi openssl rand -hex 32>
COLLABORATIVE_SERVER_URL=wss://projects.example.com/hocuspocus

# Kết nối Database PostgreSQL
DATABASE_URL=postgres://postgres:<MatKhauDatabaseManh>@db/openproject?pool=20&encoding=unicode&reconnect=true
POSTGRES_PASSWORD=<CungMatKhauDatabaseTren>

# Đường dẫn lưu trữ tài sản gắn ngoài
OPDATA=/var/openproject/assets

# Cấu hình luồng thực thi Rails tối ưu
RAILS_MIN_THREADS=2
RAILS_MAX_THREADS=6

# Tắt huy hiệu bảo mật gửi request kiểm tra phiên bản định kỳ
OPENPROJECT_SECURITY__BADGE__DISPLAYED=false

# Tắt xử lý nhận mail inbound (tránh mở thêm container)
IMAP_ENABLED=false

OPENPROJECT_DEFAULT__LANGUAGE=vi

Khóa quyền đọc tệp để bảo vệ an toàn thông tin mật khẩu và chuỗi secret key:

chmod 600 .env

Lưu ý cốt lõi về SECRET_KEY_BASE: Hãy lưu trữ khóa này an toàn như mật khẩu root. Nếu sau này bạn restore database sang một máy chủ mới với chuỗi SECRET_KEY_BASE khác, toàn bộ phiên đăng nhập của người dùng sẽ bị xóa và mã token ghi nhớ 2FA sẽ bị vô hiệu hóa.

6. Khởi Chạy Container Lần Đầu & Kiểm Tra Tiến Trình Seeder

Do container proxy được xây dựng cục bộ từ repo, bạn cần truyền cờ --build khi khởi động hệ thống:

cd /opt/openproject
docker compose up -d --build --pull always
truyền cờ --build khi khởi động hệ thống
Truyền cờ –build khi khởi động hệ thống

Nếu bạn thấy thông báo pull access denied for openproject/proxy, bạn có thể yên tâm bỏ qua vì image này được build trực tiếp từ mã nguồn chứ không kéo từ Docker Hub. Nếu bạn muốn kiểm tra tiến trình kéo image thông qua script, hãy dùng cú pháp docker compose pull --ignore-buildable.

Quá trình nạp dữ liệu ban đầu diễn ra trong vài phút. Container seeder sẽ thiết lập các loại công việc, trạng thái và quy trình mẫu vào database. Bạn có thể theo dõi trực tiếp nhật ký:

docker compose logs -f seeder
docker compose logs -f web

Kiểm tra trạng thái sẵn sàng của toàn bộ stack bằng lệnh:

docker compose ps

Khi container web chuyển sang trạng thái “healthy” (sau khi kiểm tra thành công endpoint nội bộ /health_checks/default), hãy test phản hồi dịch vụ trên máy chủ:

curl -I -H 'Host: projects.example.com' http://127.0.0.1:8080/

Kết quả trả về mã phản hồi 302 Found chuyển hướng đến /login biểu thị ứng dụng đã khởi chạy thành công. Nếu container seeder thoát với mã lỗi 137, hệ thống đã bị OOM killer can thiệp do thiếu RAM. Hãy kiểm tra trạng thái swap bằng lệnh free -h rồi chạy lại: docker compose up -d seeder.

7. Cấu Hình Nginx Reverse Proxy & Cấp Chứng Chỉ SSL Let’s Encrypt

Proxy nội bộ Caddy đi kèm theo OpenProject không đảm nhận nhiệm vụ giải mã TLS trực tiếp ra ngoài Internet. Chúng ta sẽ đặt máy chủ web Nginx phía trước để xử lý SSL và chuyển tiếp lưu lượng.

Khởi tạo chứng chỉ SSL miễn phí

Cài đặt chứng chỉ Let’s Encrypt bằng Certbot ở chế độ standalone (tạm thời dừng Nginx để tránh tranh chấp cổng 80):

sudo apt -y install certbot python3-certbot-nginx
sudo systemctl stop nginx
sudo certbot certonly --standalone -d projects.example.com --agree-tos -m [email protected] --no-eff-email

Lưu ý: Trong trường hợp cổng 80 bị nhà mạng chặn hoặc bạn cấu hình DNS qua Cloudflare ở chế độ ẩn danh, hãy chuyển sang giải pháp DNS-01 challenge:

sudo apt -y install python3-certbot-dns-cloudflare
echo "dns_cloudflare_api_token = YOUR_TOKEN_HERE" | sudo tee /etc/letsencrypt/cloudflare.ini
sudo chmod 600 /etc/letsencrypt/cloudflare.ini
sudo certbot certonly --dns-cloudflare \
  --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
  -d projects.example.com --agree-tos -m [email protected] --no-eff-email

Tạo cấu hình Virtual Host Nginx

Thực hiện mở tệp cấu hình mới: sudo nano /etc/nginx/sites-available/openproject và nhập nội dung:

upstream openproject {
    server 127.0.0.1:8080;
    keepalive 16;
}

server {
    listen 80;
    listen [::]:80;
    server_name projects.example.com;

    location /.well-known/acme-challenge/ {
        root /var/www/html;
    }

    location / {
        return 301 https://$host$request_uri;
    }
}

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    http2 on;
    server_name projects.example.com;

    ssl_certificate     /etc/letsencrypt/live/projects.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/projects.example.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers off;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 1d;
    ssl_stapling on;
    ssl_stapling_verify on;

    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;

    # Dung lượng tệp đính kèm tối đa (tăng lên nếu team tải file lớn)
    client_max_body_size 256m;

    # Timeout dự phòng cho tác vụ xuất báo cáo PDF nặng
    proxy_read_timeout 300s;
    proxy_send_timeout 300s;

    location / {
        proxy_pass http://openproject;
        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 https;
        proxy_set_header X-Forwarded-Host  $host;
        proxy_set_header X-Forwarded-Port  443;

        # Hỗ trợ Websocket cho tính năng cộng tác realtime
        proxy_set_header Upgrade    $http_upgrade;
        proxy_set_header Connection $connection_upgrade;

        proxy_buffering off;
    }
}

Khai báo biến $connection_upgrade để Nginx nâng cấp kết nối Websocket thông qua tệp: sudo nano /etc/nginx/conf.d/upgrade-map.conf:

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

Kích hoạt cấu hình, kiểm tra cú pháp và khởi động lại dịch vụ web:

sudo ln -s /etc/nginx/sites-available/openproject /etc/nginx/sites-enabled/
sudo rm -f /etc/nginx/sites-enabled/default
sudo nginx -t
sudo systemctl start nginx

Thiết lập reload Nginx tự động sau mỗi chu kỳ gia hạn chứng chỉ SSL:

sudo mkdir -p /etc/letsencrypt/renewal-hooks/deploy
echo -e '#!/bin/sh\nsystemctl reload nginx' | sudo tee /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh
sudo certbot renew --dry-run

Vấn đề bảo mật tiêu đề chuyển tiếp (Forwarded Headers): Proxy Caddy nội bộ của OpenProject được mặc định tin tưởng và chuyển tiếp mọi tiêu đề X-Forwarded-* nhận được từ bên ngoài. Do Nginx trên cùng máy chủ là thực thể duy nhất truy cập được cổng 127.0.0.1:8080 và Nginx luôn ghi đè các tiêu đề này trên từng request, mô hình này hoàn toàn an toàn. Tuyệt đối không đưa trực tiếp cổng 8080 ra dải IP công cộng.

8. Các Bước Tăng Cường Bảo Mật Sau Triển Khai

Mở trình duyệt và truy cập vào https://projects.example.com. Thông tin đăng nhập mặc định của OpenProject là tài khoản admin với mật khẩu ban đầu là admin. Hệ thống sẽ bắt buộc bạn đổi mật khẩu ngay lần truy cập đầu tiên.

Để duy trì tiêu chuẩn vận hành an toàn và tối ưu bảo mật VPS, hãy thực hiện ngay các thiết lập trong mục Quản trị hệ thống (Administration):

  • Thiết lập xác thực (Authentication Settings): Chuyển trạng thái Đăng ký tài khoản (Self-registration) sang chế độ “Vô hiệu hóa” (disabled) hoặc “Kích hoạt tài khoản thủ công” (manual activation). Mặc định hệ thống cho phép bất kỳ ai biết URL cũng có thể tự tạo tài khoản. Kích hoạt bảo mật 2 lớp (2FA) và bắt buộc áp dụng cho nhóm quản trị viên. Rút ngắn thời gian hết hạn phiên đăng nhập (session expiry) và quy định độ phức tạp mật khẩu.
  • Người dùng và phân quyền (Users & Permissions): Kiểm tra lại vai trò mặc định của nhóm “Member” vì quyền này khá rộng. Thiết lập giới hạn nhóm thành viên nào mới có quyền tạo dự án mới.
  • Cài đặt hệ thống (System Settings): Kiểm tra giá trị Host name đã khớp với domain chính thức hay chưa. Tắt tính năng kiểm tra bản tin cập nhật ra ngoài nếu không muốn máy chủ thực hiện các outbound request không cần thiết.
  • Chống tấn công dò mật khẩu (Brute Force Protection): Vào Administration > Authentication > Authentication settings. Thiết lập ngưỡng số lần đăng nhập sai tối đa trước khi khóa tài khoản và thời gian duy trì trạng thái khóa.

Kiểm tra bằng Rails runner để xác thực không còn tài khoản admin mặc định nào tồn tại ngoài các quản trị viên hợp lệ:

docker compose exec web bundle exec rails runner 'puts User.where(admin: true).pluck(:login).inspect'

9. Cấu Hình Gửi Mail Thông Báo Qua SMTP Relay

Đa số các nhà cung cấp máy chủ đám mây đều khóa cổng SMTP 25 đi ra ngoài để chống thư rác. Hơn nữa, OpenProject rất cần email để gửi thông báo thay đổi tiến độ, lời mời dự án và cấp lại mật khẩu. Do đó, bạn nên sử dụng một dịch vụ chuyển tiếp SMTP chuyên nghiệp như SendGrid, Postmark, Mailgun hoặc Amazon SES.

Bổ sung cấu hình sau vào tệp .env:

EMAIL_DELIVERY_METHOD=smtp
SMTP_ADDRESS=smtp.postmarkapp.com
SMTP_PORT=587
SMTP_DOMAIN=example.com
SMTP_AUTHENTICATION=plain
SMTP_ENABLE_STARTTLS_AUTO=true
SMTP_USER_NAME=<Tai-khoan-relay>
SMTP_PASSWORD=<Mat-khau-relay>
[email protected]

Áp dụng thay đổi cho các container:

docker compose up -d

Sau đó, truy cập giao diện web: Administration > Emails and notifications > Email notifications và ấn gửi thư thử nghiệm (test email). Nếu việc gửi mail bị treo, hãy kiểm tra khả năng phân giải DNS bên trong container:

docker compose exec web getent hosts smtp.postmarkapp.com

Hãy giữ nguyên tham số IMAP_ENABLED=false. Tính năng nhận email phản hồi ngược vào OpenProject yêu cầu kiểm tra hòm thư định kỳ và sinh thêm một container cron chạy ngầm tiêu tốn tài nguyên mà hầu như không cần dùng đến.

10. Tối Ưu Hóa Stack Cho VPS Cấu Hình Vừa & Nhỏ

Cấu hình mặc định của OpenProject tiêu thụ lượng RAM lớn hơn định mức của các gói VPS 4 GB. Để tránh xung đột khi cập nhật mã nguồn (git pull sẽ ghi đè docker-compose.yml), hãy dùng tệp docker-compose.override.yml để điều chỉnh thông số.

Tạo tệp: nano /opt/openproject/docker-compose.override.yml:

services:
  web:
    environment:
      RAILS_MIN_THREADS: 2
      RAILS_MAX_THREADS: 6
      # 1 Puma worker cho VPS 4GB RAM. Tăng lên 2 nếu có 8GB RAM.
      WEB_CONCURRENCY: 1
    deploy:
      resources:
        limits:
          memory: 1600M

  worker:
    deploy:
      resources:
        limits:
          memory: 1200M

  db:
    command: >
      postgres
      -c shared_buffers=256MB
      -c effective_cache_size=1GB
      -c work_mem=8MB
      -c maintenance_work_mem=128MB
      -c max_connections=50

Khởi động lại để nạp thông số giới hạn:

cd /opt/openproject
docker compose down && docker compose up -d
docker stats --no-stream

Nguyên tắc tinh chỉnh bộ nhớ

  • WEB_CONCURRENCY là hệ số nhân tiêu thụ RAM. Mỗi Puma worker bổ sung là một tiến trình Rails độc lập hoàn chỉnh chiếm từ 800MB đến 1.2GB bộ nhớ.
  • Tích số RAILS_MAX_THREADS * WEB_CONCURRENCY bắt buộc phải nhỏ hơn tham số pool=20 trong DATABASE_URL, nếu không hệ thống sẽ báo lỗi timeout kết nối cơ sở dữ liệu.
  • Tham số shared_buffers của PostgreSQL nên giữ ở mức khoảng 25% giới hạn bộ nhớ của container database.

Chuyển tệp đính kèm sang lưu trữ đám mây ngoài

Khi lượng tệp đính kèm lớn vượt quá dung lượng ổ cứng máy chủ, bạn nên kết nối trực tiếp với dịch vụ lưu trữ Object Storage tương thích S3. Khai báo thêm trong tệp docker-compose.override.yml ở cả hai dịch vụ web và worker:

      OPENPROJECT_ATTACHMENTS__STORAGE: fog
      OPENPROJECT_FOG_DIRECTORY: my-openproject-bucket
      OPENPROJECT_FOG_CREDENTIALS_PROVIDER: AWS
      OPENPROJECT_FOG_CREDENTIALS_AWS__ACCESS__KEY__ID: <ACCESS_KEY>
      OPENPROJECT_FOG_CREDENTIALS_AWS__SECRET__ACCESS__KEY: <SECRET_KEY>
      OPENPROJECT_FOG_CREDENTIALS_REGION: us-east-1

Lưu ý rằng các tệp cũ không tự động di chuyển. Bạn cần chạy lệnh sao chép sau khi cấu hình kho lưu trữ mới:

docker compose exec web bundle exec rake attachments:copy_to[fog]

11. Kế Hoạch Sao Lưu & Khôi Phục Dữ Liệu

Một chiến lược sao lưu dữ liệu tự động toàn diện cho OpenProject bắt buộc phải bao gồm 3 thành phần: Cơ sở dữ liệu PostgreSQL, thư mục chứa tài nguyên đính kèm assets và tệp cấu hình .env.

Script sao lưu tự động

Tạo file script: sudo nano /usr/local/bin/openproject-backup.sh:

#!/usr/bin/env bash
set -euo pipefail

STACK=/opt/openproject
DEST=/var/backups/openproject
STAMP=$(date +%F-%H%M)
KEEP_DAYS=14

mkdir -p "$DEST"
cd "$STACK"

# 1. Sao lưu cơ sở dữ liệu PostgreSQL định dạng nén
docker compose exec -T db pg_dump -U postgres -Fc openproject > "$DEST/openproject-db-$STAMP.dump"

# 2. Đóng gói thư mục tệp đính kèm
tar -czf "$DEST/openproject-assets-$STAMP.tar.gz" -C /var/openproject assets

# 3. Sao lưu cấu hình bí mật
cp "$STACK/.env" "$DEST/openproject-env-$STAMP"
if [ -f "$STACK/docker-compose.override.yml" ]; then
  cp "$STACK/docker-compose.override.yml" "$DEST/openproject-override-$STAMP.yml"
fi

chmod 600 "$DEST"/openproject-env-*

# Dọn dẹp bản sao lưu cũ quá 14 ngày
find "$DEST" -type f -mtime +$KEEP_DAYS -delete

Cấp quyền thực thi và tạo tiến trình chạy định kỳ hàng đêm vào 02:15 sáng:

sudo chmod +x /usr/local/bin/openproject-backup.sh
sudo /usr/local/bin/openproject-backup.sh

# Thêm vào crontab bằng lệnh: sudo crontab -e
15 2 * * * /usr/local/bin/openproject-backup.sh >> /var/log/openproject-backup.log 2>&1

Khuyến cáo sống còn: Một bản backup nằm ngay trên cùng ổ cứng với cơ sở dữ liệu thì không được coi là backup an toàn. Hãy dùng các công cụ như rclone, restic hoặc rsync để đồng bộ thư mục /var/backups/openproject sang một máy chủ lưu trữ dự phòng hoặc cloud storage độc lập.

Quy trình khôi phục dữ liệu (Restore)

Khi cần phục hồi hệ thống trên máy chủ mới, hãy dừng các dịch vụ ứng dụng, nạp lại database và giải nén thư mục tài sản:

cd /opt/openproject
docker compose stop web worker cron seeder

# Xóa cơ sở dữ liệu cũ và tạo mới
docker compose exec -T db dropdb -U postgres --if-exists openproject
docker compose exec -T db createdb -U postgres openproject
docker compose exec -T db pg_restore -U postgres -d openproject --no-owner < /var/backups/openproject/openproject-db-2026-07-16-0215.dump

# Phục hồi assets và phân quyền
sudo tar -xzf /var/backups/openproject/openproject-assets-2026-07-16-0215.tar.gz -C /var/openproject
sudo chown -R 1000:1000 /var/openproject/assets

# Khôi phục file .env chứa đúng SECRET_KEY_BASE ban đầu rồi chạy lại
docker compose up -d

12. Hướng Dẫn Nâng Cấp Phiên Bản Định Kỳ

Các bản nâng cấp lớn (major releases) của OpenProject thường mang theo nhiều thay đổi cấu trúc dữ liệu. Bạn hãy đọc kỹ ghi chú phát hành trước khi nâng cấp phiên bản.

Nâng cấp bản vá lỗi nhỏ (patch/minor) cùng phiên bản chính

cd /opt/openproject
sudo /usr/local/bin/openproject-backup.sh
docker compose pull --ignore-buildable
docker compose up -d --build
docker compose logs -f web

Các migration dữ liệu sẽ được tự động kích hoạt ngay khi container khởi động.

Nâng cấp phiên bản lớn (Major Bump)

Tuyệt đối không nhảy cóc qua các phiên bản chính (ví dụ từ 15 lên thẳng 17 mà phải đi tuần tự 15 > 16 > 17):

cd /opt/openproject
sudo /usr/local/bin/openproject-backup.sh

# Chuyển nhánh git sang phiên bản mới
git fetch --depth=1 origin stable/17
git checkout stable/17
git reset --hard origin/stable/17

# Cập nhật biến TAG trong .env khớp với nhánh
sed -i 's/^TAG=.*/TAG=17/' .env

docker compose pull --ignore-buildable
docker compose up -d --build
docker compose logs -f web

Quan sát log container web khi thấy dòng chữ Migrating. Trên các gói máy chủ cấu hình nhỏ, tác vụ dịch chuyển cấu trúc bảng có thể mất đến 10 phút, bạn tuyệt đối không được tắt ngang máy chủ.

Khi nâng cấp phiên bản PostgreSQL

Docker Compose cố định image PostgreSQL. Việc chỉ đổi thẻ image tag sẽ không tự động nâng cấp cấu trúc thư mục dữ liệu trên đĩa. Nếu container cơ sở dữ liệu từ chối khởi động sau khi đổi tag do xung đột phiên bản, bạn cần xuất toàn bộ dữ liệu, xóa volume và nạp lại:

docker compose exec -T db pg_dumpall -U postgres > /tmp/all.sql
docker compose down
docker volume rm openproject_pgdata
# Đổi tag image PostgreSQL trong compose file rồi chạy:
docker compose up -d db
sleep 20
docker compose exec -T db psql -U postgres < /tmp/all.sql
docker compose up -d

13. Vận Hành Nâng Cao: Rails Console, Background Jobs & Logs

Truy cập trực tiếp Rails Console

cd /opt/openproject
docker compose exec web bundle exec rails console

Một số dòng lệnh cứu nguy nhanh cực kỳ hữu ích:

  • Đặt lại mật khẩu admin khi bị mất:
    u = User.find_by(login: 'admin'); u.password = 'NewStrongPass123!'; u.password_confirmation = 'NewStrongPass123!'; u.save!
  • Xóa bộ nhớ đệm Rails:
    Rails.cache.clear
  • Thống kê số lượng gói công việc theo từng dự án:
    Project.all.map { |p| [p.identifier, p.work_packages.count] }

Giám sát hàng đợi tác vụ nền (Background Jobs)

docker compose logs -f worker
docker compose exec web bundle exec rails runner 'puts GoodJob::Job.where(finished_at: nil).count'

Nếu số lượng tác vụ chưa hoàn thành liên tục tăng vọt trong khi tiến trình worker đứng yên, điều đó đồng nghĩa container worker đã bị lỗi ngắt quãng. Hãy chạy lệnh docker compose ps để rà soát trạng thái.

Thiết lập xoay vòng nhật ký (Log Rotation) cho Docker

Driver ghi log json-file mặc định của Docker có thể phình to vô hạn làm đầy bộ nhớ đĩa. Hãy giới hạn dung lượng log qua tệp cấu hình /etc/docker/daemon.json:

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "50m",
    "max-file": "3"
  }
}

Khởi động lại Docker daemon để chính sách có hiệu lực:

sudo systemctl restart docker
cd /opt/openproject && docker compose up -d

14. Khắc Phục Các Sự Cố Phổ Biến Thường Gặp

  • Lỗi ERR_SSL_PROTOCOL_ERROR trên trình duyệt: Biến OPENPROJECT_HTTPS=true đã được bật nhưng Nginx chưa kết nối chứng chỉ SSL hoặc thiếu dòng cấu hình proxy_set_header X-Forwarded-Proto https;.
  • Vòng lặp chuyển hướng vô tận (Infinite Redirect Loop) tại /login: Cùng nguyên nhân do OpenProject nhận diện giao thức gửi đến là http nên tự động chuyển hướng về https, yêu cầu này quay lại Nginx và tiếp tục bị forward nhầm thành http. Hãy kiểm tra lại header X-Forwarded-Proto trong server block.
  • Tài nguyên CSS/JS bị 404, giao diện vỡ hoàn toàn: Thư mục chỉ định trong OPDATA không thể ghi dữ liệu. Kiểm tra quyền sở hữu của thư mục /var/openproject/assets và đảm bảo đã cấp quyền cho user 1000:1000.
  • Tải tệp đính kèm thất bại với lỗi 413 Request Entity Too Large: Do thông số client_max_body_size trên Nginx quá nhỏ. Hãy nâng lên 256m và thực hiện reload lại Nginx.
  • Tính năng soạn thảo cộng tác không kết nối được: Kết nối Websockets không chạm tới máy chủ hocuspocus. Hãy chắc chắn rằng biến COLLABORATIVE_SERVER_URL sử dụng giao thức wss:// đi kèm tên miền chính xác và Nginx đã khai báo đầy đủ các header Upgrade và Connection.
  • Container bị sập với Exit Code 137: Lỗi máy chủ hết RAM (OOM). Cần tăng dung lượng swap, giảm WEB_CONCURRENCY xuống 1 hoặc cân nhắc nâng cấp gói phần cứng máy chủ.
  • Timeout kết nối PostgreSQL Connection Pool: Tích số RAILS_MAX_THREADS * WEB_CONCURRENCY vượt quá giá trị pool trong DATABASE_URL. Cần nâng thông số pool hoặc giảm số lượng threads.
  • Hệ thống phản hồi rất chậm ngay sau khi khởi động lại: Đây là hiện tượng bình thường khi memcached chưa có dữ liệu đệm và Rails phải nạp lại mọi thiết lập ban đầu từ cơ sở dữ liệu. Hãy kiên nhẫn chờ từ 2 đến 3 phút để hệ thống ổn định.

15. OpenProject Có Phù Hợp Với Đội Ngũ Của Bạn?

OpenProject là nền tảng quản trị dự án mã nguồn mở toàn diện nhất hiện nay nhưng cũng đòi hỏi cấu hình máy chủ khắt khe nhất. Nền tảng này hoàn toàn xứng đáng với tài nguyên bạn đầu tư nếu doanh nghiệp thực sự cần tính năng lập tiến độ Gantt chuẩn chỉ, theo dõi ngân sách chi phí chi tiết, hoặc tích hợp mô hình BIM cho ngành xây dựng và kỹ thuật.

Tuy nhiên, nếu nhóm của bạn chỉ cần một bảng công việc Kanban đơn giản kết hợp backlog công việc thường nhật, OpenProject có thể sẽ quá nặng nề. Khi đó, việc cân nhắc các giải pháp thay thế linh hoạt như Taiga (dành cho đội ngũ phát triển Agile) hoặc Leantime (công cụ tinh gọn hướng chiến lược) sẽ giúp bạn tiết kiệm được một nửa lượng RAM tiêu thụ trên máy chủ.

Lựa Chọn Nền Tảng Máy Chủ Ổn Định Để Vận Hành Dự Án

Quá trình triển khai và cài OpenProject trên VPS Ubuntu 24.04 sẽ trở nên đơn giản và bền bỉ hơn rất nhiều khi bạn nắm vững cấu hình Docker Compose, tối ưu bộ nhớ đệm và thiết lập đầy đủ quy trình sao lưu định kỳ. Đừng để các rủi ro sập RAM hay mất mát cơ sở dữ liệu làm gián đoạn tiến độ công việc của toàn bộ tổ chức.

Cần một VPS giá rẻ, hiệu năng cao để bắt đầu?

Lựa chọn cấu hình phần cứng linh hoạt, ổ cứng chuẩn NVMe U.2 siêu tốc, hỗ trợ phân bổ tài nguyên tối ưu và toàn quyền quản trị root cho hệ thống của bạn.

Xem bảng giá VPS

Lưu ý kỹ thuật: Nội dung hướng dẫn trên được biên soạn cho mục đích tham khảo. Các câu lệnh, tham số phần mềm và quy trình cấu hình có thể có sự thay đổi tùy theo các bản phát hành của OpenProject, Docker cũng như đặc thù môi trường mạng thực tế. Quản trị viên nên chủ động kiểm thử, tạo bản sao lưu dữ liệu và kiểm tra độ ổn định kỹ lưỡng trước khi áp dụng vào môi trường sản xuất chính thức.

Chia sẻ: Facebook LinkedIn
Quay lại trang blog

Bài viết liên quan

Tự host Plausible Analytics trên VPS Ubuntu 24.04
Hướng dẫn chung

Tự host Plausible Analytics trên VPS Ubuntu 24.04|Đo Lường Nhẹ Dưới 1KB

Hướng dẫn thiết lập Plausible Analytics trên VPS là giải pháp tối ưu giúp bạn thoát khỏi những rắc rối về quyền riêng tư dữ liệu, cảnh báo GDPR phức tạp và các banner cookie phiền toái thường gặp khi dùng Google Analytics. Thay vì để các tập đoàn công nghệ nắm giữ toàn bộ […]

Thanh Lam Nguyễn
Đọc bài viết