Rename a Docker Compose project by migrating volumes to a new project prefix.
Project description
compose-rename
Rename a Docker Compose project by migrating volumes to a new project prefix.
Run without installing
Run compose-rename without installing it:
With uvx (from PyPI):
uvx compose-rename --help
With uvx (from Git repository, for latest version, possibly ahead of PyPI):
uvx --from git+https://github.com/jonasjancarik/compose-rename@main compose-rename --help
Or with pipx:
pipx run compose-rename --help
or
pipx run --spec git+https://github.com/jonasjancarik/compose-rename@main compose-rename --help
Usage
compose-rename \
--project-dir /path/to/project \
--new-name newproj \
[--old-name oldproj] \
[--mode labels|prefix|auto] \
[--dry-run] [--skip-down] [--up-after] \
[--rename-dir | --copy] \
[--volume-name-mode auto|update|remove|keep] \
[--force-overwrite]
Requirements: Docker CLI and PyYAML.
Default behavior
By default, the tool:
- Renames the project directory to the new name (
--new-name) - Removes any explicit project name (
name:) from the compose file - Removes
COMPOSE_PROJECT_NAMEfrom the.envfile if present
This enables directory-driven naming where Docker Compose derives the project name from the directory name. Use --copy to keep the original directory intact, or set explicit volume names with --volume-name-mode.
Always test first with --dry-run to preview the migration plan before making changes.
Options
Required
| Option | Description |
|---|---|
--project-dir PATH |
Absolute/relative path to the existing Compose project directory. The tool auto-detects the compose file inside this directory unless you set --compose-file. |
--new-name NAME |
The new Compose project name (prefix for resources, e.g., volumes become newname_<volume_key>). By default, the tool removes any explicit project name from the compose file and .env file, allowing Docker Compose to use directory-driven naming. |
Optional
| Option | Default | Description |
|---|---|---|
--compose-file PATH |
Auto-detect | Explicit path to the compose file. If unset, it searches for compose.yaml, compose.yml, docker-compose.yaml, then docker-compose.yml in --project-dir. |
--old-name NAME |
Auto-detect | Override auto-detected OLD project name. If not provided, detection order is: name: in compose → .env COMPOSE_PROJECT_NAME → directory name. |
--mode MODE |
auto |
How to discover volumes to migrate. Values: auto (tries labels first, falls back to prefix for declared volumes), labels (uses com.docker.compose.project=<old> labels), prefix (matches volumes named <old>_... - use with caution as it can include non-Compose volumes). |
--volume-name-mode MODE |
auto |
How to handle explicit volume name: for non-external volumes. Values: auto (ask if explicit names exist, otherwise keep), update (replace OLD_ prefix with NEW_), remove (delete explicit names for auto-prefixing), keep (leave as-is). |
Flags
| Option | Default | Description |
|---|---|---|
--dry-run |
Disabled | Prints the full plan and performs read-only Docker queries (volume list/inspect), but makes no changes: no down, no creates, no copy, no file writes, no directory rename, no up. |
--skip-down |
Disabled | Skip docker compose down on the OLD project. Without --dry-run, migration still occurs (creates/copies/compose file write). Use with caution if the old stack is running. |
--up-after |
Disabled | After migration, bring up the NEW project with docker compose up -d. |
--rename-dir |
Enabled* | Rename the project directory to --new-name. The tool will also remove any explicit project name (name:) from the compose file and COMPOSE_PROJECT_NAME from .env if present, allowing Docker Compose to use directory-driven naming. *Default unless --copy is used. |
--copy |
Disabled | Copy the project directory to --new-name and keep the original directory untouched. Volumes are still migrated by copying data from old to new. The tool will also remove any explicit project name from the copied compose file and .env if present. |
--force-overwrite |
Disabled | If a destination volume already exists, copy into it anyway (files with the same names are overwritten). Without this, existing destination volumes are skipped. |
-V, --version |
— | Print the installed package version and exit. |
Common commands
- Plan only (no changes), discover volumes and show migration plan:
compose-rename --project-dir /path/to/project --new-name newproj --dry-run
# or with explicit mode
compose-rename --project-dir /path/to/project --new-name newproj --dry-run --mode prefix
- Basic migration (stops old stack, migrates volumes, renames directory):
compose-rename --project-dir /path/to/project --new-name newproj
- Copy the project directory (keep the original intact):
compose-rename --project-dir /path/to/project --new-name newproj --copy
- When explicit volume names are present, choose behavior non-interactively:
# Update explicit volume names (replace OLD_ prefix with NEW_)
compose-rename --project-dir /path/to/project --new-name newproj \
--volume-name-mode update
# Remove explicit volume names (let Compose auto-prefix)
compose-rename --project-dir /path/to/project --new-name newproj \
--volume-name-mode remove
- Migrate without stopping old stack first (use with caution):
compose-rename --project-dir /path/to/project --new-name newproj --skip-down
Verify volumes manually
# For prefix mode
docker volume ls | grep '^OLDPROJECT_'
# For labels mode
docker volume ls --filter label=com.docker.compose.project=OLDPROJECT
Development
Testing
The project includes a comprehensive test suite using pytest. Tests create real Docker Compose projects and volumes to verify functionality.
Running Tests
# Run all tests
uv run pytest
# Run with coverage report
uv run pytest --cov=compose_rename --cov-report=html
# Run specific test file
uv run pytest tests/test_basic.py
# Run with verbose output
uv run pytest -v
Test Coverage
The test suite covers:
- Volume discovery modes (labels, prefix, auto)
- Volume name handling modes (update, remove, keep)
- Directory operations (rename vs copy)
- Command-line flags (dry-run, skip-down, up-after, force-overwrite)
- Project name detection scenarios
- Edge cases and error handling
- Integration scenarios
See tests/README.md for more details.
Note: Tests require Docker to be installed and running.
Automated publishing (GitHub Actions)
This repository includes a workflow that publishes to PyPI whenever you push a tag like vX.Y.Z.
- Workflow file:
.github/workflows/publish.yml - It verifies the tag matches
project.versioninpyproject.toml, builds withuv build, and publishes withuv publish. - The workflow uses PyPI trusted publishing (OIDC) for authentication, which is more secure than API tokens.
Setup (one-time)
-
Configure trusted publishing on PyPI:
- Go to your PyPI project → Settings → Publish → Add a new pending publisher
- Select "GitHub Actions" as the publisher type
- Enter your repository:
username/compose-rename(or your actual GitHub username/repo) - Enter the workflow filename:
publish.yml - Enter the environment: leave blank (or specify an environment name if you use one)
- Click "Add"
-
Verify workflow permissions:
- The workflow file includes
id-token: writepermission, which is required for OIDC authentication - This is already configured in
.github/workflows/publish.yml
- The workflow file includes
Release steps:
- Bump version in
pyproject.toml - Commit and push to
main - Tag and push the tag:
git tag vX.Y.Z && git push origin vX.Y.Z
- GitHub Actions will build and publish to PyPI automatically.
Install a tagged version from Git directly (useful for testing or pinning):
uvx --from git+https://github.com/jonasjancarik/compose-rename@vX.Y.Z compose-rename --version
pipx run --spec git+https://github.com/jonasjancarik/compose-rename@vX.Y.Z compose-rename --version
Local builds on tag push (optional)
If you want fresh dist/ artifacts locally whenever you push a version tag, enable the provided git hook:
git config core.hooksPath .githooks
Now, when you push a tag like v0.1.3, the pre-push hook will run uv build and leave dist/ ready for a manual:
uv publish
Manual build helper:
./scripts/build-dist.sh
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file compose_rename-0.4.0.tar.gz.
File metadata
- Download URL: compose_rename-0.4.0.tar.gz
- Upload date:
- Size: 39.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.5.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4b172dcb7fe634e9ab8ba18bc820547347de69b0d6df372d0bca553e85d7ebe4
|
|
| MD5 |
2c04060ec7eb0caca62aeb3d279e7feb
|
|
| BLAKE2b-256 |
e27d0eef30dfdc4c110768e8da0febea9e1d01aff84670c589be35d0302ec004
|
File details
Details for the file compose_rename-0.4.0-py3-none-any.whl.
File metadata
- Download URL: compose_rename-0.4.0-py3-none-any.whl
- Upload date:
- Size: 12.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.5.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5d8ee2953a3772ca73e2f598ae3d2b49a4eb57edca7482217dc267f5b4cd4da1
|
|
| MD5 |
664695fd1dc78bd7b0d2cd4adab8dea1
|
|
| BLAKE2b-256 |
1b60cc32c5b33f4f00d0878ac50fc4a7ae1fdfec7e37a5ea38aa3221ce8ffea0
|