Skip to contentLaunch price30% off every kit for the first 250 buyers155 left
DirectoryLab

Loading the guides…

Local LabGuides
Keep it running

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 folderWhat is in it
.envYour 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.jsonYour Google Places search settings, if you have saved any.
backups/Copies you made with Save on Server on the Database page.
Files you changedA 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.md in 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.db somewhere safe. On a server, run ./scripts/deploy.sh backup-all: see Backups, scheduled jobs and PostgreSQL.

  • Leave SECRET_KEY as 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:

bash
flask db current

If 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:

bash
flask db stamp head

If 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:

bash
git pull
pip install -r requirements.txt
flask db upgrade
python run.py

pip 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#

bash
cd /opt/directorylab
./scripts/deploy.sh backup-all
./scripts/deploy.sh update

update does these things, in this order:

  1. Pulls the new code: git pull origin main.

  2. Rebuilds the image that every site runs from.

  3. 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.

  4. Clears out old images and trims Docker's build cache to 3 GB.

  5. Runs scripts/setup-crons.sh, so the nightly schedule matches the new version.

  6. Runs flask db upgrade inside 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#

  1. Step 1: Unzip the new version beside the old one

    You now have two folders, for example local-lab-1.2.1 and 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.

  2. Step 2: Copy what is yours into the new folder

    From the old folder, copy .env, the whole instance folder, the whole static/uploads folder and places_config.json if there is one. Repeat any changes you made to templates.

  3. Step 3: Install and update the database

    In the new folder, make a virtual environment as in Install Local Lab, then:

    bash
    pip install -r requirements.txt
    flask db upgrade
  4. Step 4: Start the site

    bash
    python run.py

    Check your listings and your settings are there before you delete the old folder.

On a server#

  1. Step 1: Upload and unpack the zip

    On your computer
    scp local-lab-X.Y.Z.zip root@YOUR-SERVER-IP:/opt/
    On the server
    cd /opt
    ./directorylab/scripts/deploy.sh backup-all
    unzip local-lab-X.Y.Z.zip
  2. Step 2: Move what is yours into the new folder

    bash
    mv 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.template or any template, repeat the change in the new folder now.

  3. Step 3: Swap the folders

    bash
    mv directorylab directorylab-old
    mv local-lab-X.Y.Z directorylab

    The code must end up at /opt/directorylab: the backup script and the schedule have that path written into them.

  4. Step 4: Rebuild and restart

    bash
    cd /opt/directorylab
    docker build -t directorylab .
    ./scripts/deploy.sh update-site lawn

    Run the last line once for each site, with its name.

  5. Step 5: Update the databases and the schedule

    bash
    ./scripts/deploy.sh migrate-all
    bash scripts/setup-crons.sh
    ./scripts/deploy.sh status

    When 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.

WhereA new installAn update
Your computerThe 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 serveradd-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:

bash
git stash
git pull
git stash pop

If 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.