InvenTree 1.7.0
Overview
InvenTree is an open-source inventory management system for teams that build or stock physical products. It keeps a parts catalogue with categories, parameters and suppliers, and tracks stock across locations with a full movement history. It holds bills of materials for assemblies and runs purchase, sales and build orders against that stock. Everything in the web interface is also available through a documented REST API, and plugins extend it.
This guide covers launching and using the InvenTree 1.7.0 on Ubuntu 24.04 AMI from SecureAnyCloud on Amazon EC2. It is one version of the SecureAnyCloud help desk, IT service and project management listing on AWS Marketplace. You pick it as the software version when you subscribe and launch.
What the SecureAnyCloud image adds:
- Nothing baked into the image. The image ships with no database, no
adminaccount and no secret keys. First boot creates an empty PostgreSQL database with its own password, a new Django secret key, a new OpenID Connect signing key and a certificate for the instance. It then creates the administrator admin with a password unique to your instance. - No default logins. The package's install step that creates an
adminaccount and writes its password to a file is switched off, so the only account is the one first boot creates for you. The image's self-test (Step 3) confirms that common passwords such as admin,inventree,passwordand123456are refused. - HTTPS from first boot. nginx serves InvenTree on port 443 with a certificate generated on your instance. Port 80 redirects to HTTPS, and a request for a host name the instance does not serve gets no answer.
- The application server is not on the network. InvenTree's package starts its gunicorn application server on
0.0.0.0:6000, which would put Django on the network without TLS. On this image, gunicorn listens on127.0.0.1:6000only, PostgreSQL listens on the loopback address only, and the only open ports are 22, 80 and 443. - The configured host name, never the caller's. nginx passes InvenTree the instance's configured name. Links that InvenTree builds therefore always point at your instance, whatever
HostorX-Forwarded-*headers a client sends, and InvenTree's sign-in rate limit sees the real client address. - Uploaded files need a signed-in user. Pictures and attachments under
/media/are sent only to a signed-in user, as downloads, however the path is spelled. - Metadata access blocked. nginx, gunicorn, InvenTree's background worker, PostgreSQL, first boot and the
inventree-managehelper are blocked from the instance metadata service. An address a user enters (a supplier link, an image URL, a webhook) can never reach it, and the AMI requires IMDSv2. - No system pip. InvenTree runs from its own Python environment in
/opt/inventree/env, with its own current pip. Ubuntu'spython3-pip,python3-wheelandpython3.12-venvpackages, whose security fixes are published only through Ubuntu Pro, are removed. A small package namedsac-inventree-python-depsstands in for them so thataptstays consistent. - Fully patched Ubuntu 24.04 LTS at build time, with unattended security upgrades switched on.
What is on the image: InvenTree 1.7.0 (the project's own Ubuntu 24.04 package from the 1.7.0 GitHub release, checksum verified), Django 5.2, gunicorn, PostgreSQL 16, nginx, Ubuntu 24.04 LTS, cloud-init and the AWS Systems Manager agent.
Default user: ubuntu. Architecture: x86_64. Recommended instance type: m5.large.
Prerequisites
- An AWS account subscribed to the listing, an EC2 key pair and a VPC subnet with a route to the internet (or a private route you use for management).
- A security group that allows TCP 22 (SSH) from your admin network, and TCP 443 (InvenTree) and TCP 80 (redirects to HTTPS) from the networks your users work from. Your parts, stock and supplier data live in InvenTree, so keep ports 80 and 443 as narrow as you can.
Launch the instance
In the AWS Marketplace listing, choose Continue to Subscribe, then Continue to Configuration. Pick InvenTree 1.7.0 on Ubuntu 24.04 as the software version, select your Region, then choose Launch through EC2.
Choose m5.large (or larger for many users or large imports), your key pair and a security group as described above.
To launch with the AWS CLI instead, replace the values in angle brackets:
aws ec2 run-instances --region <region> --image-id <ami-id-from-the-listing> \
--instance-type m5.large --key-name <your-key-pair> \
--security-group-ids <your-security-group> --subnet-id <your-subnet> \
--metadata-options HttpTokens=required,HttpEndpoint=enabled \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=inventree}]'First boot builds the database and takes two to three minutes after the instance is running. The web server starts only when first boot has finished.
Connect to your instance
For the InvenTree 1.7.0 on Ubuntu 24.04 version, the SSH user is ubuntu. Connect with your key pair:
ssh -i <your-key.pem> ubuntu@<public-ip>Check the services
Confirm that PostgreSQL, the InvenTree web server (inventree-web-1), its background worker (inventree-worker-1) and nginx are running, and that first boot has finished:
systemctl is-active postgresql@16-main inventree-web-1 inventree-worker-1 nginx
sudo test -f /var/lib/sac/data/inventree-firstboot.done && echo FIRSTBOOT_DONEactive active active active FIRSTBOOT_DONEOnly SSH and nginx listen on the network. gunicorn and PostgreSQL listen on the loopback address. Check the listeners:
sudo ss -lntp | awk 'NR>1 && $4 !~ /^127\.0\.0\.5[34]/ {split($6, p, "\""); print $4, p[2]}' | sort0.0.0.0:22 sshd 0.0.0.0:443 nginx 0.0.0.0:80 nginx 127.0.0.1:5432 postgres 127.0.0.1:6000 gunicorn [::]:22 sshd [::]:443 nginx [::]:80 nginxThen run the image's self-test. It checks the open ports, signs in with your password, confirms that common passwords are refused, and checks the HTTPS redirect. It takes about 30 seconds:
sudo inventree-selftest.sh[ports] off-box TCP exactly [22 80 443]; gunicorn 127.0.0.1:6000; PostgreSQL loopback [ports] INVENTREE_PORTS_OK [login] per-instance credential authenticates (API token 200, browser sign-in 200 with a working session); default/weak passwords refused [login] INVENTREE_LOGIN_OK [http] port 80 redirects to https://<configured host>/ INVENTREE_SELFTEST_OKGet your URL and password
Read the credentials file. Only root can read it:
sudo cat /root/inventree-credentials.txtThe file looks like this:
# InvenTree 1.7.0 on Ubuntu 24.04 by sac
# Generated on this instance's first boot. These credentials are unique to THIS instance. INVENTREE_URL=https://ec2-<public-ip-dashed>.compute-1.amazonaws.com/ INVENTREE_ADMIN_USER=admin INVENTREE_ADMIN_PASSWORD=<INVENTREE_ADMIN_PASSWORD> # Sign in at the URL above as 'admin'. The certificate is a self-signed certificate made for this instance on its first # boot: compare its SHA-256 fingerprint (sudo openssl x509 -in /etc/ssl/inventree/inventree.crt -noout -fingerprint # -sha256) or replace it with a CA-issued certificate (see the user guide). Change the served name with # sudo inventree-set-hostname <name>.The URL uses the instance's public DNS name from the EC2 instance metadata, and the certificate also names the public and private IP addresses. nginx answers only to those names.
The name is fixed at first boot. If you stop and start the instance without an Elastic IP and its public address changes, run sudo inventree-set-hostname with the new name (Step 8). A better fix is to give the instance an Elastic IP or your own DNS name.
Sign in
Open the INVENTREE_URL in your browser. The certificate is self-signed, so your browser asks you to confirm it the first time. Compare the fingerprint with the command in the credentials file, or install your own certificate (Step 8). Sign in as admin with the password from Step 4.
admin is a superuser, and InvenTree shows a Superuser Mode banner as a reminder. For everyday work, create a user for each person under Admin Center, Users / Access, and give them the groups and roles they need. Keep admin for administration.
To change the admin password, open the user menu (top right), select User Settings, then choose Change Password from the menu beside Account Details. Then delete or update INVENTREE_ADMIN_PASSWORD in /root/inventree-credentials.txt, so that the file does not hold an old password.
If you lose the password, another superuser can set a new one under Admin Center, Users / Access. The Security panel of User Settings also holds multi-factor authentication and your access tokens.
Parts, stock and bills of materials
The screenshots on this page show a small example data set (an electronics assembly and its parts) that was entered during the image build to show the product working. Your instance starts with an empty database.
Parts. Parts holds your catalogue, organised in categories. Each part has an internal part number (IPN), units, parameters, suppliers and prices. A part can be marked as an assembly, a component, purchaseable, salable or trackable.
Bills of materials. An assembly part has a Bill of Materials tab that lists each component and the quantity one assembly uses. InvenTree shows the stock available for each line and how many assemblies you can build from it. Manufacturing turns that into build orders that consume the stock.
Stock. Stock shows every stock item with its quantity, status and location. Locations nest (a warehouse, its shelves, its bins), and every receipt, move, count and consumption is recorded in the item's history.
Purchasing and sales. Purchasing holds suppliers, manufacturers, supplier parts and purchase orders. Receiving a purchase order books the stock in. Sales holds customers, sales orders and shipments.
Administration, e-mail and the background worker
Admin Center. The user menu's Admin Center holds users and groups, background tasks, error reports, data import and export, project codes and the plugin settings. Its System Status panel shows InvenTree's own checks. On a new instance, the only warning is that e-mail is not configured yet.
System settings. System Settings (in the user menu) holds the company name, currencies, label and report templates, barcode support, and how parts, stock and orders behave.
E-mail. Password reset and notification e-mails need an SMTP server. Amazon SES works as the relay, on port 587 with TLS.
Put InvenTree's e-mail settings in a file of their own in /etc/inventree/conf.d, which the services read at start-up. (inventree-set-hostname rewrites config.yaml and conf.d/other, but leaves other files alone.) Then restart the web server and worker:
sudo install -m 0640 -o inventree -g inventree /dev/null /etc/inventree/conf.d/email
sudo nano /etc/inventree/conf.d/email
# export INVENTREE_EMAIL_HOST=<smtp-host>
# export INVENTREE_EMAIL_PORT=587
# export INVENTREE_EMAIL_TLS=True
# export INVENTREE_EMAIL_USERNAME=<smtp-user>
# export INVENTREE_EMAIL_PASSWORD=<smtp-password>
# export INVENTREE_EMAIL_SENDER=<inventree@your-domain>
sudo systemctl restart inventree-web-1 inventree-worker-1The background worker. InvenTree's background tasks (e-mail, notifications, report generation, stock and pricing updates, clean-up) run in inventree-worker-1 with django-q2. It uses PostgreSQL as its queue, so the image needs no Redis. Admin Center, Background Tasks shows the queue and any failed tasks.
The Django console. inventree-manage runs InvenTree's manage.py as the inventree user, in a short-lived systemd unit with the same metadata block as the services. Use it for maintenance commands such as Django's system check:
sudo inventree-manage check 2>&1 | tail -1System check identified no issues (0 silenced).The REST API. Every page of the web interface uses InvenTree's REST API at /api/, and so can your own scripts. The API root answers without a sign-in and reports the version:
curl -sk https://127.0.0.1/api/ | python3 -c 'import json, sys; d = json.load(sys.stdin); print(d["server"], d["version"], "API", d["apiVersion"])'InvenTree 1.7.0 API 570Everything else needs a user. Create an API token for a user under User Settings, Security, Access Tokens (or GET /api/user/me/token/ with the user's name and password). Send the token as Authorization: Token <token>. A token has the rights of the user it belongs to.
Your own DNS name and certificate
Point a DNS record at the instance (an Elastic IP keeps the address stable), then set the name that InvenTree is served as. The command does four things:
- It mints a new self-signed certificate for the name.
- It points nginx and InvenTree's allowed hosts, trusted origins and site URL at the name.
- It updates the URL in
/root/inventree-credentials.txt. - It keeps the name across reboots.
sudo inventree-set-hostname <your-domain>To use a certificate from a public or internal certificate authority instead (for example one issued by Let's Encrypt for <your-domain>), copy it over the generated pair and reload nginx. Running inventree-set-hostname again replaces it with a self-signed one:
sudo install -m 0644 <your-domain>.crt /etc/ssl/inventree/inventree.crt
sudo install -m 0600 <your-domain>.key /etc/ssl/inventree/inventree.key
sudo nginx -t && sudo systemctl reload nginxSecurity checks
nginx serves only the application. Without a sign-in, the API answers 401 and uploaded files under /media/ are refused. Hidden files answer 404, plain HTTP redirects to HTTPS, and a request for a name the instance does not serve gets no answer at all. Check each behaviour:
H=$(sudo grep '^INVENTREE_URL=' /root/inventree-credentials.txt | cut -d= -f2- | sed -E 's#https://([^/]+)/#\1#') for p in /web/ /api/ /api/part/ /media/ /.git/config /.env; do curl -sk -o /dev/null -w "%{http_code} $p\n" --resolve "$H:443:127.0.0.1" "https://$H$p" done curl -s -o /dev/null -w 'http:// -> %{http_code}\n' --resolve "$H:80:127.0.0.1" "http://$H/" curl -sk -o /dev/null -w 'unknown host name -> %{http_code}\n' --resolve "other.example:443:127.0.0.1" "https://other.example/" || true200 /web/ 200 /api/ 401 /api/part/ 401 /media/ 404 /.git/config 404 /.env http:// -> 301 unknown host name -> 000PostgreSQL listens on the loopback address only, and InvenTree runs with Django's debug mode off and an explicit list of allowed hosts. Check both:
sudo -u postgres psql -X -tA -c "SHOW listen_addresses"
sudo grep -E '^debug:' /etc/inventree/config.yamllocalhost debug: FalseThe certificate was generated on this instance and names its own addresses. Inspect it:
H=$(sudo grep '^INVENTREE_URL=' /root/inventree-credentials.txt | cut -d= -f2- | sed -E 's#https://([^/]+)/#\1#')
echo | openssl s_client -connect 127.0.0.1:443 -servername "$H" 2>/dev/null | openssl x509 -noout -subject -ext subjectAltNamesubject=CN = ec2-<public-ip-dashed>.compute-1.amazonaws.com, O = sac X509v3 Subject Alternative Name: DNS:ec2-<public-ip-dashed>.compute-1.amazonaws.com, IP Address:<public-ip>, IP Address:<private-ip>, IP Address:127.0.0.1, DNS:localhostNone of the services can reach the instance metadata service, so an address that a user enters can never reach it. Verify the block:
systemctl show nginx inventree-web-1 inventree-worker-1 postgresql@16-main inventree-firstboot -p Id -p IPAddressDenyIPAddressDeny=168.63.129.16/32 fd00:ec2::254/128 169.254.169.254/32 Id=nginx.service IPAddressDeny=168.63.129.16/32 fd00:ec2::254/128 169.254.169.254/32 Id=inventree-web-1.service IPAddressDeny=168.63.129.16/32 fd00:ec2::254/128 169.254.169.254/32 Id=inventree-worker-1.service IPAddressDeny=168.63.129.16/32 fd00:ec2::254/128 169.254.169.254/32 Id=postgresql@16-main.service IPAddressDeny=168.63.129.16/32 fd00:ec2::254/128 169.254.169.254/32 Id=inventree-firstboot.servicesudo inventree-manage <command> runs Django commands with the same block.
Backup, storage and maintenance
Everything you enter is in the PostgreSQL database inventree (/var/lib/postgresql/16/main). Uploaded pictures and attachments are under /opt/inventree/data/media, and the configuration, the Django secret key and the OpenID Connect key are in /etc/inventree. All of it is on the root volume, so the simplest backup is an EBS snapshot of that volume.
For a consistent copy while InvenTree is running, use:
sudo -u postgres pg_dump -Fc inventree > <backup-dir>/inventree-$(date +%F).dump
sudo tar -C / -czf <backup-dir>/inventree-files-$(date +%F).tar.gz opt/inventree/data/media etc/inventreeThe dump and /etc/inventree hold every password hash and key, so store them as carefully as the instance. InvenTree also has its own backup command (sudo inventree-manage dbbackup), which writes to /opt/inventree/data/backup.
To give the database and attachments more room, enlarge the root volume in the EC2 console (Volumes, Modify). Ubuntu grows the file system on the next boot.
New InvenTree releases arrive as new versions of this listing, and support can help you move your data to one. Operating system security updates install automatically. Run sudo apt-get update && sudo apt-get upgrade to apply everything else. nginx, PostgreSQL and InvenTree restart cleanly and keep all of their data.
Where things live:
- InvenTree: /opt/inventree (code in src, Python environment in env)
- Configuration and keys: /etc/inventree (config.yaml, secret_key.txt, oidc.pem)
- Database: PostgreSQL 16 database inventree (/var/lib/postgresql/16/main)
- Uploaded files, static files, backups: /opt/inventree/data/media, static, backup
- nginx site: /etc/nginx/sites-available/inventree
- Certificate and key: /etc/ssl/inventree/inventree.crt and /etc/ssl/inventree/inventree.key
- Services: inventree-web-1, inventree-worker-1, postgresql@16-main, nginx
- Helpers: /usr/local/sbin/inventree-set-hostname, inventree-manage, inventree-selftest.sh
- Credentials: /root/inventree-credentials.txt (mode 0600)
Security recommendations
- Allow port 22 from your admin network only, and ports 80 and 443 only from the networks your users work from.
- Use your own DNS name and a certificate that your users' browsers trust (Step 8).
- Give each person their own InvenTree user with the narrowest roles that fit, and keep
adminfor administration (Step 5). - Use API tokens rather than passwords for scripts, with one token per script. Revoke tokens you no longer use.
- Install plugins only from sources you trust. A plugin runs inside InvenTree with full access to its data.
- Keep the operating system patched, and snapshot the root volume regularly.
Support and licensing
InvenTree is open-source software under the MIT licence, developed by the InvenTree developers. There is no per-user or per-part licence fee.
The image ships InvenTree exactly as the project packages it for Ubuntu 24.04, with two changes to the package's start-up files. gunicorn listens on the loopback address instead of every address, and the package's own administrator creation is switched off. The AMI price covers SecureAnyCloud's hardening, first-boot setup and support.
- Email: sales@secureanycloud.com
- Website: https://secureanycloud.com
- Support: 24/7, with a 24-hour response SLA
All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.
Deploy on AWS
Launch InvenTree 1.7.0 on Ubuntu 24.04 on AWS with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com