Copier Installation
This guide covers all installation options for Copier.
Option 1: Python/pip (Recommended)
Best for developers who already have Python installed.
# Using pipx (recommended for CLI tools)
pipx install copier
# Or using pip
pip install copier
# Verify installation
copier --version # Should be 9.17.0 or higher
Option 2: Docker
Best for users who don’t want to install Python. This script runs Copier in a container and handles path resolution automatically.
Prerequisites
-
Docker installed and running
-
Git credentials in
~/.git-credentials(for private repositories)
Setup
Save this script as copier.sh in a convenient location (e.g., ~/bin/copier.sh):
copier.sh (click to expand)
#!/bin/bash
# Wrapper script to run Copier in a container
# Usage: ./copier.sh copy <template-url-or-path> <destination> [options]
# ./copier.sh update [destination] [options]
set -e
IMAGE_NAME="ngss-copier"
IMAGE_TAG="latest"
# Build image if it doesn't exist
if ! docker image inspect "${IMAGE_NAME}:${IMAGE_TAG}" &>/dev/null; then
echo "Building Copier Docker image..."
docker build -t "${IMAGE_NAME}:${IMAGE_TAG}" - << 'DOCKERFILE'
FROM python:3.12-slim
RUN apt-get update && apt-get install -y --no-install-recommends git && rm -rf /var/lib/apt/lists/*
RUN pip install --no-cache-dir copier>=9.7.0 copier-templates-extensions>=0.3.0 pyyaml>=6.0
RUN git config --global --add safe.directory '*' && \
git config --global credential.helper 'store --file=/root/.git-credentials' && \
git config --global init.defaultBranch main
ENV GIT_TERMINAL_PROMPT=0
WORKDIR /project
ENTRYPOINT ["copier"]
CMD ["--help"]
DOCKERFILE
fi
# Parse arguments to find and resolve paths
ARGS=()
DEST_PATH=""
SRC_PATH=""
CMD=""
POSITIONAL_COUNT=0
for arg in "$@"; do
if [[ -z "$CMD" && "$arg" =~ ^(copy|update|recopy)$ ]]; then
CMD="$arg"
ARGS+=("$arg")
elif [[ "$CMD" == "copy" || "$CMD" == "recopy" ]] && [[ ! "$arg" =~ ^- ]]; then
POSITIONAL_COUNT=$((POSITIONAL_COUNT + 1))
if [[ $POSITIONAL_COUNT -eq 1 ]]; then
# First positional after copy is source (template)
if [[ "$arg" =~ ^https?:// ]] || [[ "$arg" =~ ^git@ ]] || [[ "$arg" =~ ^gh: ]]; then
# Remote URL, pass through
ARGS+=("$arg")
elif [[ -d "$arg" ]]; then
# Local directory - resolve and mount
SRC_PATH="$(cd "$arg" && pwd)"
ARGS+=("/src")
else
# Might be a git ref, pass through
ARGS+=("$arg")
fi
elif [[ $POSITIONAL_COUNT -eq 2 ]]; then
# Second positional is destination
if [[ -d "$arg" ]]; then
DEST_PATH="$(cd "$arg" && pwd)"
else
mkdir -p "$arg"
DEST_PATH="$(cd "$arg" && pwd)"
fi
ARGS+=("/dest")
else
ARGS+=("$arg")
fi
elif [[ "$CMD" == "update" ]] && [[ -z "$DEST_PATH" ]] && [[ ! "$arg" =~ ^- ]] && [[ -d "$arg" ]]; then
# For update, first path-like arg is destination
DEST_PATH="$(cd "$arg" && pwd)"
ARGS+=("/dest")
else
ARGS+=("$arg")
fi
done
# Default destination to current directory if not specified
if [[ -z "$DEST_PATH" ]]; then
DEST_PATH="$(pwd)"
if [[ "$CMD" == "update" ]]; then
ARGS+=("/dest")
fi
fi
# Build docker run args
DOCKER_ARGS=(
--rm -it
-v "${DEST_PATH}:/dest"
-v "${HOME}/.gitconfig:/root/.gitconfig:ro"
-v "${HOME}/.ssh:/root/.ssh:ro"
-e "GIT_AUTHOR_NAME=${GIT_AUTHOR_NAME:-$(git config user.name 2>/dev/null || echo '')}"
-e "GIT_AUTHOR_EMAIL=${GIT_AUTHOR_EMAIL:-$(git config user.email 2>/dev/null || echo '')}"
-e "GIT_COMMITTER_NAME=${GIT_COMMITTER_NAME:-$(git config user.name 2>/dev/null || echo '')}"
-e "GIT_COMMITTER_EMAIL=${GIT_COMMITTER_EMAIL:-$(git config user.email 2>/dev/null || echo '')}"
# Override macOS credential helper with store helper
-e "GIT_CONFIG_COUNT=1"
-e "GIT_CONFIG_KEY_0=credential.helper"
-e "GIT_CONFIG_VALUE_0=store --file=/root/.git-credentials"
)
# Mount source template if it's a local path
if [[ -n "$SRC_PATH" ]]; then
DOCKER_ARGS+=(-v "${SRC_PATH}:/src:ro")
fi
# Mount git-credentials if it exists
if [[ -f "${HOME}/.git-credentials" ]]; then
DOCKER_ARGS+=(-v "${HOME}/.git-credentials:/root/.git-credentials:ro")
fi
# Mount copier settings.yml if it exists (check platform-specific locations)
COPIER_SETTINGS=""
if [[ -f "${HOME}/Library/Application Support/copier/settings.yml" ]]; then
# macOS
COPIER_SETTINGS="${HOME}/Library/Application Support/copier/settings.yml"
elif [[ -f "${HOME}/.config/copier/settings.yml" ]]; then
# Linux
COPIER_SETTINGS="${HOME}/.config/copier/settings.yml"
fi
if [[ -n "$COPIER_SETTINGS" ]]; then
# Mount to Linux config location inside container
DOCKER_ARGS+=(-v "${COPIER_SETTINGS}:/root/.config/copier/settings.yml:ro")
fi
# Run copier
docker run "${DOCKER_ARGS[@]}" "${IMAGE_NAME}:${IMAGE_TAG}" "${ARGS[@]}"
Make it executable and add to PATH:
chmod +x ~/bin/copier.sh
export PATH="$HOME/bin:$PATH" # Add to ~/.bashrc or ~/.zshrc
Docker Usage Examples
# Copy DevOps template
copier.sh copy https://coderepo.mobilehealth.va.gov/scm/ckm/ngss-devops-template.git .
# Update existing project
copier.sh update -a .copier-answers/devops.yaml
# Use local template (for development)
copier.sh copy ../ngss-devops-template . --trust
How It Works
The script:
-
Builds the Docker image on first run (auto-rebuilds if missing)
-
Parses arguments to detect source and destination paths
-
Resolves relative paths and mounts them into the container
-
Mounts git credentials (
~/.git-credentials) and SSH keys (~/.ssh/) -
Mounts copier
settings.yml(from macOS or Linux location) for trust configuration -
Overrides macOS credential helper to use the mounted credentials
Option 3: Maven Plugin
Projects using ngss-maven-tiles 6.x+ can use Maven goals as wrappers:
mvn filegen:copier-init # Initialize all standard templates
mvn filegen:copier-init -Dcopier.template=devops # Initialize DevOps template
mvn filegen:copier-update # Update all templates
mvn filegen:copier-update -Dcopier.template=devops # Update DevOps template
| Maven goals still require Copier to be installed via pip or Docker. |
Trusting Templates
NGSS templates use Jinja extensions and tasks which require trust. You can either:
-
Add
--trustto every command, or -
Configure trusted repositories in
settings.yml(recommended)
Configuring Trusted Repositories
Create the settings file at the platform-specific location:
| Platform | Path |
|---|---|
macOS |
|
Linux |
|
Windows |
|
Add the NGSS templates to the trust list:
trust:
- https://coderepo.mobilehealth.va.gov/scm/ckm/ngss-devops-template.git
- https://coderepo.mobilehealth.va.gov/scm/ckm/ngss-backstage-template.git
Use a trailing slash to trust all templates under a path: https://coderepo.mobilehealth.va.gov/scm/ckm/
|
The file must be named settings.yml (not settings.yaml).
|
Troubleshooting
"Template requires trust" error
Either add --trust to the command or configure trusted repositories in settings.yml.
"terminal prompts disabled" Error (Docker)
Git credentials are not being found:
-
Verify
~/.git-credentialsexists -
Check the format:
https://username:token@host -
Ensure the file is readable