I am using n8n as self host on a docker image in software engineering product. whenever I need to move from dev environment to SIT. is there any way rather than running a new docker image and copying all workflows from environment to environment each time? the number of workflows is big
@Mohamed8 dont copy them by hand, use the n8n CLI export/import, it moves your whole library at once. on the dev container export all workflows to a folder, copy that folder to the SIT box, then import:
# on dev
docker exec -u node <dev-container> n8n export:workflow --backup --output=/tmp/wf/
# copy /tmp/wf across, then on SIT
docker exec -u node <sit-container> n8n import:workflow --separate --input=/tmp/wf/
theres a matching export:credentials / import:credentials pair if you need creds moved too. beats spinning up a fresh image and copying each time.
Thanks. I am using basic Auth in my workflows, i added them in Credentials and i choose the appropriate one for each HTTP request. when i copy the workflow, it resets and chooses the first basic auth for all HTTP nodes by default and i need to fix them.
will i face the same issue with this approach?
@Mohamed8 the reset happens because nodes reference credentials by id and a plain copy doesnt carry those ids, so it falls back to the first matching one. the CLI avoids it as long as you move the credentials too, not just workflows: export:credentials --backup on dev, import:credentials on SIT. that import upserts by id so each cred keeps its original id and the workflow references resolve to the right basic auth on their own.
one catch, creds are encrypted with N8N_ENCRYPTION_KEY, so SIT needs the same key as dev or they wont decrypt. if the keys differ, export with --decrypted and theyll re-encrypt on import.
Awesome! Do you have any idea how can i access that encryption key? whether it can be exported as well or not?
@Mohamed8 its not exported with the workflows. its either the N8N_ENCRYPTION_KEY env var if you set one, or if you never did, n8n auto-generated it and saved it in the config file. read it on dev with:
docker exec -u node <dev-container> cat /home/node/.n8n/config
youll see an encryptionKey value in there. easiest path is to set that same value as N8N_ENCRYPTION_KEY on SIT (in your compose/run env), then both share the key and the imported creds decrypt. setting it explicitly on both beats relying on the auto-generated file anyway.
Hey @Mohamed8, @achamm 's CLI approach is the right fix for what you have now. One thing worth considering for the longer term, since this sounds like a recurring dev→SIT promotion in a real product pipeline, n8n supports source control via Git (Settings → Source Control, available on certain plans) which turns this into a proper CI/CD-style flow: push workflows from dev to a Git repo, then pull/deploy to SIT automatically. It also versions your workflows properly, so you get diffs and rollback for free instead of manual export/import each time.
If Git-based source control isn’t available on your plan/edition, @achamm 's CLI export/import is the right manual equivalent, just worth knowing the automated option exists if this becomes a frequent pipeline step rather than a one-off migration.
I face an issue when i try to import my workflows into my new environment.
I get an error
Active version not found for workflow
Error: Active version not found for workflow
at ActiveWorkflowManager.clearWebhooks (/usr/local/lib/node_modules/n8n/src/active-workflow-manager.ts:248:10)
at ActiveWorkflowManager.remove (/usr/local/lib/node_modules/n8n/src/active-workflow-manager.ts:872:4)
at ImportService.importWorkflows (/usr/local/lib/node_modules/n8n/src/services/import.service.ts:84:5)
at ImportWorkflowsCommand.run (/usr/local/lib/node_modules/n8n/src/commands/import/workflow.ts:104:3)
at CommandRegistry.execute (/usr/local/lib/node_modules/n8n/src/command-registry.ts:83:4)
at /usr/local/lib/node_modules/n8n/bin/n8n:63:2
Could not remove webhooks of workflow "0YdMxcy7MAjVkwy2" because of error: "Active version not found for workflow"
Could not find workflow
Error: Could not find workflow
at ActiveWorkflowManager.clearWebhooks (/usr/local/lib/node_modules/n8n/src/active-workflow-manager.ts:244:10)
at ActiveWorkflowManager.remove (/usr/local/lib/node_modules/n8n/src/active-workflow-manager.ts:872:4)
at ImportService.importWorkflows (/usr/local/lib/node_modules/n8n/src/services/import.service.ts:84:5)
at ImportWorkflowsCommand.run (/usr/local/lib/node_modules/n8n/src/commands/import/workflow.ts:104:3)
at CommandRegistry.execute (/usr/local/lib/node_modules/n8n/src/command-registry.ts:83:4)
at /usr/local/lib/node_modules/n8n/bin/n8n:63:2
given that My workflows have webhooks triggers and some of them are active and my n8n version is 2.1.4
do you have any idea?
@ShawnWilliams @achamm
@Mohamed8 thats the import trying to manage the workflows active state, newer n8n tracks active workflows by a version id and importing an active workflow whose active-version record doesnt exist yet on SIT makes clearWebhooks fail with that. cleanest fix is to bring them in inactive, deactivate the workflows on dev before exporting so they import as active:false, then activate them on SIT after theyre loaded. and if the failed run left half-imported copies stuck active on SIT, deactivate or delete those first so the next import isnt trying to clear webhooks for them.
is there a way to activate/deactivate them using CLI?
@Mohamed8 yeah, the n8n update:workflow command does it:
docker exec -u node <container> n8n update:workflow --all --active=false
flip --active=true to activate, or use --id= instead of --all to target one. so your flow becomes deactivate on dev, export, import to SIT, then run it with --active=true on SIT. if you dont want dev going offline, just deactivate the stuck copies on SIT with --all --active=false, re-import, then reactivate there.
Thanks so much for your help. @achamm
when i try to publish one by one it gives me an error
Publishing workflow with ID: Error tracking disabled because this release is older than 6 weeks. (current version)
Error updating database. See log messages for details.
GOT ERROR
Workflow "Error tracking disabled because this release is older than 6 weeks." not found.
Error: Workflow "Error tracking disabled because this release is older than 6 weeks." not found.
at WorkflowRepository.publishVersion (/usr/local/lib/node_modules/n8n/node_modules/.pnpm/
+db@file+packages+
+db_@opentelemetry+api@1.9.0_@opentelemetry+sdk-trace-base@1._ab22bba05a964211b9fe14bf4b841570/node_modules/
/db/src/repositories/workflow.repository.ts:894:11)
at PublishWorkflowCommand.run (/usr/local/lib/node_modules/n8n/src/commands/publish/workflow.ts:43:3)
at CommandRegistry.execute (/usr/local/lib/node_modules/n8n/src/command-registry.ts:83:4)
at /usr/local/lib/node_modules/n8n/bin/n8n:63:2
Workflow "Error tracking disabled because this release is older than 6 weeks." not found.
Publishing 0YdMxcy7MAjVkwy2
Error tracking disabled because this release is older than 6 weeks.
Publishing workflow with ID: 0YdMxcy7MAjVkwy2 (current version)
Error updating database. See log messages for details.
also when i try to publish it from UI, it says Workflow could not be published:
Version not found
@Mohamed8 dont do them one by one, that per-id publish is where its choking, the workflow id isnt resolving so n8n cant find it. just run the bulk activate:
docker exec -u node <container> n8n update:workflow --all --active=true
it flips them all on in one go without you passing individual ids. if even --all errors out, then its likely a quirk in the build youre on (that 6-weeks line means its an older release), and bumping to a current n8n version is worth a shot.
The CLI export/import advice is the right base. If you have a lot of workflows, I would also treat dev → SIT as a release process rather than a copy operation.
The pieces I would add:
- Keep exports in version control so you know what changed between promotions.
- Separate workflow structure from environment-specific values.
- Do not blindly move production credentials unless you have a clear credential ownership model.
- Run smoke checks after import for the workflows that matter.
- Record which workflows were promoted, which failed, and what needs manual follow-up.
- Keep a rollback path, even if it is just re-importing the previous known-good export.
The copy step is usually not what hurts later. The painful part is when nobody knows which environment has which version, whether SIT was actually tested, or which workflow broke after the move. That promotion log becomes especially important once workflows are client-facing.
@achamm but whenever i use
docker exec -u node n8n update:workflow --all --active=true
it says
⚠️ WARNING: The "update:workflow" command is deprecated.
Workflow publishing via "update:workflow --all" is no longer supported.
Please publish workflows individually using: publish:workflow --id=<workflow-id>
@Mohamed8 yeah --all got deprecated and the new publish:workflow is where you hit that version error earlier, so skip the publish CLI and use the public REST API instead, it has a dedicated activate endpoint that sidesteps the versioning entirely:
POST /api/v1/workflows/{id}/activate
generate an API key in Settings > n8n API, list your workflows with GET /api/v1/workflows to grab the ids, then loop that activate call over each. thats your bulk activate without touching the broken publish command.
@achamm querying workflow ids from sqlite and then looping over them could be an alternative?
@Mohamed8 yeah reading the ids from sqlite works fine, the table is workflow_entity so SELECT id FROM workflow_entity gets you the list (the GET /api/v1/workflows api does the same and isnt tied to the db schema, but either works). just keep it to reading, dont activate by writing active=1 directly in sqlite, that skips the trigger/webhook registration n8n does on activate which is exactly what leaves workflows in that broken active-version state. pull the ids however you like, but run the actual activation through the api endpoint so n8n wires up the triggers properly.
Thanks for your help @achamm . do you think that replicating the n8n volume of DEV to be used in SIT would keep credentials ids and nodes attached properly?
I see all details are stored in SQLite which resides in n8n volume.
@Mohamed8 yeah cloning the whole volume works and its the cleanest for keeping everything attached — its a byte-for-byte copy of the same sqlite db, so credential ids, workflow ids and every node reference stay identical, nothing to re-link. the encryption key rides along too since its in .n8n/config inside that volume, so creds decrypt on SIT, just dont set a different N8N_ENCRYPTION_KEY env var on SIT or itll clash.
two catches though: its a full overwrite, it replaces everything on SIT and carries DEVs env-specific config (urls, webhook base, dev-vs-prod cred values), so its great if SIT is meant to mirror DEV, less so if SIT needs its own settings. and stop n8n before copying the sqlite file, copying it live can corrupt it, or use sqlites .backup for a clean snapshot. if SIT needs its own config, the selective export/import is still the better route.