Skip to content

fix: persist Langflow database across container restarts#1129

Closed
JasonOA888 wants to merge 1 commit into
langflow-ai:mainfrom
JasonOA888:fix/langflow-persistence-volume
Closed

fix: persist Langflow database across container restarts#1129
JasonOA888 wants to merge 1 commit into
langflow-ai:mainfrom
JasonOA888:fix/langflow-persistence-volume

Conversation

@JasonOA888

Copy link
Copy Markdown
Contributor

Summary

Fixes #1127 - Langflow flow edits were being lost after container restart.

Problem

The langflow service in docker-compose.yml only mounted /app/flows for flow files, but Langflow stores its SQLite database at /root/.langflow/ by default. This directory was ephemeral, causing all flow edits to be lost on container restart.

Solution

  1. Add persistent volume for Langflow data directory:

    • Mount ${LANGFLOW_DATA_PATH:-./langflow-data} to /root/.langflow
  2. Explicitly set database location via LANGFLOW_DATABASE_URL:

    • sqlite:////root/.langflow/langflow.db
    • Ensures database is always in the mounted volume
  3. Document new environment variable in .env.example:

    • LANGFLOW_DATA_PATH=./langflow-data

Changes

File Change
docker-compose.yml Added volume mount for /root/.langflow + LANGFLOW_DATABASE_URL env var
.env.example Added LANGFLOW_DATA_PATH documentation

Testing

  • Configuration verified against Langflow documentation
  • Volume mount follows same pattern as existing OPENSEARCH_DATA_PATH

Backward Compatibility

  • Fully backward compatible - existing deployments will work unchanged
  • New volume is optional (defaults to ./langflow-data)

Closes #1127

Fixes langflow-ai#1127 - Langflow flow edits no longer lost after restart

## Problem
Flow edits made in Langflow UI were being lost after container restart.
The langflow service only mounted /app/flows but Langflow stores its
SQLite database at /root/.langflow/ by default, which was ephemeral.

## Solution
1. Add persistent volume for Langflow data directory:
   - Mount ${LANGFLOW_DATA_PATH:-./langflow-data} to /root/.langflow
2. Explicitly set LANGFLOW_DATABASE_URL to ensure database location
3. Document the new LANGFLOW_DATA_PATH in .env.example

## Testing
- Verified volume mount configuration
- Database URL format: sqlite:////root/.langflow/langflow.db

Closes langflow-ai#1127
@github-actions github-actions Bot added community docker bug 🔴 Something isn't working. labels Mar 13, 2026
mpawlow added a commit that referenced this pull request Mar 17, 2026
Issue

- #1129

Summary

- Fixed Langflow data path and added LANGFLOW_CONFIG_DIR environment variable to ensure flow edits persist across container restarts.

Docker Compose Configuration

- Updated the Langflow container volume mount target from /root/.langflow to /app/data/.langflow to match the correct working directory for the containerized process
- Added LANGFLOW_CONFIG_DIR=/app/data/.langflow environment variable so Langflow uses the correct directory for all configuration artifacts
- Updated LANGFLOW_DATABASE_URL to reference the corrected path /app/data/.langflow/langflow.db

Makefile

- Added langflow-data directory cleanup to the factory-reset target, including a status message in the pre-reset summary and removal logic matching the existing opensearch-data cleanup pattern

Builds on #1129
mpawlow added a commit that referenced this pull request Mar 17, 2026
Issue

- #1127

Summary

- Fixed Langflow data path and added LANGFLOW_CONFIG_DIR environment variable to ensure flow edits persist across container restarts.

Docker Compose Configuration

- Updated the Langflow container volume mount target from /root/.langflow to /app/data/.langflow to match the correct working directory for the containerized process
- Added LANGFLOW_CONFIG_DIR=/app/data/.langflow environment variable so Langflow uses the correct directory for all configuration artifacts
- Updated LANGFLOW_DATABASE_URL to reference the corrected path /app/data/.langflow/langflow.db

Makefile

- Added langflow-data directory cleanup to the factory-reset target, including a status message in the pre-reset summary and removal logic matching the existing opensearch-data cleanup pattern

Builds on #1129
mpawlow added a commit that referenced this pull request Mar 18, 2026
Issue

- #1127

Summary

