1. 参考
2. 环境
设备
- 虚拟机 16C/32G/300G/千兆
系统
- Ubuntu24.04 192.168.15.96
3. 安装OpenProject
采用官方推荐:Docker compose方式安装
官方安装文档
安装Docker
安装步骤,参见Ubuntu24.04 安装Docker
安装OpenProject
- 创建目录
bash
mkdir -p /public/application
- 下载源码
bash
cd /public/application
git clone https://github.com/opf/openproject-docker-compose.git --depth=1 --branch=stable/16 openproject
- 配置环境变量
bash
cp .env.example .env
vim .env
bash
# All environment variables defined here will only apply if you pass them
# to the OpenProject container in docker-compose.yml under x-op-app -> environment.
# For the examples here this is already the case.
#
# Please refer to our documentation to see all possible variables:
# https://www.openproject.org/docs/installation-and-operations/configuration/environment/
#
TAG=16-slim
# 因为前端使用了nginx做代理,配置了SSL域名证书,所以需要启用HTTPS
OPENPROJECT_HTTPS=true
# 必须配置与访问域名一致,且只能配置一个(域名示例,自行修改)
OPENPROJECT_HOST__NAME="openproject.xk.com:8899"
#以下是无效配置
#OPENPROJECT_HOST__NAME="openproject.xk.com:8899,192.168.7.28:8899"
#OPENPROJECT_HOST__NAME="*"
# 关闭强制浏览器使用https
OPENPROJECT_HSTS=false
# 定义监听端口需要与OPENPROJECT_HOST__NAME保持一致
PORT=8899
OPENPROJECT_RAILS__RELATIVE__URL__ROOT=
IMAP_ENABLED=false
# 定义pg的密码
#POSTGRES_PASSWORD=yourpassword
#如果定义上述密码,需要修改以下的默认密码p4ssw0rd
DATABASE_URL=postgres://postgres:p4ssw0rd@db/openproject?pool=20&encoding=unicode&reconnect=true
RAILS_MIN_THREADS=4
RAILS_MAX_THREADS=16
# postgresql数据库目录
PGDATA="/public/application/openproject/postgresql/data"
# 文件存储目录
OPDATA="/public/application/openproject/assets"
- 创建服务对应目录
bash
mkdir -p /public/application/openproject/postgresql/data
mkdir -p /public/application/openproject/assets
- 修改docker-compose.yml
- 修改 postgres:17 (默认版本是13,升级为17)
bash
vim /public/application/openproject/docker-compose.yml
bash
......
services:
db:
image: postgres:17
<<: *restart_policy
stop_grace_period: "3s"
volumes:
- "${PGDATA:-pgdata}:/var/lib/postgresql/data"
environment:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-p4ssw0rd}
POSTGRES_DB: openproject
networks:
- backend
......
导入Docker镜像
- 查看images目录下提前导出的镜像(如果可以访问Docker Hub直接拉取镜像,可以跳过导入步骤)
bash
tree
.
├── autoheal_1.2.0.tar
├── memcached_latest.tar
├── openproject_16-slim.tar
├── postgres_17.tar
└── proxy_latest.tar
- 导入Docker镜像
bash
docker load -i autoheal_1.2.0.tar
docker load -i memcached_latest.tar
docker load -i openproject_16-slim.tar
docker load -i postgres_17.tar
docker load -i proxy_latest.tar
- 查看Docker镜像
bash
docker images
bash
# 输出结果 i Info → U In Use
IMAGE ID DISK USAGE CONTENT SIZE EXTRA
memcached:latest 462fa779babc 127MB 34.2MB U
openproject/openproject:16-slim 1d26165952bb 5.58GB 2.72GB U
openproject/proxy:latest 390ce999ea0b 74.3MB 20.1MB U
postgres:17 dca7512acaa1 640MB 167MB U
willfarrell/autoheal:1.2.0 31f580ef0279 13.8MB 4.31MB U
说明:如果使用代理软件拉取的镜像,需要使用docker tag 命令修改镜像名称,名称需要与docker-compose.yml保持一致
修改工作目录权限
- 容器需要有操作外部挂载操作系统目录的权限(如果希望使用专用账号运行,可以修改docker compose指定专用账号运行,或修改1000:1000对应的账号)
bash
sudo chown 1000:1000 -R /public/application/openproject
4. 测试启动OpenProject
测试启动
- 指定OPENPROJECT_HTTPS=false,临时关闭HTTPS,然后启动服务。关闭是为了测试直接访问服务是否正常
bash
OPENPROJECT_HOST__NAME="192.168.15.96:8899" OPENPROJECT_HTTPS=false docker compose up -d --build
bash
[+] Building 23.6s (10/10) FINISHED
=> [internal] load local bake definitions 0.0s
=> => reading from stdin 581B 0.0s
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 281B 0.0s
=> [internal] load metadata for docker.io/library/caddy:2 23.1s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load build context 0.0s
=> => transferring context: 40B 0.0s
=> [1/3] FROM docker.io/library/caddy:2@sha256:dedfbbeb703b2ce9ff4a98fc06aa9c7c7d9a42f0b7d778738c1dd3ef11dcc767 0.0s
=> => resolve docker.io/library/caddy:2@sha256:dedfbbeb703b2ce9ff4a98fc06aa9c7c7d9a42f0b7d778738c1dd3ef11dcc767 0.0s
=> CACHED [2/3] COPY ./Caddyfile.template /etc/caddy/Caddyfile.template 0.0s
=> CACHED [3/3] RUN sed 's|${APP_HOST}|'"web"'|g' /etc/caddy/Caddyfile.template > /etc/caddy/Caddyfile 0.0s
=> exporting to image 0.1s
=> => exporting layers 0.0s
=> => exporting manifest sha256:7babeb6acbfe81a6a07df370523f0e1817d11e741094634ecd8ce8259d1cb88f 0.0s
=> => exporting config sha256:34cad2f332c1768c38b39a05bc89838410d369b1566cf929e9c7ec87d7162fd9 0.0s
=> => exporting attestation manifest sha256:cbd46b34bd570fe7c8a3718f1545fd15510665e958f770cb7375011abddad8b3 0.0s
=> => exporting manifest list sha256:9eef94d095922b62961dee07148e26a6ac791d353462eb55378a3756816ee9d6 0.0s
=> => naming to docker.io/openproject/proxy:latest 0.0s
=> => unpacking to docker.io/openproject/proxy:latest 0.0s
=> resolving provenance for metadata file 0.0s
[+] up 12/12
✔ Image openproject/proxy Built 23.8s
✔ Network openproject_backend Created 0.1s
✔ Network openproject_frontend Created 0.1s
✔ Network openproject_default Created 0.1s
✔ Container openproject-seeder-1 Created 0.1s
✔ Container openproject-cache-1 Created 0.1s
✔ Container openproject-autoheal-1 Created 0.1s
✔ Container openproject-db-1 Created 0.1s
✔ Container openproject-web-1 Created 0.0s
✔ Container openproject-worker-1 Created 0.0s
✔ Container openproject-cron-1 Created 0.0s
✔ Container openproject-proxy-1 Created 0.1s
- 查看容器运行状态
bash
docker compose ps
bash
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
openproject-cache-1 memcached "docker-entrypoint.s..." cache 3 days ago Up 31 hours 11211/tcp
openproject-cron-1 openproject/openproject:16-slim "./docker/prod/entry..." cron 3 days ago Up 31 hours 8080/tcp
openproject-db-1 postgres:17 "docker-entrypoint.s..." db 3 days ago Up 31 hours 5432/tcp
openproject-proxy-1 openproject/proxy "caddy run --config ..." proxy 3 days ago Up 31 hours 443/tcp, 2019/tcp, 443/udp, 0.0.0.0:8899->80/tcp, [::]:8899->80/tcp
openproject-web-1 openproject/openproject:16-slim "./docker/prod/entry..." web 3 days ago Up 31 hours (healthy) 8080/tcp
openproject-worker-1 openproject/openproject:16-slim "./docker/prod/entry..." worker 3 days ago Up 31 hours 8080/tcp
- 查看容器运行日志
bash
# -n1 查看最后一行日志(可根据需要自行修改)
docker compose logs -n1
bash
# 日志中没有错误信息
......
worker-1 | I, [2025-12-16T09:15:00.069321 #7] INFO -- : [GoodJob] [7] [GoodJob::Scheduler(queues=* max_threads=20)-thread-33] Executed GoodJob fdd6c446-c40a-43fe-a5ed-56bfe2e3e2fb
访问Web
- 默认账号 admin
- 默认密码 admin


5. 配置Nginx代理
配置Nginx代理
- 编辑虚拟配置文件,负责接收HTTPS请求,并向上游(OpenProject服务)转发HTTP请求
bash
# 定义upstream
upstream proxy_project {
# server指令指定后端服务器的IP地址和端口
server 192.168.15.96:8899;
}
# HTTPS Server
server {
# 监听端口
listen 8899 ssl;
server_name project.xk.com;
#return 301 http://$host$request_uri;
ssl_certificate /usr/local/nginx/conf/xk-com/xk.com.pem;
ssl_certificate_key /usr/local/nginx/conf/xk-com/xk.com.key;
ssl_session_cache shared:SSL:30m;
ssl_session_timeout 5m;
#ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4:!3DES;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
add_header Cache-Control no-cache;
location / {
# 代理转发,服务转发
proxy_pass http://proxy_project;
client_max_body_size 1000m;
#proxy_set_header Host $host;
# 设置Host $http_host,向上游服务传递域名:端口
proxy_set_header Host $http_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_http_version 1.1;
proxy_connect_timeout 300;
proxy_read_timeout 300;
proxy_send_timeout 300;
}
}
加载配置生效
- 加载Nginx配置
bash
systemctl reload nginx
- 查看Nginx服务状态
bash
systemctl status nginx
bash
● nginx.service - nginx - high performance web server
Loaded: loaded (/usr/local/nginx1.26.1/nginx.service; linked; vendor preset: disabled)
Active: active (running) since 四 2025-09-25 15:01:04 CST; 2 months 21 days ago
Docs: http://nginx.org/en/docs/
Process: 68645 ExecStop=/usr/local/nginx1.26.1/sbin/nginx -s stop (code=exited, status=0/SUCCESS)
Process: 1454 ExecReload=/usr/local/nginx1.26.1/sbin/nginx -s reload -c /usr/local/nginx1.26.1/conf/nginx.conf (code=exited, status=0/SUCCESS)
Process: 68658 ExecStartPost=/bin/sleep 0.1 (code=exited, status=0/SUCCESS)
Process: 68653 ExecStart=/usr/local/nginx1.26.1/sbin/nginx -c /usr/local/nginx1.26.1/conf/nginx.conf (code=exited, status=0/SUCCESS)
Process: 68650 ExecStartPre=/usr/local/nginx1.26.1/sbin/nginx -t -c /usr/local/nginx1.26.1/conf/nginx.conf (code=exited, status=0/SUCCESS)
Main PID: 68654 (nginx)
Tasks: 9
Memory: 35.7M
CGroup: /system.slice/nginx.service
├─68654 nginx: master process /usr/local/nginx1.26.1/sbin/nginx -c /usr/local/nginx1.26.1/conf/nginx.conf
├─68655 nginx: worker process
├─68656 nginx: worker process
├─68657 nginx: worker process
├─68659 nginx: worker process
├─68660 nginx: worker process
├─68661 nginx: worker process
├─68662 nginx: worker process
└─68663 nginx: worker process
6. 正式启动OpenProject
重启OpenProject服务
- 停止之前启动的测试服务
bash
cd /public/application/openproject/
docker compose down
- 使用.env中环境变量启动正式服务(支持域名,支持HTTPS)
bash
cd /public/application/openproject/
docker compose up -d
访问正式OpenProject
7. 企业版功能
部署工具
- 解压下载工具
bash
unzip f5b2e55a2c2e3abb1f9eefcdf0bfff45-25f33dd28753c908455ac9e8969955795a865fb0.zip
- 移动工具到程序目录
bash
mv f5b2e55a2c2e3abb1f9eefcdf0bfff45-25f33dd28753c908455ac9e8969955795a865fb0 /public/application/openproject/openproject_crack
bash
tree /public/application/openproject/openproject_crack/
# 显示结果
/public/application/openproject/openproject_crack/
└── enterprise_token.rb
- 赋权工具目录
- 注意:如果之前已经存在运行服务(初始化过数据库),需要单独赋权工具目录。防止误修改数据库存储目录权限,导致OpenProject服务重启失败
bash
sudo chown 1000:1000 -R /public/application/openproject/openproject_crack
修改docker-compose.yml
- 增加挂载工具的目录,"/public/application/openproject/openproject_crack/enterprise_token.rb:/app/app/models/enterprise_token.rb:ro"
bash
x-op-restart-policy: &restart_policy
restart: unless-stopped
x-op-image: &image
image: openproject/openproject:${TAG:-16-slim}
x-op-app: &app
<<: [*image, *restart_policy]
environment:
OPENPROJECT_HTTPS: "${OPENPROJECT_HTTPS:-true}"
OPENPROJECT_HOST__NAME: "${OPENPROJECT_HOST__NAME:-localhost:8080}"
OPENPROJECT_HSTS: "${OPENPROJECT_HSTS:-true}"
RAILS_CACHE_STORE: "memcache"
OPENPROJECT_CACHE__MEMCACHE__SERVER: "cache:11211"
OPENPROJECT_RAILS__RELATIVE__URL__ROOT: "${OPENPROJECT_RAILS__RELATIVE__URL__ROOT:-}"
DATABASE_URL: "${DATABASE_URL:-postgres://postgres:p4ssw0rd@db/openproject?pool=20&encoding=unicode&reconnect=true}"
RAILS_MIN_THREADS: ${RAILS_MIN_THREADS:-4}
RAILS_MAX_THREADS: ${RAILS_MAX_THREADS:-16}
# set to true to enable the email receiving feature. See ./docker/cron for more options
IMAP_ENABLED: "${IMAP_ENABLED:-false}"
volumes:
- "${OPDATA:-opdata}:/var/openproject/assets"
# 增加挂载工具的目录
- "/public/application/openproject/openproject_crack/enterprise_token.rb:/app/app/models/enterprise_token.rb:ro"
重建OpenProject服务
- 停止服务
bash
cd /public/application/openproject/
docker compose down
- 启动服务
bash
cd /public/application/openproject/
docker compose up -d
- 查看服务许可

