Workload · Running your team's project tracker

Run OpenProject self hosted, on a server that is yours

You can run OpenProject on your own dedicated server with its official Docker Compose setup, and for a team of up to 200 people the project asks for four cores at 2 GHz or faster, 4 GB of memory and 20 GB of disk to spare. Below you will find how to size the box, which install route to take, how to keep the default admin account away from strangers, and how to back it all up.

The short version
  1. Up to 200 users: 4 cores (2 GHz+), 4 GB RAM, 20 GB free disk
  2. Docker Compose is the route the OpenProject docs recommend
  3. admin/admin is the first login: change it over an SSH tunnel first
  4. Secrets go in a .env file only root can read
  5. Community edition: free, GPLv3, no user cap

How big a server does your team need?

For most teams, a modest machine is enough: OpenProject's minimum for one server serving up to 200 users is a four-core processor running at 2 GHz or more, 4096 MB of RAM, plus 20 GB of disk left free. What actually loads the server is how many people click around at the same time. The docs put it plainly: 100 accounts or 1,000, if only 20 people work at once, the processor and memory needed are the same.

Here is the documentation's rough guide as your team grows (attachments you store on the server need disk on top of this):

Active usersCoresMemoryDiskWeb / background workers
200 or fewer44 GB20 GB2 / 1
about 50088 GB40 GB4 / 2
about 1,5001616 GB80 GB8 / 4

The database is PostgreSQL. Since version 16.0.0, OpenProject officially supports PostgreSQL 16 and newer; 13 to 15 might still work but are no longer supported. Fast SSD storage helps the database most.

Packages or containers: picking your install

OpenProject offers two serious ways in, and the right one depends on your operating system and on one feature.

  • Docker Compose (recommended by the docs). Each part runs in its own container, nine in all: the app, background jobs, scheduled jobs, the one-off database seeder, PostgreSQL, memcached, a small Caddy proxy, the server behind live co-editing of documents and a watchdog (autoheal) that restarts the app if its health check fails. It runs wherever Docker runs, and OpenProject says some upcoming features will only ship for Docker installs.
  • DEB/RPM packages. You add OpenProject's package repository, install, and a setup wizard (sudo openproject reconfigure) installs the database, memcached and an Apache web server for you. Only a short list of systems still gets them: Ubuntu 22.04, Debian 12, CentOS or RHEL 9.x and SUSE Linux Enterprise 15 (Ubuntu 20.04 and Debian 11 have reached their package end of life). OpenProject does not plan to build packages for Ubuntu 24.04 or later.

Pick packages only if you want OpenProject itself to host Git or Subversion repositories, which the container setup cannot do; it can only point at repositories that live elsewhere. The single all-in-one container is fine for a quick look, but the docs tell you not to run your team on it.

Is it free? Editions and licence

Yes, the version you install yourself costs nothing. In OpenProject's own FAQ: "The (on-premise) OpenProject Community edition is completely free." The paid side is described in the same answer: "The Enterprise cloud and Enterprise on-premises edition offer Enterprise add-ons, hosting and support and thus we are charging for it."

OpenProject is licensed GPLv3, version 3 of the GNU GPL, so you are free to modify it, make copies and redistribute it on those terms. Community has no cap on users. If you later buy Enterprise, an Enterprise token switches the add-ons on in the install you already run, and your data stays where it is.

The server that fits

A project tracker becomes the place where deadlines, files and decisions live, so it should not slow down because a neighbour is busy. On a dedicated server nobody else shares the hardware: you get all of its cores and memory, its disks and an unmetered port, and you log in as root.

  • A team of up to 200: a four-core cartridge with a high clock, the Xeon E3-1585L v5 (3 GHz) or E3-1284L v4 (2.9 GHz), or the Atom C2750, eight cores, 2.4 GHz. Take 16 GB of memory if you can: the docs' 4 GB is a minimum, and PostgreSQL, the web and background workers and the co-editing server all share it.
  • Several hundred people: the eight-core Xeon E-2286M at 2.4 GHz with two NVMe disks.
  • A whole company: a pair of Xeon Gold 6130 processors, 32 cores in total at 2.1 GHz, with the memory to match.

Watch the clock speed, not only the core count. Several servers on the list run below the 2 GHz the minimum mentions: Opteron 6366 HE (1.8 GHz), Opteron X2150 (1.8 GHz), Xeon E3-1284L v3 (1.8 GHz), Atom C2730 (1.7 GHz), Xeon D-1587 (1.7 GHz), plus two of the two-processor servers, the Xeon E5-2650L v2 (1.7 GHz) and E5-2630L v3 (1.8 GHz). Ready servers are handed over within 30 minutes of payment approval, you reinstall the operating system yourself from the control panel whenever you like, while rack servers and blades also give you a console screen and power button. You manage the server; we keep the hardware and the network running.

