I’ve found some topics on this, but so far what I’ve found is how to fully integrate the save functionality with a commit. I don’t want to do that (and frankly don’t know why anyone would want to do that every single time they hit the save button…it seems excessive since 90% of the time my “commit message” would be “I’m saving this so I don’t lose my progress if the Designer crashes”), so I think what I need would be a little less complicated.
I can think of doing this in two approaches:
- Create a custom dockerfile or use a custom container with git installed inside the container.
- Bind the ignition data folder to a folder on my host drive as a volume (I know I need to launch the container, copy the contents to my host drive first, and then relaunch with an added volume line in my compose file linking the container and host folders) and manage git from my host machine.
We have a Gitlab server internally for our company that I use SSH for authentication, and it’s already set up. For that reason and others, I think option #2 would probably be the easiest for me, but often “easier” means there’s some kind of problem with doing it that way.
What do you guys recommend?
You have to be careful when syncing the entire Ignition data folder with Git. That directory includes not only static text files (which are ideal for Git) but also binary files, such as the .idb files used for internal databases and tags. Tracking these can lead to significant issues with branch merging and errors due to mismatches between your local environment and the server.
In my experience, a more robust approach is using Git to track global assets, scripts, UDTs as json, embedded views, and custom theme folders (CSS files). This allows you to create a dedicated repository that acts as a 'Company Asset Library.'
Regarding the workflow: Git isn't meant to trigger a push every time you hit 'Save' in the Designer. Instead, it should follow a standard development cycle: work on a specific view or script, test it thoroughly, and only then commit/push your changes. This transforms your Git server into a reliable bridge between workstations and production, ensuring that all changes are validated and controlled before they go live.
You have to be careful when syncing the entire Ignition data folder with Git. That directory includes not only static text files (which are ideal for Git) but also binary files, such as the .idb files used for internal databases and tags. Tracking these can lead to significant issues with branch merging and errors due to mismatches between your local environment and the server.
Oh I realize this. I’d theoretically be utilizing the .gitignore file to remove any binary files that change regularly from the equation. I probably wouldn’t save the entire gateway if it’s an 8.1 project but only the project resources themselves. Although some binary files I might want to save for things like device connections, database connections, etc. stuff that isn’t likely to change once it’s set up. That way it can be restored if needed.
In my experience, a more robust approach is using Git to track global assets, scripts, UDTs as json, embedded views, and custom theme folders (CSS files). This allows you to create a dedicated repository that acts as a 'Company Asset Library.'
When IA demonstrates this they just establish the repository in the project folder (or one level above if it’s 8.3) itself. It sounds like you’re saying you’d have to export those resources from your project and THEN do your commits and pushes from there. I can kind of see the benefit of this, but couldn’t I just as I mentioned above set up a .gitignore file and only include what I need anyway?
Regarding the workflow: Git isn't meant to trigger a push every time you hit 'Save' in the Designer…
I understand that, and I don’t intend to. I only mentioned it because the threads I’ve found specifically about working with Git and Docker together was someone wanting to do that. There’s also a module on the exchange that actually integrates Git with the Designer UI and pulls up a commit dialog every time you hit save. Like you’re saying here, that doesn’t seem like that would be a very good workflow and I have no idea why anyone would want to have to fill out a form every time they hit the save button, especially since 90% of the time I’m just saving my progress and it’s not really a good cutoff point for a feature or bug fix.
Hi Brian,
Are you using 8.1 or 8.3?
For 8.1, there are some significant steps I had to take to be able to version ignition reliably. I would recommend using a docker compose with volume mounts to point your data/projects to a directory in the git repo like your-repo/ignition. That will get you 80% there. It will version all of your views, scripts and other plain text files related to your projects. The last 20% is the hard part. I personally use the tag cicd module to store the UDTs in data/projects/.tags. For the gateway specific configurations, I have a directory inside data/projects/.config where I store my application configuration and the gateway backup artifact. To generate a gateway artifact that doesn't have the projects or UDTs (since we are already versioning those items), you have to build a custom dockerfile that has sqlite and zip installed. Note that I remove everything from TAGCONFIG because I build my tags from an application configuration. This script has to be triggered from inside the container and obviously gateway scoped. As noted in the script I query the audit table to get what changed and generate a commit message and a script that just pushes the artifact with the generated commit message. You would need to adapt this to your needs.
Example below:
script example
environmentType = "dev"
gatewayName = "some-gateway"
commitMessage = "I usually build a commit message from ignitions audit table. to get some idea of the changes."
system.util.execute(["/usr/local/bin/ignition/data/projects/.config/scripts/make-backup.sh", environmentType, gatewayName, commitMessage])
ignition/.config/scripts/make-backup.sh
#!/bin/bash
# Allows us to see output even when called from ignition
exec > /usr/local/bin/ignition/data/projects/.config/scripts/backup.log 2>&1
set -euox
ENVIRONMENT_TYPE="$1"
GATEWAY_NAME="$2"
COMMIT_MSG="$3"
BACKUP_DIR="/usr/local/bin/ignition/data/projects/.config/${ENVIRONMENT_TYPE}/${GATEWAY_NAME}"
echo $(date)
/usr/local/bin/ignition/gwcmd.sh -b /usr/local/bin/ignition/data/projects/.config/scripts/backup.gwbk -y
cd /usr/local/bin/ignition/data/projects/.config/scripts
mv backup.gwbk backup.zip
zip --delete backup.zip projects/* modules/com.inductiveautomation.perspective/*
unzip backup.zip db_backup_sqlite.idb
sqlite3 db_backup_sqlite.idb < remove-tags.sql
zip backup.zip db_backup_sqlite.idb
rm db_backup_sqlite.idb
# Create the destination directory if it doesn't exist
mkdir -p "$BACKUP_DIR"
# Move and rename the final backup
mv backup.zip "${BACKUP_DIR}/backup.gwbk"
printf '%s\n' "$COMMIT_MSG" > "${BACKUP_DIR}/commit.txt"
ignition/.config/scripts/remove-tags.sql
delete from TAGCONFIG;
dockerfile
FROM inductiveautomation/ignition:8.1.42
USER root
RUN apt-get update && apt-get install sqlite3 -y && apt-get install unzip -y && apt-get install zip -y
COPY modules/*.modl /usr/local/bin/ignition/user-lib/modules/
COPY jars/*.jar /usr/local/bin/ignition/lib/core/common/
More than happy to go into detail about this if you are curious.
For 8.3, this guide will help. I put the plain text config in data/projects/.config/ignition but you could make a separate volume mount for this. Be sure to follow the guide's .gitignore. I dont have to generate backup artifacts in a hacky way or use external modules. It actually works pretty nice now.
Hope this helps!
1 Like
Thanks so much! I’ll look into this. It sounds like your approach with 8.1 is closest to my option #2.
1 Like