The TechieCRM Local Portal
The TechieCRM Local Portal is the TechieCRM web portal, installed on one office's own computer or server instead of in the TechieCRM cloud. People in the office open it in a web browser. It can read your source CRM's SQL Server, build a TechieCRM copy of your CRM data in MongoDB, and keep that copy in step with the TechieCRM cloud. It does not need the TechieCRM desktop app, although the two can share one computer.
This chapter is for the person who installs and looks after the portal. It covers local portal version 0.8.0.1 (the number in the footer of every portal page).
In this chapter
- What the local portal is
- System requirements
- What the installer checks, and its exit codes
- Choosing the install folder
- Where everything is kept
- Installing on Windows
- Installing on macOS
- Installing on Linux
- The settings file (.env)
- Activating the licence
- Signing in the first time
- Signing in: MongoDB or SQL Server
- Who can open HR & Payroll on the local portal
- Signing out
- Connecting the databases from the portal
- Email on the local portal
- Saved logins on the local portal
- Starting the portal
- Starting the portal automatically
- Preparing your CRM's SQL Server database
- Removing TechieCRM from your CRM's SQL Server database, and putting it back
- The first data load from your SQL Server
- Syncing with the TechieCRM cloud
- The Web server page
- Sharing a computer with the TechieCRM desktop app
- Signing in from more than one place
- Running without MongoDB or without SQL Server
- Opening the portal from other computers
- Updating
- Backing up
- Uninstalling
- Troubleshooting
- Not yet available
What the local portal is
- The same pages as the cloud portal's client site, without the parts that only make sense in the cloud: the TechieCRM Admin console, online billing and the site administration pages. A page fixed in the cloud portal is fixed in the local portal with its next update.
- Your CRM data is kept in MongoDB, in the same layout the desktop app uses. There is no "data mode" to choose: the portal always reads and writes MongoDB.
- The portal's own records (portal sign-ins, roles and portal settings) are kept in a small
database file in the portal's
datafolder. - It answers only on the computer it runs on, at
http://localhost:8000/by default. See Opening the portal from other computers. - It needs a TechieCRM licence. Until the computer is activated, every page shows the activation page. When a trial or subscription ends, or its check-in with the licence server is overdue, the portal becomes read-only rather than locking you out (see When the licence has ended: read-only).
- Text messages (SMS), email marketing through Mailchimp or Constant Contact, and Connect remote support are not on the local portal in this release. They are services that run in the TechieCRM cloud and need a cloud subscription, so their pages, menu entries and ribbon buttons are left out here (the Messages window, your own email and your campaigns stay). That includes a client's Send Text…: it is not on the Clients right-click menu or the client window's toolbar, and the client's text window is not served (October 2026); Send Email… stays. On the cloud portal nothing changes.
- TechieCRM Help is always off on a local portal: a question saved on your own server could never reach the TechieCRM Help Desk, whose queue is in the cloud.
System requirements
The portal keeps your CRM data in MongoDB, so the computer must be one MongoDB supports. That, not Python, sets the minimum.
| Supported | Works, not recommended | Refused by the installer | |
|---|---|---|---|
| Windows (64-bit Intel or AMD) | Windows 11; Windows Server 2019 or 2022 | Windows 10 22H2 (build 19045): the installer warns and carries on | Windows 10 older than 22H2 (builds 17763 to 19044); anything below build 17763, including Windows Server 2016 (build 14393); 32-bit Windows; Windows on ARM |
| macOS (Intel or Apple silicon) | macOS 14 (Sonoma) or later | older macOS: the installer warns and carries on, but MongoDB does not support it | a processor that is not 64-bit |
| Linux (64-bit x86_64 or arm64) | Ubuntu 22.04 and 24.04; Debian 12 (x86_64 only); RHEL, Rocky Linux and AlmaLinux 8 and 9 (Oracle Linux 8 and 9 on x86_64) | other distributions: the installer warns and carries on | a 32-bit system or an unrecognised processor |
A Windows Server newer than 2022 is not refused; the installer says it is newer than MongoDB's supported list and carries on.
You also need:
- Python 3.12 or newer. Required. The installer stops without it.
- MongoDB. Strongly recommended. Without it the portal still installs and starts, but the CRM pages, the cloud sync and the first data load are switched off. The installer does not install MongoDB; it tells you how. On Windows, the TechieCRM desktop app installed for all users brings its own MongoDB, and the portal uses it (see Sharing a computer with the TechieCRM desktop app).
- Microsoft ODBC Driver 18 for SQL Server. Needed only to read your source CRM's SQL Server (the first data load, and the sign-in list kept in the office SQL Server). The cloud sync works without it. Download: learn.microsoft.com/sql/connect/odbc/download-odbc-driver-for-sql-server.
- A processor with AVX on x86_64 (every Intel or AMD processor since about 2011), or ARMv8.2-A or later on arm64. MongoDB needs it.
To see your Windows version and build: press Windows + R, type winver and press Enter.
Or, in a Command Prompt: systeminfo | findstr /B /C:"OS Name" /C:"OS Version". The build is the
last number of OS Version.
| Build | Windows | Portal |
|---|---|---|
| 22000 and above | Windows 11 | supported |
| 20348 | Windows Server 2022 | supported |
| 19045 | Windows 10 22H2 | works, not recommended |
| 17763 | Windows Server 2019 | supported |
| 17763 to 19044 | Windows 10 1809 to 21H2 | refused: update to 22H2 or Windows 11 |
| 14393 | Windows Server 2016, Windows 10 1607 | refused |
A computer that must stay on an older system (for example a Windows Server 2016 box): do not install the portal on it. Install it on a supported computer instead.
Trying it on an unsupported computer, for evaluation only: run the installer with
-AllowUnsupportedOS (Windows) or --allow-unsupported-os (macOS, Linux). It installs anyway and
warns that MongoDB does not support the system. Do not keep client data on such a computer.
What the installer checks, and its exit codes
The installer is installer\install.ps1 on Windows and installer/install.sh on macOS and
Linux. It asks no questions. It works through these steps in order and stops, with a plain
message, at the first thing it cannot do:
- This computer. Checked before anything is created or changed.
- Python 3.12 or newer.
- MongoDB (a warning only), and ODBC Driver 18 (a warning only).
- The Python environment. It creates the
venvfolder and installs what the portal needs, checking the fingerprint (SHA-256) of each package TechieCRM ships with the portal. - The settings file. It writes
.envwith a newly generated secret key, but only when there is no.envyet. It adds the lineTECHIECRM_TRUSTED_PROXY_COUNT=0to any.envthat lacks it, and never changes a value that is already there. - The portal's database file and web files. It creates the
datafolder, prepares the portal's database file, and collects the web files (styles, images) intodata. - What the portal can reach. It reports whether MongoDB and your SQL Server can be used
(the same check as
manage.py check_services). A missing service does not stop the install. - Windows only: the desktop app. If the TechieCRM desktop app's database is on this computer, it runs the sharing step (see Sharing a computer with the TechieCRM desktop app), or tells you the one command to run as an administrator.
- Next steps. It prints Installed. and the commands to activate, start, load your data and sync.
You can run the installer again at any time. It never overwrites an existing .env or the
portal's database file.
Exit codes. A script or remote-management tool sees these numbers; a person sees the message above them.
| Code | What it means | What to do |
|---|---|---|
| 0 | Installed | Carry on with Activating the licence |
| 1 | A step failed. The message names it: Python 3.12 or newer was not found, the Python found is too old, or installing the Python requirements failed | Install a newer Python and run the installer again; for a requirements failure, read the lines above the message (often no internet connection) |
| 2 | macOS and Linux only: an option the installer does not know. The only option is --allow-unsupported-os |
Check the spelling |
| 6 | This computer is not supported. Nothing has been changed | Use a supported computer (see the table above) |
When installing the requirements fails, the Windows message quotes a second code from the requirements step:
| Requirements code | Meaning |
|---|---|
| 1 | The Python package installer failed (read the lines above it) |
| 3 | A package shipped with the portal is missing or has been altered. Nothing was installed. Get a fresh copy of the portal |
| 4 | Everything installed, but a shipped package did not show the expected version afterwards. Run the installer again; if it repeats, contact support |
Any other code on macOS or Linux means a later step (preparing the database file or collecting the web files) failed; the lines above it say why.
Choosing the install folder
The portal has no fixed install folder. It installs into the folder you put it in: the
installer works in the folder that contains its own installer folder. TechieCRM recommends:
| Windows | macOS | Linux |
|---|---|---|
C:\techiecrm-localportal |
/opt/techiecrm-localportal |
/opt/techiecrm-localportal |
These are the folders the service examples in this chapter use. Whatever you choose:
- Choose the final place before you run the installer. The Python environment it builds
(
venv) only works in the folder it was built in. If you move the portal later, deletevenvand run the installer again. - The folder must hold the whole portal:
manage.pyand the foldersbin,installer,localportal,portalandengine. - The account that runs the portal must be able to write to the folder (the portal writes its
datafolder there).
Where everything is kept
<install folder> is the folder you chose above.
| What | Windows | macOS | Linux |
|---|---|---|---|
| The portal (program files) | <install folder>, recommended C:\techiecrm-localportal |
<install folder>, recommended /opt/techiecrm-localportal |
<install folder>, recommended /opt/techiecrm-localportal |
| Python environment | <install folder>\venv |
<install folder>/venv |
<install folder>/venv |
| Settings file | <install folder>\.env |
<install folder>/.env |
<install folder>/.env |
| Data folder | <install folder>\data |
<install folder>/data |
<install folder>/data |
| The portal's database file (portal sign-ins, roles, portal settings) | data\localportal.sqlite3 |
data/localportal.sqlite3 |
data/localportal.sqlite3 |
| Web files (styles, images) | data\staticfiles |
data/staticfiles |
data/staticfiles |
| Uploaded files | data\media |
data/media |
data/media |
| Sync progress | data\sync_state.json |
data/sync_state.json |
data/sync_state.json |
| Web server logs | none: the messages appear in the PowerShell window that runs the portal | data/access.log, data/error.log (and data/service.log when started by launchd) |
data/access.log, data/error.log |
| Cloud licence (when activated with a cloud key) | data\cloud_license.json |
data/cloud_license.json |
data/cloud_license.json |
| When the portal last tried to check in with the cloud, and how it went (shown on the Licence page) | data\cloud_checkin.json |
data/cloud_checkin.json |
data/cloud_checkin.json |
| Portal accounts linked to TechieCRM IDs, and the workspace they belong to (Signing in the first time) | data\cloud_accounts.json |
data/cloud_accounts.json |
data/cloud_accounts.json |
| Each person's email accounts and passwords, encrypted, and the key for them (Email on the local portal) | data\mail_accounts.enc, data\mail_accounts.key |
data/mail_accounts.enc, data/mail_accounts.key |
data/mail_accounts.enc, data/mail_accounts.key |
| The mail the portal has read for each person (one file each, message contents encrypted) | data\mail_cache\ |
data/mail_cache/ |
data/mail_cache/ |
| Licence file | %APPDATA%\TechieCRM\license.dat (that is, C:\Users\<you>\AppData\Roaming\TechieCRM\license.dat) |
~/Library/Application Support/TechieCRM/license.dat |
~/.config/TechieCRM/license.dat |
| CRM data (MongoDB) | Wherever your MongoDB keeps its data. With the TechieCRM desktop app on the same computer: the desktop's data folder, by default C:\ProgramData\TechiecrmData |
Wherever your MongoDB keeps its data | Wherever your MongoDB keeps its data |
.env starts with a dot, so macOS and Linux hide it in file listings (ls -a shows it), and
File Explorer shows it only with file name extensions turned on.
The licence file belongs to the account that runs the portal, not to the install folder. It
sits in that account's own folder, so run the portal, its sync and the activation as the same
account. To keep it somewhere else, set TECHIECRM_LICENSE_DIR (see
The settings file). The file is locked to this computer, so copying it
to another computer does not move the licence.
The installer does not set up MongoDB, so it does not choose where MongoDB keeps its data.
The portal connects to mongodb://localhost:27017 and the database techiecrm unless you tell it
otherwise, or unless the TechieCRM desktop app's database is on the same Windows computer. To find
a MongoDB server's data folder, look at its own configuration (the dbPath setting).
On a Windows computer shared with the desktop app, two more files matter, both in
C:\ProgramData\TechieCRM (a hidden folder: type the path into File Explorer's address bar):
techiecrm-local-db.json (where the desktop's database is) and sync-owner.json (which program
syncs this computer with the cloud).
Installing on Windows
Before you start
- Python. Install Python 3.12 or newer from python.org. On the first page of the Python installer, tick Add python.exe to PATH.
- MongoDB, one of:
- install the TechieCRM desktop app for all users on this computer (chapter
A1); the portal shares its database; or
- install MongoDB Community Server as a Windows service
(mongodb.com/try/download/community); the
installer looks for a service named
MongoDB; or - use a MongoDB server on another computer, after the install (Running without MongoDB). - ODBC Driver 18 for SQL Server, if you will load data from your SQL Server. (The desktop app's all-users install puts it on the computer for you.)
- The portal folder. Copy the portal to
C:\techiecrm-localportal(or your chosen folder).
Install
- Open Windows PowerShell. If the TechieCRM desktop app is on this computer, open it as administrator (right-click ▸ Run as administrator), so the installer can also do the sharing step.
- Go to the portal folder and run the installer:
cd C:\techiecrm-localportal
powershell -ExecutionPolicy Bypass -File installer\install.ps1
- Read the steps as they appear. Each starts with
==>; a warning starts with!!:
| Line | What it means |
|---|---|
| Checking this Windows | Your Windows edition and build, and supported, a warning (Windows 10 22H2, or a Server newer than 2022), or the refusal with exit code 6 |
| Checking Python | Which Python it will use. It tries py -3.13, then py -3.12, then python |
| Checking MongoDB | TechieCRM desktop app database found … the portal will share it, MongoDB service found, or the warning No MongoDB here with what to do (the install carries on) |
| ODBC warning | Microsoft ODBC Driver 18 for SQL Server was not detected: needed only for the first data load |
| Creating the Python environment | Builds venv and installs the requirements. This takes a few minutes the first time |
| Writing .env | A new settings file with a generated secret key (or .env already exists, leaving it alone) |
| added TECHIECRM_TRUSTED_PROXY_COUNT=0 | Explained under The settings file |
| Preparing the local database / Collecting static files | The portal's database file and web files in data |
| Checking MongoDB and SQL Server from the portal | One line per service, with the reason in words. Not configured for SQL Server is normal at this point |
| Preparing your CRM's SQL Server database for TechieCRM | Config database setup: Not configured is normal at this point. Once your CRM's SQL Server database is connected (on the portal's Config database page, or in .env), the portal does this every time it starts (see Connecting the databases from the portal). It never stops the install |
| Sharing the desktop app's database and taking over its cloud sync | Only with the desktop app on this computer and PowerShell run as administrator. Without administrator rights you get the command to run later instead |
| Installed. | Done. The next steps follow |
- Carry on with Activating the licence.
Installing on macOS
Before you start
- Python 3.12 or newer, from python.org or Homebrew.
- MongoDB. With Homebrew, the installer suggests:
brew tap mongodb/brew && brew install mongodb-community && brew services start mongodb-community. Or use a MongoDB server on another computer after the install. - ODBC Driver 18 for SQL Server, if you will load data from your SQL Server (Microsoft's download page, above).
- The portal folder. In Terminal, create the folder, make it yours, and copy the portal into it:
sudo mkdir -p /opt/techiecrm-localportal
sudo chown "$USER" /opt/techiecrm-localportal
Install
- In Terminal:
cd /opt/techiecrm-localportal
installer/install.sh
- Read the steps as they appear (the same as on Windows, with these differences):
- Checking this computer shows macOS
on , or a warning on a macOS older than 14. - Checking Python triespython3.13, thenpython3.12, thenpython3. - Checking MongoDB says mongod found when the MongoDB server program is installed or running; otherwise it warns and shows the Homebrew command above. - There is no sharing step. - Carry on with Activating the licence.
Installing on Linux
Before you start
- Python 3.12 or newer, with its
venvmodule. On Ubuntu and Debian the module is a separate package (for examplepython3.12-venv). - MongoDB, from MongoDB's own instructions (for Ubuntu: mongodb.com/docs/manual/tutorial/install-mongodb-on-ubuntu), or a MongoDB server on another computer.
- ODBC Driver 18 for SQL Server, if you will load data from your SQL Server. The installer
finds it through
odbcinst. - The portal folder, as on macOS: create
/opt/techiecrm-localportal, make it owned by the account that will run the portal, and copy the portal into it.
Install
cd /opt/techiecrm-localportal
installer/install.sh
Checking this computer shows your distribution, version and processor, or a warning when the distribution is not on MongoDB's list. The other steps are as on macOS. Then carry on with Activating the licence.
The settings file (.env)
Everything you can change about the portal is in .env, in the install folder. The installer
writes it once; after that it is yours. Your CRM's SQL Server database and the MongoDB server can instead be
chosen on the portal's Config database page, which keeps them encrypted (see
Connecting the databases from the portal);
a connection set in .env wins over the page.
To change a setting
- Open
.envin a text editor (Windows:notepad .envin the install folder). - Change the line, or add it. One setting per line:
NAME=value. A line starting with#is a note and is ignored. - Put a value that has spaces or a
#in single quotes:MAX_SQL_PASSWORD='an example#value'. Do not use the characters${in a value. - Save the file and restart the portal (and its scheduled sync picks the change up on its
next run). The portal reads
.envonly when it starts.
.env holds passwords and the secret key. Keep it readable only by the people who look after the
portal, and never send it to anyone.
Connection and address
| Setting | What it does | Default | Example |
|---|---|---|---|
PORT |
The port the portal answers on | 8000 |
PORT=8020 |
ALLOWED_HOSTS |
The names the portal answers to, separated by commas | localhost,127.0.0.1 (as written by the installer) |
ALLOWED_HOSTS=localhost,127.0.0.1,crm.example.lan |
CSRF_TRUSTED_ORIGINS |
The web addresses a sign-in form may be sent from, separated by commas | Follows PORT: http://localhost:<port>,http://127.0.0.1:<port> |
CSRF_TRUSTED_ORIGINS=http://localhost:8020,http://127.0.0.1:8020 |
TECHIECRM_TRUSTED_PROXY_COUNT |
How many proxies in front of the portal add the caller's address to the X-Forwarded-For header. 0 means none: the header is ignored, so nobody can choose the address the sign-in lockout and rate limits see. A whole number from 0 to 10 |
0 |
TECHIECRM_TRUSTED_PROXY_COUNT=1 (only with one reverse proxy in front) |
SITE_BASE_URL |
The portal's own address, used in links the portal writes into emails and web forms | http://127.0.0.1:8010 |
SITE_BASE_URL=http://localhost:8000 |
LOCALPORTAL_PUBLIC_SITE_URL |
Where the techiecrm.com link in the page header goes | https://www.techiecrm.com |
leave as it is |
SESSION_IDLE_SECONDS |
Signs a person out after this many seconds without using the portal (unless they ticked Keep me signed in) | 900 (15 minutes) |
SESSION_IDLE_SECONDS=1800 |
Changing
PORT. The trusted sign-in origins follow the port by themselves, as long asCSRF_TRUSTED_ORIGINSis not set in.env. Portals installed before 16 October 2026 have that line set to port 8000: delete it (or change it to the new port) when you changePORT. Otherwise signing in fails with a security (CSRF) error.
Your source CRM's SQL Server
Needed for the first data load, for the sign-in list when it is kept in the office SQL Server, and
for TechieCRM's own tables in your CRM's SQL Server database, which the portal creates itself (see
Preparing your CRM's SQL Server database). The portal only ever creates and
writes TechieCRM's own TCRM_ tables in this database, never the source CRM's tables.
The easier way is the portal's Config database page, which finds the server, lists its
databases and keeps the connection encrypted (see
Connecting the databases from the portal).
Use these settings instead when you prefer .env. When MAX_SQL_SERVER is set here, these
settings win and the page cannot change them.
Which login to use. The first time the portal starts against a database, the login in
MAX_SQL_USER must be allowed to create tables: the database's MASTER login, or a login with
db_owner on it. After TechieCRM's tables exist you may change it to a login with less rights; when
a newer TechieCRM version adds a column, the portal then asks again for a login that may make the
change, on the Web server page.
| Setting | What it does | Default | Example |
|---|---|---|---|
MAX_SQL_SERVER |
The SQL Server: host, host\INSTANCE or host,port. Left blank, nothing is ever contacted and the server shows as Not configured |
blank | MAX_SQL_SERVER=sql1.example.lan\CRM |
MAX_SQL_DB |
The database name | blank | MAX_SQL_DB=OfficeCRM |
MAX_SQL_USER |
A SQL Server login. The portal signs in with a SQL Server login; Windows sign-in is not supported yet. Allowed to create tables the first time (see above) | blank | MAX_SQL_USER=MASTER |
MAX_SQL_PASSWORD |
That login's password | blank | MAX_SQL_PASSWORD='your password here' |
MAX_SQL_DRIVER |
The ODBC driver's name | ODBC Driver 18 for SQL Server |
leave as it is |
MongoDB
| Setting | What it does | Default | Example |
|---|---|---|---|
MONGO_URL |
The MongoDB server, as a full address. Leave it blank to use the desktop app's database on a shared Windows computer, or otherwise mongodb://localhost:27017. A value here wins over both. Let manage.py mongo_server --set write it for you (see Running without MongoDB) |
blank | MONGO_URL=mongodb://db1.example.lan:27017 |
MONGO_DB |
The database name. A database name saved on the Config database page is used instead, unless MONGO_URL is also set here |
techiecrm (or the value of TCRM_LOCAL_DB) |
MONGO_DB=techiecrm |
TCRM_LOCAL_DB |
The desktop's name for the same setting; used when MONGO_DB is not set |
techiecrm |
leave as it is |
MONGO_HOST, MONGO_PORT |
The server used when MONGO_URL is blank and there is no desktop database |
localhost, 27017 |
MONGO_PORT=27018 |
MONGO_SERVER_SELECTION_TIMEOUT_MS |
How long a MongoDB read waits for the server, in milliseconds | 700 for a server on this computer, 5000 for one elsewhere |
MONGO_SERVER_SELECTION_TIMEOUT_MS=3000 |
LOCALPORTAL_PROBE_TIMEOUT_S |
How long each service check (MongoDB, SQL Server) may take, in seconds | 1.5 |
LOCALPORTAL_PROBE_TIMEOUT_S=3 |
LOCALPORTAL_MONGO_GUARD |
0 switches off the Unavailable without a MongoDB database page; every page then waits on MongoDB itself. Leave it on |
1 |
leave as it is |
The one-place sign-in check
| Setting | What it does | Default | Example |
|---|---|---|---|
SINGLE_SESSION_MODE |
The one-place-at-a-time check: off, observe (record sign-ins, never interrupt anyone) or enforce. Any other value stops the portal at start-up with a message naming the setting |
off |
SINGLE_SESSION_MODE=observe |
LOCALPORTAL_SESSION_REGISTRY |
Which list of sign-ins the portal uses: cloud, office_sql or local_mongo. Blank lets the portal decide. Any other value stops the portal at start-up |
blank | LOCALPORTAL_SESSION_REGISTRY=office_sql |
See Signing in from more than one place.
Licence and cloud
| Setting | What it does | Default | Example |
|---|---|---|---|
TECHIECRM_LICENSE_DIR |
The folder for the licence file, instead of the account's own folder. Must be a full path | blank (the account's own folder, see Where everything is kept) | TECHIECRM_LICENSE_DIR=C:\techiecrm-localportal\licence |
TECHIECRM_API_BASE |
Where the cloud sync connects | blank (the TechieCRM cloud) | leave blank |
TECHIECRM_LICENSE_SERVER |
Read by the portal but not used in this release | blank | leave blank |
Set by the installer: do not change
| Setting | What it does |
|---|---|
SECRET_KEY |
Protects sign-ins and forms. Generated by the installer. If it is missing, the portal refuses to start (SECRET_KEY is not set …). Changing it signs everyone out |
DEBUG |
Must stay False. True shows internal details to anyone who triggers an error |
DATABASE_URL |
The portal's database file: sqlite:///./data/localportal.sqlite3 |
The portal also reads settings meant only for the TechieCRM cloud (billing, cloud storage and the
like) and for TechieCRM's own developers (LICENSE_DEV_MODE,
LOCALPORTAL_ALLOW_UNVENDORED_PACKAGES, TECHIECRM_LOCAL_DB_ENDPOINT). Leave them out of your
.env. Never set LICENSE_DEV_MODE: it switches off every licence check.
Activating the licence
Until this computer is activated, every portal page sends you to the activation page. You need
your licence key, which starts with TCRM-. To get it, sign in at client.techiecrm.com as your
workspace's administrator, open Workspace Admin ▸ Your Licenses, and click Copy beside the key;
then paste it here. Copy it rather than typing it: one wrong character makes it fail. The key shown
there is a cloud licence key (for example TCRM-sek_Ywjo…, about 37 characters); the portal checks
it with the TechieCRM cloud, so this computer must be online to activate with it. A long signed
key (about 190 characters, with a . in it) that TechieCRM sent you directly also works, and needs
no internet connection (see below). No key yet? Register at
techiecrm.com/register; your trial key arrives by email once
your workspace is approved.
In the browser
- Start the portal (Starting the portal) and open
http://localhost:8000/activate/. - Paste your key into Licence key and click Activate.
- When it works, the portal opens. From then on
/activate/and the Licence link in the header open the Licence page instead, which shows the licence's details.
From a terminal, in the install folder (Windows: venv\Scripts\python in place of
venv/bin/python):
venv/bin/python manage.py activate_license TCRM-XXXX-XXXX
It answers Activated with the tier and the days remaining (or perpetual). Then check it at any time with:
venv/bin/python manage.py check_license
check_license prints licensed: True or licensed: False, the tier, how the computer was
activated (online, or offline with the registration still to come), the days remaining, and any
reason for a refusal. It exits with 0 when licensed and 1 when not, so a monitoring tool can
use it. check_license --checkin asks the cloud first (for a cloud key), so a licence ended or
refused at the cloud shows at once; the portal's cloud sync (sync_cloud) does the same check before
each run.
Activate as the account that will run the portal, because the licence file is kept in that account's folder (see Where everything is kept).
No internet connection? This applies to a signed key only: a cloud key must reach the cloud to
activate. With a signed key, when the licence server cannot be reached, activation completes on
this computer and the registration with the server is done later (check_license shows it as
pending). The server must still be reached in time: see needs to check in below.
When activation is refused
On the activation page, a refusal appears in a coloured box above the key. The terminal command prints the same text after activation failed: or Not licensed after activation:.
| Message | What it means | What to do |
|---|---|---|
| Enter your licence key. | You clicked Activate with the field empty | Paste the key |
| Invalid key format: missing TCRM prefix | The key does not start with TCRM- |
Copy the whole key again, from the first TCRM- to the last character |
| The TechieCRM cloud did not accept this key: followed by the reason | A cloud key the cloud does not know or has released | Copy it again from Workspace Admin ▸ Your Licenses; follow the reason |
| The TechieCRM cloud could not be reached, so the key was not activated. | This computer is offline, or a proxy or firewall blocks the cloud | Check the internet connection and try again |
| … recognised this key, but the licence is not active: … | The cloud knows the key, but the licence has ended or is suspended | Renew it in Workspace Admin, or contact support |
| A signed-key reason followed by It was also offered to the TechieCRM cloud, which did not accept it either. | A long key with a . that did not verify, and the cloud does not know it either |
Copy the whole key again; if it repeats, contact support |
| Invalid license key: signature verification failed | The key has been changed, or mistyped | Copy it again; do not type it by hand |
| Failed to parse license key: … | The key could not be read at all | Copy it again; if it repeats, contact support |
| This license key has no expiry date … | An old key with no expiry date. Every TechieCRM licence carries one | Ask TechieCRM for a replacement key |
| This license key has expired. | The key's date has passed | Use a current key |
| The licence server refused this key: followed by the server's reason | The licence server answered no (for example the key was released or revoked) | Follow the reason; contact support if it is not clear |
| Activation failed: unexpected reply from the license server. | Something between you and the server answered instead of the server | Try again later; check any proxy or filter on your network |
| License activated but failed to save: … | The licence file could not be written | Check the account can write to its licence folder (or to TECHIECRM_LICENSE_DIR) |
| That key could not be activated on this machine. | Activation ended without a licence and without a reason | Contact support |
When an activated computer stops being licensed, the activation page names the reason:
| Message | What to do |
|---|---|
| This licence has been revoked. | Contact TechieCRM support |
| The licence server refused this key: … | Follow the reason |
| This computer's clock appears to have been set back. | Correct the date and time, then reload the page |
| The stored licence could not be read: … | Enter your key again to activate again |
| Your trial or subscription has ended. | Your data, settings and local database are exactly as you left them. Enter a current key |
| This install needs to check in with the licence server. | Connect to the internet and reload. If you are online, enter your key again |
Your trial or subscription has ended. and This install needs to check in with the licence server. leave the portal readable, as the next section describes. Every other reason in this table still sends each page to the activation page.
When the licence has ended: read-only
When the trial or subscription of an activated computer ends, the portal keeps serving your data for reading (October 2026):
- Every page opens as usual, with a warning bar across the top: Read-only: the licence has ended. You can open and look up your data; changes are not saved. and an Enter a licence key link to the activation page.
- Any change is refused. Saving a form, deleting, or any other change shows a page headed
Read-only: the licence has ended with That change was not saved., the reason, Enter a
licence key and Go back. A change made from a script or a button that works in the
background gets the same answer (status 403, with
licence_read_only). Nothing reaches your data. - Still allowed: signing in and out, the one-place sign-in check, the Light / Dark switch, the activation page, and the Licence page's Check now (so a renewed licence is picked up at once).
- The cloud sync and the office writes stop too:
manage.py sync_cloudrefuses with This install is not licensed until a current key is entered.
Your data, settings and local database are exactly as you left them. Enter a current key on the
activation page (or run manage.py activate_license) and the portal is writable again straight
away.
When the check-in is overdue (October 2026). A signed key for a trial, Alpha or Beta licence
must check in with the licence server now and then. When that check-in is overdue past its grace
period (three days after it was due), the portal goes read-only in exactly the same way
instead of locking you out. Only the words name the other reason: the warning bar reads
Read-only: the licence check-in is overdue. You can open and look up your data; changes are not
saved., and a refused change shows a page headed Read-only: the licence check-in is overdue
with That change was not saved. and This portal has not checked in with the licence server for
longer than its grace period allows, so it is read-only. ... (a background change gets status
403 with licence_read_only and the reason checkin_overdue). The cloud sync and the office
writes stop as above. Connect the computer to the internet and enter your licence key again on the
activation page (or run manage.py activate_license); the portal is writable again straight away.
A licence whose date has passed shows the licence has ended words, not these.
A licence that was never activated, was revoked, was refused by the licence server, a clock set back, or a licence file that cannot be read still sends every page to the activation page.
The Licence page
Once this computer is activated, click Licence in the header bar (beside Sign out), or
Licence details on the Web server page, or open http://localhost:8000/local/licence/.
You must be signed in. The page has the same header as the other Local Portal pages (see
The header on the portal's own pages), with Licence
underlined; administrators also get a Back to Web server link at the bottom. It shows:
| Line | What it says |
|---|---|
| Kind of licence | Cloud key (the key from Workspace Admin ▸ Your License on techiecrm.com) or Signed offline key |
| Licence key | The key with only its first 9 and last 4 characters showing, for example TCRM-sek_…HiJk. Administrators also get Copy, which copies the whole key (to paste on the set-up page, or into another computer) |
| Tier | Trial, Alpha, Beta or Full |
| Trial | Yes, a trial licence or No |
| Status | Active, Ended, Refused or Revoked, with the reason under it when there is one |
| Ends | The licence's end date and the days left, or No end date |
| Workspace | The company the licence belongs to and the workspace account, as the cloud reported them |
| This computer | This computer's name, and how the cloud registered it (its name there, computer, registered, and since when) |
| Seats and devices | How many devices are registered on the licence (computers, phones, tablets), and seats when the cloud reports them |
| Release phase | The release programme's phase (for example Beta, until 31 Jan 2027) and the build channel, as the cloud reported them |
| Check-in | Last checked with the TechieCRM cloud: the time of the last successful check-in, in the portal's time zone, and when the next one is due. Only when the last attempt really could not reach the cloud does it add The cloud could not be reached at the last check, so this computer is running on the stored licence until it can check in again. |
The labels, their order and the words on this page are the same as on the desktop's Configuration window Licence page (Administrator Guide A14): both read them from one shared file, so they cannot drift apart.
Buttons (portal administrators only). Anyone else signed in sees the details, but no buttons and no Copy.
- Check now checks in with the TechieCRM cloud straight away and says how it went: Checked just now. The TechieCRM cloud confirmed this licence. It is active.; The TechieCRM cloud could not be reached (the portal keeps running on the stored licence until its end date; check the internet connection and try again later); or The TechieCRM cloud did not confirm this licence with the cloud's reason, after which the portal stops serving until a current key is entered on the activation page. With a signed key there is nothing to check with the cloud, and the page says so.
- Deactivate this computer asks first. The question explains what happens, and nothing happens until you click Yes, deactivate this computer (Keep it activated goes back).
Your CRM user ID and Link my TechieCRM ID (everyone signed in). Below the details the page shows Your CRM user ID when your account is linked, with Remove this link, and the Link my TechieCRM ID box (the same form as the desktop's Configuration window): see Managing linked CRM user IDs.
Deactivating releases this computer on the TechieCRM cloud (or, for a signed key, with the licence server) and removes the licence stored here. The portal stops serving at once and shows the activation page with This computer has been deactivated. Your data, settings and databases are not touched. Things to know before you do it:
- On a computer that also runs the TechieCRM desktop app, the cloud may keep one device record for both (it knows the computer, not the program). Releasing this computer from the portal can then release it for the desktop app as well, which may ask to be activated again. With a signed key the two use one licence file, so it deactivates the desktop app too.
- With a cloud key and no internet connection, the licence is still removed here, but the
cloud keeps its record of this computer; remove it in Workspace Admin on techiecrm.com. With a
signed key, deactivating needs the licence server; if it cannot be reached nothing is released,
and the page does not say so, so run
check_licenseafterwards to confirm.
Signing in the first time
A newly activated portal has no accounts yet. After activation it shows the sign-in page (Welcome back), and above the form a box says This portal has no accounts yet. There are two ways in. Use whichever suits you; both give you an administrator who can open the CRM and add everyone else.
Way 1: sign in with your TechieCRM ID
Your TechieCRM ID is the email and password you use at client.techiecrm.com. It works on the portal when the portal was activated with a cloud licence key (the key from Workspace Admin ▸ Your Licenses); the sign-in page then says You can sign in with your TechieCRM ID under the form.
- Open
http://localhost:8000/login/. - Enter your TechieCRM ID email and password, and click Log in.
The portal asks the TechieCRM cloud whether the email and password are right and whether the ID belongs to the workspace this portal is licensed to. When they are, the portal:
- creates its workspace the first time, named after the company on your licence;
- creates your account on the portal with the same email and name, linked to your TechieCRM ID;
- keeps your password (stored securely, as for any portal account), so the same sign-in also works later when the internet is down.
The first account made on the portal is its administrator. Anyone from your workspace who signs in with their TechieCRM ID after that gets a Staff account; an administrator can change a role on the Users page. (The cloud's sign-in check does not say who is an administrator in your workspace, so the portal cannot copy that yet.)
The first sign-in for each person needs an internet connection. After that:
- Online, the cloud has the last word: a password you changed at client.techiecrm.com works at once and replaces the one kept here, and the old one stops working; an ID removed from the workspace is refused.
- Offline, the portal checks the password it kept at your last online sign-in.
An account someone made on the portal itself (with the set-up page, or by an administrator) is a local account: it always signs in with its own portal password and is never sent to the cloud, even when its email is also a TechieCRM ID.
When a TechieCRM ID is refused, the reason appears in a red box above the form:
| Message | What it means | What to do |
|---|---|---|
| The email or password is incorrect, or this TechieCRM ID is not a member of the workspace this portal is licensed to. | The cloud said no. For safety the cloud does not say which of the two it is | Check the password at client.techiecrm.com; make sure the ID is in the workspace whose licence key activated this portal |
| This TechieCRM ID belongs to a different workspace from the one this portal is set up for, so it cannot sign in here. | The portal already belongs to one workspace (recorded at its first TechieCRM ID sign-in), and this ID is in another | Sign in with an ID from this portal's workspace |
| The TechieCRM cloud could not be reached, and this TechieCRM ID has not signed in on this portal before … | No internet connection, or the cloud is busy, and this person has never signed in here online | Check the connection and try again, or use a local account |
| The TechieCRM cloud has no workspace linked to the licence key this portal was activated with … | The licence key is not attached to a workspace at the cloud | Use Create the first administrator, or ask TechieCRM support to link the licence |
| Too many sign-in attempts for this workspace right now … | The cloud's limit for one licence (60 checks in 15 minutes) was reached | Wait a few minutes |
| This TechieCRM ID is temporarily locked …, or the cloud's own lock message | Too many wrong passwords at the cloud | Wait, or reset the password at client.techiecrm.com |
| This email already has a local account on this portal that is not linked to your TechieCRM ID … | Someone made a local account with your email | Sign in with that account's own password |
| Your account is switched off on this portal. | An administrator switched the account off | Ask your administrator |
| This portal is not activated with a licence the TechieCRM cloud can check … | No licence key is available to ask the cloud with | Use a local account, or activate with your cloud licence key |
| Incorrect email or password. Please try again. | A local account's password is wrong (or a TechieCRM ID's kept password, while offline) | Try again |
Careful with wrong passwords. The sign-in page locks an account after 5 wrong passwords in 15
minutes, and blocks all sign-ins from one address after 20 in 15 minutes. Everyone reaching the
portal on this computer counts as one address. The lock stays until a portal administrator
releases it: Unlock under Locked sign-ins on the Web server page, or
manage.py unlock_signin when no administrator can sign in (see
Unlocking a sign-in). A TechieCRM ID that fails only because the cloud cannot
be reached, or because it is in another workspace, is not counted.
Way 2: create the first administrator
Use this when you want a portal account that is not tied to a TechieCRM ID, or when the portal was activated with a signed key.
- On the sign-in page, click Create the first administrator (or open
http://localhost:8000/setup/). - Paste the licence key this portal was activated with: the same key you entered on the activation page. It proves you are the person who set the portal up.
- Enter the administrator's Email, First name, Last name (optional) and a Password twice. The password must pass the portal's password rules (long enough, not too common, not all numbers).
- Click Create the administrator. The sign-in page opens with The administrator account … is ready. Sign in with it now. Sign in with that email and password.
The page asks for the licence key, rather than only working on this computer, because the portal may be set up from another computer in the office (see Opening the portal from other computers). After 10 wrong keys in 15 minutes from one computer it stops checking for a while: wait 15 minutes.
The page exists only while the portal has no accounts at all. As soon as any account exists (made
here or by a TechieCRM ID sign-in) it is gone: the link disappears and /setup/ answers Not found.
Two people using it at the same moment cannot both succeed; the second sees Not found. Add further
people from the portal's Users page, or have them sign in with their TechieCRM IDs.
Files: the list of portal accounts linked to TechieCRM IDs, and which workspace the portal
belongs to, is kept in data/cloud_accounts.json in the install folder. Back it up with the rest of
data/. If it is lost, people who signed in with a TechieCRM ID keep their portal accounts, but
those accounts become local accounts: they sign in with the password kept at their last online
sign-in, and a password changed at client.techiecrm.com no longer reaches the portal.
Signing in: MongoDB or SQL Server
The sign-in page has the same header as the portal's own pages: TechieCRM, with Local Portal on a smaller line under it. Above the email and password fields there is the same SQL / Mongo rocker switch as the TechieCRM desktop app's sign-in window (October 2026), SQL on the left; the side that is on is filled with your theme's green, and resting the pointer on a side shows what it signs in to:
| Side | Under it, in small text | Sign in with |
|---|---|---|
| SQL | your CRM's SQL Server database, for example IslandCRM2017 on SQLSERVER\CRM | Your CRM user ID and its password, the same ones you use in your CRM and in the TechieCRM desktop app. Or your TechieCRM ID, when it is linked to your CRM user ID (below) |
| Mongo | the portal's MongoDB database, for example techiecrm on this computer | Your TechieCRM ID, or a local portal account (as in Signing in the first time) |
Whichever you choose, the CRM pages show the same data: the portal's MongoDB copy, which the first data load and the sync keep filled from your SQL Server database. The choice decides only how you sign in.
- SQL is greyed out with Not set up while no SQL Server database is set up for the portal. The page says so, in the desktop app's words: No SQL Server database is set up yet. Use the gear to set one up. (Mongo is never greyed on the portal: it is also how a portal administrator signs in to set things up.)
- The page remembers your last choice in this browser, and selects it next time. With nothing remembered it opens on Mongo (the desktop app opens on SQL, the way it always signed in).
- The ID and password fields have no label above them (October 2026): a grey tip inside each empty field says what goes there, in the desktop's words. With SQL chosen the ID field reads TechieCRM Email ID or CRM User ID; with Mongo it reads TechieCRM Email ID. The password field reads Password. The tip changes as soon as you move the switch. Screen readers and your browser's password manager still know each field by the same words.
- The gear, to the right of the switch (it said Config before October 2026), shows Database configuration: set up the SQL Server and MongoDB database connections used to sign in. when you rest the pointer on it, and opens the Config database page (and from there the header links Web server, Config database and Licence). If you are not signed in as a portal administrator, it first asks you to sign in (Sign in as a portal administrator to open Config database.); an administrator then lands on Config database. Someone who is not an administrator goes where a sign-in normally goes and is told Only a portal administrator can open Config database.
Signing in with your CRM user ID
- Choose SQL. The grey tip in the first field now reads TechieCRM Email ID or CRM User ID.
- Enter your CRM user ID (up to 12 characters, upper or lower case) and its password, and click Log in.
The portal checks them the way the TechieCRM desktop app does: it signs in to your CRM's SQL Server database as that user, so your SQL Server checks the password; the portal does not keep it. It then checks that an administrator has not switched the user off in the CRM.
- The first time, the portal finds your portal account: one already linked to your CRM user ID (in your office's database, where a TechieCRM desktop administrator may have linked it, or on this portal); the TechieCRM account your CRM user is linked to (from the TechieCRM desktop app's user links); or the portal account with your CRM user's email address. When there is none, it makes one, as Staff, named and addressed from your CRM user record (an administrator can change the role on the Users page).
- A portal administrator's account is never joined automatically. Finding an account through the user links or an email address is a guess the portal makes for you, so it may join an ordinary account but never a portal administrator's (or a superuser's). When the guess finds an administrator, the sign-in is refused with Your CRM user ID matches a portal administrator account … and nothing is made or linked; the portal log records it (the CRM user ID, the account's number and how it matched). If that administrator account is yours, link it once yourself: choose SQL Server, sign in with the account's email and password, and enter your CRM user ID and its password when asked (see Signing in to SQL Server with your TechieCRM ID). After that your CRM user ID signs in to that administrator account directly. The portal refuses rather than making a second, Staff account for you, because that second account would then hold your CRM user ID and stop you linking it to your own. Links made before 19 October 2026 are kept as they are; remove one under Linked CRM logins on Config database.
- Keep me signed in remembers your CRM user ID (not an email) for the next sign-in.
- The portal must already have an account (its first administrator) before anyone can sign in with a CRM user ID.
When a CRM user ID is refused, the reason appears in a red box above the form:
| Message | What it means | What to do |
|---|---|---|
| The CRM user ID or password is incorrect. | SQL Server refused the sign-in. For safety it does not say which of the two was wrong | Check the password in your CRM. This counts towards the lock below |
| The SQL Server … could not be reached, so your CRM user ID could not be checked … | The SQL Server is off, the network is down, or the ODBC driver is missing on the portal's computer | Try again later, or choose MongoDB and sign in with your TechieCRM ID. Not counted |
| The CRM user ID … has been switched off by an administrator, so it cannot sign in. | The user is switched off in the CRM (Administrator ▸ Disable Login). Switched off for the web only still lets you in, as in the desktop app | Ask your CRM administrator. Not counted |
| … is not a user of the CRM database …, so it cannot sign in here. | The SQL Server login exists but is not a CRM user (a service login, for example) | Use your own CRM user ID. Not counted |
| The CRM user ID … signed in, but may not open the database … | The login has no access to that database | Ask your CRM administrator. Not counted |
| A CRM user ID has at most 12 characters. | Too long to be a CRM user ID | Check what you typed. Not counted |
| This portal has no accounts yet … | The portal has never been set up | Create the first administrator first |
| Your account is switched off on this portal. | The matching portal account is switched off | Ask your portal administrator |
| Your CRM user ID matches a portal administrator account … | Your CRM user's email (or user link) points at a portal administrator's account, which is never joined automatically | If the account is yours, link it as described above. Not counted |
| The linked CRM logins could not be read just now … | The links kept in your office's database could not be read (the database did not answer), so the portal cannot tell whose CRM user ID this is | Try again in a moment, or choose MongoDB. Not counted |
| This account is locked for a technical review … | 5 wrong passwords in 15 minutes | Ask a portal administrator to unlock it (Unlocking a sign-in) |
The lock is the same as for any sign-in: 5 wrong passwords in 15 minutes lock that CRM user ID on the portal (see Careful with wrong passwords above). While it is locked the portal does not try the password on your SQL Server at all.
Signing in to SQL Server with your TechieCRM ID
With SQL Server chosen you can also enter your TechieCRM ID (your email) and its password. The TechieCRM ID is checked first, exactly as with MongoDB chosen. Then:
- The first time, a second page, Link your CRM user ID (the same heading and words as the
desktop app's second window), asks once for your CRM user ID and its password (Enter your CRM
user ID and password for
. ). When they are right you are signed in, and the portal links the two. - Save my CRM password on this portal (encrypted): tick it (it starts unticked, as the desktop app's Save in my Credential Storage Manager does) to keep your CRM password encrypted on this computer, for this SQL Server database. Then, after that, your TechieCRM ID is enough: the portal checks the saved CRM user ID and password with SQL Server at once, with no extra page. Unticked, the link is still made and the page asks for the CRM password each time. (The portal keeps the password in its own encrypted file for now; the desktop keeps it in your Credential Storage Manager.)
- If the saved CRM password stops working (you changed it in the CRM, or the user was switched off), the second page says There is a problem with the CRM user ID or password, shows your CRM user ID, and asks for the CRM password again. The save tick starts ticked here, so when it is right you are signed in and the new password replaces the saved one. Use a different CRM user ID lets you enter another one: once it is checked, your link moves to it. Forget the saved password removes the saved password (the link stays; see Managing linked CRM user IDs to remove it); Cancel and go back returns to the sign-in page without signing in.
- If the SQL Server cannot be reached, the sign-in page says so, nothing is changed, and it is not counted as a wrong password.
- If you signed in before with your CRM user ID itself, or a TechieCRM desktop administrator linked your TechieCRM ID to your CRM user ID, your account is already linked, but no password is saved on this portal yet: the second page asks for it once.
Where the link is kept (from 20 October 2026). When your account signs in with a TechieCRM ID, the link between your TechieCRM ID and your CRM user ID is kept in your office's SQL Server database, in the same place the TechieCRM desktop apps keep theirs. So it is one link: a link made on the portal is the link the desktop app uses, and a link an administrator makes in the desktop app is the one the portal uses, with no extra step. When your office has a TechieCRM cloud subscription, the cloud also checks that the CRM user ID is not already someone else's; if the cloud cannot be reached the link is still made, and a desktop finishes the check on its next sync. Your saved CRM password is never part of the link: it stays on this computer.
Some links are kept on this portal only, exactly as before:
- the account has no TechieCRM ID (a CRM user ID sign-in made it);
- the link was made by signing in with the CRM user ID itself (one password: a link the desktops share needs both passwords, or an administrator);
- the office database cannot hold the shared links yet: it has no TechieCRM workspace ID, or its link table has not been made (Save and prepare on Config database makes it).
A CRM user ID can be linked to only one person per database, wherever the link is kept. If yours is linked to someone else, the second page says so (… is already linked to another TechieCRM ID … or … is already linked to another portal account …): ask your portal administrator to remove that link. If the links cannot be read just now (the office database does not answer), the sign-in page says The linked CRM logins could not be read just now …; it never guesses, and it is not counted as a wrong password.
The saved password is never shown on any page, never sent to the browser, never put in a link and never written to the portal's logs. Links are kept per SQL Server database: if Config database is pointed at another database, the old links are not used (they come back into use if the old database does).
Managing linked CRM user IDs
Removing a link follows the same rule as making one: both passwords, or an administrator.
- Link my TechieCRM ID (October 2026, the same form as the desktop's Configuration window ▸ Linked CRM logins, Administrator Guide A14): the Licence page has a Link my TechieCRM ID box when a SQL Server database is set up and your account has a sign-in password. Your TechieCRM ID is shown; enter your sign-in password, your CRM user ID and the password of the CRM user ID, tick Save my CRM password on this portal (encrypted) if you want the portal to keep it, and click Link my TechieCRM ID. Both passwords are checked now (your sign-in password as at sign-in, the CRM password with SQL Server), so the link is yours: it is kept in your office's database for a TechieCRM ID the cloud knows (the desktop apps use it too), on this portal otherwise. Linking another CRM user ID replaces your link. A wrong password says Not linked: a password was not right … and counts towards the sign-in lock; a CRM user ID already linked to someone else is refused with who holds it. An account a CRM user ID sign-in made has no sign-in password to prove, so it is not offered the box.
-
Link another person (portal administrators, October 2026): in Config database ▸ Linked CRM logins, under the list, type the person's TechieCRM ID (their email address) and the CRM user ID, and click Link another person. The TechieCRM cloud finds the person in your office's TechieCRM account (only your own account is searched); the link is kept in your office's database, so the desktop apps use it too, and it is recorded under your own linked CRM user ID, so your own account must be linked first (To link another person, your own account must be linked to your CRM user ID for this database first …). When the cloud does not find the person, cannot be reached, or the licence has no cloud account, or the CRM user ID is already someone else's, the page says so in those words and nothing is written. A database that cannot keep the shared links yet (no workspace ID, no link table) says why instead of showing the form: Save and prepare fixes that.
-
Your own link: the Licence page shows Your CRM user ID when your account is linked, says where the link is kept (in your office's database, so the TechieCRM desktop app uses it too, or on this portal only), and has Remove this link. To remove it, enter your sign-in password (your TechieCRM ID's) and the password of your CRM user ID, then click Remove this link. An account a CRM user ID sign-in made has no other password, so it asks for the CRM password only. When a password is wrong the page says The link was not removed: a password was not right …, and the wrong password counts towards the sign-in lock like any other. Removing the link also removes the CRM password saved for it.
- Everyone's links (portal administrators): the Config database page has a Linked CRM logins section. A line above the list says where links for the database in use are kept (in the database, so the desktop apps use them too; or on this portal only, and why). The list shows each CRM user ID, the portal account linked to it (no account on this portal yet when a desktop linked a TechieCRM ID that has never signed in here; account removed when the portal account was deleted), Kept in (Shared with desktops or This portal only), whether a password is saved here, and when it was linked, with Remove. Removing a link kept in the office database removes it for the desktop apps too; it is recorded as an administrator's removal under your own CRM user ID, so your own account must be linked first (otherwise the page says To remove a link the desktops share, your own account must be linked to your CRM user ID for this database first …). A removed link is kept in the database's history, never deleted.
- The setting Let TechieCRM IDs sign in to SQL Server with a linked CRM login is in the same section (On by default; Turn off / Turn on). Off: with SQL Server chosen, people must sign in with their CRM user ID, and a TechieCRM ID is refused with In this office a TechieCRM ID cannot sign in to SQL Server: an administrator turned it off … (the older wording, On this portal a TechieCRM ID cannot sign in to SQL Server …, shows until the portal's next update of its desktop code). Links are kept. See The office-wide sign-in setting below.
The office-wide sign-in setting (October 2026). Since the desktop's Configuration window (Administrator Guide A14) this is one setting for the whole office, kept in the office database (TechieCRM's settings table, made by Save and prepare): every TechieCRM desktop and this portal follow it, and an administrator changes it here or on a desktop's Linked CRM logins page. The line under the setting says where the value in force is kept: Kept in the office database, so every TechieCRM desktop follows it too., Kept on this portal only until it is moved into the office database (manage.py move_signin_setting)., or Not changed yet: On is the default., and who last changed it. Which value counts: the office database's when it has one; otherwise this portal's own older value (from before this release) until it is moved; otherwise On. When the office database cannot keep the setting yet (it has not been prepared), Turn off changes it on this portal only and says so.
Moving this portal's older value into the office database, once (after updating):
venv/bin/python manage.py move_signin_setting
On its own it changes nothing and says what it would do: write this portal's value to the office
database (when the office database has none), Nothing to move (the portal never changed it, or
the office database already says the same), or that the office database's value is kept (an
administrator set it on a desktop; it always wins). Run it again with --apply to do it; add --by
your@email to record who moved it. The older value stays in data/crm_links.enc, marked as moved,
so nothing is lost. Exit code 0 when done (or listed), 1 when it cannot be moved here (the portal's
desktop code is older than this release, no SQL Server database is set up, or the office database
cannot keep it yet), 2 for wrong options.
Moving older links into the office database (once, after updating). Links made before 20 October 2026 were all kept on the portal only. To move them to where the desktop apps see them, run, in the portal's folder:
venv/bin/python manage.py import_crm_links
(venv\Scripts\python manage.py import_crm_links on Windows.) On its own the command changes
nothing: it lists each link with what it would do: TO LINK (made by a TechieCRM ID sign-in that
proved the CRM password), ALREADY (the office database holds it), STAYS (with the reason:
no TechieCRM ID, made by a CRM user ID sign-in alone, the account was removed),
CONFLICT (the office database says otherwise; it is left alone) or OTHER DB (made for
another database). Then run it again with --apply to do it. Links made by a CRM user ID sign-in
alone move only if you add --by YOURCRMID (your own CRM user ID): they are then recorded as an
administrator's links. Saved passwords stay on this computer; nothing is ever printed about a
password. The command ends with exit code 0 when done, 1 when nothing could be moved or a link was
refused (it says why), and 2 for wrong options.
Files: the saved CRM passwords, the links kept on this portal only and the setting's older
value (see above) are kept in
data/crm_links.enc, beside the saved database connection and encrypted with the same key file
(data/portal_connections.key). Back them up together with the rest of data/. Without the key
file they cannot be read: links kept in the office database still work, but their passwords must be
entered once more; links kept on this portal only must be made again. Links kept in the office
database are part of that database (the TCRM_IdentityLink table), so the database's own backup
keeps them.
Who can open HR & Payroll on the local portal
(October 2026.) HR & Payroll holds employee records and pay, so the portal opens it only for:
- a portal administrator (always);
- anyone signed in as, or linked to, MASTER;
- the HR users on the office's list.
Everyone else does not see HR & Payroll in the left-hand menu or as a shortcut, and opening its address gives You don't have access to HR & Payroll with the reason.
Which list. With a Config database set (your CRM's SQL Server), the portal uses the same HR users list as the desktop app, kept in that database: a change made in the desktop (Settings ▸ HR & Payroll ▸ HR & Payroll access) or on the portal is the same change. Without a Config database, the portal keeps its own list.
Who counts as "on the list". A person is matched by their sign-in e-mail, by the CRM user ID they signed in with (or linked, see Managing linked CRM user IDs above), and by any CRM user ID linked to their TechieCRM ID.
Choosing the HR users (portal administrators): open Settings (the gear), the HR & Payroll
tab, and click Choose who can open HR & Payroll, or go straight to
/admin-portal/hr-access/. Tick the people who run HR and press Save HR users. With a Config
database the change is written to the office database at once, so every desktop follows it; the
desktops then copy it to the TechieCRM cloud at their next sync.
- Never saved: only administrators and MASTER can open HR & Payroll.
- The list cannot be read (the SQL Server is down): only administrators and MASTER, until it can be read again. The page says why.
- The portal re-reads the office list at most every 30 seconds, so a change made on a desktop reaches the portal within half a minute.
Pay is not sent to other devices. When this portal syncs with the cloud, employees' pay and private HR details (pay rate, wage, commission, rating, notes, emergency contact) come down only if the portal's signed-in TechieCRM ID is an HR user. The portal's HR & Payroll list shows name, number, department, position and status, so nothing on it changes.
Signing out
Click Sign out in your user menu in the CRM (or in the header bar on the portal's own pages: Web server, Config database, Licence). You are signed out straight away, with no "are you sure" page, and you land on the sign-in page with You are signed out. at the top. Sign in as a different user... in the CRM's application menu works the same way.
Signing out does everything it always did: it ends your session in this browser (a Keep me signed in session too), frees your place for the one-place sign-in check (see Signing in from more than one place) and records signed out in the workspace's activity log. Your email or CRM user ID stays filled in on the sign-in page next time, as before.
On a shared or public computer, click Also forget this browser's saved sign-in under the sign-in form, just after signing out. It clears the remembered email and CRM user ID, the last database choice and everything TechieCRM stored in this browser. (This is what the old sign-out page's Forget my credentials on this computer tick box did.)
When the sign-out page still appears. The one-click sign-out only answers a click made on the portal itself, or the address typed into the browser. If a link on another web site, an email or a document points at the portal's sign-out address, the portal shows the sign-out page instead, with Sign out, Cancel and Forget my credentials on this computer, so another site cannot sign you out without you seeing it. An old browser that does not say where a click came from can also see this page: click Sign out on it.
When you are away from the keyboard for longer than the idle time shown on the sign-in page (and Keep me signed in was not ticked), the portal signs you out by itself and the sign-in page says so.
Connecting the databases from the portal
The portal can connect to your CRM's SQL Server database, and choose its MongoDB database, from
its own Config database page (called Office database before 19 October 2026), in the
browser, the same way the TechieCRM desktop app's sign-in and Configuration windows do
(the desktop's Database page, Administrator Guide A14, mirrors this page). When you save the connection, the portal prepares the database itself: it creates
TechieCRM's own tables there (see Preparing your CRM's SQL Server database).
You do not need to edit .env or create anything by hand.
Who can use it: a portal administrator (the first account on the portal is one). Anyone else who opens the page sees Only a portal administrator can configure the portal's databases., and their header does not offer the page. Someone who is not signed in is sent to the sign-in page first.
Where it is
- The first time an administrator signs in, and nobody has chosen a database yet, the portal opens the page by itself, once. After that, signing in takes you to the portal as usual, whether or not you connected anything; come back to the page at any time.
http://localhost:8000/local/database/.- On the Web server page, under Config database setup: Config database: connect and prepare.
- The Config database link in the header of the portal's own pages (see The header on the portal's own pages).
The header on the portal's own pages
The portal's own pages (Web server, Config database, Settings > Email, Licence, and the page shown while MongoDB is missing) share one header bar at the top, to the left of the System / Light / Dark switch:
- The brand block: TechieCRM, with Local Portal on a smaller line under it, set to the
right. The whole block is one link that opens TechieCRM (the CRM itself, the same as Open
on the Web server page), for everyone signed in, as long as a database is connected: your
CRM's SQL Server database is set (on the Config database page or in
.env), or the portal's MongoDB answers. When neither is, the block does not open the CRM: pointing at it says No database is connected yet, and clicking it shows a short note under the header. An administrator's note links to Config database; anyone else's says to ask the portal administrator. - The links. A portal administrator sees Web server · Config database · Email settings · Licence · Sign out; anyone else sees Email settings · Licence · Sign out (Web server and Config database are for administrators; Email settings is each person's own mail accounts, see Email on the local portal). The page you are on is underlined. On a narrow window the links move to their own row under the brand block.
Connect to. At the top, choose what to connect, as in the desktop's Source CRM choice:
- SQL Server (your CRM's database): your CRM's SQL Server database, where TechieCRM keeps its own tables beside your CRM's.
- MongoDB (TechieCRM's database): the TechieCRM database the portal keeps its copy of your CRM data in (see MongoDB below).
What the page finds by itself
As soon as the page opens, the box Found on this computer and your network starts looking, and shows Looking... while it does. The rest of the page can be used straight away.
- MongoDB (TechieCRM's database) lists the MongoDB servers on this computer: the standard
port (
localhost:27017), the TechieCRM desktop app's own database, the server set in the desktop app's Settings ▸ Local Database, any MongoDB program running on this computer (with its port), the server named in the portal's.env, and the one saved on this page. Each server is listed once, with where it was found, its MongoDB version and how many databases it has and how many of them already hold TechieCRM data (for example 60 databases, 18 with TechieCRM data). The server the portal uses now is marked In use now, with the database it uses (In use: …). The databases themselves are not listed here: selecting the server offers them in the Database box's drop-down list, TechieCRM ones first. A server that wants a user and password says so: select it, then type them in the MongoDB form and press List databases. A server that did not answer is shown greyed, with the reason, and cannot be selected. - SQL Server (your CRM's database) lists the SQL Servers on this computer and on your network,
as
SERVERorSERVER\INSTANCE, with the SQL Server version when the server reports it (for example SQL Server 2019 (15.0.2000.5)), and this computer or its network address. It asks the SQL Server Browser service on each computer; looking takes about three seconds.
Choosing one. Each list is a set of choices, one of which can be selected at a time: click anywhere on a server's box, or move to it with Tab and the arrow keys and press Space or Enter. The selected server has a round mark filled in and an outline in the theme's colour. Selecting a server shows its kind in Connect to and fills in the form below: for a SQL Server, the Server box (then enter the SQL login and password and continue with List databases); for MongoDB, the Address (left blank for the desktop app's database, which a blank address means), the User when one is known, and the TechieCRM database; to choose another database on that server, pick it from the Database box's drop-down list.
What is selected when the page opens:
| The list finds | What is selected |
|---|---|
| The server the form already holds (the one saved or in use, or one you typed) | That server, already selected. Nothing in the form changes |
| Only one server, and the form holds no other | That server, selected for you, and the form is filled in. Connect to stays where it was, so look at the kind you need |
| Several servers, none of them the one in the form | None. Select the right one |
| Only one server, but the form holds a different one | None, so a saved or in-use connection is never replaced without you choosing. Select it if you want it |
For MongoDB, a blank Address counts as the desktop app's database or the one in use. This computer's default MongoDB (when nothing was ever chosen) does not count as a choice: if it is not running and one other MongoDB answers, that one is selected for you.
The form stays yours. You can change any box after selecting. Typing a different server name or MongoDB address clears the selection in the list; typing the name of a server in the list selects it again.
The form's boxes are named inside them. Each box shows its name as dim text (for example Server (host, host\INSTANCE or host,port), SQL login, Password, Database) until you type in it; point at a filled box to see its name again. Server, SQL login and Password sit on one row, and Database has List databases beside it.
Refresh looks again. The page keeps the last answer for a minute, so opening the page again in that time shows it at once, and a new look runs at most every few seconds: pressing Refresh sooner shows the last answer with Refreshed a moment ago. This keeps a page left refreshing from flooding your network. A server you selected stays selected after Refresh when it is still found.
Looking never changes anything. It signs in to nothing on a SQL Server (listing a server's databases still needs the login you type), it tries no passwords on MongoDB (only none, or the ones already saved: the desktop app's for its own database, and this page's), and it creates nothing.
Nothing found? The list says why (No SQL Server answered on this computer or your network, or No MongoDB answered on this computer). A SQL Server behind a firewall, or one whose SQL Server Browser service is stopped, does not answer; a MongoDB on another computer is not looked for. Type it in the form instead.
Your CRM's SQL Server database
- Server. Select a SQL Server in the list above, or type its name as
host,host\INSTANCEorhost,port(for exampleSQLSERVER01\CRMor10.0.0.5,1433). - SQL login and Password. A SQL Server login and its password. Windows sign-in is not
supported. The first time, use the database's MASTER login, or a login with
db_owneron it, so TechieCRM may create its tables. You can change to a login with fewer rights afterwards. - Database. Click List databases: the portal signs in to the server with that login and lists its databases (system databases are left out; one this login may not open is marked no access for this login). Click your CRM's database, or type its name.
- Test connection (optional). The portal signs in to that database and says Signed in to … as …, with whether this login may create tables. It only reads; nothing is changed.
- Save and prepare. The portal tests the connection again and, only when it works, saves it and prepares the database. Wait for the page to come back; preparing a new database can take a minute.
Looking for servers, List databases and Test connection never change anything, and nothing is created before you click Save and prepare. If the test fails, the page says Nothing was saved, and nothing was created, with the reason.
What Save and prepare shows
The page shows Saved:
| Result | What it means | What to do |
|---|---|---|
| Ready | TechieCRM's tables are in place. The page lists what was Set up, the columns and indexes added, and how many tables the web users may now use | Nothing |
| Needs a login with more rights | Tables are missing and this login may not create them. The page lists what was Not allowed for this login | Enter the MASTER login, or a login with db_owner, in SQL login and Password and click Save and prepare again |
| Setup incomplete | Some tables could not be set up; the page lists them with the reason | Usually the same as above |
| Removed from this database | TechieCRM was removed from this database on purpose, so nothing was created | Nothing, or put it back with manage.py restore_techiecrm (see Removing TechieCRM), which sets the tables up again |
| Not checked | The server could not be reached, or refused the sign-in | Check the server, login and password, then try again |
Steps taken opens the list of every step the preparation took.
Running it again is safe. Prepare again runs the same preparation on the saved connection; it only adds what is missing. The portal also runs it every time it starts.
When the test says
| Message | What to do |
|---|---|
| … refused the sign-in for …: check the login and password | Check both. Careful: SQL Server may lock a login after several wrong passwords |
| No SQL Server answered at … | Check the name (host, host\INSTANCE or host,port), that the server is running and allows remote TCP/IP connections, and the firewall |
| … signed in, but may not open the database … | The database name is wrong, or this login has no access to it. Use List databases |
| … may NOT create tables … (the test worked) | Use the MASTER login, or one with db_owner, for the first Save and prepare |
| The Microsoft "ODBC Driver 18 for SQL Server" is not installed … | Install it on this computer (see System requirements) |
| The … cannot contain ';', '{' or '}' | TechieCRM cannot use a server name, login or password with those characters. Change the password, or use another login |
Changing or removing it. To change the database or the login, change the fields and click Save and prepare again. Leave Password blank to keep the saved one (the box says Password (saved: blank keeps it)). Forget this connection removes the saved connection from this computer; the portal then works without an office SQL database. TechieCRM's tables already in that database are left as they are.
In use now at the top of the page shows the SQL Server database and the MongoDB database the portal uses right now, where each comes from, and the last Config database setup result.
Shared with the TechieCRM desktop on this computer (October 2026)
The portal and a TechieCRM desktop on the same computer keep one set of office settings in the
folder they share (~/Library/Application Support/TechieCRM on macOS, %ProgramData%\TechieCRM
or %LOCALAPPDATA%\TechieCRM on Windows, ~/.config/TechieCRM on Linux), one entry per
workspace:
- Save on this page (SQL Server or MongoDB) also keeps the server, database and SQL login (or the MongoDB address, user and database) there: Shared with the TechieCRM desktop on this computer. The desktop's Configuration window then shows and uses them. Passwords are never shared; the portal's stay encrypted in its own store.
- What the desktop saved for this workspace shows under In use now as Shared on this
computer (... saved by a TechieCRM desktop on 21 Oct 2026.), and fills this page's empty
fields while the portal has no connection of its own. The portal's own saved connection, or
.env, always wins. - The licence is shared the same way. When the portal activates your office's licence, a desktop on this computer with no licence (or only a trial) uses it too, and the other way round: a portal with no licence takes the one the desktop activated, at its next start or check-in.
- Without a licence for a workspace yet, Save still saves and says it was not shared.
- Other computers. Save also keeps the names (never a password) in your workspace in the TechieCRM cloud, so a TechieCRM desktop on another computer gets them when its person signs in with a TechieCRM ID in its Configuration window.
Where the connection is kept, and .env
The connection is kept encrypted on this computer, in the portal's data folder:
portal_connections.json holds it, and portal_connections.key is the key that unlocks it
(readable only by the account that runs the portal, on macOS and Linux). The password is never
shown on the page, never sent back to the browser and never written to a log. Back the two files up
together: one is no use without the other. If the key is lost, the page says the saved connection
cannot be read; enter it again.
.env still wins. When MAX_SQL_SERVER is set in .env, the SQL connection comes from .env
and the page says This portal's .env sets the SQL Server (MAX_SQL_SERVER), and .env wins. You can
still use Test connection and Prepare again, but not save. To manage it on the page instead,
clear MAX_SQL_SERVER, MAX_SQL_DB, MAX_SQL_USER and MAX_SQL_PASSWORD in .env and restart
the portal. The same goes for MongoDB with MONGO_URL.
A saved SQL connection is used at once, by the portal and by the commands (the first data load,
ensure_office_schema, remove_techiecrm and the others): no restart is needed.
MongoDB on the Config database page
Choose MongoDB (TechieCRM's database) at the top, or select a MongoDB server in the list the page found (see What the page finds by itself).
- Address:
host,host:port, or a fullmongodb://ormongodb+srv://address. Leave it blank to keep using the TechieCRM desktop app's database on this computer, or this computer's MongoDB. - User and Password: when the server needs a sign-in.
- Database: the database name. List databases shows the databases on the server; one that already holds TechieCRM data is marked TechieCRM.
Test checks that the server answers and accepts the sign-in. Save tests first and saves
nothing when the server does not answer. Then restart the portal: it opens MongoDB when it
starts, so the page says A different MongoDB connection is saved. Restart the portal to use it
until you do. A saved address wins over the desktop app's database on this computer, so the two
programs then use different databases. Forget this connection goes back to the default after a
restart. This does the same as manage.py mongo_server --set (see
Running without MongoDB), but keeps the address
encrypted instead of in .env.
Email on the local portal
(October 2026) On the local portal, Email in the CRM opens your own mail: every account's Inbox in one list, laid out like the desktop's Email window (chapter 12, Your mail on the local portal). The portal reads your mail from your mail provider itself, so each person adds their own email accounts once, on the portal, in Settings > Email. Nothing has to be set up on the desktop for this, and nothing is copied from it.
Each person sees and changes only their own accounts and their own mail. Nobody else who signs in to the portal can open them, a portal administrator included: an administrator manages their own accounts on the same page, like everyone else. The one thing an administrator can do with another person's mail is remove it, for example when someone leaves the office (see Removing another person's email below).
Adding your email account
- Sign in to the portal and click Email settings in the header (every signed-in person has it), or click the gear (Email Settings) on the Email page, or Set up email accounts on an empty Email page (it says Add your email account to see your inbox here., the same words as the heading of Settings > Email). The page is called Settings > Email.
- Under Add an account, click your provider: Gmail, Outlook.com, Microsoft 365, Yahoo, iCloud or Other. A provider fills in its incoming and outgoing servers and ports for you; Other leaves them for you to type (your provider's help pages list them).
- Type your Email address and your Password. Under the password, the page says what your provider needs when it recognises it, for example Gmail needs an app password here (2-step verification), not your normal password. The other fields are as on the desktop: - Display name: your name as people see it. - User name: usually the whole email address; leave it empty to use the address. - Other addresses: aliases and forwarding addresses that deliver to this mailbox, separated by commas. They count as your own addresses. - Incoming mail: the server, the port (empty means the usual one: 993 for IMAP, 995 for POP), IMAP or POP, and Use SSL. With SSL on port 143 (IMAP) or 110 (POP) the server must switch to a secure connection, or your password is not sent. With POP, mail always stays on the mail server when the portal reads it. - Outgoing mail (SMTP): the server, the port (empty means 587) and Use TLS (port 465 uses a secure connection from the start; 587 switches to one). Email you write on the portal goes out through this server, from this address (19 Oct 2026); Test sign-in checks it. - Read mail from this account: untick it to keep the account here without showing its mail on the Email page. - Send from this account: the account is offered in From when you write an email on the portal (it needs an outgoing server too). Untick it to read the account without sending from it.
- Click Save. The portal does this in two steps, as the desktop does: it saves the password first (so it is kept even when the mail server cannot be reached at that moment), then signs in to your incoming server to check it, and shows the result at the top of the page (see Test sign-in below).
- Click Open Email (or Email in the CRM). The portal checks your accounts for new mail when the page opens, when you click Check for New Mail, and every 5 minutes while the page stays open.
Each account in the list shows its address (green when its last sign-in worked, red when it did not), the incoming and outgoing servers, whether a password is saved (Missing: click Edit and type it when not), the last Sign-in result, trusted certificates and other addresses, with Test sign-in, Edit and Remove.
- Edit changes an account. Leave Password empty to keep the saved one; the field always shows (unchanged) and never your password. Typing a new password checks it again when you click Save. Changing an account's server also removes any certificate you trusted for that server.
- Remove asks first. It deletes the account, its saved password and the mail this portal kept for it (the copy on the portal; nothing is deleted on your mail server). You can add it again at any time.
Test sign-in
Test sign-in connects to the account's incoming server and its outgoing server, checks each server's certificate, signs in and leaves: nothing is read, sent or changed. For each server it says one of:
| Result | What it means | What to do |
|---|---|---|
| Signed in | Signed in to imap.example.com, certificate verified. The password works. | Nothing |
| Refused | The server refused the user name or password. The password is saved, but it does not work as it is. | Follow the steps shown under it. For Gmail, Outlook.com, Yahoo and iCloud it explains the app password your provider needs and offers a button that opens the provider's own app-password page in a new tab; create one there, then Edit the account, paste it as the Password and Save |
| Password needed | No password is saved | Edit, type the password, Save |
| Certificate problem | The server's certificate could not be verified, so your password was not sent | See Trusting a server's certificate below |
| Not checked (no connection) | The server could not be reached (or did not answer in 20 seconds). The password is saved | Try again later; check the server name and port with Edit |
| Problem | Something else went wrong, said in the message | Check the server names and ports with Edit |
The table of what each provider needs (app passwords, and why a Microsoft 365 work or school mailbox accepts no password from mail programs) is in chapter 12, Two-step verification and app passwords. Sign in with Microsoft, Google or Yahoo is not available on the portal yet, so the portal always explains the app password. That means a Microsoft 365 work or school mailbox cannot be read on the portal yet: the password is kept but cannot be used.
Signatures
(19 Oct 2026) The Signatures section at the bottom of Settings > Email is the desktop's Signatures window on the portal (chapter 12, Signatures): your own signatures, as many as 20, and a default signature for each address you send from. When you write an email on the portal, the default of the From address is already in the message; the Signature pop-up beside From chooses another one or None (see chapter 12, Writing and sending on the local portal). Nobody else on the portal sees them, a portal administrator included.
- The line at the top says how many you have and for how many sending addresses a default is set, for example 2 signatures. Defaults are set for 1 of 2 sending addresses.
- Add a signature: type a name (or leave it empty for Signature, Signature 2 ...) and click the button. Its editor opens.
- Edit opens a signature's editor: its Name and its text, with Bold, Italic, Underline, Text Color, Insert link and Clear formatting. Two signatures cannot have the same name (the page says so). Text pasted from another program loses its colours, font and size. Pictures and files cannot go into a signature yet (the message would arrive with a broken picture); anything that could run in a browser is removed when you click Save.
- Delete asks first. Any address that had it as its default then has none.
- Use for All Addresses makes that signature the default for every address you send from (greyed while you send from only one address).
- Default signature has a pop-up for each address you send from (None or one of your signatures). When you send from two or more addresses, All addresses: is first: choose a signature (or None) there to make it the default of every address at once; it says Different for each address while they differ. Click Save the defaults.
Signatures are kept encrypted on the portal's server with your email accounts
(data/mail_accounts.enc), in the same form the desktop keeps them. They do not come from your
desktop and do not go to it (the desktop's signatures follow you between your computers through the
cloud; the portal is not one of them yet).
Email window (your Email preferences)
(19 Oct 2026) The Email window section of Settings > Email holds the desktop's Email preferences (chapter 12, Email preferences on the local portal), for you alone:
- Checking for new mail: Check for new mail: every minute, 2, 5 (the default), 10, 15 or 30 minutes, or Manual only. The sentence under it says what that means (with Manual only, mail is checked when you open the Email page and when you click Check for New Mail).
- Email window: Reading pane: Right (columns) (the default) or Below (rows); Conversations: On (messages grouped by thread, the default) or Off: one row per message; Mark as read: after 1, 2 (the default), 3, 5 or 10 seconds, or Only when I choose Mark as Read.
Click Save the preferences; the line at the top of the page says what was saved, and the Email
page uses them the next time it is opened. The Email page's Conversations button and its
right-click Mark as Read After Viewing change the same choices. Reading pane (Right or
Below) is chosen here only, as on the desktop (EM-9, 19 Oct 2026): the Email page's eye button
hides or shows the reading pane for the browser tab, it does not move it. They are kept encrypted with your email accounts (data/mail_accounts.enc), so they
stay when you remove an account (even your last one), and they apply in every browser you use the
portal from. They are the portal's own and do not change the desktop's.
The Email page also remembers where you were (the mailbox, the message, the scroll position, the accounts opened in the sidebar, the sidebar and the sizes of its parts), for you, in your mail cache on the portal (chapter 12, The portal remembers where you were); removing your last account forgets it with the cache.
Account problems. When an account cannot be checked (password refused or missing, an untrusted
certificate, a server that does not answer), the Email page's header shows ⚠ with the number of
accounts, and clicking it lists each problem with Open Email Settings, which opens that
account's page here (/local/email/<number>/edit/): type the password again, or use Test
sign-in and Trust this certificate. The portal's notification bell lists the same problems.
Filing email on clients
(19 Oct 2026) Save to Client…, Save to Sale… and Save to Ticket… on the Email page file an email on clients exactly as the desktop does (chapter 12, Filing an email on the local portal). Where it is written depends on this portal's Config database:
- With an office database (the CRM's SQL Server database saved on Config database), the portal writes the CRM database's own email record and activity note for each entry, owned by the person's CRM user ID, and one copy in the TechieCRM database. The portal knows a person's CRM user ID once they have signed in with SQL Server and their CRM user ID (or a TechieCRM ID linked to it); until then their filing is refused with Filing on the office database needs your CRM user ID. and nothing is written. The portal writes with the SQL login saved on Config database; the rows still name the person's own CRM user ID as owner and creator.
- Without one, the email is kept in the TechieCRM database only, linked to each entry, as the desktop does without a CRM database.
An email written with Write ▸ Email for a selected client is filed on that client when it is sent (with an office database). Filing never reads or changes anyone's mail accounts, and what is filed is visible to everyone in the office, as on the desktop.
Replies are filed when they are sent (EM-11, 20 Oct 2026). A reply, reply all or forward sent from the Email page (or from a message's own window) is filed where the answered email is filed and on the client the To address belongs to, as the desktop files it (chapter 12, Where your reply is saved): the same filing as Save to Client…, so the rules above apply unchanged (the person's CRM user ID owns the rows; a person with none linked gets the reply sent and the reason it was not saved; without an office database the TechieCRM database only). When no client has the To address, the person is asked to add it to a client or create one. Until they answer, the sent reply is kept in that person's own mail cache (encrypted, like the other messages there, for at most the cache's own limits), never in MongoDB; whatever they file then is linked to the same stored email.
A message in its own window (EM-11, 20 Oct 2026). Double-click on the Email page opens a
message in a browser window of its own (/email/mailbox/window/). Browsers block pop-up windows
unless the person allows them for the site: if people report Your browser blocked the message
window, allow pop-ups for the portal's address (for example http://127.0.0.1:8020) in each
browser's site settings. Nothing else is needed on the server.
The current client (EM-9, 19 Oct 2026). The Email page's header shows the name of the entry last selected in the portal's Clients page in that browser tab, and one click on it files the selected email there, with Undo (chapter 12, Filing an email on the local portal). It is the same filing as Save to Client…, so the rules above apply unchanged: the person's CRM user ID owns the rows on the office database, a person with none linked is refused, and without an office database the email is kept in the TechieCRM database only. Which entry is current is kept by the browser for that tab only (it is not stored on the portal), so each tab and each person has their own.
Filed emails on the portal's pages (EM-10, 19 Oct 2026). A filed email opened from a
client's, sale's or ticket's Interactions, the Email list or Documents is shown in the same reading
pane as the Email page, whichever form it was saved in, the source CRM's own stored emails
included (chapter 17, Filed emails on the web portals). Those are
converted each time they are opened, in memory only: nothing is written to the database, to MongoDB
or to data/, and the stored email is never changed. What the conversion could not carry over is
listed in small text under the message.
The Email count (EM-9, 19 Oct 2026). The Email icon in the left-hand menu carries each person's unread count, painted on the icon as on the desktop's icon bar. It is read from the person's mail cache on this server; drawing it never connects to a mail server. In the TechieCRM cloud (where Email is not a mail client) there is no count.
Creating tickets, sales and entries from an email
(EM-8, 19 Oct 2026) New Ticket… and New Sale… on the Email page, and Create client…, Create contact here, Link and Link to existing… in its File Email dialog (chapter 12, A new sale or ticket from an email on the local portal and Filing an email on the local portal), write the office database set up on Config database, with the same program code the desktop uses: the ticket, sale or client entry is the row the desktop would have written, owned by the person's CRM user ID, and Link writes the address into the entry's first empty e-mail slot.
- No office database: nothing is created (the desktop cannot create these without its CRM database either); Link still files on the entry but does not add the address.
- No CRM user ID linked: refused with Filing on the office database needs your CRM user ID., nothing written, as for filing.
- Rights: New Ticket… / New Sale… are hidden from someone whose security group denies Service / Sales; creating an entry or adding an address needs Clients access. A read-only workspace creates nothing.
Trusting a server's certificate
When Test sign-in meets a certificate it cannot verify (for example an office mail server with a self-signed certificate), it shows the server and port, who the certificate was issued to and issued by, the dates it is valid, the names it covers and its SHA-256 fingerprint. If you know the server and expect that certificate (ask your email provider and compare the fingerprint with theirs), click Trust this certificate. The portal tests the server again with it and shows the result. Trust is given to that one certificate, for that one account, and separately for its incoming and outgoing server; if the server later shows a different certificate, it is checked normally again. To stop trusting it, Edit the account and click Stop trusting under Trusted server certificates.
Removing another person's email
(19 Oct 2026) When someone leaves the office, their email accounts and the mail the portal kept for them stay on the portal's server until they are removed. A portal administrator can remove them; nobody can open them, an administrator included, and nothing is removed by itself when a portal user is deleted or disabled.
- Sign in as a portal administrator and click Email settings in the header.
- Below your own accounts, signatures and Email window sections, People's email accounts lists every other person who has email accounts or cached mail on the portal: their name and sign-in email, the addresses of their accounts, and the size of their cached mail. It never shows a password, a server, a sign-in name or any message. Someone whose portal user no longer exists is listed as Deleted user and a number; someone with cached mail but no account left shows None (cached mail only). Your own accounts are not in this list: remove them one at a time in your own list.
- Click Remove beside the person. The portal asks first and says exactly what goes: every account of that person with its saved password, and all the mail the portal kept for them. Their signatures and Email preferences on the portal go too (20 Oct 2026; they used to be kept). Nothing is deleted on their mail server. Click Yes, remove it (or Keep it to go back).
The removal is written to the workspace's activity log under your name before anything is removed (Users and security: User edit, naming the person and the account addresses). If the activity log cannot be written at that moment (for example MongoDB is not running), nothing is removed and the page says Nothing was removed; try again when MongoDB is back. Only portal administrators see the section; anyone else who opens a Remove link is refused.
What is stored where
| What | Where | How |
|---|---|---|
| Your accounts: addresses, servers, ports, other addresses, the last sign-in result, trusted certificates and passwords; your signatures and their defaults; your Email preferences (since 19 Oct 2026) | data/mail_accounts.enc in the install folder |
Encrypted (Fernet: AES with an integrity check). Nothing in the file is readable without its key |
| The key for it | data/mail_accounts.key |
Made the first time an account is saved; readable by the account that runs the portal only (on macOS and Linux). A key of its own: it is not the Config database key, and not derived from the .env secret key |
| The mail the portal has read for you (the newest 500 message headers of your Inbox, Sent, Drafts and the folder you are looking at, and the messages you have opened) | data/mail_cache/user-<number>.sqlite, one file per person |
Headers kept plain, message contents encrypted with a key made for each person. The folder is readable by the account that runs the portal only. At most 200 MB of messages per person; the oldest opened ones are dropped first. Since 19 Oct 2026 it also keeps the addresses you sent to from the portal (offered when you type an address; the 500 most recent), a note of each message sent, so the same message is never sent twice, and where you were on the Email page (the mailbox, the message, the scroll, the sidebar and its sizes). Since 20 Oct 2026 also a reply you sent to an address no client has, until you file it (encrypted like the messages; dropped with the oldest when the 200 MB limit is reached) |
Your password is never shown on any page after you save it, never written to a log, and never
stored in the portal's own database file (data/localportal.sqlite3), in MongoDB, or anywhere in
the TechieCRM cloud. The portal never puts your mail into MongoDB and never syncs it to the cloud
or to your other devices (the desktop app keeps Inbox and Sent of people with a TechieCRM ID in the
database on its own computer: see Sharing a computer with the TechieCRM desktop app). The key and the encrypted file sit side by side in data/, like .env and the
passwords in it: this keeps the passwords out of plain text, out of a backup of the file alone and
out of logs; it does not protect them from someone who can read every file in data/, so keep the
install folder's permissions as the installer set them.
If data/mail_accounts.key is lost (or replaced), the saved accounts cannot be read: Settings >
Email and the Email page say Your email accounts could not be read, and nothing can be added
until it is put back from a backup. Nothing overwrites the saved accounts meanwhile. The portal
does not need a restart for Settings > Email: accounts you add or change are used at once.
Saved logins on the local portal
Since October 2026 the local portal has the same Credential Storage Manager as the desktop app (chapter 31): Tools ▸ Security ▸ Credential Manager on the ribbon opens its pages. On techiecrm.com the button stays greyed: "Available in the desktop app and the local portal."
Who can use it is decided as on the desktop: a TechieCRM cloud subscription in force (a cloud licence key; a signed offline key is not a subscription), a sign-in with MongoDB chosen (a SQL Server sign-in counts as SQL records, so it is not eligible), a TechieCRM ID (a local account is not one), and the portal's MongoDB answering. Each missing one shows its sentence on the page. The saved logins are the same ones your desktop app keeps in the same MongoDB.
What you can do (the desktop's controls, as pages): the list with the types on the left and their counts (All, Shared with me, each type), search by title, site and user name; Add (pick the type, then its fields; Generate and Show for passwords; Business or Personal); Edit; Copy user name and Copy password; Open site; Versions and Roll back to this version; Share (who has it, Add people, Remove, Make owner, and the History for the owner); Delete; and New login type. Portal administrators also get an Administration tab: recovery requests (Approve or Refuse, nothing to type), the office recovery key, and the office's Business logins (titles, owners and people only; People and owner to move one).
Your password and your keys. The portal opens your saved logins with your TechieCRM password and keeps your keys only in the memory of the portal's running program, only while you are signed in. They are never written to disk, to the portal's database file, to MongoDB or to a log, and nobody's keys but those of the people signed in through the portal are ever there. So:
- Signing in with your TechieCRM ID opens your saved logins by itself once you have used the manager (the first time, the page asks).
- The page asks "Enter your TechieCRM password to open your saved logins." after the portal restarts, or when your page is answered by the portal's other worker (the portal runs two). Type the password you signed in with and choose Open. After five wrong tries it asks you to wait 15 minutes.
- Close closes them on the portal; signing out closes them too, and so does the end of your sign-in session.
- An administrator or anyone else with access to the computer cannot open your saved logins while you are signed out: the portal holds nothing that opens them.
Secrets never sit in a page. Copy user name, Copy password and Open site fetch the value when you click, and the browser is told not to keep it. The page clears your clipboard after 30 seconds when the browser allows it (it needs a secure connection, such as the portal opened on the same computer); over a plain connection from another computer the page says it cannot clear the clipboard, so copy something else when you are done. When you edit a login, its saved password is never shown: leave the box blank to keep it, type a new one to replace it, or tick Clear to remove it.
Known limits on the portal (October 2026):
- If your desktop app keeps your saved logins under its mail account key (mail account sync switched on), the portal says it cannot open that key yet; use the desktop app.
- Sharing with someone whose sharing key is not in this MongoDB shows them as waiting; the share is finished by the desktop app of someone who has the login.
- A recovery request filed from the portal names no computer; the Administration tab shows "(not named)".
- Every saved-login event the portal records says Local portal (computer name) in the login's history.
Starting the portal
From the install folder:
| Command | Web server | |
|---|---|---|
| Windows | powershell -ExecutionPolicy Bypass -File bin\run.ps1 |
waitress |
| macOS, Linux | bin/run.sh |
gunicorn, two workers |
Then open http://localhost:8000/ in a browser on the same computer.
Before the web server starts, both commands prepare your CRM's SQL Server database
(manage.py ensure_office_schema, see Preparing your CRM's SQL Server database).
With the SQL Server down this adds a second or two to the start; it never stops the portal starting.
- The port is
8000unless thePORTenvironment variable, or aPORT=line in.env, says otherwise. Use another port when 8000 is taken (see The settings file). - The portal listens on this computer only (address 127.0.0.1). No firewall change is needed, and other computers cannot reach it.
- To stop it, press Ctrl+C in its window, or stop its service.
- Is it up?
http://localhost:8000/health/answers{"ok": true, "licensed": true, …}. This address works without signing in and without a licence.
On macOS and Linux the web server writes data/access.log and data/error.log. On Windows its
messages appear in the PowerShell window.
Starting the portal automatically
The portal itself is one long-running program. The cloud sync is a separate, short command run
on a schedule (see Syncing with the TechieCRM cloud). Set up
both, as the account that activated the licence. Replace /opt/techiecrm-localportal or
C:\techiecrm-localportal below with your install folder.
Windows: Task Scheduler
- Open Task Scheduler ▸ Create Task….
- General: name it TechieCRM Local Portal; choose Run whether user is logged on or not.
- Triggers: At log on (or At startup).
- Actions: Start a program, program
powershell, arguments-ExecutionPolicy Bypass -File C:\techiecrm-localportal\bin\run.ps1. - Settings: tick If the task fails, restart every and choose an interval.
For the sync, create a second task, TechieCRM Local Portal Sync: trigger Daily, with
Repeat task every 15 minutes for Indefinitely; action
C:\techiecrm-localportal\venv\Scripts\python.exe, arguments manage.py sync_cloud, Start in
C:\techiecrm-localportal.
With the TechieCRM desktop app on the same computer, do not create the sync task by hand. The sharing step creates it (see Sharing a computer with the TechieCRM desktop app). The portal task above is still yours to create.
macOS: launchd
Save this as ~/Library/LaunchAgents/com.techiecrm.localportal.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"><dict>
<key>Label</key><string>com.techiecrm.localportal</string>
<key>ProgramArguments</key><array><string>/opt/techiecrm-localportal/bin/run.sh</string></array>
<key>WorkingDirectory</key><string>/opt/techiecrm-localportal</string>
<key>RunAtLoad</key><true/>
<key>KeepAlive</key><true/>
<key>StandardOutPath</key><string>/opt/techiecrm-localportal/data/service.log</string>
<key>StandardErrorPath</key><string>/opt/techiecrm-localportal/data/service.log</string>
</dict></plist>
Then run launchctl load ~/Library/LaunchAgents/com.techiecrm.localportal.plist. It starts when
you sign in to the Mac and restarts if it stops.
For the sync, save a second file, com.techiecrm.localportal.sync.plist, the same way, with the
label com.techiecrm.localportal.sync, ProgramArguments of
/opt/techiecrm-localportal/venv/bin/python, manage.py and sync_cloud, and
<key>StartInterval</key><integer>900</integer> in place of KeepAlive (900 seconds is 15
minutes).
Linux: systemd
Save this as ~/.config/systemd/user/techiecrm-localportal.service:
[Unit]
Description=TechieCRM Local Portal
After=network.target mongod.service
[Service]
WorkingDirectory=/opt/techiecrm-localportal
ExecStart=/opt/techiecrm-localportal/bin/run.sh
Restart=on-failure
[Install]
WantedBy=default.target
Then run systemctl --user enable --now techiecrm-localportal.
For the sync, save techiecrm-localportal-sync.service:
[Unit]
Description=TechieCRM Local Portal sync
[Service]
Type=oneshot
WorkingDirectory=/opt/techiecrm-localportal
ExecStart=/opt/techiecrm-localportal/venv/bin/python manage.py sync_cloud
and techiecrm-localportal-sync.timer:
[Unit]
Description=TechieCRM Local Portal sync every 15 minutes
[Timer]
OnBootSec=5min
OnUnitActiveSec=15min
[Install]
WantedBy=timers.target
Then run systemctl --user enable --now techiecrm-localportal-sync.timer.
A user service runs while that account is signed in. To keep it running after the account signs
out, an administrator runs sudo loginctl enable-linger <account> once.
Preparing your CRM's SQL Server database
TechieCRM keeps some of its own information (projects, inventory, work orders, the sign-in list,
the activity log and more) in its own TCRM_ tables inside your CRM's SQL Server database. You do not
create them by hand. Every time the portal starts it runs manage.py ensure_office_schema, which
does exactly what the TechieCRM desktop app does when someone signs in:
- creates the TechieCRM tables that are missing;
- adds columns and indexes that a newer TechieCRM version adds to TechieCRM tables that already exist;
- gives the web users' role (CRMGroup), when the database has one, permission to read, add and change rows in TechieCRM's tables. A table where someone has deliberately denied the role a permission is left alone.
It never creates, changes or writes the source CRM's own tables. So you can connect the portal or the desktop app to a new database first: whichever starts first prepares it, and the other finds it ready.
It also runs straight away when you click Save and prepare or Prepare again on the Config database page, which then shows each step and the result (see Connecting the databases from the portal).
When the login is not allowed to create tables, nothing is changed and the portal starts anyway.
The Web server page, under Config database setup, shows Needs a login with more rights,
names the features whose tables are missing, and says what to do: on the Config database page,
enter the MASTER login, or a login with db_owner on your CRM's SQL Server database, and click Save and
prepare (or, when the connection is in .env, put that login in MAX_SQL_USER and
MAX_SQL_PASSWORD there and restart the portal). You can change the login back afterwards.
| What Config database setup shows | What it means | What to do |
|---|---|---|
| Ready | Every TechieCRM table, column and permission is in place (or was just set up) | Nothing |
| Not configured | No SQL Server database is chosen, on the Config database page or in .env |
Connect one on the Config database page if you want one |
| Not checked | Your CRM's SQL Server database could not be reached, or refused the sign-in | Check the SQL Server line above it, then the connection (Test connection on the Config database page) |
| Needs a login with more rights | Tables or columns are missing and the login may not create them | Use the MASTER login, or one with db_owner, and Save and prepare (or .env and restart) |
| Setup incomplete | Some features' tables could not be set up; the reason is shown | Usually the same as above |
| Setup code missing | This portal's copy of TechieCRM is out of date | Run bin/pull_sources.sh, or install the latest portal |
| Not checked yet | The portal has not started since it was installed | Start the portal |
| Removed from this database | TechieCRM was removed from your CRM's SQL Server database on purpose, so the portal did not create its tables again | Nothing, or put it back with manage.py restore_techiecrm (see below) |
To run it by hand: venv/bin/python manage.py ensure_office_schema (Windows:
venv\Scripts\python manage.py ensure_office_schema); add --json for a machine-readable answer.
It always exits with 0.
Removing TechieCRM from your CRM's SQL Server database, and putting it back
If the office stops using TechieCRM on its CRM database, or has to hand the database back
without TechieCRM's tables, the portal can take them out. It uses the very same removal as the
desktop app's Tools ▸ Database ▸ Repair Database ▸ Remove TechieCRM from this database
(A12), with the same safeguards in the same order, on the office
database the portal is connected to (saved on the Config database page, or MAX_SQL_* in
.env).
Who may run it. The SQL login the portal uses must be the MASTER login, or a login
that is db_owner of your CRM's SQL Server database. Any other login is refused and nothing changes.
Save the MASTER login (or a db_owner login) on the Config database page (or put it in
MAX_SQL_USER and MAX_SQL_PASSWORD in .env), run the command, and change the login back
afterwards.
What is removed. Every table whose name starts with TCRM_ (including ones added by hand,
such as TCRM_Sync_Control or TCRM_Payable), every view, procedure, function and trigger
whose name starts with TCRM_ or usp_TCRM_, and the links between those tables. The source
CRM's own tables are never touched.
Run these in the install folder (on Windows use venv\Scripts\python instead of
venv/bin/python).
1. Dry run (the default). Lists every object it would remove with its type and the rows in each table, the server folder the backup will go to, and anything that stops the removal. It changes nothing.
venv/bin/python manage.py remove_techiecrm
venv/bin/python manage.py remove_techiecrm --dry-run # the same
2. The removal. Type the database's exact name (as the dry run shows it; capitals count) and name an existing folder on this computer for the copy:
venv/bin/python manage.py remove_techiecrm --confirm-database OfficeCRM --export-dir /Users/me/TechieCRM-copy
venv\Scripts\python manage.py remove_techiecrm --confirm-database OfficeCRM --export-dir D:\TechieCRM-copy
Before anything is removed it runs the dry run again and checks the login, then:
- saves a copy in a new folder
TechieCRM_removal_<database>_<date>_<time>inside the folder you named: one CSV file per table,manifest.json, the setup scripts andcleanup_log.txt; - takes a full backup of the database in the SQL Server's own default backup folder (copy-only, with checksum, so the office's backup routine is not disturbed) and checks it can be read.
If the copy or the backup fails, nothing is removed. Then the objects are removed one at a time; anything that cannot be removed is listed and the run says it was only partly done. The command prints each step, the result, and where the copy, the backup and the log are.
After the removal the database carries a note that TechieCRM was removed on purpose. While it is there, neither the portal (when it starts) nor the desktop app (when someone signs in) creates TechieCRM's tables again. The Web server page shows Config database setup: Removed from this database, "TechieCRM's tables were removed from this database on purpose", and how to put them back.
3. Putting it back. Deletes the note and runs the normal setup, so TechieCRM's tables come back empty (the old rows are in the copy and in the backup):
venv/bin/python manage.py restore_techiecrm --confirm-database OfficeCRM
The desktop app's Restore TechieCRM to this database does the same.
Exit codes (for scripts):
| Code | remove_techiecrm | restore_techiecrm |
|---|---|---|
| 0 | Dry run finished, or everything was removed | Restored and set up |
| 2 | Refused, nothing changed: wrong database name, login not MASTER or db_owner, no folder for the copy, the dry run lists a blocker, the database changed since the dry run, or MAX_SQL_* not set |
Refused, nothing changed: wrong name, or login not MASTER or db_owner |
| 3 | Partly done, or stopped (the copy or the backup failed, so nothing was removed), or the database could not be reached | The note could not be deleted, the setup was refused or failed, or the database could not be reached |
If either command says this portal's copy of the removal tool is missing, run
bin/pull_sources.sh (or install the latest portal) and try again.
The first data load from your SQL Server
The first data load reads your source CRM's SQL Server and builds the TechieCRM copy of your CRM in MongoDB. It is the same engine the desktop app uses.
Before you start
- The computer is activated.
- MongoDB answers, and ODBC Driver 18 is installed.
- Your CRM's SQL Server database is connected: saved on the Config database page (see
Connecting the databases from the portal),
or
MAX_SQL_SERVER,MAX_SQL_DB,MAX_SQL_USERandMAX_SQL_PASSWORDset in.env(see The settings file). The load never falls back to any other server: with no SQL Server database set it refuses to start. - The Web server page shows the row Create / refresh the local CRM database as Ready.
The command. Its exact name is shown in that row of the Web server page, and in the
installer's closing list of next steps. Run it from the install folder with
venv/bin/python manage.py (Windows: venv\Scripts\python manage.py) in front of it.
- Try it first without writing anything. Add
--dry-run. The load reads and checks your data and reports what it would write, but writes nothing to MongoDB. Add--limit 100to read at most 100 rows of each kind for a quick test. - Run it for real: the same command without
--dry-run. A large database takes a while; leave the window open until it finishes. - Open
http://localhost:8000/and check your clients are there.
Useful options (add them after the command):
| Option | What it does |
|---|---|
--dry-run |
Read and check, write nothing |
--list |
List the kinds of data it can load, then stop |
--entities clients,contacts |
Load only the kinds named (separated by commas). Default: all |
--limit N |
At most N rows of each kind |
--sync |
Load only what changed since the last load |
--since 2026-08-01 |
With the first --sync: start from this date |
--reconcile |
A full check: load everything again and remove copies of records that are gone from your SQL Server. Run it now and then |
--drop-first |
Empty each kind's collection before loading it (not with --dry-run) |
--batch-size N |
Rows written at a time (default 500) |
--verbose |
More detail while it runs |
--no-service-check |
Skip the check that MongoDB and your SQL Server answer before it starts |
When it refuses
| Message | What to do |
|---|---|
This install is not licensed. Run manage.py activate_license. |
Activate the licence |
| MAX_SQL_SERVER is not set … | Connect your CRM's SQL Server database on the Config database page (or set your server, database, user and password in .env) |
| not migrating: Unavailable without a MongoDB database. … | Start MongoDB, or connect to one (Running without MongoDB) |
| not migrating: The … SQL Server cannot be used. … | Follow the reason: check the server name, the network, and that ODBC Driver 18 is installed |
| migration engine exited N | The load stopped part-way; the lines above say why. Fix the cause and run it again |
Syncing with the TechieCRM cloud
The sync sends the changes made in the portal to the TechieCRM cloud and brings back the changes made elsewhere (the desktop app, the phones, the cloud portal) on the same licence. It is the desktop app's own sync, so the two work the same way.
Run one sync now, from the install folder:
venv/bin/python manage.py sync_cloud
It prints sync ok: with a summary, or sync failed: with the reason.
Keep it running on a schedule. Every 15 minutes is what the desktop app uses. Either schedule
the command (see Starting the portal automatically), or
leave it running in a window of its own with --loop:
| Option | What it does |
|---|---|
--loop |
Keep running, syncing again after each interval |
--interval N |
Seconds between syncs with --loop. Default 900 (15 minutes); never less than 60 |
--skip-publishers |
Do not refresh the list of users, user-defined fields and key fields from your SQL Server first |
Before each sync it refreshes the list of users, key fields and user-defined fields from your SQL
Server (the one set on the Config database page or in .env), exactly as the desktop app does,
and prints one line for each:
| Line | Meaning |
|---|---|
| publish_users: N written, N unchanged | The CRM users were mirrored for the web and the phones (names on owners, assigned-to and created-by) |
| publish_key_field_setups: N written, N unchanged | The "Key Fields For:" lists were mirrored |
| publish_udf_definitions: N written, N unchanged | The user-defined field definitions (type, order, allowed values) were mirrored |
| … skipped: no office SQL Server is configured … | No SQL Server is set. The sync itself still runs |
| … skipped: office SQL read failed: … | The SQL Server could not be read; the reason follows. Nothing was changed |
| … then failed: … | It stopped part-way; the counts are what was done before the problem |
| … skipped: the vendored engine predates the office SQL seam … | The portal's copy of the desktop code is older than this release. Run bin/pull_sources.sh |
These steps run only when this portal syncs with the cloud (on a computer shared with the desktop app, the program that holds the sync does them).
The office writes run on every sync, cloud or not (October 2026). Web and phone changes that are
waiting for the office (next section) are already in this portal's MongoDB, so the portal writes
them after the cloud part of each sync even when the cloud sync fails, when this portal has no
cloud to sync with, or when the desktop app holds the sync on a shared computer. The office-write
lease and the one-request-at-a-time rule below still decide which program writes each one. When the
cloud part did not happen, the line cloud sync skipped: not syncing: … (or sync failed: …) says
why, the office writes still run, and a single sync_cloud run then ends with that reason as an
error so a scheduled task shows it failed. With --loop it simply tries again next time.
The portal as the office computer: web and phone changes to sales (24 Oct 2026)
A change made on the web portal, on this portal or on a phone to a sale that came from your office
database (its competitors and partners, or closing it Won or Lost with a reason) is not written
into your SQL Server by the cloud. It waits for the office computer, which reads the request,
checks it against the office, writes it and reports back; until then the sale shows Waiting for
the office (chapter 13). Until now only the TechieCRM desktop app could
be that computer. Now a local portal does the same whenever your SQL Server is set for it (on the
Config database page or in .env):
- A change made in the desktop app is written by the desktop app straight away, as before.
- A change made in the portal, on the web or on a phone waits as a request and is written by
whichever office program picks it up first, the portal on its next sync or the desktop app on
its next one. There is no setting that decides it, and on a computer shared with the desktop
app you no longer claim anything extra for it (the old step of also claiming the office
database scope is not needed).
manage.py sync_owner --claimstill decides which program syncs with the cloud; when the desktop app holds that, the portal does not sync with the cloud, but it still writes the requests it picks up while it holds the lease below (so an always-on portal on the office server writes them when the desktop app is closed). When the portal holds it, the desktop app can still write the requests (from the shared database the portal's sync fills) whenever it holds the lease below; the results go up with whichever program syncs next. - A change is never written twice. The programs take turns through a 20-minute office-write lease on the TechieCRM database, as two desktop apps do, and each request is taken by one program at a time; the one that does not hold the lease prints deferred: and the computer's name. This lease is used for office changes only: holding it never stops the desktop app refreshing the shared database from your office database, running its monitors or sending their emails.
Each sync prints what happened:
| Line | Meaning |
|---|---|
| office side: held by this portal | This portal writes office changes this time |
| office side: skipped: no office SQL Server is configured … | No SQL Server set; nothing is written and the lease is not taken |
| office side: skipped: deferred: PC2 | Another program holds the office-write lease (another computer, or the desktop app on this one); it writes the changes |
| office side: skipped: the vendored engine predates the office-write lease … | The portal's copy of the desktop code is older than this release. Run bin/pull_sources.sh; until then the desktop app on this TechieCRM database writes the changes |
| publish_sale_reasons: N written, N unchanged, N retired | The office's completion-reason list (Won, Lost, Abandoned, Suspended reasons) was mirrored for the web and the phones. skipped: names the reason |
| publish_sla_trackers: N written, N unchanged, N retired | The office's SLA clocks (the Compliance & SLA trackers) were mirrored for the web SLA board and the monitoring rules, their times converted to UTC from the portal's time zone (TIME_ZONE, the same zone as the desktop app's). retired counts clocks no longer in the office, kept as no longer in use. skipped: the vendored engine predates the SLA tracker publisher … means run bin/pull_sources.sh; until then the desktop app on this TechieCRM database sends them |
| office writes: ran: 2 done, 1 conflict, 0 failed, 0 released | Requests written, refused because the office changed meanwhile (the person sees the office's value), failed (with the real reason on the request) or put back for the next sync because the office could not be read |
| office writes: ran: nothing waiting | No requests this time |
The rules are the desktop app's: a request is written with the requesting person's linked CRM
user ID (it must hold the Opportunities modify right in your CRM, or the request fails with
Your office CRM login is not allowed to change sales.), the office wins every conflict, and the
sale is re-read into the TechieCRM database right after, so the web and the phones show what the
office holds. --skip-publishers skips the reason list and the SLA clocks; it never skips the writing of requests.
To-dos, meetings and tickets from phones wait for a desktop (October 2026). A to-do, meeting or ticket added or changed on a phone goes through the same queue (chapter 13), but the portal does not write those: the desktop's To-Do, Meeting and Ticket writers run only on a desktop app signed in to the office database. The portal applies the sale requests as before, leaves the record requests waiting for a desktop on the same TechieCRM database, and prints why on the office writes line (records: ...). An office with a local portal and no desktop therefore sees phone to-dos, meetings and tickets on the web and the phones, marked Waiting for the office, until a desktop app checks in.
When it refuses
| Message | What to do |
|---|---|
| This install is not licensed … | Activate the licence. Nothing runs, the office writes included (an ended licence, or an overdue check-in, leaves the portal read-only) |
| not syncing: unavailable without a MongoDB database. … | Start MongoDB, or connect to one. Nothing runs |
When the cloud part is skipped (the office writes still run, then the run ends with the reason):
| Message | What to do |
|---|---|
| cloud sync skipped: not syncing: licensed, but no licence key is available to sync with | Activate again with your key |
| cloud sync skipped: not syncing: the cloud sync client could not start (…) | Follow the reason; check the account can write the portal's data folder |
| cloud sync skipped: not syncing: no sync owner is recorded for this computer … / … is held by 'desktop', not by this portal … | The portal shares the desktop app's database and does not hold the sync. Nothing to do if the desktop app should sync; otherwise run the sharing step (next sections) |
| cloud sync skipped: not syncing: this portal holds the sync but cannot refresh its lease … | The account running the sync cannot write sync-owner.json. Run the sharing step again as an administrator |
| sync failed: … | The cloud could not be reached or refused; the reason follows. The next sync tries again |
The Web server page
Click Web server in the header, or open http://localhost:8000/local/. It was called This
computer before 19 October 2026. It is an administrator's view of the portal's own server: the
web server program, the databases it reaches, its licence, its local database and sync, and what
can be run there. Portal administrators only: anyone else signed in sees Only a portal
administrator can see the web server page., and someone not signed in is sent to the sign-in
page. It works without MongoDB, so it is the place to start when something is missing, and it
always has the portal's own header (it never opens inside the CRM's ribbon). Nothing on it changes
anything except Unlock under Locked sign-ins, and it shows no secret (no SECRET_KEY, no
password, no MongoDB address with a password).
- Web server: the running web server, read from the server itself:
| Line | What it says |
|---|---|
| Server program | gunicorn (started by bin/run.sh on macOS and Linux), waitress (bin/run.ps1 on Windows) or Django runserver (development server), with its own version when it reports one, and how many worker processes or threads answer requests |
| Listens on | The address and port, for example 127.0.0.1:8000. With 127.0.0.1 only this computer can reach it directly; the line names this computer's network name and address, which other computers use through a web server in front of the portal (see Opening the portal from other computers). A server listening on the network lists the addresses to type on another computer instead |
| Started | When this server process started, in the portal's time zone, and how long it has been running, with its process number |
| Versions | The TechieCRM portal, Django and Python versions, and which Python program runs it |
| Debug mode | Off, as it should be. On is shown as a warning: error pages then show internal details to anyone who can open the portal. Set DEBUG=False in .env and restart |
| Time zone | The portal's time zone |
| Data folder | The portal's data folder (see Where everything is kept) |
| Logs | With gunicorn, data/access.log and data/error.log (not written yet until the first line). With waitress or runserver the log is printed in the window or service that runs the server |
| Portal's own records | The database that holds sign-ins, accounts and sessions: SQLite, data/localportal.sqlite3. Your CRM's records are in MongoDB |
- Services: MongoDB and SQL Server, each with a badge and the reason in words. MongoDB can be Available, Not installed, Not found, Not answering, Sign-in refused or Address not valid. SQL Server can be Available, Not configured, No ODBC driver, Not answering, Address not valid or Not checked. The SQL Server check never signs in; it checks that the driver is installed and the server answers on the network. It also lists SQL Server instances it finds on this computer. Check again checks at once; otherwise answers are reused for up to 30 seconds (10 while something is missing).
- Config database setup (in the Services box): whether your CRM's SQL Server database has every TechieCRM table, from the check made when the portal last started, with what to do when it does not (see Preparing your CRM's SQL Server database). This line never contacts the SQL Server itself. Under it, Config database: connect and prepare opens the Config database page.
- Locked sign-ins: every sign-in the portal has locked after wrong passwords, with Unlock on each and Unlock all (see Unlocking a sign-in), or No sign-in is locked.
- Licence: licensed or not, tier, days remaining, activation mode, and Manage licence.
- Local database & sync: which MongoDB database and server the portal uses (with shared with the TechieCRM desktop app when it is), who holds the sync, and the sync progress (or No sync has run yet on this computer.).
- What you can do on this computer: every action, with Ready or Unavailable: and the reason:
| Action | Needs |
|---|---|
| Open the CRM (Clients, Sales, Service …), with the Open button | MongoDB and a licence |
Sync with the TechieCRM cloud (manage.py sync_cloud) |
MongoDB, a licence, and the sync (when the database is shared with the desktop app) |
Take over this computer's cloud sync from the desktop app (manage.py sync_owner --claim) |
MongoDB, and the desktop app's database on this computer |
| Create / refresh the local CRM database from your CRM's SQL Server database (the first data load) | MongoDB, the SQL Server, MAX_SQL_USER and MAX_SQL_PASSWORD, and a licence |
Use a MongoDB server on another computer (manage.py mongo_server --set …) |
nothing: always available |
From a terminal, manage.py check_services gives the same service check (add --json for a
machine-readable answer). It exits with 0 when both services can be used, 1 when MongoDB
cannot, and 2 when MongoDB can but the SQL Server cannot.
Unlocking a sign-in
After 5 wrong passwords in 15 minutes the sign-in page locks that account (an email, or a CRM user ID), and after 20 from one address it locks every sign-in from that address. The person then sees This account is locked for a technical review after repeated failed sign-in attempts … (or Sign-in from your network is temporarily blocked …). The lock does not run out by itself.
On the Web server page (portal administrators), the Locked sign-ins box lists each lock:
| Column | What it shows |
|---|---|
| Who | Email, CRM user ID or Network address, then the account (with the person's name when the portal knows it), or Every sign-in from the address |
| Locked since | When it locked, in the portal's time zone |
| Failed attempts | The wrong passwords that locked it, and how many sign-ins it has refused since |
| From address | The address the last wrong password came from |
Unlock releases one lock, Unlock all every one. The page then says The sign-in was unlocked. The wrong passwords that caused the lock stop counting, so the person starts again with 5 tries (they are kept in the portal's records). Unlocking an address also gives every account that failed from it a fresh count. Everyone reaching the portal through a web server on the same computer counts as one address, so an address lock there stops all sign-ins: unlock it the same way.
When no administrator can sign in (for example the only administrator is locked), open a terminal in the portal's install folder, as the account that runs the portal:
venv/bin/python manage.py unlock_signin --list
venv/bin/python manage.py unlock_signin --user admin@yourcompany.com
venv/bin/python manage.py unlock_signin --user DENIS
venv/bin/python manage.py unlock_signin --all
On Windows use venv\Scripts\python instead of venv/bin/python. --list (also what it does with
no option) shows each lock as the page does; --user releases one account, by its email or its CRM
user ID in any case; --all releases every account and address lock. It prints what it released.
It exits with 0 when it listed, or released at least one lock; 1 when there was nothing to
release (that account is not locked, or nothing is); 2 when the options were wrong (more than
one of --list, --user, --all, or a blank --user).
Every unlock, from the page or the command, is written to the portal's log with what was unlocked and who did it (the administrator's email, or manage.py unlock_signin and the computer account).
Sharing a computer with the TechieCRM desktop app
On Windows, the portal and the desktop app can run on one computer when the desktop app was installed for all users (a "just for me" desktop install has no database to share). Then there is:
- one database: the portal finds the desktop's database through
C:\ProgramData\TechieCRM\techiecrm-local-db.jsonand signs in with the desktop's own protected account. LeaveMONGO_URLblank in.env; a value there makes the two programs use different databases; - one licence: when the portal runs as the Windows account that uses the desktop, both read the same licence file. Activate once;
- one sync: exactly one of the two talks to the TechieCRM cloud. The portal takes over the sync; the desktop leaves it to the portal and keeps refreshing the shared database from your source CRM while it is open.
The sharing step does three things: it adds the account to the TechieCRM Users group (so it
can read the desktop's database password), creates the scheduled task TechieCRM Local Portal
Sync (every 15 minutes, as that account, whether or not anyone is signed in, without storing a
password), and records the portal as the sync owner in C:\ProgramData\TechieCRM\sync-owner.json.
The installer runs it for you when PowerShell runs as administrator. Otherwise run it once, in
PowerShell as administrator:
powershell -NoProfile -ExecutionPolicy Bypass -File C:\techiecrm-localportal\installer\coexist.ps1
| Option | What it does |
|---|---|
-Account DOMAIN\name |
The account that runs the sync. Default: the person signed in at this desktop, not the administrator who approved the prompt |
-IntervalMinutes N |
Minutes between syncs (default 15) |
-NoTask |
Do not create the scheduled task |
-Remove |
Undo: remove the task and give the sync back to the desktop app. The group membership is kept |
-AllowUnsupportedOS |
Evaluation only, as for the installer |
A group membership added now takes effect at that account's next sign-in.
| Exit code | Meaning |
|---|---|
| 0 | Done, or nothing to do (the desktop's database is not on this computer, or the desktop was installed without its database engine) |
| 1 | A step failed; the message says which |
| 3 | The claim was written, but the portal still may not sync; the status lines above say why |
| 5 | Not run as an administrator |
| 6 | This Windows is not supported; nothing was changed |
Checking who syncs: venv\Scripts\python manage.py sync_owner shows the desktop's database, the
account's access to its password, and the sync owner with its last run. --claim hands the sync to
the portal; --release gives it back to the desktop app. It exits with 0 when the portal may
sync (or there is no desktop database), 1 when the record cannot be read or written, and 3
when the desktop's database is here and the portal does not hold the sync. The desktop app shows
the same under Settings ▸ Local Database ▸ Sync (chapter
A1).
If the portal stops syncing, the desktop notices within the hour and syncs again itself.
The desktop app's Inbox and Sent in the shared database (20 Oct 2026). For a person who signs
in to the desktop app with a TechieCRM ID, the desktop keeps their Inbox and Sent in this database
(record types named mailbox_..., one set per TechieCRM ID), with the message text encrypted by a
key in that person's folder under C:\ProgramData\TechieCRM\users\ (macOS: ~/Library/Application
Support/TechieCRM/users/); subjects and senders are readable to anyone with access to the database.
Mail saved on a record leaves that copy (the record's document is the one copy). People who sign in
with a CRM user ID only keep their mail on the desktop's computer as before. The portal does not
read this copy yet (it keeps its own, see What is stored where); the two will share it in a later
update. It is never uploaded to the cloud or put in a cloud backup.
On macOS and Linux the desktop app runs its database only while the desktop app is open, so the portal cannot rely on it. Give the portal a MongoDB of its own, or a MongoDB server on another computer.
Signing in from more than one place
TechieCRM can limit each ID to one place at a time (chapter 30). A desktop sign-in and a browser sign-in are always two places, even on the same computer.
On the local portal this check is off until you switch it on. Set SINGLE_SESSION_MODE in
.env to observe (record sign-ins, never interrupt anyone) or enforce (apply the rule), then
restart the portal.
The portal shares one list of who is signed in where with the desktops of the same workspace, and works out which list that is:
| Your setup | Where sign-ins are recorded | Does the portal check them? |
|---|---|---|
No cloud subscription; MAX_SQL_SERVER is set |
Your office's SQL Server database | Yes, when switched on |
No cloud subscription, no MAX_SQL_SERVER |
The TechieCRM database on this computer | Yes, when switched on |
| The licence has a cloud subscription | The TechieCRM cloud | Not yet: nobody is refused or signed out here |
To choose the list yourself, set LOCALPORTAL_SESSION_REGISTRY to office_sql, local_mongo or
cloud. For the office SQL Server list, the SQL Server login needs the right to create and write
tables in that database.
A portal user and a desktop user count as the same person when the portal user is linked to the person's source-CRM login (office SQL Server list), or when their email addresses match (list on this computer).
Signing in with a CRM user ID counts as that CRM user, as on the desktop. With the office SQL
Server list, a portal account linked to a CRM user ID on this portal (because the person signed in
with SQL Server and their CRM user ID, or with their TechieCRM ID and the CRM user ID it asked
for) is recorded under the same name the desktop app uses for that CRM user in that database. So
signing in to the portal as DENIS while DENIS is signed in on a desktop is one person in two
places, and the usual question appears. The link belongs to the account, so the same account
counts as that CRM user whichever way it signs in. A TechieCRM ID with no linked CRM user ID is
recorded by its email, as before. If the linked CRM logins file cannot be read while the check is
on (for example data/portal_connections.key is missing), signing in answers Sign-in is
temporarily unavailable, as for any list that cannot be reached. If the list cannot be reached while the check is on, signing in answers Sign-in is
temporarily unavailable rather than letting anyone in unchecked.
Running without MongoDB or without SQL Server
Without MongoDB the portal still starts. Signing in and out, the activation page, This
computer and /health/ work. Every page that needs CRM data answers at once with
Unavailable without a MongoDB database, the reason, and a link to the Web server page. The sync
and the first data load refuse with the reason.
To use a MongoDB server on another computer, from the install folder:
venv/bin/python manage.py mongo_server --set db1.example.lan:27017 --user techiecrm
It asks for the password, tests the server first (nothing is saved if it does not answer or
refuses the sign-in), then saves it as MONGO_URL in .env. The password is never shown. Restart
the portal afterwards.
| Command | What it does |
|---|---|
mongo_server |
Which MongoDB the portal uses, and whether it answers |
mongo_server --test |
Test it; exit 0 when it answers, 1 when not |
mongo_server --set ADDRESS --user NAME |
Test and save a server. The address can be host, host:port or a full mongodb:// or mongodb+srv:// address |
mongo_server --clear |
Go back to the desktop's database, or to this computer's MongoDB |
Options for --set: --tls (connect with TLS), --auth-source NAME (default admin),
--db NAME (also sets MONGO_DB), --no-test (save a server that is not running yet),
--password-stdin (read the password from the input, for scripts) and --timeout N (seconds,
default 5). On a computer that shares the desktop's database, the command warns you first: a saved
server wins over the desktop's database.
Without SQL Server everything works except the first data load. The sync still runs; it just cannot refresh the list of users and fields from your SQL Server.
Opening the portal from other computers
The installer sets the portal up for the computer it runs on only. It listens on 127.0.0.1,
so other computers cannot reach it, which is also why it can use plain http://.
Reaching it from other computers is a deliberate network change that the installer does not do in
this release. It needs, at least: a web server in front of the portal on the same computer (such as
IIS or nginx) that offers HTTPS to your network and passes requests to the portal's port;
ALLOWED_HOSTS and CSRF_TRUSTED_ORIGINS in .env naming the address people will use (for
example crm.example.lan and https://crm.example.lan); and TECHIECRM_TRUSTED_PROXY_COUNT=1
when that web server adds the caller's address to X-Forwarded-For. Plan it with whoever looks
after your network.
Updating
- Stop the portal, and pause its scheduled sync.
- Back up (next section).
- Replace the portal's files with the new version, keeping your
.envand yourdatafolder. - Run the installer again (
installer\install.ps1orinstaller/install.sh). It installs the new requirements and brings the portal's database file up to date. It keeps your.envand your data. - Start the portal and check the version in the page footer.
If you skip step 4, the portal may refuse to start with a message naming a package and the
command installer/install_requirements.py; run the installer again.
Backing up
Stop the portal before you copy its database file. Keep:
| What | Where | Why |
|---|---|---|
.env |
install folder | Your settings, passwords and secret key |
data/localportal.sqlite3 |
install folder | Portal sign-ins, roles and portal settings |
data/sync_state.json |
install folder | Where the sync got to |
data/portal_connections.json and data/portal_connections.key |
install folder | The SQL Server and MongoDB connections saved on the Config database page, and the key that unlocks it. Keep the two together |
data/mail_accounts.enc and data/mail_accounts.key |
install folder | Everyone's email accounts and passwords from Settings > Email, and the key that unlocks them. Keep the two together, and keep the backup as private as .env. (data/mail_cache need not be backed up: the portal reads the mail again) |
data/media |
install folder | Files uploaded through the portal |
| Your CRM data | MongoDB | With MongoDB's own mongodump tool. On a computer shared with the desktop app, use the desktop's backups (chapter 13). A desktop backup never contains anyone's cached Inbox or Sent mail (the record types named mailbox_...): that copy stays on this computer and is never uploaded to the cloud. In it, subjects, senders and recipients are readable to anyone with access to the database (so the lists can sort and search them); message text is encrypted with each person's key on this computer |
The licence file does not need a backup: it is locked to this computer, and you can activate again with your key.
Uninstalling
- On a computer shared with the desktop app, give the sync back first, in PowerShell as
administrator:
powershell -NoProfile -ExecutionPolicy Bypass -File C:\techiecrm-localportal\installer\coexist.ps1 -Remove. - Remove the scheduled start: delete the Task Scheduler tasks, the launchd files (after
launchctl unload), or the systemd units (aftersystemctl --user disable --now). - Release the licence, if this computer will not use it again: Deactivate this computer on the activation page. Not on a computer shared with the desktop app: they share one licence.
- Delete the install folder. That removes the portal, its settings and its
datafolder.
Deleting the install folder never deletes your CRM data in MongoDB, the licence file, or anything
of the desktop app's. It also leaves TechieCRM's TCRM_ tables in your CRM's SQL Server database; to take
those out too, run manage.py remove_techiecrm first (see
Removing TechieCRM from your CRM's SQL Server database).
Troubleshooting
| What you see | What to do |
|---|---|
The browser cannot connect to localhost:8000 |
Start the portal; check the port in .env; on macOS and Linux read data/error.log |
| Address already in use, or the portal stops at once | Another program uses the port. Set PORT= in .env (on an older install also remove CSRF_TRUSTED_ORIGINS) |
| Signing in fails with a security (CSRF) error | CSRF_TRUSTED_ORIGINS does not match the address and port in the browser |
The portal stops at start-up naming SINGLE_SESSION_MODE, LOCALPORTAL_SESSION_REGISTRY or TECHIECRM_TRUSTED_PROXY_COUNT |
That setting in .env has a value it does not accept; the message lists the allowed values |
| The portal stops at start-up with SECRET_KEY is not set … | .env lost its secret key. Restore .env from a backup, or delete it and run the installer again (then set your other settings again) |
The portal stops at start-up naming a package and install_requirements.py |
Run the installer again |
| Every page shows the activation page | Activate the licence as the account that runs the portal |
| Nobody can sign in on a new portal | It has no accounts yet: see Signing in the first time |
| A TechieCRM ID is refused with a red box | The table in Signing in the first time explains each message |
| This account is locked for a technical review … or Sign-in from your network is temporarily blocked … | Too many wrong passwords. An administrator clicks Unlock on the Web server page; with no administrator able to sign in, run manage.py unlock_signin --list, then --user or --all (Unlocking a sign-in) |
| Your CRM user ID matches a portal administrator account … | Link it yourself once with the account's email and password, SQL Server chosen (Signing in with your CRM user ID) |
| Unavailable without a MongoDB database | Open the Web server page (administrators); start MongoDB or connect to one |
| The Config database page says Only a portal administrator can configure the portal's databases, or the Web server page says Only a portal administrator can see the web server page | Sign in with an administrator's account |
| Clicking TechieCRM Local Portal at the top says No database is connected yet | Connect your CRM's SQL Server database or TechieCRM's MongoDB on the Config database page (administrators), or start MongoDB |
| The Config database page says the saved connection cannot be read | data/portal_connections.key is missing or is not the one it was saved with. Enter the connection again and click Save and prepare |
| The Config database page finds no SQL Server | A firewall, or a stopped SQL Server Browser service, hides it. Type the server name (host, host\INSTANCE or host,port) |
| The Config database page finds no MongoDB | It looks only on this computer. Check that MongoDB (or the TechieCRM desktop app) is running and press Refresh, or type the address of a MongoDB on another computer |
| Sign-in is temporarily unavailable | The sign-in check is on and its list cannot be reached (for example the office SQL Server is down). Bring it back, or set SINGLE_SESSION_MODE=off and restart |
| This Windows account may not read the desktop's database credential | Add the account to TechieCRM Users (the sharing step does), then sign out of Windows and in again |
| The sync does not run | Run manage.py sync_cloud by hand and read its message; on a shared computer run manage.py sync_owner |
| Email says Add your email account to see your inbox here | You have no email account on the portal yet: Set up email accounts (Email on the local portal) |
| Email or Settings > Email says Your email accounts could not be read | data/mail_accounts.key is missing or is not the one the accounts were saved with. Put both data/mail_accounts.enc and data/mail_accounts.key back from the same backup |
| Test sign-in says Refused for Gmail, Outlook.com, Yahoo or iCloud | The provider needs an app password: follow the steps shown and paste the app password with Edit |
Where to look: data/error.log and data/access.log (macOS, Linux), the PowerShell window
(Windows), manage.py check_services, manage.py check_license, and the Web server page.
When you contact TechieCRM support, include their output.
Not yet available
- An installer that sets up MongoDB, a Windows service for the portal, or HTTPS for other computers. Set these up as described above.
- The first data load with Windows sign-in to SQL Server: it needs a SQL Server login.
- The local portal refreshing a shared database from your source CRM on a computer shared with the desktop app: the desktop app still does that while it is open.
- The one-place sign-in check for workspaces with a cloud subscription.
- Windows sign-in to the office SQL Server on the Config database page: it needs a SQL Server login.
- On the portal's Email page (October 2026): sending, replying and forwarding; marking read, flags, deleting and moving; filing an email on a client; Sign in with Microsoft, Google or Yahoo (so a Microsoft 365 work or school mailbox cannot be read yet); and email accounts arriving from your desktop by themselves. Send Later and Email to Many are not planned for the portal in this round.