Up and running in an evening

Start from a fresh Ubuntu or Debian server that has Docker Engine, release 28 or newer, and its Compose plugin, installed from Docker's repository. Switch to root (sudo -i), then paste the commands below. In order, they let only SSH through the firewall (for IPv6 too, which has to be switched on before any rule is added), download OpenProject's official Compose files, make a private .env settings file with two freshly generated secrets, and start everything.

sed -i 's/^IPV6=.*/IPV6=yes/' /etc/default/ufw
ufw allow 22/tcp
ufw --force enable
mkdir -p /srv && cd /srv
git clone https://github.com/opf/openproject-docker-compose.git --depth=1 --branch=stable/17 openproject
cd /srv/openproject
umask 077
cp .env.example .env
sed -i -e '/^SECRET_KEY_BASE=/d' -e '/^COLLABORATIVE_SERVER_SECRET=/d' .env
printf 'SECRET_KEY_BASE=%s\n' "$(openssl rand -hex 64)" >> .env
printf 'COLLABORATIVE_SERVER_SECRET=%s\n' "$(openssl rand -hex 32)" >> .env
ls -l .env
grep -E '^(PORT|OPENPROJECT_HTTPS|OPENPROJECT_HOST__NAME|POSTGRES_VERSION)=' .env
mkdir -p /var/openproject/assets
chown -R 1000:1000 /var/openproject/assets
docker compose up -d --build --pull always

umask 077 makes .env readable by root only (ls -l should show -rw-------). Because the secrets are made inside printf, which is built into the shell, they never show up in your command history or the process list. Read the grep output before trusting the start: you want PORT=127.0.0.1:8080, then POSTGRES_VERSION=17 (followed by a comment on the same line), OPENPROJECT_HTTPS=false and OPENPROJECT_HOST__NAME=localhost for the private first start. If no POSTGRES_VERSION line shows up, stop and add it before starting: without it the stack quietly drops back to PostgreSQL 13, a version OpenProject no longer supports.

Why the port matters: PORT is not an OpenProject option, it just decides which address the bundled proxy container is published on, and OpenProject's docs warn that leaving it out binds the proxy to 0.0.0.0, meaning anyone can reach it. A Docker port mapping with no address opens on 0.0.0.0 and [::] alike. On IPv4 Docker's own rules bypass ufw, and on IPv6 they do as well once Docker's IPv6 networking is switched on. Tying the port to 127.0.0.1 keeps it private, which holds from Engine 28 onward.

Guard SECRET_KEY_BASE like a password and never change it. It protects sign-in sessions and encrypted data in the database; OpenProject will not start with a weak or default one, and a backup restored without the original value loses what it encrypted.

Change the admin password while only you can reach it

