Updating Local Lab
Move to a new version without losing your data or your settings, with repository access or with a zip, on your computer or on a server.
Updated 7 Oct 2026 · written for Local Lab 1.2.1
On this page
A new version of Local Lab is new code. Your data and your settings are in a handful of files and folders that the code never touches, so an update means replacing the code round them and then letting the database catch up. How you do it depends on how you got the kit: from the repository with git, or as a zip.
What is yours#
Keep these through every update.
| File or folder | What is in it |
|---|---|
.env | Your secret key and any other settings. |
instance/ | The database, directory.db, and anything the Google Places scraper has saved. |
static/uploads/ | Logos and pictures that you and business owners have uploaded. |
places_config.json | Your Google Places search settings, if you have saved any. |
backups/ | Copies you made with Save on Server on the Database page. |
| Files you changed | A template whose wording you edited, for example. Note which ones: you repeat the change in the new copy. |
On a server set up with deploy.sh the list is shorter: the sites/ folder (each site's .env, port and uploads, with the database password), the backups/ folder and .backup.env if you made one. The databases are in a Docker volume, outside the code folder.
Before you update#
Read
CHANGELOG.mdin the new version. It lists what changed in each version, newest first. The version you have now is at the top of your own copy.Take a backup. On your computer, stop the site and copy
instance/directory.dbsomewhere safe. On a server, run./scripts/deploy.sh backup-all: see Backups, scheduled jobs and PostgreSQL.Leave
SECRET_KEYas it is. Why is below.
The first update on your own computer#
With the site stopped and the virtual environment active, in the Local Lab folder:
flask db currentIf that prints a line such as g4d5e6f7a8b9 (head), the database is marked and there is nothing to do. If it prints no such line, mark it:
flask db stamp headIf you have already replaced the code, mark the version you came from. For 1.2.0 and 1.2.1 that is flask db stamp g4d5e6f7a8b9.
A site made on a server with deploy.sh add-site is marked from the start.
With repository access#
On your own computer#
Stop the site, then in the Local Lab folder with the virtual environment active:
git pull
pip install -r requirements.txt
flask db upgrade
python run.pypip install adds any packages the new version needs. flask db upgrade makes the changes to the database that the new code expects. Your .env, database and uploads are not in the repository, so git pull leaves them alone.
On a server#
cd /opt/directorylab
./scripts/deploy.sh backup-all
./scripts/deploy.sh updateupdate does these things, in this order:
Pulls the new code:
git pull origin main.Rebuilds the image that every site runs from.
For each site in turn, stops its container and starts a new one from the new image. A site does not answer while its own container is swapped.
Clears out old images and trims Docker's build cache to 3 GB.
Runs
scripts/setup-crons.sh, so the nightly schedule matches the new version.Runs
flask db upgradeinside every site's container.
Sites are restarted at step 3 and their databases are changed at step 6, so for a short time a site runs new code on the old database. If a database change fails, the script names the sites after "Migrations FAILED for:". The reason is printed above that line. Fix it and run ./scripts/deploy.sh migrate-all before you leave the site in use.
With a zip#
If your tier has no repository access, download the new zip from your dashboard at directorylab.io. deploy.sh update cannot be used: its first step is git pull, and it stops there.
On your own computer#
Step 1: Unzip the new version beside the old one
You now have two folders, for example
local-lab-1.2.1and the new one. Leave the old one as it is. If this is your first update, do the step above in the old folder first.Step 2: Copy what is yours into the new folder
From the old folder, copy
.env, the wholeinstancefolder, the wholestatic/uploadsfolder andplaces_config.jsonif there is one. Repeat any changes you made to templates.Step 3: Install and update the database
In the new folder, make a virtual environment as in Install Local Lab, then:
bashpip install -r requirements.txt flask db upgradeStep 4: Start the site
bashpython run.pyCheck your listings and your settings are there before you delete the old folder.
On a server#
Step 1: Upload and unpack the zip
On your computerscp local-lab-X.Y.Z.zip root@YOUR-SERVER-IP:/opt/On the servercd /opt ./directorylab/scripts/deploy.sh backup-all unzip local-lab-X.Y.Z.zipStep 2: Move what is yours into the new folder
bashmv directorylab/sites directorylab/backups local-lab-X.Y.Z/ mv directorylab/.backup.env local-lab-X.Y.Z/The second line is only for a server where you made that file. If you changed
nginx/site.conf.templateor any template, repeat the change in the new folder now.Step 3: Swap the folders
bashmv directorylab directorylab-old mv local-lab-X.Y.Z directorylabThe code must end up at
/opt/directorylab: the backup script and the schedule have that path written into them.Step 4: Rebuild and restart
bashcd /opt/directorylab docker build -t directorylab . ./scripts/deploy.sh update-site lawnRun the last line once for each site, with its name.
Step 5: Update the databases and the schedule
bash./scripts/deploy.sh migrate-all bash scripts/setup-crons.sh ./scripts/deploy.sh statusWhen every site shows UP and you have looked at each one, delete
/opt/directorylab-old.
How the database catches up#
Each version carries a list of small changes to the database, in the migrations folder. flask db upgrade applies the ones your database has not had yet, and records where it got to.
A new database is not built that way. The app makes every table in one go, as the newest version wants them, and the database is then marked as up to date.
| Where | A new install | An update |
|---|---|---|
| Your computer | The tables are made the first time the site is opened. The database is not marked. | Mark it once with flask db stamp head, then run flask db upgrade after each update. |
| A server | add-site makes the tables and marks the database. | update runs flask db upgrade for every site. ./scripts/deploy.sh migrate lawn does it for one. |
Do not change SECRET_KEY#
The secret key is in .env on your computer and in sites/<name>/.env on a server. No update needs a new one: carry the same file across.
If it changes:
The Stripe keys, the Google Places key and the email password you saved in the admin can no longer be read. You type them all in again.
Everyone is signed out.
Verification and password-reset links already sent by email stop working.
flask db upgrade fails with "already exists"
The database was never marked with its version. Do the first update step, then run flask db upgrade again.
deploy.sh update says "not a git repository"
The server was installed from a zip. Use the zip steps for a server.
git pull refuses because of my local changes
You changed a file that the kit also changed. Put your change aside, pull, then bring it back:
git stash
git pull
git stash popIf git reports a conflict in the file, open it and keep the lines you want.
How do I go back to the old version?
Put the old code back and restore the backup you took before the update. Do not run old code on a database that the new version has already changed.
Which version am I on?
The top entry in CHANGELOG.md in your Local Lab folder.
Stuck on a step? Send a message.