__ ___
/ /__ _ __ ___ __| \ \
| / _ \| '_ \ / __/ _` || |
< < (_) | |_) | (_| (_| | > >
| \___/| .__/ \___\__,_|| |
\_\ |_| /_/
open · project · code

Reusable Dev Containers for any project — without modifying the repository.
opcd is a CLI that opens any project in VS Code Dev Containers using reusable, local templates.
Define your environment once and reuse it across projects.
Typical Dev Container workflows involve:
.devcontainer/ directories between projectsopcd separates environment configuration from project code:
pip install opcd
# Open a project (auto-detects template from container history, or uses default)
opcd open ~/projects/my-app
# Open with an explicit template
opcd open ~/projects/my-app opcd
opcd template new python-dev
opcd template edit python-dev
opcd open ~/projects/my-app python-dev
opcd list -a -i
Lists containers and allows reopening projects interactively.
-v)--dry-run)opcd reads settings.json from:
~/.config/opcd/settings.json
Override the config directory:
OPCD_CONF_DIR=/custom/path opcd open ~/projects/my-app
The file is created automatically with defaults on first run.
{
"template_sources": ["~/.local/share/opcd/templates"],
"default_template": "opcd",
"template_write_dir": null
}
| Key | Description |
|---|---|
template_sources |
Ordered list of template directories searched when resolving templates. |
default_template |
Template used when opcd open is called without a template argument and no container history is found. Error if unset. |
template_write_dir |
Directory where opcd template new writes new templates. null (default) uses the XDG data home: ~/.local/share/opcd/templates. Overridden per-invocation by --path. |
~/.local/share/opcd/templates/
Configure additional paths via template_sources in settings.json (see Configuration).
Inject files from the host into the container at startup.
{
"customizations": {
"opcd": {
"cp": [
{
"source": "${localEnv:HOME}/.config/myapp",
"target": "/home/vscode/.config/myapp"
}
]
}
}
}
| Field | Required | Description |
|---|---|---|
source |
Yes | Host path |
target |
Yes | Container path |
override |
No | Skip if target exists (default: false) |
owner |
No | Requires group |
group |
No | Requires owner |
permissions |
No | chmod applied recursively |
${localEnv:VAR}.devcontainer/Use /. suffix:
{
"source": "${localEnv:HOME}/.config/myapp/.",
"target": "/home/vscode/.config/myapp/"
}
Copies directory contents instead of the directory itself.
target/ copies into the directory/ copies as a file or directoryoverride=false skips existing filesFull reference for all opcd commands and flags.
-v, --verbose Enable debug output
--version Show version and exit
opcd open <path> [template] [options]
Open a project in VS Code using a devcontainer template.
<path> — Project directory (must exist)[template] (optional) — Template name, path to a devcontainer.json, or path to a directory containing it. Paths must start with ./, ../, /, or ~/. If omitted, opcd resolves in this order:
default_template from settings.json (error if not set)| Option | Default | Description |
|---|---|---|
--dry-run |
— | Print resolved configuration and actions without executing |
--container-folder <path> |
resolved from devcontainer config | Container mount path |
--timeout <seconds> |
300 |
Time to wait for container startup |
opcd list [-a] [-i]
List dev containers.
| Flag | Description |
|---|---|
-a, --all |
Include stopped containers |
-i, --interactive |
Prompt to reopen a listed container |
Interactive mode prompts Open [1-N]: — selecting a number reopens the project in VS Code.
opcd prune [path] [options]
Remove stopped dev containers. Either [path] or --all-projects is required.
[path] (optional) — Limit pruning to containers for this project directory.| Option | Description |
|---|---|
--all-projects |
Prune stopped containers across all projects |
--include-recent |
Also prune the most recently used container (skipped by default) |
opcd template <subcommand>
Manage dev container templates.
opcd template new <name> [base] [options]
Create a new template by copying a base template.
| Argument | Default | Description |
|---|---|---|
[base] |
opcd |
Template to copy from |
| Option | Description |
|---|---|
--edit |
Launch the new template as a Dev Container in VS Code after creation |
--path <dir> |
Write the new template into <dir> instead of the configured write target |
opcd template edit <template>
Open a template directory in VS Code for editing.
opcd template list [--long]
List available templates.
| Option | Description |
|---|---|
--long |
Show description and full path for each template |
opcd template default [name]
Get or set the default template.
name: prints the current default.name: sets default_template in settings.json.opcd template source <subcommand>
Manage template search paths stored in settings.json.
opcd template source list
Print all configured template search paths, one per line.
opcd template source add <path>
Append <path> to template_sources in settings.json. Prints a notice and exits cleanly if already present.
opcd template source remove <path>
Remove <path> from template_sources in settings.json. Exits with an error if not found.
opcd completion bash
opcd completion zsh
opcd completion fish
Print the shell completion setup command for the given shell.
Add to your shell rc file for persistent completion:
# bash (~/.bashrc)
eval "$(opcd completion bash)"
# zsh (~/.zshrc)
eval "$(opcd completion zsh)"
# fish (~/.config/fish/config.fish)
eval (opcd completion fish)
Ask questions, report bugs, or request features in Issues.
PRs welcome. Open an issue first for significant changes.
Run tox (or pytest for a single-interpreter run) before submitting.
MIT © Nasser Alansari (dacrystal)
See LICENSE.