---
title: "Improved migrations and Audit log management | Phase Changelog"
description: "This release sees improvements to running and maintaining self-hosted instances of Phase, with an improved migration strategy for multi-container deployments and a utility to cleanup unused logs entries."
url: https://phase.dev/changelog/improved-migrations-and-log-management/
---

[Changelog](https://phase.dev/changelog/)

2025.02.11

# Improved migrations and Audit log management

This release sees improvements to running and maintaining self-hosted instances of Phase, with an improved migration strategy for multi-container deployments and a utility to cleanup unused logs entries.

[console](https://phase.dev/changelog/tag/console/)[self-hosting](https://phase.dev/changelog/tag/self-hosting/)[maintenance](https://phase.dev/changelog/tag/maintenance/)

We've improved the way database migrations are handled in the Console, giving self-hosted users more control over how and when migrations are run. We've also added a utility to manage audit log retention.

* * *

## Improved migrations

As we continue to ship new features, updates and improvements to Phase, we often need to make updates to the database schema in the Console. These schema changes are applied via *migrations* by Django, which powers the backend of the Phase Console. So far, these migrations were automatically applied when starting or restarting an instance of the Console. This strategy works fine for basic deployments, but for more complex multi-container deployments of Phase, this approach was problematic and could potentially cause unexpected database locks, race conditions or other issues that would lead to downtime.

To address this, we've reworked how database migrations are applied. Migrations can now be handled by a dedicated migration service, ensuring schema changes are applied in a controlled and predictable manner. In multi-container deployments, `backend` and `worker` services can now be configured to wait for migrations to complete before starting, reducing the risk of conflicts. Additionally, we've introduced an environment variable, `EXTERNAL_MIGRATION`, allowing deployments to explicitly control whether migrations should be applied externally or not. This value is `false` by default to preserve backward compatibility with previous versions of Phase.

For self-hosted single-instance deployments, no changes are required — migrations will continue to work as before. However, for multi-instance deployments, setting `EXTERNAL_MIGRATION=true` ensures that migrations are handled by the dedicated service, improving stability and reliability. Here's a template for the migration service:

```yaml
migrations:
  container_name: phase-migrations
  image: phasehq/backend:latest
  command: python manage.py migrate
  env_file: .env
  environment:
    OAUTH_REDIRECT_URI: "${HTTP_PROTOCOL}${HOST}"
    ALLOWED_HOSTS: "${HOST},backend"
    ALLOWED_ORIGINS: "${HTTP_PROTOCOL}${HOST}"
    SESSION_COOKIE_DOMAIN: "${HOST}"
  depends_on:
    postgres:
      condition: service_healthy
    redis:
      condition: service_started
  networks:
    - phase-net
```

When using this migration strategy, make sure to configure your `backend` and `worker` service to wait for migrations to complete before starting by adding:

```yaml
depends_on:
  migrations:
    condition: service_completed_successfully
```

Check out the standard [docker compose template](https://github.com/phasehq/console/blob/main/docker-compose.yml) for a full example on setting this up.

For Kubernetes deployments, we've introduced managed migrations through a dedicated Kubernetes job and improved the deployment sequence with post-install/upgrade hooks. This ensures migrations are completed before the main application pods start running.

We've also improved the Redis integration with password authentication support and added readiness checks to prevent worker pod restarts.

Going forward, any releases that require migrations to be run will be marked with a `Migration required` label at the top of the release notes. Use this to determine whether or not to run migrations before starting the service. If you're using this strategy, you'll need to ensure that your workflow runs are configured to wait for migrations to complete successfully before starting.

## Audit log cleanup

Self-hosted instances of Phase retain all logs permanently by default, but workflows that frequently poll for updated secrets can quickly generate thousands of log entries as `Read` events. Over time, this can lead to a gradual degradation in the performance of your instance. To help deal with this, we've added a utility to easily purge old log entries.

This utility is run via a Django management command from either the `backend` or `worker` containers. Simply shell into your container with:

```bash
docker exec -it <container_id> /bin/sh
```

and run the `purge_app_logs` command via `manage.py`:

```bash
python manage.py purge_app_logs <organisation_name>
```

By default, this will purge logs older than 30 days for all apps in the specified Organisation. You can optionally specify the number of days to retain logs, and purge logs for a specific app if required. For example, to delete logs older than 60 days for a specific App:

```bash
python manage.py purge_app_logs <organisation_name> --retain 60 --app-id <app-id>
```

You can find complete documentation on this utility [here](https://docs.phase.dev/self-hosting/maintenance#purging-old-audit-logs).

* * *

Upgrade to [v2.37.2](https://github.com/phasehq/console/releases/tag/v2.37.2) of the Phase Console to check out these features, along with all the new features and bugfixes.

Reach out on [Slack](https://slack.phase.dev) or [GitHub](https://github.com/phasehq) for any questions or feedback on this release!

RoadmapCommunity-driven

Request a feature

We build features based on community requests and feedback. Looking for a specific feature or have a use-case in mind? Reach out to us.

[Feature request](https://github.com/phasehq/console/issues/new?template=feature_request.md)

DeploymentSelf-hosted / Cloud

Get started

## Keep your secrets

Self-host or start on fully managed Cloud in under a minute.

Self-hosted

Run Phase on your own infrastructure. Free and open source.

AI agent deployment skill

[![Docker Compose logo](https://phase.dev/assets/images/docker.svg)](https://docs.phase.dev/self-hosting/docker-compose)[![Kubernetes logo](https://phase.dev/assets/images/kubernetes.svg)](https://docs.phase.dev/self-hosting/kubernetes)[![AWS logo](https://phase.dev/assets/images/aws.svg)](https://docs.phase.dev/self-hosting/aws-eks)[![GCP logo](https://phase.dev/assets/images/gcp.svg)](https://docs.phase.dev/self-hosting/gcp)[![Azure logo](https://phase.dev/assets/images/azure.svg)](https://docs.phase.dev/self-hosting/azure)[![Railway logo](https://phase.dev/assets/images/railway.svg)](https://docs.phase.dev/self-hosting/railway)[![Raspberry Pi logo](https://phase.dev/assets/images/raspberry.svg)](https://docs.phase.dev/self-hosting/raspberrypi)

[Self-hosting guide](https://docs.phase.dev/self-hosting)

Cloud

Fully managed. From signup to your first secret in 60 seconds.

Sign up with

[Google](https://console.phase.dev/login?provider=google)[GitHub](https://console.phase.dev/login?provider=github)[GitLab](https://console.phase.dev/login?provider=gitlab)