- User-made edits to Langflow flows were silently discarded on every container restart.
- Two root causes were identified and corrected:
- (1) The Langflow data volume was mounted to the wrong path inside the container.
- (2) The LANGFLOW_LOAD_FLOWS_PATH mechanism performed a blind upsert of all flows on every startup, overwriting any changes made in the Langflow UI.

Docker / Infrastructure

- Corrected the Langflow data volume mount target from /root/.langflow to /app/langflow-data in docker-compose.yml
- Replaced LANGFLOW_LOAD_FLOWS_PATH env var with LANGFLOW_CONFIG_DIR=/app/langflow-data so Langflow resolves its config and database from the persisted volume
- Updated LANGFLOW_DATABASE_URL to reference the new path (sqlite:////app/langflow-data/langflow.db)
- Pre-created /app/langflow-data in Dockerfile.langflow during image build to ensure named Docker volumes are initialised with the correct ownership for the non-root container user
- Added langflow-data/ directory with a .gitkeep file; updated .gitignore to track the directory stub while ignoring its contents

Backend — Flow Bootstrapping

- Added FlowsService.ensure_flows_exist(): a create-only startup routine that checks each configured flow ID against the Langflow API and creates missing flows from their JSON files, without ever patching or
overwriting an existing flow
- Replaced the LANGFLOW_LOAD_FLOWS_PATH blind-upsert behaviour with a call to ensure_flows_exist() inside startup_tasks() in src/main.py

Makefile

- Extended the factory-reset target to remove the langflow-data/ directory alongside opensearch-data/ and config/

Code Cleanup

- Removed trailing whitespace throughout src/services/flows_service.py

Builds on #1129
mpawlow added a commit that referenced this pull request Mar 19, 2026
Issue

- #1127

Summary

- User-made edits to Langflow flows were silently discarded on every container restart.
- Two root causes were identified and corrected:
- (1) The Langflow data volume was mounted to the wrong path inside the container.
- (2) The LANGFLOW_LOAD_FLOWS_PATH mechanism performed a blind upsert of all flows on every startup, overwriting any changes made in the Langflow UI.

Docker / Infrastructure

- Corrected the Langflow data volume mount target from /root/.langflow to /app/langflow-data in docker-compose.yml
- Replaced LANGFLOW_LOAD_FLOWS_PATH env var with LANGFLOW_CONFIG_DIR=/app/langflow-data so Langflow resolves its config and database from the persisted volume
- Updated LANGFLOW_DATABASE_URL to reference the new path (sqlite:////app/langflow-data/langflow.db)
- Pre-created /app/langflow-data in Dockerfile.langflow during image build to ensure named Docker volumes are initialised with the correct ownership for the non-root container user
- Added langflow-data/ directory with a .gitkeep file; updated .gitignore to track the directory stub while ignoring its contents

Backend — Flow Bootstrapping

- Added FlowsService.ensure_flows_exist(): a create-only startup routine that checks each configured flow ID against the Langflow API and creates missing flows from their JSON files, without ever patching or
overwriting an existing flow
- Replaced the LANGFLOW_LOAD_FLOWS_PATH blind-upsert behaviour with a call to ensure_flows_exist() inside startup_tasks() in src/main.py

Makefile

- Extended the factory-reset target to remove the langflow-data/ directory alongside opensearch-data/ and config/

Code Cleanup

- Removed trailing whitespace throughout src/services/flows_service.py

Builds on #1129
mpawlow added a commit that referenced this pull request Mar 19, 2026
Issue

- #1127

Summary

- User-made edits to Langflow flows were silently discarded on every container restart.
- Two root causes were identified and corrected:
- (1) The Langflow data volume was mounted to the wrong path inside the container.
- (2) The LANGFLOW_LOAD_FLOWS_PATH mechanism performed a blind upsert of all flows on every startup, overwriting any changes made in the Langflow UI.

Docker / Infrastructure

- Corrected the Langflow data volume mount target from /root/.langflow to /app/langflow-data in docker-compose.yml
- Replaced LANGFLOW_LOAD_FLOWS_PATH env var with LANGFLOW_CONFIG_DIR=/app/langflow-data so Langflow resolves its config and database from the persisted volume
- Updated LANGFLOW_DATABASE_URL to reference the new path (sqlite:////app/langflow-data/langflow.db)
- Pre-created /app/langflow-data in Dockerfile.langflow during image build to ensure named Docker volumes are initialised with the correct ownership for the non-root container user
- Added langflow-data/ directory with a .gitkeep file; updated .gitignore to track the directory stub while ignoring its contents

Backend — Flow Bootstrapping

- Added FlowsService.ensure_flows_exist(): a create-only startup routine that checks each configured flow ID against the Langflow API and creates missing flows from their JSON files, without ever patching or
overwriting an existing flow
- Replaced the LANGFLOW_LOAD_FLOWS_PATH blind-upsert behaviour with a call to ensure_flows_exist() inside startup_tasks() in src/main.py

Makefile

- Extended the factory-reset target to remove the langflow-data/ directory alongside opensearch-data/ and config/

Code Cleanup

- Removed trailing whitespace throughout src/services/flows_service.py

Builds on #1129
@JasonOA888

Copy link
Copy Markdown
Contributor Author

Closing this PR as #1167 by @mpawlow addresses the same issue and was created earlier. Please review that PR instead.

@JasonOA888 JasonOA888 closed this Mar 19, 2026
@mpawlow

mpawlow commented Mar 19, 2026

Copy link
Copy Markdown
Collaborator

Thanks for the contribution, @JasonOA888 🙏
You're commits serve as the basis / foundation for the new PR.

mpawlow added a commit that referenced this pull request Mar 19, 2026
Issue

- #1127

Summary

- User-made edits to Langflow flows were silently discarded on every container restart.
- Two root causes were identified and corrected:
- (1) The Langflow data volume was mounted to the wrong path inside the container.
- (2) The LANGFLOW_LOAD_FLOWS_PATH mechanism performed a blind upsert of all flows on every startup, overwriting any changes made in the Langflow UI.

Docker / Infrastructure

- Corrected the Langflow data volume mount target from /root/.langflow to /app/langflow-data in docker-compose.yml
- Replaced LANGFLOW_LOAD_FLOWS_PATH env var with LANGFLOW_CONFIG_DIR=/app/langflow-data so Langflow resolves its config and database from the persisted volume
- Updated LANGFLOW_DATABASE_URL to reference the new path (sqlite:////app/langflow-data/langflow.db)
- Pre-created /app/langflow-data in Dockerfile.langflow during image build to ensure named Docker volumes are initialised with the correct ownership for the non-root container user
- Added langflow-data/ directory with a .gitkeep file; updated .gitignore to track the directory stub while ignoring its contents

Backend — Flow Bootstrapping

- Added FlowsService.ensure_flows_exist(): a create-only startup routine that checks each configured flow ID against the Langflow API and creates missing flows from their JSON files, without ever patching or
overwriting an existing flow
- Replaced the LANGFLOW_LOAD_FLOWS_PATH blind-upsert behaviour with a call to ensure_flows_exist() inside startup_tasks() in src/main.py

Makefile

- Extended the factory-reset target to remove the langflow-data/ directory alongside opensearch-data/ and config/

Code Cleanup

- Removed trailing whitespace throughout src/services/flows_service.py

Builds on #1129
mpawlow added a commit that referenced this pull request Mar 19, 2026
Issue

- #1127

Summary

- User-made edits to Langflow flows were silently discarded on every container restart.
- Two root causes were identified and corrected:
- (1) The Langflow data volume was mounted to the wrong path inside the container.
- (2) The LANGFLOW_LOAD_FLOWS_PATH mechanism performed a blind upsert of all flows on every startup, overwriting any changes made in the Langflow UI.

Docker / Infrastructure

- Corrected the Langflow data volume mount target from /root/.langflow to /app/langflow-data in docker-compose.yml
- Replaced LANGFLOW_LOAD_FLOWS_PATH env var with LANGFLOW_CONFIG_DIR=/app/langflow-data so Langflow resolves its config and database from the persisted volume
- Updated LANGFLOW_DATABASE_URL to reference the new path (sqlite:////app/langflow-data/langflow.db)
- Pre-created /app/langflow-data in Dockerfile.langflow during image build to ensure named Docker volumes are initialised with the correct ownership for the non-root container user
- Added langflow-data/ directory with a .gitkeep file; updated .gitignore to track the directory stub while ignoring its contents

Backend — Flow Bootstrapping

- Added FlowsService.ensure_flows_exist(): a create-only startup routine that checks each configured flow ID against the Langflow API and creates missing flows from their JSON files, without ever patching or
overwriting an existing flow
- Replaced the LANGFLOW_LOAD_FLOWS_PATH blind-upsert behaviour with a call to ensure_flows_exist() inside startup_tasks() in src/main.py

Makefile

- Extended the factory-reset target to remove the langflow-data/ directory alongside opensearch-data/ and config/

Code Cleanup

- Removed trailing whitespace throughout src/services/flows_service.py

Builds on #1129
mpawlow added a commit that referenced this pull request Mar 20, 2026
Issue

- #1127

Summary

- User-made edits to Langflow flows were silently discarded on every container restart.
- Two root causes were identified and corrected:
- (1) The Langflow data volume was mounted to the wrong path inside the container.
- (2) The LANGFLOW_LOAD_FLOWS_PATH mechanism performed a blind upsert of all flows on every startup, overwriting any changes made in the Langflow UI.

Docker / Infrastructure

- Corrected the Langflow data volume mount target from /root/.langflow to /app/langflow-data in docker-compose.yml
- Replaced LANGFLOW_LOAD_FLOWS_PATH env var with LANGFLOW_CONFIG_DIR=/app/langflow-data so Langflow resolves its config and database from the persisted volume
- Updated LANGFLOW_DATABASE_URL to reference the new path (sqlite:////app/langflow-data/langflow.db)
- Pre-created /app/langflow-data in Dockerfile.langflow during image build to ensure named Docker volumes are initialised with the correct ownership for the non-root container user
- Added langflow-data/ directory with a .gitkeep file; updated .gitignore to track the directory stub while ignoring its contents

Backend — Flow Bootstrapping

- Added FlowsService.ensure_flows_exist(): a create-only startup routine that checks each configured flow ID against the Langflow API and creates missing flows from their JSON files, without ever patching or
overwriting an existing flow
- Replaced the LANGFLOW_LOAD_FLOWS_PATH blind-upsert behaviour with a call to ensure_flows_exist() inside startup_tasks() in src/main.py

Makefile

- Extended the factory-reset target to remove the langflow-data/ directory alongside opensearch-data/ and config/

Code Cleanup

- Removed trailing whitespace throughout src/services/flows_service.py

Builds on #1129
mpawlow added a commit that referenced this pull request Mar 23, 2026
Issue

- #1127

Summary

- User-made edits to Langflow flows were silently discarded on every container restart.
- Two root causes were identified and corrected:
- (1) The Langflow data volume was mounted to the wrong path inside the container.
- (2) The LANGFLOW_LOAD_FLOWS_PATH mechanism performed a blind upsert of all flows on every startup, overwriting any changes made in the Langflow UI.

Docker / Infrastructure

- Corrected the Langflow data volume mount target from /root/.langflow to /app/langflow-data in docker-compose.yml
- Replaced LANGFLOW_LOAD_FLOWS_PATH env var with LANGFLOW_CONFIG_DIR=/app/langflow-data so Langflow resolves its config and database from the persisted volume
- Updated LANGFLOW_DATABASE_URL to reference the new path (sqlite:////app/langflow-data/langflow.db)
- Pre-created /app/langflow-data in Dockerfile.langflow during image build to ensure named Docker volumes are initialised with the correct ownership for the non-root container user
- Added langflow-data/ directory with a .gitkeep file; updated .gitignore to track the directory stub while ignoring its contents

Backend — Flow Bootstrapping

- Added FlowsService.ensure_flows_exist(): a create-only startup routine that checks each configured flow ID against the Langflow API and creates missing flows from their JSON files, without ever patching or
overwriting an existing flow
- Replaced the LANGFLOW_LOAD_FLOWS_PATH blind-upsert behaviour with a call to ensure_flows_exist() inside startup_tasks() in src/main.py

Makefile

- Extended the factory-reset target to remove the langflow-data/ directory alongside opensearch-data/ and config/

Code Cleanup

- Removed trailing whitespace throughout src/services/flows_service.py

Builds on #1129
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug 🔴 Something isn't working. community docker

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Langflow flow edits are not persisting after restart.

2 participants