Compare commits

..

1 commit

Author SHA1 Message Date
5c3c32bb6a
add initial setup hints 2025-01-28 22:45:57 +01:00
7 changed files with 185 additions and 161 deletions

View file

@ -1,77 +0,0 @@
# Example Caddyfile for InvenTree
# The following environment variables may be used:
# - INVENTREE_SITE_URL: The upstream URL of the InvenTree site (default: inventree.localhost)
# - INVENTREE_SERVER: The internal URL of the InvenTree container (default: http://inventree-server:8000)
#
# Note that while this file is a good starting point, it may need to be modified to suit your specific requirements
#
# Ref to the Caddyfile documentation: https://caddyserver.com/docs/caddyfile
# Logging configuration for Caddy
(log_common) {
log {
output file /var/log/caddy/{args[0]}.access.log
}
}
# CORS headers control (used for static and media files)
(cors-headers) {
header Allow GET,HEAD,OPTIONS
header Access-Control-Allow-Origin *
header Access-Control-Allow-Methods GET,HEAD,OPTIONS
header Access-Control-Allow-Headers Authorization,Content-Type,User-Agent
@cors_preflight{args[0]} method OPTIONS
handle @cors_preflight{args[0]} {
respond "" 204
}
}
# The default server address is configured in the .env file
# If not specified, the default address is used - http://inventree.localhost
# If you need to listen on multiple addresses, or use a different port, you can modify this section directly
http://inventree.ctbk.de {
import log_common inventree
encode gzip
request_body {
max_size 100MB
}
# Handle static request files
handle_path /static/* {
import cors-headers static
root * /var/www/static
file_server
}
# Handle media request files
handle_path /media/* {
import cors-headers media
root * /var/www/media
file_server
# Force download of media files (for security)
# Comment out this line if you do not want to force download
header Content-Disposition attachment
# Authentication is handled by the forward_auth directive
# This is required to ensure that media files are only accessible to authenticated users
forward_auth {$INVENTREE_SERVER:"http://inventree-server:8000"} {
uri /auth/
}
}
# All other requests are proxied to the InvenTree server
reverse_proxy {$INVENTREE_SERVER:"http://inventree-server:8000"} {
# If you are running behind another proxy, you may need to specify 'trusted_proxies'
# Ref: https://caddyserver.com/docs/json/apps/http/servers/trusted_proxies/
# trusted_proxies ...
}
}

View file

@ -8,9 +8,9 @@ psql:
update:
read -p "Update will cause downtime of the server. Are you sure you want to continue? Press Ctrl+c to abort!" _
$(COMPOSE) pull
$(COMPOSE) down
$(COMPOSE) run --rm inventree-server invoke update
$(COMPOSE) pull
$(COMPOSE) run inventree-server invoke update
$(COMPOSE) up -d
data: # podman does not autocreate data folder

View file

@ -14,6 +14,10 @@ Copy the `sample.env` into a file named `.env` and make sure to adapt all values
In order to run invoke an update or complete the first setup, the data folder must be created (`mkdir data`) and `make update` is used to pull the latest images and apply all database migrations.
`make update` involves the command `docker compose run --rm inventree-server invoke update` which is performs the initial database setup.
To create an admin account, the command `docker compose run inventree-server invoke superuser` can be run.
The command `make up` can be used to run the setup as a foreground service, `make "up -d"` can be used to run the setup in detached mode.
> Warning:
@ -30,7 +34,7 @@ This can be required because Docker does not like ZFS and might have issues to s
### SSO
The following is an example on configuring SSO using OIDC and Keycloak as IdP. See the [InvenTree SSO docs](https://docs.inventree.org/en/latest/settings/SSO) as well as the [AllAuth social providers](https://django-allauth.readthedocs.io/en/latest/socialaccount/providers/index.html) for more details. Note that Keycloak is not a valid provider anymore any OIDC [should be used](https://django-allauth.readthedocs.io/en/latest/socialaccount/providers/keycloak.html).
The following is an example on configuring SSO using OIDC and Keycloak as IdP. See the [InvenTree SSO docs](https://docs.inventree.org/en/latest/settings/SSO) as well as the [AllAuth social providers](https://django-allauth.readthedocs.io/en/latest/socialaccount/providers/index.html) for more details. Note that Keycloak is not a valid provider anymore and OIDC [should be used](https://django-allauth.readthedocs.io/en/latest/socialaccount/providers/keycloak.html).
#### Keycloak

View file

@ -1,6 +0,0 @@
#!/bin/sh
time=$(date +"%Y-%m-%dT%H:%M:%S%z")
dir=backup
[ -d "${dir}" ] || mkdir -p "${dir}"
docker compose run --rm -u postgres inventree-db sh -c 'PGPASSWORD=$POSTGRES_PASSWORD pg_dump -h inventree-db -p 5432 -U $POSTGRES_USER inventree' > "${dir}/${time}.sql"
# to restore: pg_restore -d newdb db.dump

View file

@ -1,8 +1,10 @@
version: "3.8"
# Docker compose recipe for a production-ready InvenTree setup, with the following containers:
# - PostgreSQL as the database backend
# - gunicorn as the InvenTree web server
# - django-q as the InvenTree background worker process
# - Caddy as a reverse proxy
# - nginx as a reverse proxy
# - redis as the cache manager (optional, disabled by default)
# ---------------------
@ -32,20 +34,16 @@
# INVENTREE_TAG=0.7.5
#
# ----------------------------
# Docker compose customization
# ----------------------------
# If you wish to customize the docker-compose script, you should only do so if you understand the stack!
# Do not expect support for customizations that are not part of the standard InvenTree setup!
services:
# Database service
# Use PostgreSQL as the database backend
inventree-db:
image: postgres:17-alpine
container_name: inventree-db
image: ${POSTGRES_IMAGE:?You must provide the 'POSTGRES_IMAGE' variable in the .env file}
expose:
- ${INVENTREE_DB_PORT:-5432}/tcp
env_file:
- .env
environment:
- PGDATA=/var/lib/postgresql/data/pgdb
- POSTGRES_USER=${INVENTREE_DB_USER:?You must provide the 'INVENTREE_DB_USER' variable in the .env file}
@ -53,15 +51,20 @@ services:
- POSTGRES_DB=${INVENTREE_DB_NAME:?You must provide the 'INVENTREE_DB_NAME' variable in the .env file}
volumes:
# Map 'data' volume such that postgres database is stored externally
- ${INVENTREE_EXT_VOLUME:?You must specify the 'INVENTREE_EXT_VOLUME' variable in the .env file!}:/var/lib/postgresql/data/:z
- inventree_data:/var/lib/postgresql/data/:z
restart: unless-stopped
# redis acts as database cache manager
# only runs under the "redis" profile : https://docs.docker.com/compose/profiles/
inventree-cache:
image: redis:7-alpine
container_name: inventree-cache
image: ${REDIS_IMAGE:?You must provide the 'REDIS_IMAGE' variable in the .env file}
depends_on:
- inventree-db
env_file:
- .env
profiles:
- redis
expose:
- ${INVENTREE_CACHE_PORT:-6379}
restart: always
@ -69,27 +72,41 @@ services:
# InvenTree web server service
# Uses gunicorn as the web server
inventree-server:
# If you wish to specify a particular InvenTree version, do so here
image: inventree/inventree:${INVENTREE_TAG:-stable}
container_name: inventree-server
# Only change this port if you understand the stack.
# If you wish to specify a particular InvenTree version, do so here
image: ${INVENTREE_IMAGE:?You must provide the 'INVENTREE_IMAGE' variable in the .env file}
expose:
- 8000
depends_on:
- inventree-db
- inventree-cache
env_file:
- .env
environment:
INVENTREE_SOCIAL_PROVIDERS: |
{
"openid_connect": {
"SERVERS": [{
"id": "oidc",
"name": "Hacknang SSO",
"server_url": "${HKNG_OIDC_URL:?You must provide the 'HKNG_OIDC_URL' variable in the .env file}",
"APP": {
"client_id": "${HKNG_OIDC_CLIENT_ID:?You must provide the 'HKNG_OIDC_CLIENT_ID' variable in the .env file}",
"secret": "${HKNG_OIDC_CLIENT_SECRET:?You must provide the 'HKNG_OIDC_CLIENT_SECRET' variable in the .env file}"
}
}]
}
}
depends_on:
- inventree-db
volumes:
# Data volume must map to /home/inventree/data
- ${INVENTREE_EXT_VOLUME}:/home/inventree/data:z
- inventree_data:/home/inventree/data:z
- ./plugins:/home/inventree/InvenTree/plugins:z
restart: unless-stopped
# Background worker process handles long-running or periodic tasks
inventree-worker:
# If you wish to specify a particular InvenTree version, do so here
image: inventree/inventree:${INVENTREE_TAG:-stable}
container_name: inventree-worker
# If you wish to specify a particular InvenTree version, do so here
image: ${INVENTREE_IMAGE:?You must provide the 'INVENTREE_IMAGE' variable in the .env file}
command: invoke worker
depends_on:
- inventree-server
@ -97,26 +114,36 @@ services:
- .env
volumes:
# Data volume must map to /home/inventree/data
- ${INVENTREE_EXT_VOLUME}:/home/inventree/data:z
- inventree_data:/home/inventree/data:z
restart: unless-stopped
# caddy acts as reverse proxy and static file server
# https://hub.docker.com/_/caddy
# nginx acts as a reverse proxy
# static files are served directly by nginx
# media files are served by nginx, although authentication is redirected to inventree-server
# web requests are redirected to gunicorn
# NOTE: You will need to provide a working nginx.conf file!
inventree-proxy:
container_name: inventree-proxy
image: caddy:alpine
restart: always
image: ${NGINX_IMAGE:?You must provide the 'NGINX_IMAGE' variable in the .env file}
depends_on:
- inventree-server
ports:
- ${INVENTREE_WEB_PORT:-80}:80
- 443:443
env_file:
- .env
# Default web port is 1337 (can be changed in the .env file)
- ${INVENTREE_WEB_PORT:-1337}:8080
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro,z
- ${INVENTREE_EXT_VOLUME}/static:/var/www/static:z
- ${INVENTREE_EXT_VOLUME}/media:/var/www/media:z
- ${INVENTREE_EXT_VOLUME}:/var/log:z
- ${INVENTREE_EXT_VOLUME}:/data:z
- ${INVENTREE_EXT_VOLUME}:/config:z
# Provide nginx configuration file to the container
# Refer to the provided example file as a starting point
- ./nginx.prod.conf:/etc/nginx/conf.d/default.conf:ro,Z
# nginx proxy needs access to static and media files
- inventree_data:/var/www:z
restart: unless-stopped
volumes:
# Persistent data, stored external to the container(s)
inventree_data:
driver: local
driver_opts:
type: none
o: bind
# This directory specified where InvenTree data are stored "outside" the docker containers
device: ${INVENTREE_EXT_VOLUME:?You must specify the 'INVENTREE_EXT_VOLUME' variable in the .env file!}

64
nginx.prod.conf Normal file
View file

@ -0,0 +1,64 @@
server {
# Listen for connection on (internal) port 8080 (unprivileged nginx)
listen 8080;
real_ip_header proxy_protocol;
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-By $server_addr:$server_port;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header CLIENT_IP $remote_addr;
proxy_pass_request_headers on;
proxy_redirect off;
client_max_body_size 100M;
proxy_buffering off;
proxy_request_buffering off;
# Change 'inventree-server' to the name of the inventree server container,
# and '8000' to the INVENTREE_WEB_PORT (if not default)
proxy_pass http://inventree-server:8000;
}
# Redirect any requests for static files
location /static/ {
alias /var/www/static/;
autoindex on;
# Caching settings
expires 30d;
add_header Pragma public;
add_header Cache-Control "public";
}
# Redirect any requests for media files
location /media/ {
alias /var/www/media/;
# Media files require user authentication
auth_request /auth;
# Content header to force download
add_header Content-disposition "attachment";
}
# Use the 'user' API endpoint for auth
location /auth {
internal;
proxy_pass http://inventree-server:8000/auth/;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Original-URI $request_uri;
}
}

View file

@ -1,55 +1,67 @@
# InvenTree environment variables for docker compose deployment
# For a full list of the available configuration options, refer to the InvenTree documentation:
# https://docs.inventree.org/en/stable/start/config/
# Specify the name of the docker-compose project
# InvenTree environment variables for a postgresql production setup
COMPOSE_PROJECT_NAME=inventree
# InvenTree version tag (e.g. 'stable' / 'latest' / 'x.x.x')
INVENTREE_TAG=stable
# Location of persistent database data (stored external to the docker containers)
# Note: You *must* un-comment this line, and point it to a path on your local machine
# InvenTree server URL - update this to match your server URL
INVENTREE_SITE_URL="http://inventree.localhost"
#INVENTREE_SITE_URL="http://192.168.1.2" # You can specify a local IP address here
#INVENTREE_SITE_URL="https://inventree.my-domain.com" # Or a public domain name (which you control)
# e.g. Linux
INVENTREE_EXT_VOLUME=data
# Specify the location of the external data volume
# By default, placed in local directory 'inventree-data'
INVENTREE_EXT_VOLUME=./inventree-data
# e.g. Windows (docker desktop)
#INVENTREE_EXT_VOLUME=c:/Users/me/inventree-data
# Default web port for the InvenTree server
INVENTREE_WEB_PORT=8080
# Ensure debug is false for a production setup
INVENTREE_DEBUG=False
INVENTREE_LOG_LEVEL=WARNING
# Enable custom plugins?
INVENTREE_PLUGINS_ENABLED=True
# Run migrations automatically?
INVENTREE_AUTO_UPDATE=True
# InvenTree superuser account details
# Un-comment (and complete) these lines to auto-create an admin account
#INVENTREE_ADMIN_USER=
#INVENTREE_ADMIN_PASSWORD=
#INVENTREE_ADMIN_EMAIL=
# Database configuration options
# DO NOT CHANGE THESE SETTINGS (unless you really know what you are doing)
# Note: The example setup is for a PostgreSQL database
INVENTREE_DB_ENGINE=postgresql
INVENTREE_DB_NAME=inventree
INVENTREE_DB_HOST=inventree-db
INVENTREE_DB_PORT=5432
# Database credentials - These should be changed from the default values!
# Note: These are *NOT* the InvenTree server login credentials,
# they are the credentials for the PostgreSQL database
INVENTREE_DB_USER=pguser
INVENTREE_DB_PASSWORD=pgpassword
# Redis cache setup
# Refer to the documentation for other cache options
INVENTREE_CACHE_ENABLED=True
INVENTREE_CACHE_HOST=inventree-cache
INVENTREE_CACHE_PORT=6379
# Redis cache setup (disabled by default)
# Un-comment the following lines to enable Redis cache
# Note that you will also have to run docker-compose with the --profile redis command
# Refer to settings.py for other cache options
#INVENTREE_CACHE_HOST=inventree-cache
#INVENTREE_CACHE_PORT=6379
# Options for gunicorn server
INVENTREE_GUNICORN_TIMEOUT=90
INVENTREE_GUNICORN_TIMEOUT=30
# Enable custom plugins?
INVENTREE_PLUGINS_ENABLED=False
# Image tag that should be used
INVENTREE_IMAGE=inventree/inventree:0.11.3
REDIS_IMAGE=redis:7.0-alpine
NGINX_IMAGE=nginxinc/nginx-unprivileged:stable-alpine
# Postgres image must match version of pgdump in inventree image
POSTGRES_IMAGE=postgres:13-alpine
# InvenTree admin account details
# make sure to use secure credentials these lines to auto-create an admin acount
INVENTREE_ADMIN_USER=admin
INVENTREE_ADMIN_PASSWORD=password
INVENTREE_ADMIN_EMAIL=admin@inventree.example
# Database credentials - These must be configured before running
# Change from the default values!
INVENTREE_DB_USER=inventree
INVENTREE_DB_PASSWORD=password
# Django configuration
INVENTREE_SECRET_KEY=some-secret-key
ALLOWED_HOSTS=inventree.example.com,www.inventree.example.com
# SSO Config
INVENTREE_SOCIAL_BACKENDS=allauth.socialaccount.providers.openid_connect
HKNG_OIDC_URL=https://keycloak.example.com/realms/master/.well-known/openid-configuration
HKNG_OIDC_CLIENT_ID=example-client
HKNG_OIDC_SECRET=example-secret