A new OpenProject always starts with the username admin and the password admin. It asks you to replace that password the first time you sign in, and you want that to happen before anyone else can see the login page.

  1. On your own computer, open a tunnel with your usual login: ssh -N -L 8080:localhost:8080 you@203.0.113.10 (use your server's address).
  2. Browse to http://localhost:8080. The first start fills the database, so give it a few minutes; docker compose logs -f web tells you when it is ready.
  3. Sign in as admin with password admin and choose a strong new password.
  4. Put your real email on the admin account, then move on to DNS and HTTPS.

Wait with inviting colleagues until your domain, HTTPS and email sending all work. OpenProject builds the links in its emails from the host name, so an invitation sent while that is still localhost points nowhere.

Thinking about lighter tools too? Compare this with running Plane on your own server, and if your developers want code review next to the tracker, see a self-hosted GitLab.

Opening it to your team over HTTPS

When the password is changed, point your domain at the server. OpenProject is configured through environment variables whose names start with OPENPROJECT_; a double underscore stands for an underscore inside a setting's name, which is why the host name lives in OPENPROJECT_HOST__NAME. A comment at the top of .env.example explains that its values only count when docker-compose.yml hands them to the containers; that file does so for the host name, the HTTPS switch, the co-editing address and secrets, and the database URL. Settings it does not list, such as your mail server (SMTP_ADDRESS, SMTP_USER_NAME and friends), go in a docker-compose.override.yml beside it, since docker-compose.yml is replaced whenever you update. Package installs use sudo openproject config:set NAME=value followed by sudo openproject configure.

The commands below switch those three settings to your real domain, put nginx in front with a free Let's Encrypt certificate, and open ports 80 and 443. Run them as root, with your own domain in place of projects.yourcompany.com.

cd /srv/openproject
sed -i -e 's/^OPENPROJECT_HOST__NAME=.*/OPENPROJECT_HOST__NAME=projects.yourcompany.com/' \
  -e 's/^OPENPROJECT_HTTPS=.*/OPENPROJECT_HTTPS=true/' \
  -e 's|^COLLABORATIVE_SERVER_URL=.*|COLLABORATIVE_SERVER_URL=wss://projects.yourcompany.com/hocuspocus|' .env
docker compose up -d
apt install -y nginx certbot python3-certbot-nginx
cat > /etc/nginx/conf.d/openproject.conf <<'EOF'
server {
    listen 80;
    listen [::]:80;
    server_name projects.yourcompany.com;
    client_max_body_size 256m;
    location / {
        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_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_pass http://127.0.0.1:8080;
    }
}
EOF
nginx -t && systemctl reload nginx
ufw allow 80,443/tcp
certbot --nginx -d projects.yourcompany.com

The X-Forwarded-Proto https line comes from OpenProject's own proxy example and tells the app your visitors arrived over HTTPS. Two additions are our own suggestion: the Upgrade lines let live co-editing reach its /hocuspocus address over a WebSocket, and client_max_body_size lifts nginx's 1 MB upload limit so attachments go through. Because nginx runs directly on the server rather than in Docker, ufw does guard ports 80 and 443, which is why they need their own allow rule.

Keeping copies and staying current

OpenProject's backup guide names four things to keep: the database, your configuration, uploaded files and any repositories. The Compose files include a ready-made backup job that packs the database files and attachments into a backups folder, but the stack has to be stopped while it runs (docker compose down, build and run the backup service from docker-compose.control.yml, then docker compose up -d). To keep a nightly copy without stopping anything, make a private folder with install -d -m 700 /root/op-backups and add this cron file:

# Save as /etc/cron.d/openproject-dump
15 3 * * * root umask 077; cd /srv/openproject && docker compose exec -T db pg_dump -U postgres -d openproject -x -O > /root/op-backups/openproject-$(date +\%F).sql && tar czf /root/op-backups/attachments-$(date +\%F).tar.gz -C /var/openproject/assets . && cp .env /root/op-backups/dotenv-$(date +\%F)

It saves a database dump with the flags the docs use, the attachments, and a copy of .env, because a dump without its secret key cannot fully come back. Package installs have their own one-liner, sudo openproject run backup, which writes everything to /var/db/openproject/backup. Whichever you use, copy the files to another place regularly so a dead disk does not take the backups with it.

To apply a 17.x update to a Compose install, back up first, run git pull in /srv/openproject, fetch the new images with docker compose pull --ignore-buildable, then restart with docker compose up -d. The example settings track the floating 17-slim image; OpenProject suggests pinning an exact release tag in production so updates happen when you choose. Big version jumps go one at a time: from 16.x you can go to 17.x, but not straight to 18.x. For a new major, a plain pull is not enough: fetch and switch to its branch (git fetch --depth=1 origin stable/18, then git checkout -b stable/18 FETCH_HEAD), change TAG in .env to match, and pull and restart as above. On a package install, small updates are sudo apt-get --only-upgrade install openproject and then sudo openproject configure, every time; for a new major, first point the apt source at that version's repository the way the install steps did.

Questions people ask

Does a business have to pay to use OpenProject?
No. The Community edition is free and released under GPLv3, with no limit on how many people you add. A paid Enterprise token adds extras such as LDAP group synchronisation and professional support, and turning it on keeps the data you already have.
Will the packages install on Ubuntu 24.04?
No. OpenProject builds DEB packages up to Ubuntu 22.04 and has said it will not build them for newer releases. On 24.04 use Docker Compose, which works on any system Docker supports.
My browser shows an SSL error on the new install. Why?
OpenProject switches HTTPS mode on by default but does not handle certificates itself. Keep OPENPROJECT_HTTPS=false only for the private first login, then put a proxy like nginx with a certificate in front and switch HTTPS back on.
Can several of us edit a document at the same time?
Yes. The Compose setup includes the hocuspocus server that powers real-time collaboration in documents. Give it its own secret, as the setup above does, and make sure your proxy passes WebSocket traffic to its address.
Can I bring our projects over from Jira?
OpenProject is building an importer for Jira Data Center versions 10.x and 11.x. It is still in beta, and the documentation asks you to try it on a test install only, so run a trial import before you plan the switch.

Give your projects a home of their own

Choose a server with the cores and memory your team needs, and have OpenProject running the same evening.

Get a server for your team's projects

Read next