# index.html.md

<a id="rest-api"></a>

# REST API


            <p class="youtube_link">
              <a href="https://www.youtube.com/watch?v=YvGbvspXObI" target="_blank">
                <span title="LXD REST API" class="play_icon">▶</span>
                <span title="LXD REST API">Watch on YouTube</span>
              </a>
            </p>
        
All communication between LXD and its clients happens using a RESTful API over HTTP.
This API is encapsulated over either TLS (for remote operations) or a Unix socket (for local operations).

See [Remote API authentication](authentication.md#authentication) for information about how to access the API remotely.

## API versioning

The list of supported major API versions can be retrieved using `GET /`.

The reason for a major API bump is if the API breaks backward compatibility.

Feature additions done without breaking backward compatibility only
result in addition to `api_extensions` which can be used by the client
to check if a given feature is supported by the server.

## Return values

There are three standard return types:

* Standard return value
* Background operation
* Error

### Standard return value

For a standard synchronous operation, the following JSON object is returned:

```js
{
    "type": "sync",
    "status": "Success",
    "status_code": 200,
    "metadata": {}                          // Extra resource/action specific metadata
}
```

HTTP code must be 200.

### Background operation

When a request results in a background operation, the HTTP code is set to 202 (Accepted)
and the Location HTTP header is set to the operation URL.

The body is a JSON object with the following structure:

```js
{
    "type": "async",
    "status": "OK",
    "status_code": 100,
    "operation": "/1.0/instances/<id>",                     // URL to the background operation
    "metadata": {}                                          // Operation metadata (see below)
}
```

The operation metadata structure looks like:

```js
{
    "id": "a40f5541-5e98-454f-b3b6-8a51ef5dbd3c",           // UUID of the operation
    "class": "websocket",                                   // Class of the operation (task, websocket or token)
    "created_at": "2015-11-17T22:32:02.226176091-05:00",    // When the operation was created
    "updated_at": "2015-11-17T22:32:02.226176091-05:00",    // Last time the operation was updated
    "status": "Running",                                    // String version of the operation's status
    "status_code": 103,                                     // Integer version of the operation's status (use this rather than status)
    "resources": {                                          // Dictionary of resource types (container, snapshots, images) and affected resources
      "containers": [
        "/1.0/instances/test"
      ]
    },
    "metadata": {                                           // Metadata specific to the operation in question (in this case, exec)
      "fds": {
        "0": "2a4a97af81529f6608dca31f03a7b7e47acc0b8dc6514496eb25e325f9e4fa6a",
        "control": "5b64c661ef313b423b5317ba9cb6410e40b705806c28255f601c0ef603f079a7"
      }
    },
    "may_cancel": false,                                    // Whether the operation can be canceled (DELETE over REST)
    "err": ""                                               // The error string should the operation have failed
}
```

The body is mostly provided as a user friendly way of seeing what’s
going on without having to pull the target operation, all information in
the body can also be retrieved from the background operation URL.

### Error

There are various situations in which something may immediately go
wrong, in those cases, the following return value is used:

```js
{
    "type": "error",
    "error": "Failure",
    "error_code": 400,
    "metadata": {}                      // More details about the error
}
```

HTTP code must be one of of 400, 401, 403, 404, 409, 412 or 500.

## Status codes

The LXD REST API often has to return status information, be that the
reason for an error, the current state of an operation or the state of
the various resources it exports.

To make it simple to debug, all of those are always doubled. There is a
numeric representation of the state which is guaranteed never to change
and can be relied on by API clients. Then there is a text version meant
to make it easier for people manually using the API to figure out what’s
happening.

In most cases, those will be called status and `status_code`, the former
being the user-friendly string representation and the latter the fixed
numeric value.

The codes are always 3 digits, with the following ranges:

* 100 to 199: resource state (started, stopped, ready, …)
* 200 to 399: positive action result
* 400 to 599: negative action result
* 600 to 999: future use

### List of current status codes

|   Code | Meaning           |
|--------|-------------------|
|    100 | Operation created |
|    101 | Started           |
|    102 | Stopped           |
|    103 | Running           |
|    104 | Canceling         |
|    105 | Pending           |
|    106 | Starting          |
|    107 | Stopping          |
|    108 | Aborting          |
|    109 | Freezing          |
|    110 | Frozen            |
|    111 | Thawed            |
|    112 | Error             |
|    113 | Ready             |
|    200 | Success           |
|    400 | Failure           |
|    401 | Canceled          |

<a id="rest-api-recursion"></a>

## Recursion

To optimize queries of large lists, recursion is implemented for collections.
A `recursion` argument can be passed to a GET query against a collection.

The default value is 0 which means that collection member URLs are
returned. Setting it to 1 will have those URLs be replaced by the object
they point to (typically another JSON object).

Recursion is implemented by simply replacing any pointer to a job (URL)
by the object itself.

<a id="rest-api-filtering"></a>

## Filtering

To filter your results on certain values, filter is implemented for collections.
A `filter` argument can be passed to a GET query against a collection.

Filtering is available for the instance, image and storage volume endpoints.

There is no default value for filter which means that all results found will
be returned. The following is the language used for the filter argument:

```none
?filter=field_name eq desired_field_assignment
```

The language follows the OData conventions for structuring REST API filtering
logic. Logical operators are also supported for filtering: not (`not`), equals (`eq`),
not equals (`ne`), and (`and`), or (`or`). Filters are evaluated with left associativity.
Values with spaces can be surrounded with quotes. Nesting filtering is also supported.
For instance, to filter on a field in a configuration you would pass:

```none
?filter=config.field_name eq desired_field_assignment
```

For filtering on device attributes you would pass:

```none
?filter=devices.device_name.field_name eq desired_field_assignment
```

Here are a few GET query examples of the different filtering methods mentioned above:

```none
containers?filter=name eq "my container" and status eq Running

containers?filter=config.image.os eq ubuntu or devices.eth0.nictype eq bridged

images?filter=Properties.os eq Centos and not UpdateSource.Protocol eq simplestreams
```

## Asynchronous operations

Any operation which may take more than a second to be done must be done
in the background, returning a background operation ID to the client.

The client will then be able to either poll for a status update or wait
for a notification using the long-poll API.

## Notifications

A WebSocket-based API is available for notifications, different notification
types exist to limit the traffic going to the client.

It’s recommended that the client always subscribes to the operations
notification type before triggering remote operations so that it doesn’t
have to then poll for their status.

<a id="rest-api-put-vs-patch"></a>

## PUT vs PATCH

The LXD API supports both PUT and PATCH to modify existing objects:

<a id="rest-api-put"></a>

### The PUT method

PUT *replaces* the entire object with a new definition. Since it overwrites the existing state, it’s often called after retrieving and recording the current object state through GET.

To avoid race conditions, the ETag header should be read from the GET response and sent as If-Match for the PUT request. This will cause LXD to fail the request if the object was modified between GET and PUT.

<a id="rest-api-patch"></a>

### The PATCH method

PATCH can be used to modify a single field inside an object by only specifying the property that you want to change. To unset a key, setting it to empty will usually do the trick, but there are cases where PATCH won’t work and PUT needs to be used instead.

## Instances

The documentation shows paths such as `/1.0/instances/...`, which is the canonical API path since LXD 3.19.
To filter by instance type, use the `instance-type` query parameter (e.g. `/1.0/instances?instance-type=container` or `/1.0/instances?instance-type=virtual-machine`).

## API structure

LXD has an auto-generated [Swagger](https://swagger.io/) specification describing its API endpoints.
The YAML version of this API specification can be found in [`rest-api.yaml`](https://github.com/canonical/lxd/blob/main/doc/rest-api.yaml).
See [Main API specification](api.md) for a convenient web rendering of it.


# index.html.md

<a id="daemon-behavior"></a>

# Daemon behavior

This specification covers some of the [LXD daemon](explanation/lxd_lxc.md#lxd-daemon)’s behavior.

## Startup

On every start, LXD checks that its directory structure exists. If it
doesn’t, it creates the required directories, generates a key pair and
initializes the database.

Once the daemon is ready for work, LXD scans the instances table
for any instance for which the stored power state differs from the
current one. If an instance’s power state was recorded as running and the
instance isn’t running, LXD starts it.

## Signal handling

### `SIGINT`, `SIGQUIT`, `SIGTERM`

For those signals, LXD assumes that it’s being temporarily stopped and
will be restarted at a later time to continue handling the instances.

The instances will keep running and LXD will close all connections and
exit cleanly.

### `SIGPWR`

Indicates to LXD that the host is going down.

LXD will attempt a clean shutdown of all the instances. After 30 seconds, it
kills any remaining instance.

The instance `power_state` in the instances table is kept as it was so
that LXD can restore the instances as they were after the host is done rebooting.

### `SIGUSR1`

Write a memory profile dump to the file specified with `--memprofile`.


# index.html.md

<a id="howto-contribute"></a>

# How to contribute to LXD

<!-- Include content from [../CONTRIBUTING.md](../CONTRIBUTING.md) -->

The LXD team welcomes contributions through pull requests, issue reports, and discussions.

- Contribute to the code or documentation, report bugs, or request features in the [GitHub repository](https://github.com/canonical/lxd)
- Ask questions or join discussions in the [LXD forum](https://discourse.ubuntu.com/c/project/lxd/126).

Review the following guidelines before contributing to the project.

## Code of Conduct

All contributors must adhere to the [Ubuntu Code of Conduct](https://ubuntu.com/community/docs/ethos/code-of-conduct).

## License and copyright

All contributors must sign the [Canonical contributor license agreement (CCLA)](https://canonical.com/legal/contributors), which grants Canonical permission to use the contributions.

- You retain copyright ownership of your contributions (no copyright assignment).
- By default, contributions are licensed under the project’s **AGPL-3.0-only** license.
- Exceptions:
  - Canonical may import code under AGPL-3.0-only compatible licenses, such as Apache-2.0.
  - Such code retains its original license and is marked as such in commit messages or file headers.
  - Some files and commits are licensed under Apache-2.0 rather than AGPL-3.0-only. These are indicated in their package-level COPYING file, file header, or commit message.

## Pull requests

Submit pull requests on GitHub at: [`https://github.com/canonical/lxd`](https://github.com/canonical/lxd).

All pull requests undergo review and must be approved before being merged into the main branch.

### Commit structure

See [`COMMITS.md`](https://github.com/canonical/lxd/blob/main/COMMITS.md) for the full commit prefix table and signing requirements.

Depending on complexity, large changes might be further split into smaller, logical commits. This commit structure facilitates the review process and simplifies backporting fixes to stable branches.

### Developer Certificate of Origin sign-off

To ensure transparency and accountability in contributions to this project, all contributors must include a **Signed-off-by** line in their commits in accordance with DCO 1.1:

```text
Developer Certificate of Origin
Version 1.1

Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
660 York Street, Suite 102,
San Francisco, CA 94110 USA

Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.

Developer's Certificate of Origin 1.1

By making a contribution to this project, I certify that:

(a) The contribution was created in whole or in part by me and I
    have the right to submit it under the open source license
    indicated in the file; or

(b) The contribution is based upon previous work that, to the best
    of my knowledge, is covered under an appropriate open source
    license and I have the right under that license to submit that
    work with modifications, whether created in whole or in part
    by me, under the same open source license (unless I am
    permitted to submit under a different license), as indicated
    in the file; or

(c) The contribution was provided directly to me by some other
    person who certified (a), (b) or (c) and I have not modified
    it.

(d) I understand and agree that this project and the contribution
    are public and that a record of the contribution (including all
    personal information I submit with it, including my sign-off) is
    maintained indefinitely and may be redistributed consistent with
    this project or the open source license(s) involved.
```

#### Including a Signed-off-by line in your commits

Every commit must include a **Signed-off-by** line, even when part of a larger set of contributions. To do this, use the `-s` flag when committing:

```sh
git commit -s -m "Your commit message"
```

This automatically adds the following to your commit message:

```text
Signed-off-by: Your Name <your.email@example.com>
```

By including this line, you acknowledge your agreement to the DCO 1.1 for that specific contribution.

- Use a valid name and email address—anonymous contributions are not accepted.
- Ensure your email matches the one associated with your GitHub account.

If you forgot to sign off on one or more commits and the DCO check fails, you can retroactively add the sign-off to all commits on your branch with:

```sh
git rebase --signoff main
git push --force-with-lease
```

### Commit signature verification

In addition to the sign-off requirement, contributors must also cryptographically sign their commits to verify authenticity. See: [GitHub’s documentation on commit signature verification](https://docs.github.com/en/authentication/managing-commit-signature-verification).

### Make-generated files

Some changes require regenerating certain files using Makefile commands.

After you run any of the commands below, you’ll be prompted whether to commit the changes. If you respond `Y`, only the re-generated files are committed—any other staged files are ignored.

#### Formatting

If you modify any Go source files, format them:

```sh
make update-fmt
```

#### API updates

If you modify the LXD API (`shared/api`), regenerate and commit the Swagger YAML file (`doc/rest-api.yaml`) used for API reference documentation:

```sh
make update-api
```

#### Configuration options updates

If you add or update configuration options, regenerate and commit the documentation metadata files (`lxd/metadata/configuration.json` and `doc/metadata.txt`):

```sh
make update-metadata
```

#### Development environment setup

Several pieces of software are needed in order to build and test LXD. Here is an easy way to create a virtual-machine to use as a development environment. LXD itself is needed to power that virtual-machine so install it first: [How to install LXD](installing.md#installing).

Once LXD is installed and [initialized](howto/initialize.md#initialize), a special profile (`lxd-test`) needs to be loaded. The profile includes a `lxd-git` device (see [Types of disk devices](reference/devices_disk.md#devices-disk-types) for details) that will share LXD’s git repository with the virtual-machine. Since this path is specific to your environment you need to adjust it when loading the profile:

```sh
# this needs to be run from inside the git repository
GIT_ROOT="$(git rev-parse --show-toplevel)"
# create or edit the profile based on the provided template
lxc profile list | grep -qwF lxd-test || lxc profile create lxd-test
sed "s|@@PATH_TO_LXD_GIT@@|${GIT_ROOT}|" "${GIT_ROOT}/doc/lxd-test.yaml" | lxc profile edit lxd-test
```

The `lxd-test` profile assigns CPU and memory limits similar to those available in free GitHub Action runners. Those can be adapted to the specifications of a more modest physical machine:

```sh
lxc profile set lxd-test limits.cpu=2
lxc profile set lxd-test limits.memory=4GiB
lxc profile device set lxd-test root size=8GiB
```

This profile can then be used to launch an Ubuntu Noble VM and start using it:

```sh
lxc launch ubuntu-minimal-daily:24.04 v1 --vm -p lxd-test
sleep 30
# this may take a while as many packages need to be installed
lxc exec v1 -- cloud-init status --wait --long
```

If testing with the `ceph` storage backend, it is also possible to attach an ephemeral disk to be assigned to MicroCeph automatically during tests:

```sh
# The volume name must **end** with `lxd-ephemeral` to be considered for auto-assignment to MicroCeph
lxc storage volume create default v1-lxd-ephemeral --type=block size=32GiB
lxc storage volume attach default v1-lxd-ephemeral v1
```

Then it is possible to build all the dependencies, LXD binaries and even run tests either automatically or manually:

```sh
# start a root shell in the VM
lxc exec v1 -- bash

# go into the git repo
cd lxd

# build deps and LXD binaries
make deps && make

# get an interactive test shell session with all the needed environment variables to use and test LXD
make test-shell

# run the `exec` and `query` tests
./main.sh exec
./main.sh query

# or manually interact with LXD, for example:
lxc launch ubuntu:24.04 u1
lxc exec u1 -- hostname
lxc delete --force u1

# for a barebones test instance with just busybox (note: no IP automatically configured)
./deps/import-busybox --alias testimage
lxc launch testimage c1
```

At this point you might want to learn more on [How to debug LXD](debugging.md).

#### Copilot instructions file updates

The LXD repository includes a [Copilot instructions file](https://github.com/canonical/lxd/blob/main/.github/copilot-instructions.md) to improve Copilot Code Review responses. When updating this file, include concise context about LXD’s architecture, coding standards, and best practices. Clear guidance helps Copilot produce accurate, relevant suggestions. For details and tips, see the documentation on [GitHub Copilot repository custom instructions](https://docs.github.com/en/copilot/how-tos/copilot-on-github/customize-copilot/add-custom-instructions/add-repository-instructions).

## Contribute to the code

Follow the steps below to set up your development environment and start working on new LXD features.

### Install LXD from source

To build the dependencies, follow the instructions in [Install LXD from source](installing.md#id1).

### Add your fork as a remote

After setting up your build environment, add your GitHub fork as a remote and fetch the latest updates:

```none
git remote add myfork git@github.com:<your_username>/lxd.git
git remote update
```

Then switch to the main branch of your fork:

```none
git switch myfork/main
```

### Build LXD

Now you can build your fork of the project by running:

```none
make
```

Before making changes, create a new branch on your fork:

```bash
git switch -c <name_of_your_new_branch>
```

Set up tracking for the new branch to make future pushes easier:

```bash
git push -u myfork <name_of_your_new_branch>
```

### Important notes for new LXD contributors

- Persistent data is stored in the `LXD_DIR` directory, which is created by running `lxd init`.
  - By default, `LXD_DIR` is located at `/var/lib/lxd` (for non-snap installations) or `/var/snap/lxd/common/lxd` (for snap users).
  - To prevent version conflicts, consider setting a separate `LXD_DIR` for your development fork.
- Binaries compiled from your source are placed in `$(go env GOPATH)/bin` by default.
  - When testing, explicitly invoke these binaries instead of the global `lxd` you might have installed.
  - For convenience, you can create an alias in your `~/.bashrc` to call these binaries with the appropriate flags.
- If you have a `systemd` service running LXD from a previous installation, consider disabling it to prevent version conflicts with your development build.

## Contribute to the documentation

We strive to make LXD as easy and straightforward to use as possible. To achieve this, our documentation aims to provide the information users need, cover all common use cases, and answer typical questions.

You can contribute to the documentation in several ways. We appreciate your help!

### Ways to contribute

Document new features or improvements you contribute to the code.
: - Submit documentation updates in pull requests alongside your code changes. We will review and merge them together with the code.

Clarify concepts or common questions based on your own experience.
: - Submit a pull request with your documentation improvements.

Report documentation issues by opening an issue on [GitHub](https://github.com/canonical/lxd/issues).
: - We will evaluate and update the documentation as needed.

Ask questions or suggest improvements in the [LXD forum](https://discourse.ubuntu.com/c/project/lxd/126).
: - We monitor discussions and update the documentation when necessary.

If you contribute images to `doc/images`:

- Use **SVG** or **PNG** formats.
- Optimize PNG images for smaller file size using a tool like [TinyPNG](https://tinypng.com/) (web-based), [OptiPNG](https://optipng.sourceforge.net/) (CLI-based), or similar.

<!-- Include content from [README.md](README.md) -->

### Documentation framework

LXD’s documentation is built with [Sphinx](https://www.sphinx-doc.org) and hosted on [Read the Docs](https://about.readthedocs.com/).

It is written in [Markdown](https://commonmark.org/) with [MyST](https://myst-parser.readthedocs.io/) extensions.
For syntax help and guidelines, see the [MyST syntax guide](https://documentation.ubuntu.com/sphinx-stack/latest/reference/myst-syntax/) in the [Sphinx Stack documentation](https://documentation.ubuntu.com/sphinx-stack/latest/).

The documentation structure follows the [Diátaxis](https://diataxis.fr/) framework.

### Build the documentation

To build the documentation, run `make doc` from the root directory of the repository.
This command installs the required tools and renders the output to the `doc/_build/` directory.
To update the documentation for changed files only (without re-installing the tools), run `make doc-incremental`.

Before opening a pull request, make sure that the documentation builds without any warnings (warnings are treated as errors).
To preview the documentation locally, run `make doc-serve` and go to [`http://localhost:8000`](http://localhost:8000) to view the rendered documentation.

When you open a pull request, a preview of the documentation hosted by Read the Docs is built automatically.
To see this, view the details for the `docs/readthedocs.com:canonical-lxd` check on the pull request. Others can also use this preview to validate your changes.

### Automatic documentation checks

GitHub runs automatic checks on the documentation to verify the spelling, the validity of links, correct formatting of the Markdown files, and the use of inclusive language.

You can (and should!) run these tests locally before pushing your changes:

- Check the spelling: `make doc-spellcheck` (or `make doc-spelling` to first build the documentation and then check it)
- Check the validity of links: `make doc-linkcheck`
- Check the Markdown formatting: `make doc-lint`
- Check for inclusive language: `make doc-woke`

### Document instructions (how-to guides)

LXD can be used with different clients, primarily the command-line interface (CLI), API, and UI.
The documentation contains instructions for all of these, so when adding or updating how-to guides, remember to update the documentation for all clients.

#### Using tabs for client-specific information

When instructions differ between clients, use tabs to organize them:

```default
````{tabs}
```{group-tab} CLI
[...]
```
```{group-tab} API
[...]
```
```{group-tab} UI
[...]
```
````
```

#### Guidelines for writing instructions

CLI instructions
: - Link to the relevant `lxc` command reference. Example: `[`lxc init`](lxc_init.md)`
  - You don’t need to document all available command flags, but mention any that are especially relevant.
  - Examples are very helpful, so add a few if it makes sense.

API instructions
: - When possible, use [`lxc query`](reference/manpages/lxc/query.md#lxc-query-md) to demonstrate API calls.
    For complex calls, use `curl` or other widely available tools.
  - In the request data, include all required fields but keep it minimal—there’s no need to list every possible field.
  - Link to the API call reference. Example: `[`POST /1.0/instances`](swagger:/instances/instances_post)`

UI instructions
: - Use screenshots sparingly—they are difficult to keep up to date.
  - When referring to labels in the UI, use the `{guilabel}` role.
    Example: `To create an instance, go to the {guilabel}`Instances` section and click {guilabel}`Create instance`.`

### Document configuration options

Configuration options are documented by comments in the Go code. These comments are extracted automatically.

#### Adding or modifying configuration options

- Look for comments that start with `lxdmeta:generate` in the code.
- When adding or modifying a configuration option, include the corresponding documentation comment.
- Refer to the [`lxd-metadata` README file](https://github.com/canonical/lxd/blob/main/lxd/lxd-metadata/README.md) for formatting guidelines.
- When you add or modify configuration options, you must re-generate `doc/metadata.txt` and `lxd/metadata/configuration.json`. See the [Configuration options updates]() section for instructions.

#### Including configuration options in documentation

The documentation pulls sections from `doc/metadata.txt` to display a group of configuration options.
For example, to include the core server options, use:

```default
% Include content from [metadata.txt](metadata.txt)
```{include} metadata.txt
    :start-after: <!-- config group server-core start -->
    :end-before: <!-- config group server-core end -->
```
```

#### When to update documentation files

- If you add a new option to an existing group, no changes to the documentation files are needed, aside from [re-generating `metadata.txt`](). The option will be included automatically.
- If you define a new group, to add it to the documentation, you must add an `{include}` directive to the appropriate Markdown file in `doc/`.


# index.html.md

<a id="container-runtime-environment"></a>

# Container runtime environment

LXD attempts to present a consistent environment to all containers it runs.

The exact environment will differ slightly based on kernel features and user configuration, but otherwise, it is identical for all containers.

## File system

LXD assumes that any image it uses to create a new container comes with at least the following root-level directories:

- `/dev` (empty)
- `/proc` (empty)
- `/sbin/init` (executable)
- `/sys` (empty)

## Devices

LXD containers have a minimal and ephemeral `/dev` based on a `tmpfs` file system.
Since this is a `tmpfs` and not a `devtmpfs` file system, device nodes appear only if manually created.

The following standard set of device nodes is set up automatically:

- `/dev/console`
- `/dev/fd`
- `/dev/full`
- `/dev/log`
- `/dev/null`
- `/dev/ptmx`
- `/dev/random`
- `/dev/stdin`
- `/dev/stderr`
- `/dev/stdout`
- `/dev/tty`
- `/dev/urandom`
- `/dev/zero`

In addition to the standard set of devices, the following devices are also set up for convenience:

- `/dev/fuse`
- `/dev/net/tun`
- `/dev/mqueue`

### Network

LXD containers may have any number of network devices attached to them.
The naming for those (unless overridden by the user) is `ethX`, where `X` is an incrementing number.

### Container-to-host communication

LXD sets up a socket at `/dev/lxd/sock` that the root user in the container can use to communicate with LXD on the host.

See [Communication between instance and host](dev-lxd.md) for the API documentation.

## Mounts

The following mounts are set up by default:

- `/proc` (<spellexception>proc</spellexception>)
- `/sys` (`sysfs`)
- `/sys/fs/cgroup/*` (`cgroupfs`) (only on kernels that lack cgroup namespace support)

If they are present on the host, the following paths will also automatically be mounted:

- `/proc/sys/fs/binfmt_misc` (only on kernels that lack `binfmt_misc` namespace support)
- `/sys/firmware/efi/efivars`
- `/sys/fs/fuse/connections`
- `/sys/fs/pstore`
- `/sys/kernel/debug`
- `/sys/kernel/security`

The reason for passing all of those paths is that legacy init systems require them to be mounted, or be mountable, inside the container.

The majority of those paths will not be writable (or even readable) from inside an unprivileged container.
In privileged containers, they will be blocked by the AppArmor policy.

### LXCFS

If LXCFS is present on the host, it is automatically set up for the container.

This normally results in a number of `/proc` files being overridden through bind-mounts.
On older kernels, a virtual version of `/sys/fs/cgroup` might also be set up by LXCFS.

<a id="container-runtime-environment-binfmt-misc"></a>

### `binfmt_misc`

The `binfmt_misc` kernel feature allows the system to run binaries for foreign architectures by registering interpreters for different binary types. See the [kernel documentation](https://docs.kernel.org/admin-guide/binfmt-misc.html) for more details.

On kernels that lack `binfmt_misc` namespace support, LXD automatically bind-mounts `/proc/sys/fs/binfmt_misc` from the host into the container. This allows containers to use the host’s registered binary types.

On kernels with `binfmt_misc` namespace support, unprivileged containers can mount their own isolated `binfmt_misc`. To enable `binfmt_misc` in an unprivileged container, run:

```bash
mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc
```

The container can now register its own binary types without affecting the host or other containers. This is useful for running foreign architecture binaries within the container.

## PID1

LXD spawns whatever is located at `/sbin/init` as the initial process of the container (PID 1).
This binary should act as a proper init system, including handling re-parented processes.

LXD’s communication with PID1 in the container is limited to two signals:

- `SIGINT` to trigger a reboot of the container
- `SIGPWR` (or alternatively `SIGRTMIN`+3) to trigger a clean shutdown of the container

The initial environment of PID1 is blank except for `container=lxc`, which can be used by the init system to detect the runtime.

All file descriptors above the default three are closed prior to PID1 being spawned.

## Related topics

How-to guides:

- [Instances](instances.md#instances)

Explanation:

- [Instance types in LXD](explanation/instances.md#expl-instances)


# index.html.md

<a id="cloud-init"></a>

# How to use `cloud-init`


            <p class="youtube_link">
              <a href="https://www.youtube.com/watch?v=8OCG15TAldI" target="_blank">
                <span title="LXD instance configuration with cloud-init" class="play_icon">▶</span>
                <span title="LXD instance configuration with cloud-init">Watch on YouTube</span>
              </a>
            </p>
        
[`cloud-init`](https://cloud-init.io/) is a tool for automatically initializing and customizing an instance of a Linux distribution.

By adding `cloud-init` configuration to your instance, you can instruct `cloud-init` to execute specific actions at the first start of an instance.
Possible actions include, for example:

* Updating and installing packages
* Applying certain configurations
* Adding users
* Enabling services
* Running commands or scripts
* Automatically growing the file system of a VM to the size (quota) of the disk

See the [Cloud-init documentation](https://docs.cloud-init.io/en/latest/index.html#index) for detailed information.

#### NOTE
The `cloud-init` actions are run only once on the first start of the instance.
Rebooting the instance does not re-trigger the actions.

<a id="cloud-init-support"></a>

## `cloud-init` support in images

To use `cloud-init`, you must base your instance on an image that has `cloud-init` installed:

* All images from the `ubuntu` and `ubuntu-daily` [image servers](reference/remote_image_servers.md#remote-image-servers) have `cloud-init` support.
  However, images for Ubuntu releases prior to 20.04 LTS require special handling to integrate properly with `cloud-init`, so that `lxc exec` works correctly with virtual machines that use those images. Refer to [VM `cloud-init`](reference/devices_disk.md#vm-cloud-init-config).
* Images from the [`images` remote](https://images.lxd.canonical.com/) have `cloud-init`-enabled variants, which are usually bigger in size than the default variant.
  The cloud variants use the `/cloud` suffix, for example, `images:alpine/edge/cloud`.

## Configuration options

LXD supports two different sets of configuration options for configuring `cloud-init`: `cloud-init.*` and `user.*`.
Which of these sets you must use depends on the `cloud-init` support in the image that you use.
As a rule of thumb, newer images support the `cloud-init.*` configuration options, while older images support `user.*`.
However, there might be exceptions to that rule.

The following configuration options are supported:

* `cloud-init.vendor-data` or `user.vendor-data` (see [Vendor-data](https://docs.cloud-init.io/en/latest/explanation/vendordata.html#vendor-data))
* `cloud-init.user-data` or `user.user-data` (see [User-data formats](https://docs.cloud-init.io/en/latest/explanation/format/index.html#user-data-formats))
* `cloud-init.network-config` or `user.network-config` (see [Network configuration](https://docs.cloud-init.io/en/latest/reference/network-config.html#network-config))

For more information about the configuration options, see the [`cloud-init` instance options](reference/instance_options.md#instance-options-cloud-init), and the documentation for the [LXD data source](https://docs.cloud-init.io/en/latest/reference/datasources/lxd.html#datasource-lxd) in the `cloud-init` documentation.

#### NOTE
Ubuntu 20.04 and earlier have recent versions of the `cloud-init` package but support for the modern `cloud-init.*` configuration options is disabled in those series. As such, when using such old instances, remember to use the `user.*` configuration options instead.

### Vendor data and user data

Both `vendor-data` and `user-data` are used to provide [cloud configuration data](https://docs.cloud-init.io/en/latest/explanation/format/cloud-config.html#user-data-formats-cloud-config) to `cloud-init`.

The main idea is that `vendor-data` is used for the general default configuration, while `user-data` is used for instance-specific configuration.
This means that you should specify `vendor-data` in a profile and `user-data` in the instance configuration.
LXD does not enforce this method, but allows using both `vendor-data` and `user-data` in profiles and in the instance configuration.

If both `vendor-data` and `user-data` are supplied for an instance, `cloud-init` merges the two configurations.
However, if you use the same keys in both configurations, merging might not be possible.
In this case, configure how `cloud-init` should merge the provided data.
See [Merging cloud-config](https://docs.cloud-init.io/en/latest/reference/merging.html#merging-user-data) for instructions.

## How to configure `cloud-init`

To configure `cloud-init` for an instance, add the corresponding configuration options to a [profile](profiles.md#profiles) that the instance uses or directly to the [instance configuration](howto/instances_configure.md#instances-configure).

When configuring `cloud-init` directly for an instance, keep in mind that `cloud-init` runs only on instance start.
This means any changes to `cloud-init` configuration only take effect after the next instance start. To ensure `cloud-init` configurations are applied on every boot, LXD changes the instance ID whenever relevant `cloud-init` configuration keys are modified. This triggers `cloud-init` to fetch and apply the updated data from LXD as if it were the instance’s first boot. For more information, see the `cloud-init` docs regarding [First boot determination](https://docs.cloud-init.io/en/latest/explanation/first_boot.html#first-boot-determination).

To add your configuration:

CLI

Write the configuration to a file and pass that file to the `lxc config` command.
For example, create `cloud-init.yml` with the following content:

```none
#cloud-config
package_upgrade: true
packages:
  - package1
  - package2
```

Then run the following command:

```none
lxc config set <instance_name> cloud-init.user-data - < cloud-init.yml
```

API

Provide the `cloud-init` configuration as a string with escaped newline characters.

For example:

```none
lxc query --request PATCH /1.0/instances/<instance_name> --data '{
  "config": {
    "cloud-init.user-data": "#cloud-config\npackage_upgrade: true\npackages:\n  - package1\n  - package2"
  }
}'
```

Alternatively, to avoid mistakes, write the configuration to a file and include that in your request.
For example, create `cloud-init.txt` with the following content:

```none
#cloud-config
package_upgrade: true
packages:
  - package1
  - package2
```

Then send the following request:

```none
lxc query --request PATCH /1.0/instances/<instance_name> --data '{
"config": {
  "cloud-init.user-data": "'"$(awk -v ORS='\\n' '1' cloud-init.txt)"'"
  }
}'
```

UI

Go to the Configuration tab of the instance detail page and select Advanced > Cloud init.
Then click Edit instance and override the configuration for one or more of the `cloud-init` configuration options.

### YAML format for `cloud-init` configuration

The `cloud-init` options require YAML’s [literal style format](https://yaml.org/spec/1.2.2/#812-literal-style).
You use a pipe symbol (`|`) to indicate that all indented text after the pipe should be passed to `cloud-init` as a single string, with new lines and indentation preserved.

The `vendor-data` and `user-data` options usually start with `#cloud-config`. But `cloud-init` has an array of [configuration types](https://docs.cloud-init.io/en/latest/explanation/format/index.html#user-data-formats) available.

For example:

```yaml
config:
  cloud-init.user-data: |
    #cloud-config
    package_upgrade: true
    packages:
      - package1
      - package2
```

```yaml
config:
  cloud-init.user-data: |
    #!/usr/bin/bash
    echo hello | tee -a /tmp/example.txt
```

## How to check the `cloud-init` status

`cloud-init` runs automatically on the first start of an instance.
Depending on the configured actions, it might take a while until it finishes.

To check the `cloud-init` status, log on to the instance and enter the following command:

```none
cloud-init status
```

If the result is `status: running`, `cloud-init` is still working. If the result is `status: done`, it has finished.

Alternatively, use the `--wait` flag to be notified only when `cloud-init` is finished:

`root@instance:~# ``cloud-init status --wait
`
```text
.....................................
status: done
```

## How to specify user or vendor data

The `user-data` and `vendor-data` configuration can be used to, for example, upgrade or install packages, add users, or run commands.

The provided values must have a first line that indicates what type of [user data format](https://docs.cloud-init.io/en/latest/explanation/format/index.html#user-data-formats) is being passed to `cloud-init`.
For activities like upgrading packages or setting up a user, `#cloud-config` is the data format to use.

The configuration data is stored in the following files in the instance’s root file system:

* `/var/lib/cloud/instance/cloud-config.txt`
* `/var/lib/cloud/instance/user-data.txt`

### Examples

See the following sections for the user data (or vendor data) configuration for different example use cases.

You can find more advanced [examples](https://docs.cloud-init.io/en/latest/reference/examples.html#yaml-examples) in the `cloud-init` documentation.

#### Upgrade packages

To trigger a package upgrade from the repositories for the instance right after the instance is created, use the `package_upgrade` key:

```yaml
config:
  cloud-init.user-data: |
    #cloud-config
    package_upgrade: true
```

#### Install packages

To install specific packages when the instance is set up, use the `packages` key and specify the package names as a list:

```yaml
config:
  cloud-init.user-data: |
    #cloud-config
    packages:
      - git
      - openssh-server
```

#### Set the time zone

To set the time zone for the instance on instance creation, use the `timezone` key:

```yaml
config:
  cloud-init.user-data: |
    #cloud-config
    timezone: Europe/Rome
```

#### Run commands

To run a command (such as writing a marker file), use the `runcmd` key and specify the commands as a list:

```yaml
config:
  cloud-init.user-data: |
    #cloud-config
    runcmd:
      - [touch, /run/cloud.init.ran]
```

#### Add a user account

To add a user account, use the `users` key.
See the [Including users and groups](https://docs.cloud-init.io/en/latest/reference/examples.html#including-users-and-groups) example in the `cloud-init` documentation for details about default users and which keys are supported.

```yaml
config:
  cloud-init.user-data: |
    #cloud-config
    users:
      - name: documentation_example
```

## How to specify network configuration data

By default, `cloud-init` configures a DHCP client on an instance’s `eth0` interface.
You can define your own network configuration using the `network-config` option to override the default configuration (this is due to how the template is structured).

`cloud-init` then renders the relevant network configuration on the system using either `ifupdown` or `netplan`, depending on the Ubuntu release.

The configuration data is stored in the following files in the instance’s root file system:

* `/var/lib/cloud/seed/nocloud-net/network-config`
* `/etc/network/interfaces.d/50-cloud-init.cfg` (if using `ifupdown`)
* `/etc/netplan/50-cloud-init.yaml` (if using `netplan`)

### Example

To configure a specific network interface with a static IPv4 address and also use a custom name server, use the following configuration:

```yaml
config:
  cloud-init.network-config: |
    version: 2
    ethernets:
      eth1:
        addresses:
          - 10.10.101.20/24
        gateway4: 10.10.101.1
        nameservers:
          addresses:
            - 10.10.10.254
```

## How to inject SSH keys into instances

To inject SSH keys into LXD instances for an arbitrary user, use the configuration key `cloud-init.ssh-keys.<keyName>`.

Use the format `<user>:<key>` for its value, where `<user>` is a Linux username and `<key>` can be either a pure SSH public key or an import ID for a key hosted elsewhere. For example, `root:gh:githubUser` and `myUser:ssh-keyAlg publicKeyHash` are valid values. To prevent a particular SSH key from being inherited from a profile by an instance, edit the instance configuration by setting the `cloud-init.ssh-keys.<keyName>` key that references the target SSH key to `none`, and the key will not be injected.

The contents of the `cloud-init.ssh-keys.<keyName>` keys are merged into both [`cloud-init.vendor-data`](reference/instance_options.md#instance-cloud-init:cloud-init.vendor-data) and [`cloud-init.user-data`](reference/instance_options.md#instance-cloud-init:cloud-init.user-data) before being passed to the guest, following the `cloud-config` specification. (See the [cloud-init reference](https://docs.cloud-init.io/en/latest/reference/index.html) for details.) Therefore, keys defined via `cloud-init.ssh-keys.<keyName>` cannot be applied if LXD cannot parse the existing `cloud-init.vendor-data` and `cloud-init.user-data` for that instance. This might occur if those keys are not in YAML format or contain invalid YAML. Other configuration formats are not yet supported.

You can define SSH keys via `cloud-init.vendor-data` or `cloud-init.user-data` directly. Keys defined using `cloud-init.ssh-keys.<keyName>` do not conflict with those defined in either of those settings. For details on defining SSH keys with `cloud-config`, see [the cloud-init documentation for SSH configuration](https://docs.cloud-init.io/en/latest/reference/yaml_examples/ssh.html#cce-ssh). Changing a `cloud-init.*` key does not remove previously applied keys.

Since `cloud-init` only runs on instance start, updates to `cloud-init.*` keys on a running instance only take effect after restart.

### Examples

The following command injects `someuser`’s key from Launchpad into the newly created `container`:

```bash
lxc launch ubuntu:24.04 container -c cloud-init.ssh-keys.mykey=root:lp:someuser
```

The example profile configuration below defines a key to be injected on an instance. The injected key enables the owner of the private key to SSH into the instance as a user named `user`:

```yaml
config:
  cloud-init.vendor-data: |
    users:
      - name: user
        ssh_authorized_keys: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJFDWcYmMrCZdk9JI29bAiHKD90oEUr8tqK5VvoO8Vcj
```


# index.html.md

<a id="database"></a>

# The LXD Dqlite database

LXD uses a distributed database to store the server configuration and state, which allows for quicker queries than if the configuration was stored inside each instance’s directory (as it is done by LXC, for example).

To understand the advantages, consider a query against the configuration of all instances, like “what instances are using `br0`?”.
To answer that question without a database, you would have to iterate through every single instance, load and parse its configuration, and then check which network devices are defined in there.
With a database, you can run a simple query on the database to retrieve this information.

## Dqlite

In a LXD cluster, all members of the cluster must share the same database state.
Therefore, LXD uses [Dqlite](https://canonical.com/dqlite), a distributed version of SQLite.
Dqlite provides replication, fault-tolerance, and automatic failover without the need of external database processes.

When using LXD as a single machine and not as a cluster, the Dqlite database effectively behaves like a regular SQLite database.

For more information, see [Dqlite internals](reference/dqlite-internals.md#dqlite-internals).

<a id="database-location"></a>

## File location

The database files are stored in the `database` sub-directory of your LXD data directory (thus `/var/snap/lxd/common/lxd/database/` if you use the snap, or `/var/lib/lxd/database/` otherwise).

Upgrading LXD to a newer version might require updating the database schema.
In this case, LXD automatically stores a backup of the database and then runs the update.
See [Database schema update and backup](reference/releases-snap.md#ref-snap-database) for more information.

## Backup

See [Back up the database](backup.md#backup-database) for instructions on how to back up the contents of the LXD database.


# index.html.md

<a id="lxd-server"></a>

# LXD server and client

These how-to guides cover common operations related to the LXD server and client.

## Configure the LXD server

* [Configure the LXD server](howto/server_configure.md)
* [Expose LXD to the network](howto/server_expose.md)
* [Configure single sign-on with OIDC](howto/oidc.md)

## Configure the LXD CLI client

The LXD CLI client (`lxc`) can be configured to use remote servers instead of the local LXD daemon. For convenience, aliases can be set up for frequently used commands.

* [Add remote servers](remotes.md)
* [Add command aliases](howto/lxc_alias.md)

## Related topics

Explanation:

- [About `lxd` and `lxc`](explanation/lxd_lxc.md#lxd-lxc)
- [The LXD Dqlite database](database.md#database)

Reference:

- [Architectures](architectures.md#architectures)
- [Server configuration](server.md#server)
- [REST API](restapi_landing.md#restapi)


# index.html.md

<a id="ref-idmap"></a>

# Idmaps for user namespace

LXD runs safe containers. This is achieved mostly through the use of
user namespaces which make it possible to run containers unprivileged,
greatly limiting the attack surface.

User namespaces work by mapping a set of UIDs and GIDs on the host to a
set of UIDs and GIDs in the container.

For example, we can define that the host UIDs and GIDs from 100000 to
165535 may be used by LXD and should be mapped to UID/GID 0 through
65535 in the container.

As a result a process running as UID 0 in the container will actually be
running as UID 100000.

Allocations should always be of at least 65536 UIDs and GIDs to cover
the POSIX range including root (0) and nobody (65534).

## Kernel support

User namespaces require a kernel >= 3.12, LXD will start even on older
kernels but will refuse to start containers.

<a id="ref-idmap-allowed-ranges"></a>

## Allowed ranges

On most hosts, LXD will check `/etc/subuid` and `/etc/subgid` for
allocations for the `root` user and on first start, set the default
profile to use the first 65536 UIDs and GIDs from that range.

If the range is shorter than 65536 (which includes no range at all),
then LXD will fail to create or start any container until this is corrected.

If some but not all of `/etc/subuid`, `/etc/subgid`, `newuidmap` (path lookup)
and `newgidmap` (path lookup) can be found on the system, LXD will fail
the startup of any container until this is corrected as this shows a
broken shadow setup.

If none of those files can be found, then LXD will assume a 1000000000
UID/GID range starting at a base UID/GID of 1000000.

This is the most common case and is usually the recommended setup when
not running on a system which also hosts fully unprivileged containers
(where the container runtime itself runs as a user).

## Varying ranges between hosts

The source map is sent when moving containers between hosts so that they
can be remapped on the receiving host.

## Different idmaps per container

LXD supports using different idmaps per container, to further isolate
containers from each other. This is controlled with two per-container
configuration keys, [`security.idmap.isolated`](reference/instance_options.md#instance-security:security.idmap.isolated) and [`security.idmap.size`](reference/instance_options.md#instance-security:security.idmap.size).

Containers with `security.idmap.isolated` will have a unique ID range computed
for them among the other containers with `security.idmap.isolated` set (if none
is available, setting this key will simply fail).

Containers with `security.idmap.size` set will have their ID range set to this
size. Isolated containers without this property set default to a ID range of
size 65536; this allows for POSIX compliance and a `nobody` user inside the
container.

To select a specific map, the `security.idmap.base` key will let you
override the auto-detection mechanism and tell LXD what host UID/GID you
want to use as the base for the container.

These properties require a container reboot to take effect.

## Custom idmaps

LXD also supports customizing bits of the idmap, e.g. to allow users to bind
mount parts of the host’s file system into a container without the need for any
UID-shifting file system. The per-container configuration key for this is
[`raw.idmap`](reference/instance_options.md#instance-raw:raw.idmap), and looks like:

```none
both 1000 1000
uid 50-60 500-510
gid 100000-110000 10000-20000
```

The first line configures both the UID and GID 1000 on the host to map to UID
1000 inside the container (this can be used for example to bind mount a user’s
home directory into a container).

The second and third lines map only the UID or GID ranges into the container,
respectively. The second entry per line is the source ID, i.e. the ID on the
host, and the third entry is the range inside the container. These ranges must
be the same size.

This property requires a container reboot to take effect.

For non-snap installations of LXD, you might need to add an entry for the `root` user into
`/etc/subuid` and/or `/etc/subgid` so the container is allowed to make use of it. See: [Allowed ranges](#ref-idmap-allowed-ranges).


# index.html.md

# How to debug LXD

For information on debugging instance issues, see [How to troubleshoot failing instances](howto/instances_troubleshoot.md#instances-troubleshoot).

## Debugging `lxc` and `lxd`

Here are different ways to help troubleshooting `lxc` and `lxd` code.

### `lxc --debug`

Adding `--debug` flag to any client command will give extra information
about internals. If there is no useful info, it can be added with the
logging call:

```none
logger.Debugf("Hello: %s", "Debug")
```

### `lxc monitor`

This command will monitor messages as they appear on remote server.

## REST API through local socket

On server side the most easy way is to communicate with LXD through
local socket. This command accesses `GET /1.0` and formats JSON into
human readable form using [jq](https://stedolan.github.io/jq/tutorial/)
utility:

```bash
curl --unix-socket /var/lib/lxd/unix.socket lxd/1.0 | jq .
```

or for snap users:

```bash
curl --unix-socket /var/snap/lxd/common/lxd/unix.socket lxd/1.0 | jq .
```

See the [RESTful API](rest-api.md) for available API.

## REST API through HTTPS

[HTTPS connection to LXD](explanation/security.md#security) requires valid
client certificate that is generated on first [`lxc remote add`](reference/manpages/lxc/remote/add.md#lxc-remote-add-md). This
certificate should be passed to connection tools for authentication
and encryption.

If desired, `openssl` can be used to examine the certificate (`~/.config/lxc/client.crt`
or `~/snap/lxd/common/config/client.crt` for snap users):

```bash
openssl x509 -text -noout -in client.crt
```

Among the lines you should see:

```none
Certificate purposes:
SSL client : Yes
```

### With command line tools

```bash
wget --no-check-certificate --certificate=$HOME/.config/lxc/client.crt --private-key=$HOME/.config/lxc/client.key -qO - https://127.0.0.1:8443/1.0

# or for snap users
wget --no-check-certificate --certificate=$HOME/snap/lxd/common/config/client.crt --private-key=$HOME/snap/lxd/common/config/client.key -qO - https://127.0.0.1:8443/1.0
```

### With browser

Some browser plugins provide convenient interface to create, modify
and replay web requests. To authenticate against LXD server, convert
`lxc` client certificate into importable format and import it into
browser.

For example this produces `client.pfx` in Windows-compatible format:

```bash
openssl pkcs12 -clcerts -inkey client.key -in client.crt -export -out client.pfx
```

After that, opening [`https://127.0.0.1:8443/1.0`](https://127.0.0.1:8443/1.0) should work as expected.

## Debug LXD using `pprof`

LXD provides a Go [`pprof`](https://pkg.go.dev/net/http/pprof) server when the [`core.debug_address`](server.md#server-core:core.debug_address) is set.

The debug server should not be exposed to an externally accessible address for production use cases. Use the following command to enable the server on the loopback interface:

```none
lxc config set core.debug_address=localhost:8080
```

If the LXD server is running on your workstation, you can view a summary of available information by navigating to [`http://localhost:8080/debug/pprof/`](http://localhost:8080/debug/pprof/).

## Debug the LXD database

The files of the global [database](database.md#database) are stored under the `./database/global`
sub-directory of your LXD data directory (e.g. `/var/lib/lxd/database/global` or
`/var/snap/lxd/common/lxd/database/global` for snap users).

Since each member of the cluster also needs to keep some data which is specific
to that member, LXD also uses a plain SQLite database (the “local” database),
which you can find in `./database/local.db`.

Backups of the global database directory and of the local database file are made
before upgrades, and are tagged with the `.bak` suffix. You can use those if
you need to revert the state as it was before the upgrade.

### Dumping the database content or schema

If you want to get a SQL text dump of the content or the schema of the databases,
use the `lxd sql <local|global> [.dump|.schema]` command, which produces the
equivalent output of the `.dump` or `.schema` directives of the `sqlite3`
command line tool.

### Running custom queries from the console

If you need to perform SQL queries (e.g. `SELECT`, `INSERT`, `UPDATE`)
against the local or global database, you can use the `lxd sql` command (run
`lxd sql --help` for details).

You should only need to do that in order to recover from broken updates or bugs.
Please consult the LXD team first (creating a [GitHub
issue](https://github.com/canonical/lxd/issues/new) or
[forum](https://discourse.ubuntu.com/c/project/lxd/126) post).

### Running custom queries at LXD daemon startup

In case the LXD daemon fails to start after an upgrade because of SQL data
migration bugs or similar problems, it’s possible to recover the situation by
creating `.sql` files containing queries that repair the broken update.

To perform repairs against the local database, write a
`./database/patch.local.sql` file containing the relevant queries, and
similarly a `./database/patch.global.sql` for global database repairs.

Those files will be loaded very early in the daemon startup sequence and deleted
if the queries were successful (if they fail, no state will change as they are
run in a SQL transaction).

As above, please consult the LXD team first.

### Syncing the cluster database to disk

If you want to flush the content of the cluster database to disk, use the `lxd sql global .sync` command, that will write a plain SQLite database file into
`./database/global/db.bin`, which you can then inspect with the `sqlite3`
command line tool.

## Inspect a core dump file

In our continuous integration tests, we have configured the `core_pattern` as follows:

```none
echo '|/bin/sh -c $@ -- eval exec gzip --fast > /var/crash/%e.%p.gz' | sudo tee /proc/sys/kernel/core_pattern
```

Additionally, we have set the `GOTRACEBACK` environment variable to `crash`.
Together, these ensure that when LXD crashes a core dump is compressed with `gzip` and placed in `/var/crash`.

To inspect a core dump file, you will need the LXD binary that was running at the time of the crash.
The binary must include symbols; you can check this with the `file` utility.
You will also need any C libraries that are used by LXD which must also include symbols.

You can inspect a core dump using [Delve](https://github.com/go-delve/delve) (see the [Go Wiki](https://go.dev/wiki/CoreDumpDebugging) for more information), but this does not support any dynamically linked C libraries.
Instead, you can use [GDB](https://sourceware.org/gdb/) which can inspect linked libraries and allows sourcing a file to load Golang support.

To do this, run:

```none
gdb <LXD binary> <coredump file>
```

Then in the GDB REPL, run:

```none
(gdb) source <GOROOT>/src/runtime/runtime-gdb.py
```

Substituting in the actual path to your `$GOROOT`.
This will add Golang runtime support.

Finally, set the search path for C libraries using:

```none
(gdb) set solib-search-path <path to C libraries>
```

You can now use the GDB REPL to inspect the core dump.
Some useful commands are:

- `backtrace` (print stack trace).
- `info goroutines` (show goroutines).
- `info threads` (show threads).
- `thread <thread_number>` (change thread).


# index.html.md

<a id="getting-started"></a>

# Getting started

The following how-to guides cover the initial steps for setting up and accessing LXD.

## Perform initial setup

LXD is most commonly installed using its snap, but other installation methods are possible. Afterward, LXD can be initialized using an interactive CLI or a preseed file.

* [Install LXD](installing.md)
* [Initialize LXD](howto/initialize.md)

## Access the UI and offline documentation

The LXD UI client provides a graphical, browser-based alternative to the CLI for interacting with the LXD server. The offline documentation is especially useful for air-gapped deployments.

* [Access the UI](howto/access_ui.md)
* [Access documentation locally](howto/access_documentation.md)

## Watch videos

The following clip gives a quick and easy introduction for standard use cases:

<div>
 <script id="asciicast-226224" src="https://asciinema.org/a/226224.js" async></script>
</div>

A series of demos and tutorials is also available on [YouTube](https://www.youtube.com/c/LXDvideos):

<iframe width="560" height="315" src="https://www.youtube.com/embed/videoseries?list=PLddduKsl-KEhleT9VTR4hbtlNdtMr6cFd" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

## Related topics

Tutorial:

- [First steps with LXD](tutorial/first_steps.md#first-steps)

Explanation:

- [Containers and VMs](explanation/instances.md#containers-and-vms)

Reference:

- [Requirements](requirements.md#requirements)
- [Releases and snap](reference/releases-snap.md#ref-releases-snap)


# index.html.md

<a id="dev-lxd"></a>

# Communication between instance and host


            <p class="youtube_link">
              <a href="https://www.youtube.com/watch?v=xZSnqqWykmo" target="_blank">
                <span title="The LXD instance API" class="play_icon">▶</span>
                <span title="The LXD instance API">Watch on YouTube</span>
              </a>
            </p>
        
The DevLXD API allows for limited communication between guest instances and the host.

The API is available inside each LXD guest as a Unix socket at `/dev/lxd/sock`, using JSON over plain HTTP.
Multiple concurrent connections are allowed.

#### NOTE
[`security.devlxd`](reference/instance_options.md#instance-security:security.devlxd) must be set to `true` (which is the default) for an instance to allow access to the socket.

Additionally, for virtual machines, the LXD agent must be present and running for the socket to be available.

<a id="dev-lxd-implementation"></a>

## Implementation details

<a id="dev-lxd-implementation-containers"></a>

### Containers

LXD on the host binds `/var/lib/lxd/devlxd/sock` and listens for connections.
This single socket is exposed into every container started by LXD at `/dev/lxd/sock`.

#### NOTE
The alternative to using a single socket is to create a socket for every container.
This approach was discarded to avoid issues with file descriptor limits for hosts with thousands of containers.

<a id="dev-lxd-implementation-vms"></a>

### Virtual machines

LXD on the host starts a HTTPS  server.
The LXD agent on the virtual machine communicates securely with the Vsock server using a certificate mounted in the VM’s configuration drive.
The LXD agent creates the socket at `/dev/lxd/sock` and proxies requests to the Vsock server.

<a id="devlxd-authentication"></a>

## Authentication

Queries on `/dev/lxd/sock` only return information related to the requesting instance.

For containers, LXD inspects user credentials associated with the connection and matches them with a running instance.

For virtual machines, LXD extracts the virtual socket ID from the remote address of the caller (the LXD agent), and matches it with a virtual machine.

<a id="devlxd-authentication-bearer"></a>

### Bearer tokens

Processes within guest instances can now authenticate over the DevLXD socket using a bearer token.
To do this, set an `Authorization: Bearer {token}` header on requests to the socket.

Bearer tokens can be obtained by creating a `DevLXD token bearer` identity in the identities API and issuing a token for it.
For more information, see [How to authenticate to the DevLXD API](howto/devlxd_authenticate.md#devlxd-authenticate).

<a id="devlxd-api-spec"></a>

## REST-API

<link rel="stylesheet" type="text/css" href="../_static/swagger-ui/swagger-ui.css" ></link>
<link rel="stylesheet" type="text/css" href="../_static/swagger-override.css" ></link>
<div id="swagger-ui"></div>
<script src="../_static/swagger-ui/swagger-ui-bundle.js" charset="UTF-8"> </script>
<script src="../_static/swagger-ui/swagger-ui-standalone-preset.js" charset="UTF-8"> </script>
<script>
window.onload = function() {
  // Begin Swagger UI call region
  const ui = SwaggerUIBundle({
    url: window.location.pathname + "../devlxd-api.yaml",
    dom_id: '#swagger-ui',
    deepLinking: true,
    presets: [
      SwaggerUIBundle.presets.apis,
      SwaggerUIStandalonePreset
    ],
    plugins: [],
    validatorUrl: "none",
    defaultModelsExpandDepth: -1,
    supportedSubmitMethods: []
  })
  // End Swagger UI call region

  window.ui = ui
}
</script>


# index.html.md

<a id="metrics"></a>

# How to monitor metrics


            <p class="youtube_link">
              <a href="https://www.youtube.com/watch?v=EthK-8hm_fY" target="_blank">
                <span title="LXD metrics with Prometheus and Grafana" class="play_icon">▶</span>
                <span title="LXD metrics with Prometheus and Grafana">Watch on YouTube</span>
              </a>
            </p>
        <!-- Include start metrics intro -->

LXD collects metrics for all running instances as well as some internal metrics.
These metrics cover the CPU, memory, network, disk and process usage.
They are meant to be consumed by Prometheus, and you can use Grafana to display the metrics as graphs.
See [Provided metrics](reference/provided_metrics.md#provided-metrics) for lists of available metrics and [Set up a Grafana dashboard](howto/grafana.md#grafana) for instructions on how to display the metrics in Grafana.

<!-- Include end metrics intro -->

In a cluster environment, LXD returns only the values for instances running on the server that is being accessed.
Therefore, you must scrape each cluster member separately.

The instance metrics are updated when calling the `/1.0/metrics` endpoint.
To handle multiple scrapers, they are cached for 8 seconds.
Fetching metrics is a relatively expensive operation for LXD to perform, so if the impact is too high, consider scraping at a higher than default interval.

## Query the raw data

To view the raw data that LXD collects, use the [`lxc query`](reference/manpages/lxc/query.md#lxc-query-md) command to query the `/1.0/metrics` endpoint:

`user@host:~$ ``lxc query /1.0/metrics
`
```text
# HELP lxd_api_requests_completed_total The total number of completed API requests.
# TYPE lxd_api_requests_completed_total counter
lxd_api_requests_completed_total{entity_type="server",result="error_client"} 0
lxd_api_requests_completed_total{entity_type="server",result="succeeded"} 9
lxd_api_requests_completed_total{entity_type="server",result="error_server"} 0
lxd_api_requests_completed_total{entity_type="network",result="error_server"} 0
lxd_api_requests_completed_total{entity_type="network",result="error_client"} 0
lxd_api_requests_completed_total{entity_type="network",result="succeeded"} 0
lxd_api_requests_completed_total{entity_type="cluster_member",result="error_server"} 0
lxd_api_requests_completed_total{entity_type="cluster_member",result="error_client"} 0
lxd_api_requests_completed_total{entity_type="cluster_member",result="succeeded"} 0
lxd_api_requests_completed_total{entity_type="project",result="succeeded"} 0
lxd_api_requests_completed_total{entity_type="project",result="error_server"} 0
lxd_api_requests_completed_total{entity_type="project",result="error_client"} 0
lxd_api_requests_completed_total{entity_type="image",result="error_server"} 0
lxd_api_requests_completed_total{entity_type="image",result="error_client"} 0
lxd_api_requests_completed_total{entity_type="image",result="succeeded"} 0
lxd_api_requests_completed_total{entity_type="operation",result="error_server"} 0
lxd_api_requests_completed_total{entity_type="operation",result="error_client"} 0
lxd_api_requests_completed_total{entity_type="operation",result="succeeded"} 0
lxd_api_requests_completed_total{entity_type="storage_pool",result="error_server"} 0
lxd_api_requests_completed_total{entity_type="storage_pool",result="error_client"} 0
lxd_api_requests_completed_total{entity_type="storage_pool",result="succeeded"} 0
lxd_api_requests_completed_total{entity_type="warning",result="error_server"} 0
lxd_api_requests_completed_total{entity_type="warning",result="error_client"} 0
lxd_api_requests_completed_total{entity_type="warning",result="succeeded"} 0
lxd_api_requests_completed_total{entity_type="identity",result="error_client"} 0
lxd_api_requests_completed_total{entity_type="identity",result="succeeded"} 0
lxd_api_requests_completed_total{entity_type="identity",result="error_server"} 0
lxd_api_requests_completed_total{entity_type="profile",result="error_server"} 0
lxd_api_requests_completed_total{entity_type="profile",result="error_client"} 0
lxd_api_requests_completed_total{entity_type="profile",result="succeeded"} 0
lxd_api_requests_completed_total{entity_type="instance",result="succeeded"} 2
lxd_api_requests_completed_total{entity_type="instance",result="error_server"} 0
lxd_api_requests_completed_total{entity_type="instance",result="error_client"} 0
# HELP lxd_api_requests_ongoing The number of API requests currently being handled.
# TYPE lxd_api_requests_ongoing gauge
lxd_api_requests_ongoing{entity_type="server"} 1
lxd_api_requests_ongoing{entity_type="network"} 0
lxd_api_requests_ongoing{entity_type="cluster_member"} 0
lxd_api_requests_ongoing{entity_type="project"} 0
lxd_api_requests_ongoing{entity_type="image"} 0
lxd_api_requests_ongoing{entity_type="operation"} 0
lxd_api_requests_ongoing{entity_type="storage_pool"} 0
lxd_api_requests_ongoing{entity_type="warning"} 0
lxd_api_requests_ongoing{entity_type="identity"} 0
lxd_api_requests_ongoing{entity_type="profile"} 0
lxd_api_requests_ongoing{entity_type="instance"} 0
# HELP lxd_cpu_effective_total The total number of effective CPUs.
# TYPE lxd_cpu_effective_total gauge
lxd_cpu_effective_total{name="c",project="default",type="container"} 8
# HELP lxd_cpu_seconds_total The total number of CPU time used in seconds.
# TYPE lxd_cpu_seconds_total counter
lxd_cpu_seconds_total{cpu="0",mode="system",name="c",project="default",type="container"} 1.53794
lxd_cpu_seconds_total{cpu="0",mode="user",name="c",project="default",type="container"} 2.613658
# HELP lxd_disk_read_bytes_total The total number of bytes read.
# TYPE lxd_disk_read_bytes_total counter
lxd_disk_read_bytes_total{device="nvme0n1",name="c",project="default",type="container"} 3.6151296e+07
# HELP lxd_disk_reads_completed_total The total number of completed reads.
# TYPE lxd_disk_reads_completed_total counter
...
```

## Set up Prometheus

To gather and store the raw metrics, you should set up [Prometheus](https://prometheus.io/).
You can then configure it to scrape the metrics through the metrics API endpoint.

### Expose the metrics endpoint

To expose the `/1.0/metrics` API endpoint, you must set the address on which it should be available.

To do so, you can set either the [`core.metrics_address`](server.md#server-core:core.metrics_address) server configuration option or the [`core.https_address`](server.md#server-core:core.https_address) server configuration option.
The `core.metrics_address` option is intended for metrics only, while the `core.https_address` option exposes the full API.
So if you want to use a different address for the metrics API than for the full API, or if you want to expose only the metrics endpoint but not the full API, you should set the `core.metrics_address` option.

For example, to expose the full API on the `8443` port, enter the following command:

```none
lxc config set core.https_address ":8443"
```

To expose only the metrics API endpoint on the `8444` port, enter the following command:

```none
lxc config set core.metrics_address ":8444"
```

To expose only the metrics API endpoint on a specific IP address and port, enter a command similar to the following:

```none
lxc config set core.metrics_address "192.0.2.101:8444"
```

### Add a metrics certificate to LXD

Authentication for the `/1.0/metrics` API endpoint is done through a metrics certificate.
A metrics certificate (type `metrics`) is different from a client certificate (type `client`) in that it is meant for metrics only and doesn’t work for interaction with instances or any other LXD entities.

To create a certificate, enter the following command:

```none
openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:secp384r1 -sha384 -keyout metrics.key -nodes -out metrics.crt -days 3650 -subj "/CN=metrics.local"
```

#### NOTE
The command requires OpenSSL version 1.1.0 or later.

Then add this certificate to the list of trusted clients, specifying the type as `metrics`:

```none
lxc config trust add metrics.crt --type=metrics
```

If requiring TLS client authentication isn’t possible in your environment, the `/1.0/metrics` API endpoint can be made available to unauthenticated clients.
While not recommended, this might be acceptable if you have other controls in place to restrict who can reach that API endpoint. To disable the authentication on the metrics API:

```bash
# Disable authentication (NOT RECOMMENDED)
lxc config set core.metrics_authentication false
```

### Make the metrics certificate available for Prometheus

If you run Prometheus on a different machine than your LXD server, you must copy the required certificates to the Prometheus machine:

- The metrics certificate (`metrics.crt`) and key (`metrics.key`) that you created
- The LXD server certificate (`server.crt`) located in `/var/snap/lxd/common/lxd/` (if you are using the snap) or `/var/lib/lxd/` (otherwise)

Copy these files into a `tls` directory that is accessible to Prometheus, for example, `/var/snap/prometheus/common/tls` (if you are using the snap) or `/etc/prometheus/tls` (otherwise).
See the following example commands:

```bash
# Create tls directory
mkdir /var/snap/prometheus/common/tls

# Copy newly created certificate and key to tls directory
cp metrics.crt metrics.key /var/snap/prometheus/common/tls/

# Copy LXD server certificate to tls directory
cp /var/snap/lxd/common/lxd/server.crt /var/snap/prometheus/common/tls/

# Create a symbolic link pointing to tls directory that you created
# https://bugs.launchpad.net/prometheus-snap/+bug/2066910
ln -s /var/snap/prometheus/common/tls/ /var/snap/prometheus/current/tls
```

If you are not using the snap, you must also make sure that Prometheus can read these files (usually, Prometheus is run as user `prometheus`):

```none
chown -R prometheus:prometheus /etc/prometheus/tls
```

### Configure Prometheus to scrape from LXD

Finally, you must add LXD as a target to the Prometheus configuration.

To do so, edit `/var/snap/prometheus/current/prometheus.yml` (if you are using the snap) or `/etc/prometheus/prometheus.yaml` (otherwise) and add a job for LXD.

Here’s what the configuration needs to look like:

```yaml
global:
  # How frequently to scrape targets by default. The Prometheus default value is 1m.
  scrape_interval: 15s

scrape_configs:
  - job_name: lxd
    metrics_path: '/1.0/metrics'
    scheme: 'https'
    static_configs:
      - targets: ['foo.example.com:8443']
    tls_config:
      ca_file: 'tls/server.crt'
      cert_file: 'tls/metrics.crt'
      key_file: 'tls/metrics.key'
      # XXX: server_name is required if the target name
      #      is not covered by the certificate (not in the SAN list)
      server_name: 'foo'
```

#### NOTE
* By default, the Grafana Prometheus data source assumes the `scrape_interval` to be 15 seconds.
  If you decide to use a different `scrape_interval` value, you must change it in both the Prometheus configuration and the Grafana Prometheus data source configuration.
  Otherwise, the Grafana `$__rate_interval` value will be calculated incorrectly, which might cause a `no data` response in queries that use it.
* The `server_name` must be specified if the LXD server certificate does not contain the same host name as used in the `targets` list.
  To verify this, open `server.crt` and check the Subject Alternative Name (SAN) section.

  For example, assume that `server.crt` has the following content:
  `user@host:~$ ``openssl x509 -noout -text -in /var/snap/prometheus/common/tls/server.crt
  `
  ```text
  ...
              X509v3 Subject Alternative Name:
                  DNS:foo, IP Address:127.0.0.1, IP Address:0:0:0:0:0:0:0:1
  ...
  ```

  Since the Subject Alternative Name (SAN) list doesn’t include the host name provided in the `targets` list (`foo.example.com`), you must override the name used for comparison using the `server_name` directive.

Here is an example of a `prometheus.yml` configuration where multiple jobs are used to scrape the metrics of multiple LXD servers:

```yaml
global:
  # How frequently to scrape targets by default. The Prometheus default value is 1m.
  scrape_interval: 15s

scrape_configs:
  # abydos, langara and orilla are part of a single cluster (called `hdc` here)
  # initially bootstrapped by abydos which is why all 3 targets
  # share the same `ca_file` and `server_name`. That `ca_file` corresponds
  # to the `/var/snap/lxd/common/lxd/cluster.crt` file found on every member of
  # the LXD cluster.
  #
  # Note: When using a certificate restricted to multiple projects,
  #       use the `project` param to only scrape a specific project or projects.
  #       Otherwise, omit it to return the metrics for all the accessible
  #       projects in one scrape.
  #
  # Note: Each member of the cluster only provides metrics for instances it runs
  #       locally. This is why the `lxd-hdc` cluster lists 3 targets.
  - job_name: "lxd-hdc"
    metrics_path: '/1.0/metrics'
    params:
      # If no project parameter is defined, by default, metrics for all
      # accessible projects are returned.
      project: ['jdoe']
    scheme: 'https'
    static_configs:
      - targets:
        - 'abydos.hosts.example.net:8444'
        - 'langara.hosts.example.net:8444'
        - 'orilla.hosts.example.net:8444'
    tls_config:
      ca_file: 'tls/abydos.crt'
      cert_file: 'tls/metrics.crt'
      key_file: 'tls/metrics.key'
      server_name: 'abydos'

  # jupiter, mars and saturn are 3 standalone LXD servers.
  # Note: only the `default` project is used on them, so it is not specified.
  - job_name: "lxd-jupiter"
    metrics_path: '/1.0/metrics'
    scheme: 'https'
    static_configs:
      - targets: ['jupiter.example.com:9101']
    tls_config:
      ca_file: 'tls/jupiter.crt'
      cert_file: 'tls/metrics.crt'
      key_file: 'tls/metrics.key'
      server_name: 'jupiter'

  - job_name: "lxd-mars"
    metrics_path: '/1.0/metrics'
    scheme: 'https'
    static_configs:
      - targets: ['mars.example.com:9101']
    tls_config:
      ca_file: 'tls/mars.crt'
      cert_file: 'tls/metrics.crt'
      key_file: 'tls/metrics.key'
      server_name: 'mars'

  - job_name: "lxd-saturn"
    metrics_path: '/1.0/metrics'
    scheme: 'https'
    static_configs:
      - targets: ['saturn.example.com:9101']
    tls_config:
      ca_file: 'tls/saturn.crt'
      cert_file: 'tls/metrics.crt'
      key_file: 'tls/metrics.key'
      server_name: 'saturn'
```

After editing the configuration, restart Prometheus (`snap restart prometheus` if using the snap, otherwise `systemctl restart prometheus`) to start scraping.


# index.html.md

<a id="networking"></a>

# Networking

These how-to guides cover common operations related to LXD networking.

## Create and configure networks

* [Create a network](howto/network_create.md)
* [Configure a network](howto/network_configure.md)

## Configure networking features

These features are available for multiple types of networks.

* [Configure as BGP server](howto/network_bgp.md)
* [Configure network ACLs](howto/network_acls.md)
* [Configure forwards](howto/network_forwards.md)
* [Configure network zones](howto/network_zones.md)

## Configure bridge network features

These features are available for managed bridge networks only.

* [Configure your firewall](howto/network_bridge_firewalld.md)
* [Integrate with resolved](howto/network_bridge_resolved.md)

## Configure OVN network features

These features are available for OVN networks only.

* [Set up OVN](howto/network_ovn_setup.md)
* [Configure load balancers](howto/network_load_balancers.md)
* [Configure peer routing](howto/network_ovn_peers.md)

## Troubleshoot networks

IPAM information shows the IP addresses allocated across networks and instances, useful for diagnosing network issues.

* [Display IPAM information](howto/network_ipam.md)

## Related topics

Explanation:

- [Networking setups](explanation/networks.md#networks)

Reference:

- [Networks](reference/networks.md#ref-networks)


# index.html.md

# Index

<!-- Placeholder page required to add the automatically generated config-options page to the ToC. -->
<!-- To update content on that page, edit \_templates/domainindex.html. -->


# index.html.md

<a id="images"></a>

# Images

These how-to guides cover common operations related to LXD images.

## Work with existing images

Images are used to create instances. Pre-configured images can be downloaded from remote servers and managed locally, including configuring profiles to use specific images.

* [Use remote images](howto/images_remote.md)
* [Manage images](howto/images_manage.md)
* [Associate profiles](howto/images_profiles.md)

## Import and create images

Images can be copied or imported from other servers or files. They can also be created from scratch, or from existing instances or snapshots.

* [Copy and import images](howto/images_copy.md)
* [Create images](howto/images_create.md)

## Related topics

Explanation:

- [Local and remote images](image-handling.md#about-images)

Reference:

- [Image format](reference/image_format.md#image-format)
- [Remote image servers](reference/remote_image_servers.md#remote-image-servers)


# index.html.md

<a id="support"></a>

# How to get support

<!-- Include content from [../README.md](../README.md) -->

## Community support

You can seek support from the LXD developers as well as the wider community through the following channels.

### Forum

Ask questions or engage in discussions: [`https://discourse.ubuntu.com/c/project/lxd/`](https://discourse.ubuntu.com/c/project/lxd/126)

### Documentation

Access the official documentation: [`https://documentation.ubuntu.com/lxd/latest/`](https://documentation.ubuntu.com/lxd/latest/)

### Bug reports and feature requests

To file a new bug or feature request, [submit an issue on GitHub](https://github.com/canonical/lxd/issues/new).

### Other community resources

You can find additional resources on the [LXD website](https://canonical.com/lxd), on [YouTube](https://www.youtube.com/channel/UCuP6xPt0WTeZu32CkQPpbvA), and the [community-created tutorials](https://discourse.ubuntu.com/c/project/lxd/tutorials/146).

## Commercial support

LTS releases of LXD receive standard support for five years, which means they receive continuous updates. Commercial support for LXD is provided as part of [Ubuntu Pro](https://ubuntu.com/pro) (both Infra-only and full Ubuntu Pro), including for [attached LXD instances running Ubuntu](https://documentation.ubuntu.com/lxd/latest/howto/instances_ubuntu_pro_attach/). See the [full service description](https://ubuntu.com/legal/ubuntu-pro-description) for details.

Managed solutions and firefighting support are also available for LXD deployments. See: [Managed services](https://ubuntu.com/managed).

## Related topics

For information about supported releases, see: [Releases](reference/releases-snap.md#ref-releases).


# index.html.md

<a id="storage"></a>

# Storage

These how-to guides cover common operations related to storage in LXD.

## Create and manage storage

LXD storage pools contain instance volumes and custom volumes, as well as buckets accessible via the S3 protocol.

* [Manage pools](howto/storage_pools.md)
* [Manage volumes](howto/storage_volumes.md)
* [Manage buckets](howto/storage_buckets.md)

## Extend storage use

Instance volumes can be created directly in a specific storage pool. Custom volumes can also be moved, copied, and backed up.

* [Create or move an instance in a pool](howto/storage_create_instance.md)
* [Back up a custom volume](howto/storage_backup_volume.md)
* [Move or copy a custom volume](howto/storage_move_volume.md)

## Use storage with Kubernetes

The LXD CSI driver integrates LXD storage backends with Kubernetes.

* [Use the LXD CSI driver with Kubernetes](howto/storage_csi.md)

## Related topics

Explanation:

- [Storage pools, volumes, and buckets](explanation/storage.md#exp-storage)

Reference:

- [Storage drivers](reference/storage_drivers.md#storage-drivers)


# index.html.md

# System call interception

LXD supports intercepting some specific system calls from unprivileged
containers. If they’re considered to be safe, it executes them with
elevated privileges on the host.

Doing so comes with a performance impact for the syscall in question and
will cause some work for LXD to evaluate the request and if allowed,
process it with elevated privileges.

Enabling of specific system call interception options is done on a
per-container basis through container configuration options.

## Available system calls

<a id="syscall-mknod"></a>

### `mknod` / `mknodat`

The `mknod` and `mknodat` system calls can be used to create a variety of special files.

Most commonly inside containers, they may be called to create block or character devices.
Creating such devices isn’t allowed in unprivileged containers as this
is a very easy way to escalate privileges by allowing direct write
access to resources like disks or memory.

But there are files which are safe to create. For those, intercepting
this syscall may unblock some specific workloads and allow them to run
inside an unprivileged containers.

The devices which are currently allowed are:

- OverlayFS whiteout (char 0:0)
- `/dev/console` (char 5:1)
- `/dev/full` (char 1:7)
- `/dev/null` (char 1:3)
- `/dev/random` (char 1:8)
- `/dev/tty` (char 5:0)
- `/dev/urandom` (char 1:9)
- `/dev/zero` (char 1:5)

All file types other than character devices are currently sent to the
kernel as usual, so enabling this feature doesn’t change their behavior
at all.

This can be enabled by setting [`security.syscalls.intercept.mknod`](reference/instance_options.md#instance-security:security.syscalls.intercept.mknod) to `true`.

### `bpf`

The `bpf` system call is used to manage eBPF programs in the kernel.
Those can be attached to a variety of kernel subsystems.

In general, loading of eBPF programs that are not trusted can be problematic as it
can facilitate timing based attacks.

LXD’s eBPF support is currently restricted to programs managing devices
cgroup entries. To enable it, you need to set both
[`security.syscalls.intercept.bpf`](reference/instance_options.md#instance-security:security.syscalls.intercept.bpf) and
[`security.syscalls.intercept.bpf.devices`](reference/instance_options.md#instance-security:security.syscalls.intercept.bpf.devices) to true.

### `mount`

The `mount` system call allows for mounting both physical and virtual file systems.
By default, unprivileged containers are restricted by the kernel to just
a handful of virtual and network file systems.

To allow mounting physical file systems, system call interception can be used.
LXD offers a variety of options to handle this.

[`security.syscalls.intercept.mount`](reference/instance_options.md#instance-security:security.syscalls.intercept.mount) is used to control the entire
feature and needs to be turned on for any of the other options to work.

[`security.syscalls.intercept.mount.allowed`](reference/instance_options.md#instance-security:security.syscalls.intercept.mount.allowed) allows specifying a list of
file systems which can be directly mounted in the container. This is the
most dangerous option as it allows the user to feed data that is not trusted at
the kernel. This can easily be used to crash the host system or to
attack it. It should only ever be used in trusted environments.

[`security.syscalls.intercept.mount.shift`](reference/instance_options.md#instance-security:security.syscalls.intercept.mount.shift) can be set on top of that so
the resulting mount is shifted to the UID/GID map used by the container.
This is needed to avoid everything showing up as `nobody`/`nogroup` inside
of unprivileged containers.

The much safer alternative to those is
[`security.syscalls.intercept.mount.fuse`](reference/instance_options.md#instance-security:security.syscalls.intercept.mount.fuse) which can be set to pairs of
file-system name and FUSE handler. When this is set, an attempt at
mounting one of the configured file systems will be transparently
redirected to instead calling the FUSE equivalent of that file system.

As this is all running as the caller, it avoids the entire issue around
the kernel attack surface and so is generally considered to be safe,
though you should keep in mind that any kind of system call interception
makes for an easy way to overload the host system.

### `sched_setscheduler`

The `sched_setscheduler` system call is used to manage process priority.

Granting this may allow a user to significantly increase the priority of
their processes, potentially taking a lot of system resources.

It also allows access to schedulers like `SCHED_FIFO` which are generally
considered to be flawed and can significantly impact overall system
stability. This is why under normal conditions, only the real root user
(or global `CAP_SYS_NICE`) would allow its use.

<a id="syscall-setxattr"></a>

### `setxattr`

The `setxattr` system call is used to set extended attributes on files.

The attributes which are handled by this currently are:

- `trusted.overlay.opaque` (OverlayFS directory whiteout)

Note that because the mediation must happen on a number of character
strings, there is no easy way at present to only intercept the few
attributes we care about. As we only allow the attributes above, this
may result in breakage for other attributes that would have been
previously allowed by the kernel.

This can be enabled by setting [`security.syscalls.intercept.setxattr`](reference/instance_options.md#instance-security:security.syscalls.intercept.setxattr) to `true`.

### `sysinfo`

The `sysinfo` system call is used by some distributions instead of `/proc/` entries to report on resource usage.

In order to provide resource usage information specific to the container, rather than the whole system, this
syscall interception mode uses cgroup-based resource usage information to fill in the system call response.


# index.html.md

<a id="remotes"></a>

# How to add remote servers

#### NOTE
Remote servers are a concept in the LXD CLI.

If you are using the UI or the API, you can interact with different remotes by using their exposed UI or API addresses instead.

By default, the command-line client interacts with the local LXD daemon, but you can add other servers or clusters to interact with.

One use case for remote servers is to distribute images that can be used to create instances on local servers.
See [Remote image servers](reference/remote_image_servers.md#remote-image-servers) for more information.

You can also add a full LXD server as a remote server to your client.
In this case, you can interact with the remote server in the same way as with your local daemon.
For example, you can manage instances or update the server configuration on the remote server.

## Authentication

To be able to add a LXD server as a remote server, the server’s API must be exposed, which means that its [`core.https_address`](server.md#server-core:core.https_address) server configuration option must be set.

When adding the server, you must then authenticate with it using the chosen method for [Remote API authentication](authentication.md#authentication).

See [How to expose LXD to the network](howto/server_expose.md#server-expose) for more information.

## List configured remotes

<!-- Include parts of the content from file [howto/images_remote.md](howto/images_remote.md) -->

To see all configured remote servers, enter the following command:

```none
lxc remote list
```

Remote servers that use the [simple streams format](https://git.launchpad.net/simplestreams/tree/) are pure image servers.
Servers that use the `lxd` format are LXD servers, which either serve solely as image servers or might provide some images in addition to serving as regular LXD servers.
See [Remote server types](reference/remote_image_servers.md#remote-image-server-types) for more information.

## Add a remote LXD server

<!-- Include parts of the content from file [howto/images_remote.md](howto/images_remote.md) -->

To add a LXD server as a remote, enter the following command:

```none
lxc remote add <remote_name> <IP|FQDN|URL|token> [flags]
```

Some authentication methods require specific flags (for example, use [`lxc remote add <remote_name> <IP|FQDN|URL> --auth-type=oidc`](reference/manpages/lxc/remote/add.md#lxc-remote-add-md) for OIDC authentication).
See [Authenticate with the LXD server](howto/server_expose.md#server-authenticate) and [Remote API authentication](authentication.md#authentication) for more information.

For example, enter the following command to add a remote through an IP address:

```none
lxc remote add my-remote 192.0.2.10
```

You are prompted to confirm the remote server fingerprint and then asked for the token.

## Select a default remote

The LXD command-line client is pre-configured with the `local` remote, which is the local LXD daemon.

To select a different remote as the default remote, enter the following command:

```none
lxc remote switch <remote_name>
```

To see which server is configured as the default remote, enter the following command:

```none
lxc remote get-default
```

## Configure a global remote

You can configure remotes on a global, per-system basis.
These remotes are available for every user of the LXD server for which you add the configuration.

Users can override these system remotes (for example, by running [`lxc remote rename`](reference/manpages/lxc/remote/rename.md#lxc-remote-rename-md) or [`lxc remote set-url`](reference/manpages/lxc/remote/set-url.md#lxc-remote-set-url-md)), which results in the remote and its associated certificates being copied to the user configuration.

To configure a global remote, edit the `config.yml` file that is located in one of the following directories:

- the directory specified by `LXD_GLOBAL_CONF` (if defined)
- `/var/snap/lxd/common/global-conf/` (if you use the snap)
- `/etc/lxd/` (otherwise)

Certificates for the remotes must be stored in the `servercerts` directory in the same location (for example, `/etc/lxd/servercerts/`).
They must match the remote name (for example, `foo.crt`).

See the following example configuration:

```default
remotes:
  foo:
    addr: https://192.0.2.4:8443
    auth_type: tls
    project: default
    protocol: lxd
    public: false
  bar:
    addr: https://192.0.2.5:8443
    auth_type: tls
    project: default
    protocol: lxd
    public: false
```


# index.html.md

<a id="profiles"></a>

# How to use profiles

Profiles store a set of configuration options.
They can contain [Instance options](reference/instance_options.md#instance-options), [Devices](reference/devices.md#devices), and device options.

You can apply any number of profiles to an instance.
They are applied in the order they are specified, so the last profile to specify a specific key takes precedence.
However, instance-specific configuration always overrides the configuration coming from the profiles.

#### NOTE
Profiles can be applied to containers and virtual machines.
Therefore, they might contain options and devices that are valid for either type.

When applying a profile that contains configuration that is not suitable for the instance type, this configuration is ignored and does not result in an error.

If you don’t specify any profiles when launching a new instance, the `default` profile is applied automatically.
This profile defines a network interface and a root disk.
The `default` profile cannot be renamed or removed.

## View profiles

CLI

Enter the following command to display a list of all available profiles:

```none
lxc profile list
```

Enter the following command to display the contents of a profile:

```none
lxc profile show <profile_name>
```

API

To display all available profiles, send a request to the `/1.0/profiles` endpoint:

```none
lxc query --request GET /1.0/profiles?recursion=1
```

To display a specific profile, send a request to that profile:

```none
lxc query --request GET /1.0/profiles/<profile_name>
```

See [`GET /1.0/profiles`](/api/#/profiles/profiles_get) and [`GET /1.0/profiles/{name}`](/api/#/profiles/profile_get) for more information.

UI

Go to the Profiles section to view all available profiles.

To view information about a specific profile, click its line in the overview.
To display the full information about a profile, including its configuration, click the profile name to go to the profile detail page.

## Create an empty profile

CLI

Enter the following command to create an empty profile:

```none
lxc profile create <profile_name>
```

API

To create an empty profile, send a POST request to the `/1.0/profiles` endpoint:

```none
lxc query --request POST /1.0/profiles --data '{"name": "<profile_name>"}'
```

See [`POST /1.0/profiles`](/api/#/profiles/profiles_post) for more information.

UI

To create a profile, go to the Profiles section and click Create profile.

Enter at least a profile name and click Create to save the new profile.

<a id="profiles-edit"></a>

## Edit a profile

You can either set specific configuration options for a profile or edit the full profile.
See [Instance configuration](explanation/instance_config.md#instance-config) (and its subpages) for the available options.

<a id="profiles-set-options"></a>

### Set specific options for a profile

CLI

To set an instance option for a profile, use the [`lxc profile set`](reference/manpages/lxc/profile/set.md#lxc-profile-set-md) command.
Specify the profile name and the key and value of the instance option:

```none
lxc profile set <profile_name> <option_key>=<option_value> <option_key>=<option_value> ...
```

To add and configure an instance device for your profile, use the [`lxc profile device add`](reference/manpages/lxc/profile/device/add.md#lxc-profile-device-add-md) command.
Specify the profile name, a device name, the device type and maybe device options (depending on the [device type](reference/devices.md#devices)):

```none
lxc profile device add <profile_name> <device_name> <device_type> <device_option_key>=<device_option_value> <device_option_key>=<device_option_value> ...
```

To configure instance device options for a device that you have added to the profile earlier, use the [`lxc profile device set`](reference/manpages/lxc/profile/device/set.md#lxc-profile-device-set-md) command:

```none
lxc profile device set <profile_name> <device_name> <device_option_key>=<device_option_value> <device_option_key>=<device_option_value> ...
```

API

To set an instance option for a profile, send a PATCH request to the profile.
Specify the key and value of the instance option under the `"config"` field:

```none
lxc query --request PATCH /1.0/profiles/<profile_name> --data '{
  "config": {
    "<option_key>": "<option_value>",
    "<option_key>": "<option_value>"
  }
}'
```

To add and configure an instance device for your profile, specify the device name, the device type and maybe device options (depending on the [device type](reference/devices.md#devices)) under the `"devices"` field:

```none
lxc query --request PATCH /1.0/profiles/<profile_name> --data '{
  "devices": {
    "<device_name>": {
      "type": "<device_type>",
      "<device_option_key>": "<device_option_value>",
      "<device_option_key>": "<device_option_value>"
    }
  }
}'
```

See [`PATCH /1.0/profiles/{name}`](/api/#/profiles/profile_patch) for more information.

UI

To configure a profile, select it from the Profiles overview, switch to the Configuration tab and click Edit profile.
You can then configure options for the profile in the same way as you [configure instance options](howto/instances_configure.md#instances-configure-options).

### Edit the full profile

Instead of setting each configuration option separately, you can provide all options at once.

Check the contents of an existing profile or instance configuration for the required fields.
For example, the `default` profile might look like this:

```none
config: {}
description: Default LXD profile
devices:
  eth0:
    name: eth0
    network: lxdbr0
    type: nic
  root:
    path: /
    pool: default
    type: disk
name: default
used_by:
```

Instance options are provided as an array under `config`.
Instance devices and instance device options are provided under `devices`.

CLI

To edit a profile using your standard terminal editor, enter the following command:

```none
lxc profile edit <profile_name>
```

Alternatively, you can create a YAML file (for example, `profile.yaml`) with the configuration and write the configuration to the profile with the following command:

```none
lxc profile edit <profile_name> < profile.yaml
```

API

To update the entire profile configuration, send a PUT request to the profile:

```none
lxc query --request PUT /1.0/profiles/<profile_name> --data '{
  "config": { ... },
  "description": "<description>",
  "devices": { ... }
}'
```

See [`PUT /1.0/profiles/{name}`](/api/#/profiles/profile_put) for more information.

UI

To edit the YAML configuration of a profile, go to the profile detail page, switch to the Configuration tab and select YAML configuration.
Then click Edit profile.

Edit the YAML configuration as required.
Then click Save changes to save the updated configuration.

#### IMPORTANT
When doing updates, do not navigate away from the YAML configuration without saving your changes.
If you do, your updates are lost.

## Apply a profile to an instance

CLI

Enter the following command to apply a profile to an instance:

```none
lxc profile add <instance_name> <profile_name>
```

You can also specify profiles when launching an instance by adding the `--profile` flag:

```none
lxc launch <image> <instance_name> --profile <profile> --profile <profile> ...
```

API

To apply a profile to an instance, add it to the profile list in the instance configuration:

```none
lxc query --request PATCH /1.0/instances/<instance_name> --data '{
  "profiles": [ "default", "<profile_name>" ]
}'
```

See [`PATCH /1.0/instances/{name}`](/api/#/instances/instance_patch) for more information.

You can also specify profiles when [creating an instance](howto/instances_create.md#instances-create):

```none
lxc query --request POST /1.0/instances --data '{
  "name": "<instance_name>",
  "profiles": [ "default", "<profile_name>" ],
  "source": {
    "alias": "<image_alias>",
    "protocol": "simplestreams",
    "server": "<server_URL>",
    "type": "image"
  }
}'
```

UI

To apply a profile to an instance, select the instance from the Instances overview, switch to the Configuration tab and click Edit instance.
You can then select a profile from the drop-down list, or click Add profile to attach another profile in addition to the one (or more) that are already attached to the instance.

If you attach more than one profile to an instance, you can specify the order in which the profiles are applied by moving each profile up or down the list.

You can also apply profiles in the same way when [creating an instance](howto/instances_create.md#instances-create).

## Remove a profile from an instance

CLI

Enter the following command to remove a profile from an instance:

```none
lxc profile remove <instance_name> <profile_name>
```

API

To remove a profile from an instance, send a PATCH request to the instance configuration with the new profile list.
For example, to revert back to using only the default profile:

```none
lxc query --request PATCH /1.0/instances/<instance_name> --data '{
  "profiles": [ "default" ]
}'
```

See [`PATCH /1.0/instances/{name}`](/api/#/instances/instance_patch) for more information.

UI

To remove a profile from an instance, select the instance from the Instances overview, switch to the Configuration tab and click Edit instance.
Click the Delete link next to a profile to remove it from the instance.


# index.html.md

<a id="instances"></a>

# Instances

These how-to guides cover common operations related to LXD instances.

## Create and manage instances

LXD supports both system containers and virtual machines, configured using direct settings or reusable profiles.

* [Create instances](howto/instances_create.md)
* [Configure instances](howto/instances_configure.md)
* [Manage instances](howto/instances_manage.md)
* [Use profiles](profiles.md)
* [Troubleshoot errors](howto/instances_troubleshoot.md)

## Attach instances to Ubuntu Pro

An LXD server can automatically attach guest instances to its Ubuntu Pro subscription.

* [Auto attach Ubuntu Pro](howto/instances_ubuntu_pro_attach.md)

## Work with instances

Instance files can be accessed from the host, and the instance console can be attached to for log output and debugging. Commands can also be run inside instances through the `lxc` CLI or by opening a shell.

* [Access files](howto/instances_access_files.md)
* [Access the console](howto/instances_console.md)
* [Run commands](instance-exec.md)
* [Use cloud-init](cloud-init.md)
* [Add a routed NIC to a VM](howto/instances_routed_nic_vm.md)

## Back up, import, and migrate instances

Instances can be backed up using snapshots, export files, or copies. Physical machines, as well as virtual machines and containers created using a different technology, can be imported as LXD instances. Instances can also be migrated between LXD servers, including live migration for VMs.

* [Back up instances](howto/instances_backup.md)
* [Import existing machines](howto/import_machines_to_instances.md)
* [Migrate instances](howto/instances_migrate.md)

## Pass through an NVIDIA GPU

An NVIDIA GPU can be passed through to a container running a Docker workload.

* [Pass NVIDIA GPUs](howto/container_gpu_passthrough_with_docker.md)

## Related topics

Explanation:

- [Instance types in LXD](explanation/instances.md#expl-instances)

Reference:

- [Container runtime environment](container-environment.md#container-runtime-environment)
- [Instance configuration](explanation/instance_config.md#instance-config)


# index.html.md

<a id="api-specification"></a>

# Main API specification

<link rel="stylesheet" type="text/css" href="../_static/swagger-ui/swagger-ui.css" ></link>
<link rel="stylesheet" type="text/css" href="../_static/swagger-override.css" ></link>
<div id="swagger-ui"></div>
<script src="../_static/swagger-ui/swagger-ui-bundle.js" charset="UTF-8"> </script>
<script src="../_static/swagger-ui/swagger-ui-standalone-preset.js" charset="UTF-8"> </script>
<script>
window.onload = function() {
  // Begin Swagger UI call region
  const ui = SwaggerUIBundle({
    url: window.location.pathname +"../rest-api.yaml",
    dom_id: '#swagger-ui',
    deepLinking: true,
    presets: [
      SwaggerUIBundle.presets.apis,
      SwaggerUIStandalonePreset
    ],
    plugins: [],
    validatorUrl: "none",
    defaultModelsExpandDepth: -1,
    supportedSubmitMethods: []
  })
  // End Swagger UI call region

  window.ui = ui
}
</script>


# index.html.md

<a id="restapi"></a>

# REST API

These reference guides cover the REST APIs exposed by LXD, its main API and the DevLXD API.

## The main LXD API

The main LXD API can be used for managing instances, networks, storage, and other resources, and for subscribing to the event log.

* [Main API overview](rest-api.md)
* [Main API specification](api.md)
* [Main API extensions](api-extensions.md)
* [Events stream](events.md)

## DevLXD API

The DevLXD API allows instances to communicate with their host over a Unix socket.

* [DevLXD API for instances](dev-lxd.md)

## Related topics

How-to guides:

- [LXD server and client](operation.md#lxd-server)

Explanation:

- [About `lxd` and `lxc`](explanation/lxd_lxc.md#lxd-lxc)
- [The LXD Dqlite database](database.md#database)


# index.html.md

<a id="installing"></a>

# How to install LXD

There are multiple approaches to installing LXD, depending on your Linux distribution, operating system, and use case.

<a id="installing-snap-package"></a>

## Install the LXD snap package

The recommended way to install LXD is its [snap package](https://snapcraft.io/lxd), available for many Linux distributions. For alternative methods, see: [Other Linux installation options](#installing-other), [Other operating systems](#installing-other-os), or [Install LXD from source](#installing-from-source).

### Requirements

- The LXD snap must be [available for your Linux distribution](https://snapcraft.io/lxd#distros).
- The `snapd` daemon must be installed. See [Install the daemon](https://snapcraft.io/docs/tutorials/install-the-daemon/#tutorials-install-the-daemon-index) in the Snap documentation for details.

### Install

Use this command to install LXD from the recommended [default snap track](reference/releases-snap.md#ref-snap-tracks-default) (currently 5.21):

```bash
sudo snap install lxd
```

If you are installing LXD on a [cluster member](explanation/clusters.md#exp-clusters), add the `--cohort="+"` flag to [keep cluster members synchronized](howto/snap.md#howto-snap-updates-sync) to the same snap version:

```bash
sudo snap install lxd --cohort="+"
```

Next, follow the [Post-installation](#installing-snap-post) steps below.

<a id="installing-snap-channel"></a>

#### Optionally specify a channel

Channels correspond to different [LXD releases](reference/releases-snap.md#ref-releases). When unspecified, the LXD snap defaults to the most recent `stable` LTS, which is recommended for most use cases.

To specify a different channel, add the `--channel` flag at installation:

```bash
sudo snap install lxd --channel=<target channel> [--cohort="+"]
```

For example, to use the `6/stable` channel, run:

```bash
sudo snap install lxd --channel=6/stable
```

For details about LXD snap channels, see: [Channels](reference/releases-snap.md#ref-snap-channels).

<a id="installing-snap-post"></a>

### Post-installation

Follow these steps after installing the LXD snap.

<a id="installing-snap-user"></a>

#### Add the current user

To allow the current user to interact with the LXD daemon, update the `lxd` group:

```bash
getent group lxd | grep -qwF "$USER" || sudo usermod -aG lxd "$USER"
```

<!-- Include start newgrp -->

Afterward, apply the change to your current shell session by running:

```bash
newgrp lxd
```

This only applies to the current shell.
You will need to log out and log back in again for the change to appear in a new terminal.

<!-- Include end newgrp -->

For more information, see the [Manage access to LXD](#installing-manage-access) section below.

<a id="installing-snap-hold-updates"></a>

#### Hold or schedule updates

When a new release is published to a snap channel, installed snaps following that channel update automatically by default.

For [LXD clusters](explanation/clusters.md#exp-clusters), or on any machine where you want control over updates, you should override this default behavior by either holding or scheduling updates. See: [Manage updates](howto/snap.md#howto-snap-updates).

<a id="installing-other"></a>

## Other Linux installation options

Some Linux installations can use package managers other than Snap to install LXD. These managers all install the latest [feature release](reference/releases-snap.md#ref-releases-feature).

Alpine Linux

Run:

```bash
apk add lxd
```

Arch Linux

Run:

```bash
pacman -S lxd
```

Fedora

Fedora RPM packages for LXC/LXD are available in the [COPR repository](https://copr.fedorainfracloud.org/coprs/ganto/lxc4/). These are unofficial and minimally tested; use at your own risk.

View the [installation guide](https://github.com/ganto/copr-lxc4/wiki) for details.

Gentoo

Run:

```bash
emerge --ask lxd
```

Following installation, make sure to [manage access to LXD](#installing-manage-access).

<a id="installing-other-os"></a>

## Other operating systems

Builds of the [`lxc`](reference/manpages/lxc.md#lxc-md) client are available for non-Linux operating systems to enable interaction with remote LXD servers. For more information, see: [About `lxd` and `lxc`](explanation/lxd_lxc.md#lxd-lxc).

macOS

The [Homebrew](https://brew.sh) package manager must be installed on your system.

To install the client from the latest [feature release](reference/releases-snap.md#ref-releases-feature) of LXD, run:

```bash
brew install lxc
```

Windows

The [Chocolatey](https://chocolatey.org) package manager must be installed on your system.

To install the client from the latest [feature release](reference/releases-snap.md#ref-releases-feature) of LXD, run:

```bash
choco install lxc
```

<a id="installing-native"></a>

## Native builds of the client

You can find native builds of the [`lxc`](reference/manpages/lxc.md#lxc-md) client on [GitHub](https://github.com/canonical/lxd):

- Linux: [`bin.linux.lxc.aarch64`](https://github.com/canonical/lxd/releases/latest/download/bin.linux.lxc.aarch64), [`bin.linux.lxc.x86_64`](https://github.com/canonical/lxd/releases/latest/download/bin.linux.lxc.x86_64)
- Windows: [`bin.windows.lxc.aarch64.exe`](https://github.com/canonical/lxd/releases/latest/download/bin.windows.lxc.aarch64.exe), [`bin.windows.lxc.x86_64.exe`](https://github.com/canonical/lxd/releases/latest/download/bin.windows.lxc.x86_64.exe)
- macOS: [`bin.macos.lxc.aarch64`](https://github.com/canonical/lxd/releases/latest/download/bin.macos.lxc.aarch64), [`bin.macos.lxc.x86_64`](https://github.com/canonical/lxd/releases/latest/download/bin.macos.lxc.x86_64)

To download a specific build:

1. Make sure that you are logged into your GitHub account.
2. Filter for the branch or tag that you are interested in (for example, the latest release tag or `main`).
3. Select the latest build and download the suitable artifact.

These builds are for the [`lxc`](reference/manpages/lxc.md#lxc-md) client only, not the LXD daemon. For an explanation of the differences, see: [About `lxd` and `lxc`](explanation/lxd_lxc.md#lxd-lxc).

<a id="installing-from-source"></a>

<a id="id1"></a>

## Install LXD from source

These instructions for building and installing from source are suitable for developers who want to build the latest version of LXD, or to build a specific release of LXD which may not be offered by their Linux distribution.
Source builds for integration into Linux distributions are not covered.
This guide is written for Ubuntu 24.04 LTS on x86_64.

We recommend having the latest versions of `liblxc` (see [LXC requirements](requirements.md#requirements-lxc))
available for LXD development. For convenience, `make deps` will pull the
appropriate versions of `liblxc` and `dqlite` from their corresponding upstream
Git repository. Additionally, LXD requires a modern Golang (see
[Go](requirements.md#requirements-go)) version to work. On Ubuntu, you can install these with:

```bash
sudo apt update
sudo apt install \
    autoconf \
    automake \
    build-essential \
    git \
    libacl1-dev \
    libapparmor-dev \
    libcap-dev \
    liblz4-dev \
    libseccomp-dev \
    libsqlite3-dev \
    libtool \
    libudev-dev \
    libuv1-dev \
    xfslibs-dev \
    make \
    meson \
    ninja-build \
    pkg-config \
    python3-venv
command -v snap >/dev/null || sudo apt-get install snapd
sudo snap install --classic go
```

#### NOTE
If you use the `liblxc-dev` package and get compile time errors when building the `go-lxc` module,
ensure that the value for `LXC_DEVEL` is `0` for your `liblxc` build. To check this, look at `/usr/include/lxc/version.h`.
If the `LXC_DEVEL` value is `1`, replace it with `0` to work around the problem. It’s a packaging bug that is now fixed,
see [LP: #2039873](https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/2039873).

For your local build of LXD to support virtual machines, you must install QEMU with:

```bash
sudo apt install --no-install-recommends \
    qemu-system-x86 \
    qemu-block-extra \
    qemu-utils \
    qemu-system-modules-spice \
    virtiofsd \
    ovmf \
    swtpm
```

There are a few storage drivers for LXD besides the default `dir` driver. Installing these tools adds a bit to `initramfs` and may slow down your host boot, but are needed if you’d like to use a particular driver:

```bash
sudo apt install lvm2 thin-provisioning-tools
sudo apt install btrfs-progs
```

At runtime, LXD might need the following packages to be installed on the host system:

```bash
sudo apt update
sudo apt install \
    attr \
    iproute2 \
    nftables \
    rsync \
    squashfs-tools \
    squashfs-tools-ng \
    tar \
    xz-utils

# `nftables` can be replaced by `iptables` on older systems
```

To run the test suite or test related `make` targets, you’ll also need:

```bash
sudo apt update
sudo apt install \
    acl \
    bind9-dnsutils \
    btrfs-progs \
    busybox-static \
    curl \
    dnsmasq-base \
    dosfstools \
    e2fsprogs \
    expect \
    iputils-ping \
    jq \
    netcat-openbsd \
    s3cmd \
    shellcheck \
    socat \
    sqlite3 \
    swtpm \
    xdelta3 \
    xfsprogs \
    yq
```

### From source: Build the latest version

These instructions for building from source are suitable for individual developers who want to build the latest version
of LXD, or build a specific release of LXD which may not be offered by their Linux distribution. Source builds for
integration into Linux distributions are not covered here and may be covered in detail in a separate document in the
future.

```bash
git clone https://github.com/canonical/lxd
cd lxd
```

This will download the current development tree of LXD and place you in the source tree.
Then proceed to the instructions below to actually build and install LXD.

### From source: Build a release

The LXD release tarballs bundle a complete dependency tree as well as a
local copy `libdqlite` for LXD’s database setup.

```bash
tar zxvf lxd-4.18.tar.gz
cd lxd-4.18
```

This will unpack the release tarball and place you inside of the source tree.
Then proceed to the instructions below to actually build and install LXD.

### Start the build

The actual building is done by two separate invocations of the `Makefile`: `make deps` – which builds libraries required
by LXD – and `make`, which builds LXD itself. At the end of `make deps`, a message will be displayed which will specify environment variables that should be set prior to invoking `make`. As new versions of LXD are released, these environment
variable settings may change, so be sure to use the ones displayed at the end of the `make deps` process, as the ones
below (shown for example purposes) may not exactly match what your version of LXD requires:

We recommend having at least 2GiB of RAM to allow the build to complete.

`user@host:~$ ``make deps
`
```text
...
make[1]: Leaving directory '/root/go/deps/dqlite'
# environment

Please set the following in your environment (possibly ~/.bashrc)
#  export CGO_CFLAGS="${CGO_CFLAGS} -I$(go env GOPATH)/deps/dqlite/include/"
#  export CGO_LDFLAGS="${CGO_LDFLAGS} -L$(go env GOPATH)/deps/dqlite/.libs/"
#  export LD_LIBRARY_PATH="$(go env GOPATH)/deps/dqlite/.libs/${LD_LIBRARY_PATH}"
#  export CGO_LDFLAGS_ALLOW="(-Wl,-wrap,pthread_create)|(-Wl,-z,now)"
```

`user@host:~$ ``make
`

### From source: Install

Once the build completes, you simply keep the source tree, add the directory referenced by `$(go env GOPATH)/bin` to
your shell path, and set the `LD_LIBRARY_PATH` variable printed by `make deps` to your environment. This might look
something like this for a `~/.bashrc` file:

```bash
export PATH="${PATH}:$(go env GOPATH)/bin"
export LD_LIBRARY_PATH="$(go env GOPATH)/deps/dqlite/.libs/:${LD_LIBRARY_PATH}"
```

Now, the `lxd` and `lxc` binaries will be available to you and can be used to set up LXD. The binaries will automatically find and use the dependencies built in `$(go env GOPATH)/deps` thanks to the `LD_LIBRARY_PATH` environment variable.

### Machine setup

You’ll need sub{u,g}ids for root, so that LXD can create the unprivileged containers:

```bash
echo "root:1000000:1000000000" | sudo tee -a /etc/subuid /etc/subgid
```

By default, only users added to the `lxd` group can interact with the LXD daemon. Installing from source doesn’t guarantee that the `lxd` group exists in the system. If you want the current user (or any other user) to be able to interact with the LXD daemon, create the group and add the user to it:

```bash
getent group lxd >/dev/null || sudo groupadd --system lxd # create the group if needed
getent group lxd | grep -qwF "$USER" || sudo usermod -aG lxd "$USER"
```

Afterward, apply the change to your current shell session by running:

```bash
newgrp lxd
```

This only applies to the current shell.
You will need to log out and log back in again for the change to appear in a new terminal.

Now you can run the daemon (the `--group lxd` bit allows everyone in the `lxd`
group to talk to LXD):

```bash
sudo PATH=${PATH} LD_LIBRARY_PATH=${LD_LIBRARY_PATH} $(go env GOPATH)/bin/lxd --group lxd
```

#### NOTE
If `newuidmap/newgidmap` tools are present on your system and `/etc/subuid`, `/etc/subgid` exist, they must be configured to allow the root user a contiguous range of at least 65536 UIDs/GIDs.

### Shell completions

Shell completion profiles can be generated with `lxc completion <shell>` (e.g. `lxc completion bash`). Supported shells are `bash`, `zsh`, `fish`, and `powershell`.

```bash
lxc completion bash > /etc/bash_completion.d/lxc # generating completions for bash as an example
. /etc/bash_completion.d/lxc
```

<a id="installing-manage-access"></a>

## Manage access to LXD

Access control for LXD is based on group membership. The root user and all members of the `lxd` group can interact with the local daemon.

On Ubuntu images, the `lxd` group already exists and the root user is automatically added to it. The group is also created during installation if you [installed LXD from the snap](#installing-snap-package).

To check if the `lxd` group exists, run:

```bash
getent group lxd
```

If this command returns no result, the `lxd` group is missing from your system. This might be the case if you [installed LXD from source](#installing-from-source). To create the group and restart the LXD daemon, run:

```bash
getent group lxd >/dev/null || sudo groupadd --system lxd
```

Afterward, add trusted users to the group so they can use LXD. The following command adds the current user:

```bash
getent group lxd | grep -qwF "$USER" || sudo usermod -aG lxd "$USER"
```

Afterward, apply the change to your current shell session by running:

```bash
newgrp lxd
```

This only applies to the current shell.
You will need to log out and log back in again for the change to appear in a new terminal.

<a id="installing-upgrade"></a>

## Updates and upgrades

For information on updates and upgrades, see the relevant sections in the following guides:

How-to guide:

- [How to manage the LXD snap](howto/snap.md#howto-snap)

Reference:

- [Releases and snap](reference/releases-snap.md#ref-releases-snap)


# index.html.md

# Frequently asked questions

The following sections give answers to frequently asked questions.
They explain how to resolve common issues and point you to more detailed information.

## Why do my instances not have network access?

Most likely, your firewall blocks network access for your instances.
See [How to configure your firewall](howto/network_bridge_firewalld.md#network-bridge-firewall) for more information about the problem and how to fix it.

Another frequent reason for connectivity issues is running LXD and Docker on the same host.
See [Prevent connectivity issues with LXD and Docker](howto/network_bridge_firewalld.md#network-lxd-docker) for instructions on how to fix such issues.

## How to enable the LXD server for remote access?

By default, the LXD server is not accessible from the network, because it only listens on a local Unix socket.

You can enable it for remote access by following the instructions in [How to expose LXD to the network](howto/server_expose.md#server-expose).

## When I do a `lxc remote add`, it asks for a token?

To be able to access the remote API, clients must authenticate with the LXD server.

See [Authenticate with the LXD server](howto/server_expose.md#server-authenticate) for instructions on how to authenticate using a trust token.

## Why should I not run privileged containers?

A privileged container can do things that affect the entire host - for example, it can use things in `/sys` to reset the network card, which will reset it for the entire host, causing network blips.
See [Container security](explanation/security.md#container-security) for more information.

Almost everything can be run in an unprivileged container, or - in cases of things that require unusual privileges, like wanting to mount NFS file systems inside the container - you might need to use bind mounts.

## Can I bind-mount my home directory in a container?

Yes, you can do this by using a [disk device](reference/devices_disk.md#devices-disk):

```none
lxc config device add container-name home disk source=/home/${USER} path=/home/ubuntu
```

For unprivileged containers, you need to make sure that the user in the container has working read/write permissions.
Otherwise, all files will show up as the overflow UID/GID (`65536:65536`) and access to anything that’s not world-readable will fail.
Use either of the following methods to grant the required permissions:

- Pass `shift=true` to the [`lxc config device add`](reference/manpages/lxc/config/device/add.md#lxc-config-device-add-md) call. This depends on the kernel and file system supporting either idmapped mounts (see [`lxc info`](reference/manpages/lxc/info.md#lxc-info-md)).
- Add a `raw.idmap` entry (see [Idmaps for user namespace](userns-idmap.md)).
- Place recursive POSIX ACLs on your home directory.

Privileged containers do not have this issue because all UID/GID in the container are the same as outside.
But that’s also the cause of most of the security issues with such privileged containers.

## How can I run Docker inside a LXD container?


            <p class="youtube_link">
              <a href="https://www.youtube.com/watch?v=_fCSSEyiGro" target="_blank">
                <span title="Running Docker inside of a LXD container" class="play_icon">▶</span>
                <span title="Running Docker inside of a LXD container">Watch on YouTube</span>
              </a>
            </p>
        
To run Docker inside a LXD container, set the [`security.nesting`](reference/instance_options.md#instance-security:security.nesting) option of the container to `true`:

```none
lxc config set <container> security.nesting true
```

If you plan to use the OverlayFS storage driver in Docker, you should also set the [`security.syscalls.intercept.mknod`](reference/instance_options.md#instance-security:security.syscalls.intercept.mknod) and [`security.syscalls.intercept.setxattr`](reference/instance_options.md#instance-security:security.syscalls.intercept.setxattr) options to `true`.
See [`mknod` / `mknodat`](syscall-interception.md#syscall-mknod) and [`setxattr`](syscall-interception.md#syscall-setxattr) for more information.

Note that LXD containers cannot load kernel modules, so depending on your Docker configuration, you might need to have extra kernel modules loaded by the host.
You can do so by setting a comma-separated list of kernel modules that your container needs:

```none
lxc config set <container_name> linux.kernel_modules <modules>
```

In addition, creating a `/.dockerenv` file in your container can help Docker ignore some errors it’s getting due to running in a nested environment.

## Where does the LXD client (`lxc`) store its configuration?

The [`lxc`](reference/manpages/lxc.md#lxc-md) command stores its configuration under `~/.config/lxc`, or in `~/snap/lxd/common/config` for snap users.

Various configuration files are stored in that directory, for example:

- `client.crt`: client certificate (generated on demand)
- `client.key`: client key (generated on demand)
- `config.yml`: configuration file (info about `remotes`, `aliases`, etc.)
- `servercerts/`: directory with server certificates belonging to `remotes`

## Why can I not ping my LXD instance from another host?

Many switches do not allow MAC address changes, and will either drop traffic with an incorrect MAC or disable the port totally.
If you can ping a LXD instance from the host, but are not able to ping it from a different host, this could be the cause.

The way to diagnose this problem is to run a `tcpdump` on the uplink and you will see either `ARP Who has `xx.xx.xx.xx` tell `yy.yy.yy.yy` `, with you sending responses but them not getting acknowledged, or ICMP packets going in and out successfully, but never being received by the other host.

<a id="faq-monitor"></a>

## How can I monitor what LXD is doing?

To see detailed information about what LXD is doing and what processes it is running, use the [`lxc monitor`](reference/manpages/lxc/monitor.md#lxc-monitor-md) command.

For example, to show a human-readable output of all types of messages, enter the following command:

```none
lxc monitor --pretty
```

See [`lxc monitor --help`](reference/manpages/lxc/monitor.md#lxc-monitor-md) for all options, and [How to debug LXD](debugging.md) for more information.

## Why does LXD stall when creating an instance?

Check if your storage pool is out of space (by running [`lxc storage info <pool_name>`](reference/manpages/lxc/storage/info.md#lxc-storage-info-md)).
In that case, LXD cannot finish unpacking the image, and the instance that you’re trying to create shows up as stopped.

To get more insight into what is happening, run [`lxc monitor`](reference/manpages/lxc/monitor.md#lxc-monitor-md) (see [How can I monitor what LXD is doing?](#faq-monitor)), and check `sudo dmesg` for any I/O errors.

## Why does starting containers suddenly fail?

If starting containers suddenly fails with a cgroup-related error message (`Failed to mount "/sys/fs/cgroup"`), this might be due to running a VPN client on the host.

This is a known issue for both [Mullvad VPN](https://github.com/mullvad/mullvadvpn-app/issues/3651) and [Private Internet Access VPN](https://github.com/pia-foss/desktop/issues/50), but might occur for other VPN clients as well.
The problem is that the VPN client mounts the `net_cls` cgroup1 over cgroup2 (which LXD uses).

The easiest fix for this problem is to stop the VPN client and unmount the `net_cls` cgroup1 with the following command:

```none
umount /sys/fs/cgroup/net_cls
```

If you need to keep the VPN client running, mount the `net_cls` cgroup1 in another location and reconfigure your VPN client accordingly.
See [this Discourse post](https://discuss.linuxcontainers.org/t/help-help-help-cgroup2-related-issue-on-ubuntu-jammy-with-mullvad-and-privateinternetaccess-vpn/14705/18) for instructions for Mullvad VPN.

## Why does LXD not start on Ubuntu 22.04 LTS or earlier?

If you are running LXD on Ubuntu 22.04 LTS or earlier, you might be missing support for ZFS 2.2 in the kernel (see the [requirements](requirements.md#requirements-zfs)).

If LXD fails to start, check the `/var/snap/lxd/common/lxd/logs/lxd.log` log file for the following error to see if the reason is missing ZFS support:

```none
Error: Required tool ‘zpool’ is missing
```

If you are on Ubuntu 22.04 LTS, you can resolve the issue by installing the HWE kernel and rebooting the nodes to provide the required kernel drivers for ZFS 2.2:

```none
sudo apt-get update
sudo apt-get install linux-generic-hwe-22.04
```

If you are on earlier versions of Ubuntu, you should use a compatible LTS release of LXD.

<a id="faq-gpu-passthrough-stop"></a>

## Why does my VM stop responding when I try to pass through a GPU?

If you try to pass through a GPU with a large amount of VRAM, the VM might stop responding during boot or fail to start. This is often caused by the default  window size in QEMU being too small to map the GPU’s memory.

To resolve this, stop the instance, then increase the available 64-bit PCI MMIO address space by setting the following values in [`raw.qemu`](reference/instance_options.md#instance-raw:raw.qemu):

```bash
lxc config set <vm-name> raw.qemu='
-global q35-pcihost.pci-hole64-size=2048G
-fw_cfg name=opt/ovmf/X-PciMmio64Mb,string=65536
'
```

These settings reserve sufficient 64-bit MMIO space in both the QEMU host and the guest firmware (), which is required for GPUs with large .


# index.html.md

# LXD

LXD (<a href="#" title="Listen" onclick="document.getElementById('player').play();return false;">`[lɛks'di:]`🔈</a>) is a modern, secure and powerful system container and virtual machine manager.

<audio id="player"><source src="_static/lxd.mp3" type="audio/mpeg"></audio>

<!-- Include content from [../README.md](../README.md) -->

It provides a unified experience for running and managing full Linux systems inside containers or virtual machines. LXD supports images for a large number of Linux distributions (official Ubuntu images and images provided by the community) and is built around a very powerful, yet pretty simple, REST API. LXD scales from one instance on a single machine to a cluster in a full data center rack, making it suitable for running workloads both for development and in production.

LXD allows you to easily set up a system that feels like a small private cloud. You can run any type of workload in an efficient way while keeping your resources optimized.

You should consider using LXD if you want to containerize different environments or run virtual machines, or in general run and manage your infrastructure in a cost-effective way.

---

## In this documentation

### Start here

Follow the tutorial for a guided introduction to LXD, including installing it using its snap.

- **Tutorial**: [Requirements](tutorial/first_steps.md#tutorial-requirements) • [Install LXD using the snap](tutorial/first_steps.md#tutorial-install) • [Create](tutorial/first_steps.md#tutorial-create-instances) and [configure](tutorial/first_steps.md#tutorial-configure) test instances • Learn how to [open an interactive shell](tutorial/first_steps.md#tutorial-shell) into an instance • Learn how to [back up and restore instances](tutorial/first_steps.md#tutorial-snapshots)

### Server and client

These guides help you manage a standalone LXD server or a cluster of servers, including how to access and communicate with servers.

- **Server**: [Server configuration options](server.md#server) • [Expose the server to the network](howto/server_expose.md#server-expose)  • [Supported server architectures](architectures.md#architectures)
- **Clusters**: [About clusters](explanation/clusters.md#exp-clusters) • [Form a cluster](howto/cluster_form.md#cluster-form) • [Use placement groups for instance distribution across a cluster](howto/cluster_placement_groups.md#cluster-placement-groups) • [Recover a cluster](howto/cluster_recover.md#cluster-recover) • [Set up a highly available virtual IP](howto/cluster_vip.md#howto-cluster-vip)
- **Access**: [Access the graphical UI](howto/access_ui.md#access-ui) • [Authentication](authentication.md#authentication) and [authorization](explanation/authorization.md#authorization) • [Use single sign-on with OIDC](howto/oidc.md#howto-oidc) • [Use bearer tokens](howto/auth_bearer.md#howto-auth-bearer) • [Permissions reference](reference/permissions.md#permissions-reference) • [Add remote servers](remotes.md#remotes) • [Instances grouping with projects](explanation/projects.md#exp-projects)
- **Client-server communication**: [REST API reference](reference/index.md#reference-api) • [lxc CLI man pages](reference/manpages.md#reference-manpages) • About the [lxd and lxc](explanation/lxd_lxc.md#lxd-lxc) CLIs

### Workload management

An LXD server runs workloads on containers or virtual machines, which are created using images and can be grouped using projects.

- **Instances**: [System containers and virtual machines](explanation/instances.md#containers-and-vms) • [Guest OS compatibility matrix](guest-os-compatibility.md#guest-os-compatibility) • [Create](howto/instances_create.md#instances-create), [configure](howto/instances_configure.md#instances-configure), and [manage](howto/instances_manage.md#instances-manage) instances • [Configuration options](reference/instance_options.md#instance-options) • [Store configuration options in profiles](profiles.md#profiles) • [Automate configuration with cloud-init](cloud-init.md#cloud-init) • [Back up](howto/instances_backup.md#instances-backup), [migrate](howto/instances_migrate.md#howto-instances-migrate), and [import](howto/import_machines_to_instances.md#import-machines-to-instances) instances • [Live migration](howto/instances_migrate.md#live-migration)
- **Images**: [About local and remote images](image-handling.md#about-images) • [List of remote image servers](reference/remote_image_servers.md#remote-image-servers) •  [Manage images](howto/images_manage.md#images-manage)
- **Projects**: [Create and configure projects](howto/projects_create.md#projects-create) • [Confine users to projects](howto/projects_confine.md#projects-confine) • [About grouping instances](explanation/projects.md#exp-projects)

### Storage and networks

Each LXD server is configured with storage and network options. These guides will help you understand and work with these resources.

- **Storage**: [Storage concepts](explanation/storage.md#exp-storage) • [Driver types and configuration options](reference/storage_drivers.md#storage-drivers) • Manage [pools](howto/storage_pools.md#howto-storage-pools), [volumes](howto/storage_volumes.md#howto-storage-volumes), and [buckets](howto/storage_buckets.md#howto-storage-buckets) • [Back up volumes](howto/storage_backup_volume.md#howto-storage-backup-volume) • [Move or copy volumes](howto/storage_move_volume.md#howto-storage-move-volume)
- **Networks**: [Networking setups](explanation/networks.md#networks) • [Network types and configuration options](howto/network_create.md#network-types) • [Create](howto/network_create.md#network-create) and [configure](howto/network_configure.md#network-configure) networks • Configure [ACLs](howto/network_acls.md#network-acls), [forwards](howto/network_forwards.md#network-forwards), and [load balancers](howto/network_load_balancers.md#network-load-balancers) • [Configure a firewall](howto/network_bridge_firewalld.md#network-bridge-firewall)

### Lifecycle and administration

These guides cover lifecycle and ongoing administration concerns, such as installation (including non-snap options), production deployment setup, and security.

- **Lifecycle**: [Installation](installing.md#installing) • [Initialization](howto/initialize.md#initialize) • [Releases and snap reference](reference/releases-snap.md#ref-releases-snap)  • [Snap updates and upgrades](howto/snap.md#howto-snap-updates-upgrades) • [Release notes](reference/release-notes/index.md#ref-release-notes)
- **Production setup**: [Production server settings](reference/index.md#reference-production) • [Back up a server](backup.md#backups) • [Benchmark performance](howto/benchmark_performance.md#benchmark-performance) • [Monitor metrics](metrics.md#metrics) • [Perform disaster recovery](howto/disaster_recovery.md#disaster-recovery) • [Performance tuning](explanation/performance_tuning.md#performance-tuning)
- **Security**: [Overview](explanation/security.md#security) • [Harden security](howto/security_harden.md#howto-security-harden) • [Instance security policies](reference/instance_options.md#instance-options-security)

## How this documentation is organized

This documentation uses the Diátaxis documentation structure.

- The [Tutorial](tutorial/first_steps.md#first-steps) takes you step-by-step through installing and initializing LXD, and learning how to use basic features such as launching instances.
- The [How-to guides](howto/index.md#howtos) assume you have basic familiarity with LXD. They walk you through specific tasks, such as creating storage pools and managing clusters.
- The [Reference](reference/index.md#reference) guides include configuration options, API references, and other technical details.
- The [Explanation](explanation/index.md#explanation) section includes topic overviews and detailed explanations of key concepts, such as the difference between system containers and virtual machines.

## Project and community

LXD is a member of the [Canonical](https://canonical.com) family. It’s an open source project that warmly welcomes community contributions, suggestions, fixes, and constructive feedback.

### Get involved

- [Support](support.md#support)
- [Discussion forum](https://discourse.ubuntu.com/c/project/lxd/126)
- [Contribute](contributing.md#howto-contribute)
- [YouTube channel](https://www.youtube.com/c/LXDvideos)

### Releases

- [Release notes](reference/release-notes/index.md#ref-release-notes)
- [Release tarballs](https://github.com/canonical/lxd/releases/)

### Governance and policies

- [Code of conduct](https://ubuntu.com/community/docs/ethos/code-of-conduct)

### Commercial support

Thinking about using LXD for your next project? [Get in touch](https://canonical.com/contact-us)!


# index.html.md

<a id="guest-os-compatibility"></a>

# Guest OS compatibility

## Virtual machines

The following operating systems (OS) were tested as virtual machine guest running on top of on LXD `5.21/stable`. Each OS was tested by doing a manual installation using the official ISO as provided by the vendor.

| OS vendor   | OS version                        | OS support   | [LXD agent]()                                | VirtIO-SCSI   | VirtIO-BLK              | NVMe                    | CSM (BIOS)              | UEFI   | Secure Boot   |
|-------------|-----------------------------------|--------------|----------------------------------------------|---------------|-------------------------|-------------------------|-------------------------|--------|---------------|
| CentOS      | CentOS 6.10 <sup>[1](#id17)</sup> | EOL          | ❌ <sup>[2](#id18)</sup>                      | ✅             | ❌ <sup>[6](#id22)</sup> | 🟢                       | ✅                       | ❌      | ❌             |
| CentOS      | CentOS 7.9                        | EOL          | ❌ <sup>[2](#id18)</sup>                      | ✅             | 🟢                       | 🟢                       | 🟢                       | ✅      | ✅             |
| CentOS      | CentOS 8.5                        | EOL          | ✅                                            | ✅             | 🟢                       | 🟢                       | 🟢                       | ✅      | ✅             |
| CentOS      | CentOS 8-Stream                   | EOL          | ✅                                            | ✅             | 🟢                       | 🟢                       | 🟢                       | ✅      | ✅             |
| CentOS      | CentOS 9-Stream                   | Supported    | ✅                                            | ✅             | 🟢                       | 🟢                       | 🟢                       | ✅      | ✅             |
| Red Hat     | RHEL 7.9                          | EOL          | ❌ <sup>[2](#id18)</sup>                      | ✅             | 🟢                       | 🟢                       | 🟢                       | ✅      | ✅             |
| Red Hat     | RHEL 8.10                         | Supported    | ✅                                            | ✅             | 🟢                       | 🟢                       | 🟢                       | ✅      | ✅             |
| Red Hat     | RHEL 9.4                          | Supported    | ✅                                            | ✅             | 🟢                       | 🟢                       | 🟢                       | ✅      | ✅             |
| SUSE        | SLES 12 SP5                       | Supported    | ✅                                            | ✅             | 🟢                       | 🟢                       | 🟢                       | ✅      | ✅             |
| SUSE        | SLES 15 SP6                       | Supported    | ✅                                            | ✅             | 🟢                       | 🟢                       | 🟢                       | ✅      | ✅             |
| Ubuntu      | 14.04.6 LTS                       | EOL          | ❌ <sup>[7](#id23)</sup>                      | ✅             | 🟢                       | 🟢                       | 🟢                       | ✅      | ✅             |
| Ubuntu      | 16.04.7 LTS                       | ESM          | ✅ <sup>[8](#id24)</sup><sup>[9](#id25)</sup> | ✅             | 🟢                       | 🟢                       | 🟢                       | ✅      | ✅             |
| Ubuntu      | 18.04.6 LTS                       | ESM          | ✅ <sup>[9](#id25)</sup>                      | ✅             | 🟢                       | 🟢                       | 🟢                       | ✅      | ✅             |
| Ubuntu      | 20.04.6 LTS                       | Supported    | ✅                                            | ✅             | 🟢                       | 🟢                       | 🟢                       | ✅      | ✅             |
| Ubuntu      | 22.04.4 LTS                       | Supported    | ✅                                            | ✅             | 🟢                       | 🟢                       | 🟢                       | ✅      | ✅             |
| Ubuntu      | 24.04.1 LTS                       | Supported    | ✅                                            | ✅             | 🟢                       | 🟢                       | 🟢                       | ✅      | ✅             |
| Windows     | Server 2012                       | Supported    | ➖                                            | ✅             | 🟢                       | ❌                       | 🟢                       | ✅      | ✅             |
| Windows     | Server 2016                       | Supported    | ➖                                            | ✅             | 🟢                       | 🟢 <sup>[3](#id19)</sup> | ❌ <sup>[5](#id21)</sup> | ✅      | ✅             |
| Windows     | Server 2019                       | Supported    | ➖                                            | ✅             | 🟢                       | 🟢                       | ❌ <sup>[5](#id21)</sup> | ✅      | ✅             |
| Windows     | Server 2022                       | Supported    | ➖                                            | ✅             | 🟢                       | 🟢                       | ❌ <sup>[5](#id21)</sup> | ✅      | ✅             |
| Windows     | 10 22H2                           | Supported    | ➖                                            | ✅             | 🟢                       | 🟢                       | ❌ <sup>[5](#id21)</sup> | ✅      | ✅             |
| Windows     | 11 23H2 <sup>[4](#id20)</sup>     | Supported    | ➖                                            | ✅             | 🟢                       | 🟢                       | ❌                       | ✅      | ✅             |

| Legend         | Icon   |
|----------------|--------|
| recommended    | ✅      |
| supported      | 🟢      |
| not applicable | ➖      |
| not supported  | ❌      |

## Notes

### LXD agent

The LXD agent provides the ability to execute commands inside of the virtual machine guest without relying on traditional access solution like secure shell (SSH) or Remote Desktop Protocol (RDP). This agent is only supported on Linux guests using `systemd`.
For how to manually setup the agent, see [Install the LXD agent into virtual machine instances](howto/instances_create.md#lxd-agent-manual-install).

### BIOS boot

```bash
lxc config set v1 boot.mode=bios
```

### Virtual TPM

```bash
lxc config device add v1 vtpm tpm path=/dev/tpm0
```

### VirtIO-BLK or NVMe

```bash
lxc config device override v1 root io.bus=virtio-blk
# or
lxc config device override v1 root io.bus=nvme
```

### Disconnect the ISO

```bash
lxc config device remove v1 iso
```

## Containers

Unlike virtual machines, container guests rely on the host’s kernel for execution. Since each Linux distribution ships with a unique set of features supported by their official kernels, the possibilities are almost endless.
As such, the following compatibility table focuses on hosts running Ubuntu LTS releases with LXD `5.21/stable` and Ubuntu releases as container guests. The main compatibility factor is the `cgroup` version required by the container and supported by the host.

| Host OS   /  Guest OS                              | Ubuntu 16.04 LTS         | Ubuntu 18.04 LTS   | Ubuntu 20.04 LTS   | Ubuntu 22.04 LTS   | Ubuntu 24.04 LTS   | Ubuntu 24.10             |
|----------------------------------------------------|--------------------------|--------------------|--------------------|--------------------|--------------------|--------------------------|
| Ubuntu 20.04 LTS 5.4.0      <sup>[10](#id32)</sup> | 🟢                        | 🟢                  | 🟢                  | 🟢                  | 🟢                  | ❌ <sup>[11](#id33)</sup> |
| Ubuntu 20.04 LTS 5.15.0 (HWE)                      | ✅                        | ✅                  | ✅                  | ✅                  | ✅                  | 🟢 <sup>[12](#id34)</sup> |
| Ubuntu 22.04 LTS 5.15.0                            | 🟢 <sup>[13](#id35)</sup> | ✅                  | ✅                  | ✅                  | ✅                  | ✅                        |
| Ubuntu 22.04 LTS 6.8.0 (HWE)                       | 🟢 <sup>[13](#id35)</sup> | ✅                  | ✅                  | ✅                  | ✅                  | ✅                        |
| Ubuntu 24.04 LTS 6.8.0                             | 🟢 <sup>[13](#id35)</sup> | ✅                  | ✅                  | ✅                  | ✅                  | ✅                        |

| Legend         | Icon   |
|----------------|--------|
| recommended    | ✅      |
| supported      | 🟢      |
| not applicable | ➖      |
| not supported  | ❌      |

---
* <a id='id17'>**[1]**</a> No network support despite having VirtIO-NET module.
* <a id='id18'>**[2]**</a> Support for 9P or `virtiofs` not available. Note: CentOS 7 has a `kernel-plus` kernel with 9P support allowing LXD agent to work (with `selinux=0`).
* <a id='id19'>**[3]**</a> NVMe disks are visible but the installer lists all 255 namespaces slowing down the initialization.
* <a id='id20'>**[4]**</a> A virtual TPM is required.
* <a id='id21'>**[5]**</a> The OS installer stalls when booting in CSM/BIOS mode.
* <a id='id22'>**[6]**</a> The OS installer stalls when booting with VirtIO-BLK despite having VirtIO-BLK supported by the kernel.
* <a id='id23'>**[7]**</a> This Linux version does not use `systemd` which the LXD agent requires.
* <a id='id24'>**[8]**</a> Requires the HWE kernel (`4.15`) for proper `vsock` support which is required by the LXD agent.
* <a id='id25'>**[9]**</a> The `lxd-agent-installer` package is not available so `lxd-agent` has to be manually setup (see [Install the LXD agent into virtual machine instances](howto/instances_create.md#lxd-agent-manual-install)) or through `cloud-init` (see [VM cloud-init](reference/devices_disk.md#vm-cloud-init-config)).
* <a id='id32'>**[10]**</a> The 5.4.0 kernel is below the minimum required version (see [Requirements](requirements.md#requirements))
* <a id='id33'>**[11]**</a> Ubuntu 24.10 and later require `cgroupv2` which is not supported by Ubuntu 20.04 LTS regular kernel.
* <a id='id34'>**[12]**</a> Requires enabling `cgroupv2` support by booting with `systemd.unified_cgroup_hierarchy=1`
* <a id='id35'>**[13]**</a> Requires enabling `cgroupv1` support by booting with `systemd.unified_cgroup_hierarchy=0`


# index.html.md

<a id="clustering"></a>

# Clustering

These how-to guides cover common operations related to clustering in LXD.

## Create and configure clusters

LXD servers can join together as members of a cluster, then be configured for features such as control plane mode and cluster healing.

* [Form a cluster](howto/cluster_form.md)
* [Manage a cluster](howto/cluster_manage.md)
* [Configure networks](howto/cluster_config_networks.md)
* [Configure storage](howto/cluster_config_storage.md)

## Manage instances and cluster groups

Instances on cluster members can be accessed from and migrated to other members. Cluster groups and placement groups can be used to control how instances are distributed across cluster members.

* [Manage instances](howto/cluster_manage_instance.md)
* [Set up cluster groups](howto/cluster_groups.md)
* [Use placement groups](howto/cluster_placement_groups.md)

## Recover clusters or cluster volumes

Quorum loss from member failures and orphaned volume entries from interrupted migrations can both be recovered.

* [Recover a cluster](howto/cluster_recover.md)
* [Recover orphaned volume entries](howto/cluster_recover_volumes.md)

## Set up a virtual IP

A highly available virtual IP provides a stable entry point for client connections even if individual cluster members go offline.

* [Set up a highly available virtual IP](howto/cluster_vip.md)

## Link clusters

Clusters can be linked together for authenticated communication, enabling features such as replicators.

* [Create cluster links](howto/cluster_links_create.md)
* [Manage cluster links](howto/cluster_links_manage.md)

## Use replicators

Replicators continuously copy storage volumes from one LXD cluster to another for disaster recovery purposes.

* [Set up replicators](howto/replicators_create.md)
* [Manage replicators](howto/replicators_manage.md)

## Related topics

Explanation:

- [Clusters](explanation/clusters.md#exp-clusters)

Reference:

- [Clusters](reference/clusters.md#ref-clusters)


# index.html.md

<a id="requirements"></a>

# Requirements

<a id="requirements-go"></a>

## Go

LXD requires Go 1.26.4 or higher and is only tested with the Golang compiler.

We recommend having at least 2GiB of RAM to allow the build to complete.

## Kernel requirements

The minimum supported kernel version is 6.8, but older kernels should also work to some degree.

LXD requires a kernel with support for:

* Namespaces (`pid`, `net`, `uts`, `ipc` and `mount`)
* Seccomp
* Native Linux AIO
  ([`io_setup(2)`](https://man7.org/linux/man-pages/man2/io_setup.2.html), etc.)

The following optional features also require extra kernel options or newer versions:

* Namespaces (`user` and `cgroup`)
* AppArmor (including Ubuntu patch for mount mediation)
* Control Groups (`blkio`, `cpuset`, `devices`, `memory`, `pids` and `net_prio`)
* CRIU (exact details to be found with CRIU upstream)
* SKBPRIO/QFQ qdiscs (for `limits.priority`, minimum kernel 5.17)

As well as any other kernel feature required by the LXC version in use.

<a id="requirements-lxc"></a>

## LXC

LXD requires LXC 5.0.0 or higher with the following build options:

* `apparmor` (if using LXD’s AppArmor support)
* `seccomp`

To run recent version of various distributions, including Ubuntu, LXCFS
should also be installed.

## QEMU

For virtual machines, QEMU 8.2.2 or higher and `virtiofsd` 1.10.0 or higher are required.
Some features like Confidential Guest support require a more recent QEMU and kernel version.

Hardware-assisted virtualization (Intel VT-x, AMD-V, etc) is required for
running virtual machines. Additional hardware support (Intel VT-d, AMD-Vi) may
be required for device pass-through.

<a id="requirements-zfs"></a>

## ZFS

For the ZFS storage driver, ZFS 2.2 or higher is required.

## Additional libraries (and development headers)

LXD uses `dqlite` for its database, to build and set it up, you can
run `make deps`.

LXD itself also uses a number of (usually packaged) C libraries:

* `libacl1`
* `libcap2`
* `liblz4` (for `dqlite`)
* `libuv1` (for `dqlite`)
* `libsqlite3` >= 3.37.2 (for `dqlite`)

Make sure you have all these libraries themselves and their development
headers (`-dev` packages) installed.

## Related topics

Tutorial:

- [First steps with LXD](tutorial/first_steps.md#first-steps)

How-to guides:

- [Getting started](getting_started.md#getting-started)


# index.html.md

<a id="about-images"></a>

# Local and remote images


            <p class="youtube_link">
              <a href="https://www.youtube.com/watch?v=wT7IDjo0Wgg" target="_blank">
                <span title="Image servers and image handling in LXD" class="play_icon">▶</span>
                <span title="Image servers and image handling in LXD">Watch on YouTube</span>
              </a>
            </p>
        
LXD uses an image-based workflow.
Each instance is based on an image, which contains a basic operating system (for example, a Linux distribution) and some LXD-related information.

Images are available from remote image stores (see [Remote image servers](reference/remote_image_servers.md#remote-image-servers) for an overview), but you can also create your own images, either based on an existing instances or a rootfs image.

You can copy images from remote servers to your local image store, or copy local images to remote servers.
You can also use a local image to create a remote instance.

Each image is identified by a fingerprint (SHA256).
To make it easier to manage images, LXD allows defining one or more aliases for each image.

## Caching

When you create an instance using a remote image, LXD downloads the image and caches it locally.
It is stored in the local image store with the cached flag set.
The image is kept locally as a private image until either:

- The image has not been used to create a new instance for the number of days set in [`images.remote_cache_expiry`](server.md#server-images:images.remote_cache_expiry).
- The image’s expiry date (one of the image properties; see [Edit image properties](howto/images_manage.md#images-manage-edit) for information on how to change it) is reached.

LXD keeps track of the image usage by updating the `last_used_at` image property every time a new instance is spawned from the image.

## Auto-update

LXD can automatically keep images that come from a remote server up to date.

#### NOTE
Only images that are requested through an alias can be updated.
If you request an image through a fingerprint, you request an exact image version.

Whether auto-update is enabled for an image depends on how the image was downloaded:

- If the image was downloaded and cached when creating an instance, it is automatically updated if [`images.auto_update_cached`](server.md#server-images:images.auto_update_cached) was set to `true` (the default) at download time.
- If the image was copied from a remote server using the [`lxc image copy`](reference/manpages/lxc/image/copy.md#lxc-image-copy-md) command, it is automatically updated only if the `--auto-update` flag was specified.

You can change this behavior for an image by [editing the `auto_update` property](howto/images_manage.md#images-manage-edit).

On startup and after every [`images.auto_update_interval`](server.md#server-images:images.auto_update_interval) (by default, every six hours), the LXD daemon checks for more recent versions of all the images in the store that are marked to be auto-updated and have a recorded source server.

When a new version of an image is found, it is downloaded into the image store.
Then any aliases pointing to the old image are moved to the new one, and the old image is removed from the store.

To not delay instance creation, LXD does not check if a new version is available when creating an instance from a cached image.
This means that the instance might use an older version of an image for the new instance until the image is updated at the next update interval.

## Special image properties

Image properties that begin with the prefix `requirements` (for example, `requirements.XYZ`) are used by LXD to determine the compatibility of the host system and the instance that is created based on the image.
If these are incompatible, LXD does not start the instance.

The following requirements are supported:

| Key                       | Type   | Default   | Description                                                                     |
|---------------------------|--------|-----------|---------------------------------------------------------------------------------|
| `requirements.secureboot` | string | -         | If set to `false`, indicates that the image cannot boot under secure boot.      |
| `requirements.cgroup`     | string | -         | If set to `v1`, indicates that the image requires the host to run cgroup v1.    |
| `requirements.nesting`    | bool   | -         | If set to `true`, indicates that the image cannot work without nesting enabled. |

## Related topics

How-to guides:

- [Images](images.md#images)

Reference:

- [Image format](reference/image_format.md#image-format)
- [Remote image servers](reference/remote_image_servers.md#remote-image-servers)


# index.html.md

<a id="events"></a>

# Events

## Introduction

Events are messages about actions that have occurred over LXD. Using the API endpoint `/1.0/events` directly or via
[`lxc monitor`](reference/manpages/lxc/monitor.md#lxc-monitor-md) will connect to a WebSocket through which events of the selected types will be streamed.

## Event types

LXD currently supports five event types.

- `logging`: Shows all logging messages regardless of the server logging level.
- `operation`: Shows all ongoing operations from creation to completion (including updates to their state and progress metadata).
- `lifecycle`: Shows an audit trail for specific actions occurring over LXD.
- `ovn`: Shows network-related events from OVN (Open Virtual Network).
- `security`: Shows security-related events including authentication attempts, authorization decisions, and administrative changes. Requires appropriate permissions to view.

## Event structure

### Example

```yaml
location: cluster_name
metadata:
  action: network-updated
  requestor:
    protocol: unix
    username: root
  source: /1.0/networks/lxdbr0
timestamp: "2021-03-14T00:00:00Z"
type: lifecycle
```

- `location`: The cluster member name (if clustered).
- `timestamp`: Time that the event occurred in RFC3339 format.
- `type`: Type of event (one of `logging`, `operation`, `lifecycle`, `ovn`, or `security`).
- `metadata`: Information about the specific event type.

### Logging event structure

- `message`: The log message.
- `level`: The log-level of the log.
- `context`: Additional information included in the event.

<a id="ref-events-operation"></a>

### Operation event structure

- `id`: The UUID of the operation.
- `class`: The type of operation (`task`, `token`, or `websocket`).
- `description`: A description of the operation.
- `created_at`: The operation’s creation date.
- `updated_at`: The operation’s date of last change.
- `status`: The current state of the operation.
- `status_code`: The operation status code.
- `resources`: Resources affected by this operation.
- `metadata`: Operation specific metadata.
- `may_cancel`: Whether the operation may be canceled.
- `err`: Error message of the operation.
- `location`: The cluster member name (if clustered).

### Life-cycle event structure

- `action`: The life-cycle action that occurred.
- `requestor`: Information about who is making the request (if applicable).
- `source`: Path to what is being acted upon.
- `context`: Additional information included in the event.

## Supported life-cycle events

| Name                                   | Description                                                           | Additional Information                                                                               |
|----------------------------------------|-----------------------------------------------------------------------|------------------------------------------------------------------------------------------------------|
| `certificate-created`                  | A new certificate has been added to the server trust store.           |                                                                                                      |
| `certificate-deleted`                  | The certificate has been deleted from the trust store.                |                                                                                                      |
| `certificate-updated`                  | The certificate’s configuration has been updated.                     |                                                                                                      |
| `cluster-certificate-updated`          | The certificate for the whole cluster has changed.                    |                                                                                                      |
| `cluster-disabled`                     | Clustering has been disabled for this machine.                        |                                                                                                      |
| `cluster-enabled`                      | Clustering has been enabled for this machine.                         |                                                                                                      |
| `cluster-group-created`                | A new cluster group has been created.                                 |                                                                                                      |
| `cluster-group-deleted`                | A cluster group has been deleted.                                     |                                                                                                      |
| `cluster-group-renamed`                | A cluster group has been renamed.                                     |                                                                                                      |
| `cluster-group-updated`                | A cluster group has been updated.                                     |                                                                                                      |
| `cluster-member-added`                 | A new machine has joined the cluster.                                 |                                                                                                      |
| `cluster-member-removed`               | The cluster member has been removed from the cluster.                 |                                                                                                      |
| `cluster-member-renamed`               | The cluster member has been renamed.                                  | `old_name`: the previous name.                                                                       |
| `cluster-member-updated`               | The cluster member’s configuration been edited.                       |                                                                                                      |
| `cluster-token-created`                | A join token for adding a cluster member has been created.            |                                                                                                      |
| `config-updated`                       | The server configuration has changed.                                 |                                                                                                      |
| `image-alias-created`                  | An alias has been created for an existing image.                      | `target`: the original instance.                                                                     |
| `image-alias-deleted`                  | An alias has been deleted for an existing image.                      | `target`: the original instance.                                                                     |
| `image-alias-renamed`                  | The alias for an existing image has been renamed.                     | `old_name`: the previous name.                                                                       |
| `image-alias-updated`                  | The configuration for an image alias has changed.                     | `target`: the original instance.                                                                     |
| `image-created`                        | A new image has been added to the image store.                        | `type`: `container` or `vm`.                                                                         |
| `image-deleted`                        | The image has been deleted from the image store.                      |                                                                                                      |
| `image-refreshed`                      | The local image copy has updated to the current source image version. |                                                                                                      |
| `image-retrieved`                      | The raw image file has been downloaded from the server.               | `target`: destination server.                                                                        |
| `image-secret-created`                 | A one-time key to fetch this image has been created.                  |                                                                                                      |
| `image-updated`                        | The image’s configuration has changed.                                |                                                                                                      |
| `instance-backup-created`              | A backup of the instance has been created.                            |                                                                                                      |
| `instance-backup-deleted`              | The instance backup has been deleted.                                 |                                                                                                      |
| `instance-backup-renamed`              | The instance backup has been renamed.                                 | `old_name`: the previous name.                                                                       |
| `instance-backup-retrieved`            | The raw instance backup file has been downloaded.                     |                                                                                                      |
| `instance-console`                     | Connected to the console of the instance.                             | `type`: `console` or `vga`.                                                                          |
| `instance-console-reset`               | The console buffer has been reset.                                    |                                                                                                      |
| `instance-console-retrieved`           | The console log has been downloaded.                                  |                                                                                                      |
| `instance-created`                     | A new instance has been created.                                      |                                                                                                      |
| `instance-deleted`                     | The instance has been deleted.                                        |                                                                                                      |
| `instance-exec`                        | A command has been executed on the instance.                          | `command`: the command to be executed.                                                               |
| `instance-file-deleted`                | A file on the instance has been deleted.                              | `file`: path to the file.                                                                            |
| `instance-file-pushed`                 | The file has been pushed to the instance.                             | `file-source`: local file path. `file-destination`: destination file path. `info`: file information. |
| `instance-file-retrieved`              | The file has been downloaded from the instance.                       | `file-source`: instance file path. `file-destination`: destination file path.                        |
| `instance-log-deleted`                 | The instance’s specified log file has been deleted.                   |                                                                                                      |
| `instance-log-retrieved`               | The instance’s specified log file has been downloaded.                |                                                                                                      |
| `instance-metadata-retrieved`          | The instance’s image metadata has been downloaded.                    |                                                                                                      |
| `instance-metadata-template-created`   | A new image template file for the instance has been created.          | `path`: relative file path.                                                                          |
| `instance-metadata-template-deleted`   | The image template file for the instance has been deleted.            | `path`: relative file path.                                                                          |
| `instance-metadata-template-retrieved` | The image template file for the instance has been downloaded.         | `path`: relative file path.                                                                          |
| `instance-metadata-updated`            | The instance’s image metadata has changed.                            |                                                                                                      |
| `instance-paused`                      | The instance has been put in a paused state.                          |                                                                                                      |
| `instance-ready`                       | The instance is ready.                                                |                                                                                                      |
| `instance-renamed`                     | The instance has been renamed.                                        | `old_name`: the previous name.                                                                       |
| `instance-restarted`                   | The instance has restarted.                                           |                                                                                                      |
| `instance-restored`                    | The instance has been restored from a snapshot.                       | `snapshot`: name of the snapshot being restored.                                                     |
| `instance-resumed`                     | The instance has resumed after being paused.                          |                                                                                                      |
| `instance-shutdown`                    | The instance has shut down.                                           |                                                                                                      |
| `instance-snapshot-created`            | A snapshot of the instance has been created.                          |                                                                                                      |
| `instance-snapshot-deleted`            | The instance snapshot has been deleted.                               |                                                                                                      |
| `instance-snapshot-renamed`            | The instance snapshot has been renamed.                               | `old_name`: the previous name.                                                                       |
| `instance-snapshot-updated`            | The instance snapshot’s configuration has changed.                    |                                                                                                      |
| `instance-started`                     | The instance has started.                                             |                                                                                                      |
| `instance-stopped`                     | The instance has stopped.                                             |                                                                                                      |
| `instance-updated`                     | The instance’s configuration has changed.                             |                                                                                                      |
| `network-acl-created`                  | A new network ACL has been created.                                   |                                                                                                      |
| `network-acl-deleted`                  | The network ACL has been deleted.                                     |                                                                                                      |
| `network-acl-renamed`                  | The network ACL has been renamed.                                     | `old_name`: the previous name.                                                                       |
| `network-acl-updated`                  | The network ACL configuration has changed.                            |                                                                                                      |
| `network-created`                      | A network device has been created.                                    |                                                                                                      |
| `network-deleted`                      | The network device has been deleted.                                  |                                                                                                      |
| `network-forward-created`              | A new network forward has been created.                               |                                                                                                      |
| `network-forward-deleted`              | The network forward has been deleted.                                 |                                                                                                      |
| `network-forward-updated`              | The network forward has been updated.                                 |                                                                                                      |
| `network-peer-created`                 | A new network peer has been created.                                  |                                                                                                      |
| `network-peer-deleted`                 | The network peer has been deleted.                                    |                                                                                                      |
| `network-peer-updated`                 | The network peer has been updated.                                    |                                                                                                      |
| `network-renamed`                      | The network device has been renamed.                                  | `old_name`: the previous name.                                                                       |
| `network-updated`                      | The network device’s configuration has changed.                       |                                                                                                      |
| `network-zone-created`                 | A new network zone has been created.                                  |                                                                                                      |
| `network-zone-deleted`                 | The network zone has been deleted.                                    |                                                                                                      |
| `network-zone-record-created`          | A new network zone record has been created.                           |                                                                                                      |
| `network-zone-record-deleted`          | The network zone record has been deleted.                             |                                                                                                      |
| `network-zone-record-updated`          | The network zone record has been updated.                             |                                                                                                      |
| `network-zone-updated`                 | The network zone has been updated.                                    |                                                                                                      |
| `operation-cancelled`                  | The operation has been canceled.                                      |                                                                                                      |
| `profile-created`                      | A new profile has been created.                                       |                                                                                                      |
| `profile-deleted`                      | The profile has been deleted.                                         |                                                                                                      |
| `profile-renamed`                      | The profile has been renamed .                                        | `old_name`: the previous name.                                                                       |
| `profile-updated`                      | The profile’s configuration has changed.                              |                                                                                                      |
| `project-created`                      | A new project has been created.                                       |                                                                                                      |
| `project-deleted`                      | The project has been deleted.                                         |                                                                                                      |
| `project-renamed`                      | The project has been renamed.                                         | `old_name`: the previous name.                                                                       |
| `project-updated`                      | The project’s configuration has changed.                              |                                                                                                      |
| `storage-pool-created`                 | A new storage pool has been created.                                  | `target`: cluster member name.                                                                       |
| `storage-pool-deleted`                 | The storage pool has been deleted.                                    |                                                                                                      |
| `storage-pool-updated`                 | The storage pool’s configuration has changed.                         | `target`: cluster member name.                                                                       |
| `storage-volume-backup-created`        | A new backup for the storage volume has been created.                 | `type`: `container`, `virtual-machine`, `image`, or `custom`.                                        |
| `storage-volume-backup-deleted`        | The storage volume’s backup has been deleted.                         |                                                                                                      |
| `storage-volume-backup-renamed`        | The storage volume’s backup has been renamed.                         | `old_name`: the previous name.                                                                       |
| `storage-volume-backup-retrieved`      | The storage volume’s backup has been downloaded.                      |                                                                                                      |
| `storage-volume-created`               | A new storage volume has been created.                                | `type`: `container`, `virtual-machine`, `image`, or `custom`.                                        |
| `storage-volume-deleted`               | The storage volume has been deleted.                                  |                                                                                                      |
| `storage-volume-renamed`               | The storage volume has been renamed.                                  | `old_name`: the previous name.                                                                       |
| `storage-volume-restored`              | The storage volume has been restored from a snapshot.                 | `snapshot`: name of the snapshot being restored.                                                     |
| `storage-volume-snapshot-created`      | A new storage volume snapshot has been created.                       | `type`: `container`, `virtual-machine`, `image`, or `custom`.                                        |
| `storage-volume-snapshot-deleted`      | The storage volume’s snapshot has been deleted.                       |                                                                                                      |
| `storage-volume-snapshot-renamed`      | The storage volume’s snapshot has been renamed.                       | `old_name`: the previous name.                                                                       |
| `storage-volume-snapshot-updated`      | The configuration for the storage volume’s snapshot has changed.      |                                                                                                      |
| `storage-volume-updated`               | The storage volume’s configuration has changed.                       |                                                                                                      |
| `warning-acknowledged`                 | The warning’s status has been set to “acknowledged”.                  |                                                                                                      |
| `warning-deleted`                      | The warning has been deleted.                                         |                                                                                                      |
| `warning-reset`                        | The warning’s status has been set to “new”.                           |                                                                                                      |

<a id="events-security"></a>

## Security events

### Security event structure

- `name`: The security event identifier (e.g., `authn_login_fail:tls`, `authz_fail:can_edit:/1.0/projects/foo`).
- `level`: The severity level (`info`, `warning`).
- `description`: A human-readable description of the event.
- `requestor`: Who triggered the event (username, protocol, address, user agent). Omitted for daemon-level events.
- `project`: The project the request targeted. Omitted for daemon-level events.
- `request_path`: The REST API endpoint path. Omitted for daemon-level events.
- `request_method`: The HTTP method used. Omitted for daemon-level events.

### Security event types

LXD emits events across four categories.

**Authentication events**

| Event                                    | Description                                                                                                                                    |
|------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------|
| `authn_login_fail:tls`                   | Failed authentication attempt when an untrusted TLS client certificate is presented to a protected endpoint.                                   |
| `authn_token_created:<identity>`         | A new bearer token was issued for an identity. The identity UUID is included in the event identifier.                                          |
| `authn_token_revoked:<identity>`         | A bearer token was revoked for an identity. The identity UUID is included in the event identifier.                                             |
| `authn_token_reuse`                      | A bearer token was presented in an invalid, expired, or otherwise disallowed way, indicating possible token reuse, tampering, or other misuse. |
| `authn_certificate_change:<fingerprint>` | A TLS client certificate was replaced. The old certificate fingerprint is included in the event identifier.                                    |

**Authorization events**

| Event                                               | Description                                                                                                                    |
|-----------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------|
| `authz_fail:<entitlement>:<entity>`                 | An action was denied due to insufficient permissions. Includes the required entitlement and the entity path that was accessed. |
| `authz_admin:group_create:<name>`                   | A new authentication group was created.                                                                                        |
| `authz_admin:group_edit:<name>`                     | An authentication group was modified.                                                                                          |
| `authz_admin:group_delete:<name>`                   | An authentication group was deleted.                                                                                           |
| `authz_admin:idp_group_create:<name>`               | A new identity provider group was created.                                                                                     |
| `authz_admin:idp_group_edit:<name>`                 | An identity provider group was modified.                                                                                       |
| `authz_admin:idp_group_delete:<name>`               | An identity provider group was deleted.                                                                                        |
| `authz_admin:identity_create:<method>/<identifier>` | A new identity was created (TLS certificates or bearer tokens only). OIDC identities are not created via API actions.          |
| `authz_admin:identity_edit:<method>/<identifier>`   | An identity was modified.                                                                                                      |
| `authz_admin:identity_delete:<method>/<identifier>` | An identity was deleted.                                                                                                       |

**Daemon lifecycle events**

| Event                  | Description                                                                                                |
|------------------------|------------------------------------------------------------------------------------------------------------|
| `sys_startup`          | The LXD daemon has started. Emitted once the event system is fully available.                              |
| `sys_shutdown`         | The LXD daemon is shutting down.                                                                           |
| `sys_monitor_disabled` | Security event monitoring (Loki) was disabled via a configuration change. This is a `warning`-level event. |

**User lifecycle events**

| Event          | Description                                                                                                        |
|----------------|--------------------------------------------------------------------------------------------------------------------|
| `user_created` | A new identity has been created (TLS, bearer, OIDC, or cluster-link methods). For OIDC, this fires on first login. |
| `user_updated` | An identity has been modified. For OIDC, this fires when user metadata changes on subsequent logins.               |
| `user_deleted` | An identity has been deleted.                                                                                      |

<a id="events-security-loki-fields"></a>

### Security event fields in Loki

When security events are forwarded to Loki, they are stored in
[OWASP (Open Worldwide Application Security Project)](https://owasp.org/)
audit log format with the following key fields:

| Field                 | Description                                                                    |
|-----------------------|--------------------------------------------------------------------------------|
| `name`                | The security event type identifier.                                            |
| `event_source`        | The cluster member name where the event occurred.                              |
| `cluster_identifier`  | Unique identifier for the LXD cluster.                                         |
| `cluster_member_name` | Name of the cluster member.                                                    |
| `project`             | The project targeted by the request. Empty or omitted for daemon-level events. |
| `request_method`      | The HTTP method used.                                                          |
| `request_uri`         | The API endpoint path.                                                         |
| `user_id`             | The requestor identity in format `<auth_method>/<identifier>`.                 |
| `source_ip`           | The source IP address of the request.                                          |
| `useragent`           | The HTTP user agent string.                                                    |
| `level`               | The event severity (`info`, `warning`).                                        |
| `description`         | Human-readable event description.                                              |

For how to monitor and query security events, see [How to monitor security events](howto/security_events.md#howto-security-events).


# index.html.md

# Internals

These reference guides document the internal workings of LXD and are primarily intended for contributors and developers.

## Runtime behavior

The LXD client and daemon can use environment variables for paths, proxies, and advanced features. Daemon startup, shutdown, and signal handling are also documented here.

* [Environment variables](environment.md)
* [Daemon behavior](daemon-behavior.md)
* [UEFI variables for VMs](reference/uefi_variables.md)

## Security and isolation

Specific system calls from containers can be intercepted and handled safely by the LXD daemon. User namespaces use UID/GID idmaps to isolate containers from the host.

* [System call interception](syscall-interception.md)
* [User namespace setup](userns-idmap.md)

## Subsystem internals

* [OVN implementation](reference/ovn-internals.md)
* [VM live migration implementation](reference/vm_live_migration_internals.md)
* [Dqlite database for cluster state](reference/dqlite-internals.md)
* [ZFS storage driver](reference/storage_zfs_internals.md)

## Related topics

How-to guides:

- [Troubleshooting](howto/troubleshoot.md#troubleshoot)
- [Track a bugfix in the LXD snap](howto/snap_track_fix.md#snap-track-bugfix)


# index.html.md

<a id="server"></a>

# Server configuration

The LXD server can be configured through a set of key/value configuration options.

The key/value configuration is namespaced.
The following options are available:

- [Core configuration](#server-options-core)
- [ACME configuration](#server-options-acme)
- [OpenID Connect configuration](#server-options-oidc)
- [Cluster configuration](#server-options-cluster)
- [Images configuration](#server-options-images)
- [Loki configuration](#server-options-loki)
- [Miscellaneous options](#server-options-misc)

See [How to configure the LXD server](howto/server_configure.md#server-configure) for instructions on how to set the configuration options.

#### NOTE
Options marked with a `global` scope are immediately applied to all cluster members.
Options with a `local` scope must be set on a per-member basis.

<a id="server-options-core"></a>

## Core configuration

The following server options control the core daemon configuration:

<!-- Include content from [metadata.txt](metadata.txt) -->

<a id="server-core:core.auth_secret_expiry"></a>
`core.auth_secret_expiry`

How long to use a given cluster secret

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-core:core.auth_secret_expiry)

| **Key:**     | `core.auth_secret_expiry`   |
|--------------|-----------------------------|
| **Type:**    | string                      |
| **Default:** | `1m`                        |
| **Scope:**   | global                      |

The secret is used for various cryptographic purposes, such as cookie encryption.
When a given secret is older than the configured expiry, a new secret is generated.

This configuration option accepts multiple space-separated values of the form `[0-9]+(S|M|H|d|w|m|y)`,
where `S` is seconds, `M` is minutes, `H` is hours, `d` is days, `w` is weeks, `m` is months, and `y` is years.
For example, `1d 3H` is 1 day and 3 hours.

The default value is `1m` (1 month).
The minimum value is `1d` (1 day).

<a id="server-core:core.bgp_address"></a>
`core.bgp_address`

Address to bind the BGP server to

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-core:core.bgp_address)

| **Key:**    | `core.bgp_address`   |
|-------------|----------------------|
| **Type:**   | string               |
| **Scope:**  | local                |

See [How to configure LXD as a BGP server](howto/network_bgp.md#network-bgp).

<a id="server-core:core.bgp_asn"></a>
`core.bgp_asn`

BGP Autonomous System Number for the local server

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-core:core.bgp_asn)

| **Key:**     | `core.bgp_asn`   |
|--------------|------------------|
| **Type:**    | string           |
| **Default:** | `0`              |
| **Scope:**   | global           |

<a id="server-core:core.bgp_routerid"></a>
`core.bgp_routerid`

A unique identifier for the BGP server

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-core:core.bgp_routerid)

| **Key:**    | `core.bgp_routerid`   |
|-------------|-----------------------|
| **Type:**   | string                |
| **Scope:**  | local                 |

The identifier must be formatted as an IPv4 address.

<a id="server-core:core.debug_address"></a>
`core.debug_address`

Address to bind the [`pprof`](https://pkg.go.dev/net/http/pprof) debug server to (HTTP)

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-core:core.debug_address)

| **Key:**    | `core.debug_address`   |
|-------------|------------------------|
| **Type:**   | string                 |
| **Scope:**  | local                  |

<a id="server-core:core.dns_address"></a>
`core.dns_address`

Address to bind the authoritative DNS server to

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-core:core.dns_address)

| **Key:**    | `core.dns_address`   |
|-------------|----------------------|
| **Type:**   | string               |
| **Scope:**  | local                |

See [Enable the built-in DNS server](howto/network_zones.md#network-dns-server).

<a id="server-core:core.https_address"></a>
`core.https_address`

Address to bind for the remote API (HTTPS)

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-core:core.https_address)

| **Key:**    | `core.https_address`   |
|-------------|------------------------|
| **Type:**   | string                 |
| **Scope:**  | local                  |

See [How to expose LXD to the network](howto/server_expose.md#server-expose).

<a id="server-core:core.https_allowed_credentials"></a>
`core.https_allowed_credentials`

Whether to set `Access-Control-Allow-Credentials`

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-core:core.https_allowed_credentials)

| **Key:**     | `core.https_allowed_credentials`   |
|--------------|------------------------------------|
| **Type:**    | bool                               |
| **Default:** | `false`                            |
| **Scope:**   | global                             |

If enabled, the `Access-Control-Allow-Credentials` HTTP header value is set to `true`.

<a id="server-core:core.https_allowed_headers"></a>
`core.https_allowed_headers`

`Access-Control-Allow-Headers` HTTP header value

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-core:core.https_allowed_headers)

| **Key:**    | `core.https_allowed_headers`   |
|-------------|--------------------------------|
| **Type:**   | string                         |
| **Scope:**  | global                         |

<a id="server-core:core.https_allowed_methods"></a>
`core.https_allowed_methods`

`Access-Control-Allow-Methods` HTTP header value

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-core:core.https_allowed_methods)

| **Key:**    | `core.https_allowed_methods`   |
|-------------|--------------------------------|
| **Type:**   | string                         |
| **Scope:**  | global                         |

<a id="server-core:core.https_allowed_origin"></a>
`core.https_allowed_origin`

`Access-Control-Allow-Origin` HTTP header value

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-core:core.https_allowed_origin)

| **Key:**    | `core.https_allowed_origin`   |
|-------------|-------------------------------|
| **Type:**   | string                        |
| **Scope:**  | global                        |

<a id="server-core:core.https_trusted_proxy"></a>
`core.https_trusted_proxy`

Trusted servers to provide the client’s address via the PROXY protocol

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-core:core.https_trusted_proxy)

| **Key:**    | `core.https_trusted_proxy`   |
|-------------|------------------------------|
| **Type:**   | string                       |
| **Scope:**  | global                       |

Specify a comma-separated list of IP addresses of trusted servers that provide the client’s address through the PROXY protocol connection header.

<a id="server-core:core.metrics_address"></a>
`core.metrics_address`

Address to bind the metrics server to (HTTPS)

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-core:core.metrics_address)

| **Key:**    | `core.metrics_address`   |
|-------------|--------------------------|
| **Type:**   | string                   |
| **Scope:**  | local                    |

See [How to monitor metrics](metrics.md#metrics).

<a id="server-core:core.metrics_authentication"></a>
`core.metrics_authentication`

Whether to enforce authentication on the metrics endpoint

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-core:core.metrics_authentication)

| **Key:**     | `core.metrics_authentication`   |
|--------------|---------------------------------|
| **Type:**    | bool                            |
| **Default:** | `true`                          |
| **Scope:**   | global                          |

<a id="server-core:core.proxy_http"></a>
`core.proxy_http`

HTTP proxy to use

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-core:core.proxy_http)

| **Key:**    | `core.proxy_http`   |
|-------------|---------------------|
| **Type:**   | string              |
| **Scope:**  | global              |

If this option is not specified, LXD falls back to the `HTTP_PROXY` environment variable (if set).

<a id="server-core:core.proxy_https"></a>
`core.proxy_https`

HTTPS proxy to use

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-core:core.proxy_https)

| **Key:**    | `core.proxy_https`   |
|-------------|----------------------|
| **Type:**   | string               |
| **Scope:**  | global               |

If this option is not specified, LXD falls back to the `HTTPS_PROXY` environment variable (if set).

<a id="server-core:core.proxy_ignore_hosts"></a>
`core.proxy_ignore_hosts`

Hosts that don’t need the proxy

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-core:core.proxy_ignore_hosts)

| **Key:**    | `core.proxy_ignore_hosts`   |
|-------------|-----------------------------|
| **Type:**   | string                      |
| **Scope:**  | global                      |

Specify this option in a similar format to `NO_PROXY` (for example, `1.2.3.4,1.2.3.5`)

If this option is not specified, LXD falls back to the `NO_PROXY` environment variable (if set).

<a id="server-core:core.remote_token_expiry"></a>
`core.remote_token_expiry`

Time after which a remote add token expires

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-core:core.remote_token_expiry)

| **Key:**     | `core.remote_token_expiry`   |
|--------------|------------------------------|
| **Type:**    | string                       |
| **Default:** | `15d`                        |
| **Scope:**   | global                       |

<a id="server-core:core.shutdown_timeout"></a>
`core.shutdown_timeout`

How long to wait before shutdown

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-core:core.shutdown_timeout)

| **Key:**     | `core.shutdown_timeout`   |
|--------------|---------------------------|
| **Type:**    | integer                   |
| **Default:** | `5`                       |
| **Scope:**   | global                    |

Specify the number of minutes to wait for running operations to complete before the LXD server shuts down.

<a id="server-core:core.syslog_socket"></a>
`core.syslog_socket`

Whether to enable the syslog unixgram socket listener

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-core:core.syslog_socket)

| **Key:**     | `core.syslog_socket`   |
|--------------|------------------------|
| **Type:**    | bool                   |
| **Default:** | `false`                |
| **Scope:**   | local                  |

Set this option to `true` to enable the syslog unixgram socket to receive log messages from external processes.

<a id="server-core:core.trust_ca_certificates"></a>
`core.trust_ca_certificates`

Whether to automatically trust clients signed by the CA

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-core:core.trust_ca_certificates)

| **Key:**     | `core.trust_ca_certificates`   |
|--------------|--------------------------------|
| **Type:**    | bool                           |
| **Default:** | `false`                        |
| **Scope:**   | global                         |

<a id="server-options-acme"></a>

## ACME configuration

The following server options control the [ACME](authentication.md#authentication-server-certificate) configuration:

<!-- Include content from [metadata.txt](metadata.txt) -->

<a id="server-acme:acme.agree_tos"></a>
`acme.agree_tos`

Agree to ACME terms of service

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-acme:acme.agree_tos)

| **Key:**     | `acme.agree_tos`   |
|--------------|--------------------|
| **Type:**    | bool               |
| **Default:** | `false`            |
| **Scope:**   | global             |

<a id="server-acme:acme.ca_url"></a>
`acme.ca_url`

URL to the directory resource of the ACME service

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-acme:acme.ca_url)

| **Key:**     | `acme.ca_url`                                    |
|--------------|--------------------------------------------------|
| **Type:**    | string                                           |
| **Default:** | `https://acme-v02.api.letsencrypt.org/directory` |
| **Scope:**   | global                                           |

<a id="server-acme:acme.domain"></a>
`acme.domain`

Domain for which the certificate is issued

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-acme:acme.domain)

| **Key:**    | `acme.domain`   |
|-------------|-----------------|
| **Type:**   | string          |
| **Scope:**  | global          |

<a id="server-acme:acme.email"></a>
`acme.email`

Email address used for the account registration

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-acme:acme.email)

| **Key:**    | `acme.email`   |
|-------------|----------------|
| **Type:**   | string         |
| **Scope:**  | global         |

<a id="server-options-oidc"></a>

## OpenID Connect configuration

The following server options configure external user authentication through [OpenID Connect authentication](authentication.md#authentication-openid):

<!-- Include content from [metadata.txt](metadata.txt) -->

<a id="server-oidc:oidc.audience"></a>
`oidc.audience`

Expected audience value for the application

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-oidc:oidc.audience)

| **Key:**    | `oidc.audience`   |
|-------------|-------------------|
| **Type:**   | string            |
| **Scope:**  | global            |

This value is required by some providers.

<a id="server-oidc:oidc.client.id"></a>
`oidc.client.id`

OpenID Connect client ID

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-oidc:oidc.client.id)

| **Key:**    | `oidc.client.id`   |
|-------------|--------------------|
| **Type:**   | string             |
| **Scope:**  | global             |

<a id="server-oidc:oidc.client.secret"></a>
`oidc.client.secret`

OpenID Connect client secret

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-oidc:oidc.client.secret)

| **Key:**    | `oidc.client.secret`   |
|-------------|------------------------|
| **Type:**   | string                 |
| **Scope:**  | global                 |

<a id="server-oidc:oidc.device.client.id"></a>
`oidc.device.client.id`

OpenID Connect client ID (CLI)

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-oidc:oidc.device.client.id)

| **Key:**     | `oidc.device.client.id`               |
|--------------|---------------------------------------|
| **Type:**    | string                                |
| **Default:** | The value of `oidc.client.id` if set. |
| **Scope:**   | global                                |

The OIDC client ID used by the LXD CLI. This configuration value overrides the client ID that is made public
to the LXD CLI.

<a id="server-oidc:oidc.groups.claim"></a>
`oidc.groups.claim`

A claim used for mapping identity provider groups to LXD groups.

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-oidc:oidc.groups.claim)

| **Key:**    | `oidc.groups.claim`   |
|-------------|-----------------------|
| **Type:**   | string                |
| **Scope:**  | global                |

Specify a custom token claim to denote groups defined at the identity provider.
The contents of this claim can be mapped to LXD groups for managing access control.
The value of the claim is expected to be a JSON string array.

<a id="server-oidc:oidc.issuer"></a>
`oidc.issuer`

OpenID Connect Discovery URL for the provider

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-oidc:oidc.issuer)

| **Key:**    | `oidc.issuer`   |
|-------------|-----------------|
| **Type:**   | string          |
| **Scope:**  | global          |

<a id="server-oidc:oidc.scopes"></a>
`oidc.scopes`

Space-separated list of OpenID Connect scopes

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-oidc:oidc.scopes)

| **Key:**     | `oidc.scopes`                         |
|--------------|---------------------------------------|
| **Type:**    | space-delimited string                |
| **Default:** | `openid email offline_access profile` |
| **Scope:**   | global                                |

A list of OpenID Connect scopes to request from the identity provider.
This must include the `openid` and `email` scopes.
The remaining optional scopes are `offline_access` and `profile`.
If you remove the `offline_access` scope, users might be required to log in more frequently.
If you remove the `profile` scope, user information may not be displayed in LXD UI (or in `lxc auth identity` commands).
You may add additional scopes if this is required by your identity provider, or if necessary for configuration of [identity provider groups](explanation/authorization.md#identity-provider-groups).

<a id="server-oidc:oidc.session.expiry"></a>
`oidc.session.expiry`

The duration of an OIDC session

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-oidc:oidc.session.expiry)

| **Key:**     | `oidc.session.expiry`   |
|--------------|-------------------------|
| **Type:**    | string                  |
| **Default:** | `1w`                    |
| **Scope:**   | global                  |

The duration of an OIDC session.

This configuration option accepts multiple space-separated values of the form `[0-9]+(S|M|H|d|w|m|y)`,
where `S` is seconds, `M` is minutes, `H` is hours, `d` is days, `w` is weeks, `m` is months, and `y` is years.
For example, `1d 3H` is 1 day and 3 hours.

The default value is `1w` (1 week).
The minimum value is `1d` (1 day).

#### IMPORTANT
Setting `oidc.client.secret` might prevent LXD CLI clients from authenticating via the Identity Provider.
This is because the client secret is used only for communication between LXD and the Identity Provider.
LXD CLI clients, who do not have access to the client secret, authenticate separately with the Identity Provider and send their credentials to LXD for verification.
You can create a separate client in the identity provider for the LXD CLI and configure this using the `oidc.device.client.id`

<a id="server-options-cluster"></a>

## Cluster configuration

The following server options control [Clustering](clustering.md#clustering):

<!-- Include content from [metadata.txt](metadata.txt) -->

<a id="server-cluster:cluster.healing_threshold"></a>
`cluster.healing_threshold`

Threshold when to evacuate an offline cluster member

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-cluster:cluster.healing_threshold)

| **Key:**     | `cluster.healing_threshold`   |
|--------------|-------------------------------|
| **Type:**    | integer                       |
| **Default:** | `0`                           |
| **Scope:**   | global                        |

Specify the number of seconds after which an offline cluster member is to be evacuated.
To disable evacuating offline members, set this option to `0`.

<a id="server-cluster:cluster.https_address"></a>
`cluster.https_address`

Address to use for clustering traffic

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-cluster:cluster.https_address)

| **Key:**    | `cluster.https_address`   |
|-------------|---------------------------|
| **Type:**   | string                    |
| **Scope:**  | local                     |

See [Separate REST API and clustering networks](howto/cluster_config_networks.md#cluster-https-address).

<a id="server-cluster:cluster.images_minimal_replica"></a>
`cluster.images_minimal_replica`

Number of cluster members that replicate an image

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-cluster:cluster.images_minimal_replica)

| **Key:**     | `cluster.images_minimal_replica`   |
|--------------|------------------------------------|
| **Type:**    | integer                            |
| **Default:** | `3`                                |
| **Scope:**   | global                             |

Specify the minimal number of cluster members that keep a copy of a particular image.
Set this option to `1` for no replication, or to `-1` to replicate images on all members.

<a id="server-cluster:cluster.join_token_expiry"></a>
`cluster.join_token_expiry`

Time after which a cluster join token expires

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-cluster:cluster.join_token_expiry)

| **Key:**     | `cluster.join_token_expiry`   |
|--------------|-------------------------------|
| **Type:**    | string                        |
| **Default:** | `3H`                          |
| **Scope:**   | global                        |

<a id="server-cluster:cluster.max_standby"></a>
`cluster.max_standby`

Number of database stand-by members

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-cluster:cluster.max_standby)

| **Key:**     | `cluster.max_standby`   |
|--------------|-------------------------|
| **Type:**    | integer                 |
| **Default:** | `2`                     |
| **Scope:**   | global                  |

Specify the maximum number of cluster members that are assigned the database stand-by role.
This must be a number between `0` and `5`.

<a id="server-cluster:cluster.max_voters"></a>
`cluster.max_voters`

Number of database voter members

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-cluster:cluster.max_voters)

| **Key:**     | `cluster.max_voters`   |
|--------------|------------------------|
| **Type:**    | integer                |
| **Default:** | `3`                    |
| **Scope:**   | global                 |

Specify the maximum number of cluster members that are assigned the database voter role.
This must be an odd number >= `3`.

<a id="server-cluster:cluster.offline_threshold"></a>
`cluster.offline_threshold`

Threshold when an unresponsive member is considered offline

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-cluster:cluster.offline_threshold)

| **Key:**     | `cluster.offline_threshold`   |
|--------------|-------------------------------|
| **Type:**    | integer                       |
| **Default:** | `20`                          |
| **Scope:**   | global                        |

Specify the number of seconds after which an unresponsive member is considered offline.

<a id="server-options-images"></a>

## Images configuration

The following server options configure how to handle [Images](images.md#images):

<!-- Include content from [metadata.txt](metadata.txt) -->

<a id="server-images:images.auto_update_cached"></a>
`images.auto_update_cached`

Whether to automatically update cached images

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-images:images.auto_update_cached)

| **Key:**     | `images.auto_update_cached`   |
|--------------|-------------------------------|
| **Type:**    | bool                          |
| **Default:** | `true`                        |
| **Scope:**   | global                        |

<a id="server-images:images.auto_update_interval"></a>
`images.auto_update_interval`

Interval at which to look for updates to cached images

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-images:images.auto_update_interval)

| **Key:**     | `images.auto_update_interval`   |
|--------------|---------------------------------|
| **Type:**    | integer                         |
| **Default:** | `6`                             |
| **Scope:**   | global                          |

Specify the interval in hours.
To disable looking for updates to cached images, set this option to `0`.

<a id="server-images:images.compression_algorithm"></a>
`images.compression_algorithm`

Compression algorithm to use for new images

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-images:images.compression_algorithm)

| **Key:**     | `images.compression_algorithm`   |
|--------------|----------------------------------|
| **Type:**    | string                           |
| **Default:** | `gzip`                           |
| **Scope:**   | global                           |

Possible values are `bzip2`, `gzip`, `lzma`, `xz`, or `none`.

<a id="server-images:images.default_architecture"></a>
`images.default_architecture`

Default architecture to use in a mixed-architecture cluster

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-images:images.default_architecture)

| **Key:**    | `images.default_architecture`   |
|-------------|---------------------------------|
| **Type:**   | string                          |

<a id="server-images:images.remote_cache_expiry"></a>
`images.remote_cache_expiry`

When an unused cached remote image is flushed

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-images:images.remote_cache_expiry)

| **Key:**     | `images.remote_cache_expiry`   |
|--------------|--------------------------------|
| **Type:**    | integer                        |
| **Default:** | `10`                           |
| **Scope:**   | global                         |

Specify the number of days after which the unused cached image expires.

<a id="server-options-loki"></a>

## Loki configuration

The following server options configure the external log aggregation system:

<!-- Include content from [metadata.txt](metadata.txt) -->

<a id="server-loki:loki.api.ca_cert"></a>
`loki.api.ca_cert`

CA certificate for the Loki server

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-loki:loki.api.ca_cert)

| **Key:**    | `loki.api.ca_cert`   |
|-------------|----------------------|
| **Type:**   | string               |
| **Scope:**  | global               |

<a id="server-loki:loki.api.url"></a>
`loki.api.url`

URL to the Loki server

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-loki:loki.api.url)

| **Key:**    | `loki.api.url`   |
|-------------|------------------|
| **Type:**   | string           |
| **Scope:**  | global           |

Specify the protocol, name or IP and port. For example `https://loki.example.com:3100`. LXD will automatically add the `/loki/api/v1/push` suffix so there’s no need to add it here.

<a id="server-loki:loki.auth.password"></a>
`loki.auth.password`

Password used for Loki authentication

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-loki:loki.auth.password)

| **Key:**    | `loki.auth.password`   |
|-------------|------------------------|
| **Type:**   | string                 |
| **Scope:**  | global                 |

<a id="server-loki:loki.auth.username"></a>
`loki.auth.username`

User name used for Loki authentication

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-loki:loki.auth.username)

| **Key:**    | `loki.auth.username`   |
|-------------|------------------------|
| **Type:**   | string                 |
| **Scope:**  | global                 |

<a id="server-loki:loki.instance"></a>
`loki.instance`

Name to use as the instance field in Loki events.

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-loki:loki.instance)

| **Key:**     | `loki.instance`                               |
|--------------|-----------------------------------------------|
| **Type:**    | string                                        |
| **Default:** | Local server host name or cluster member name |
| **Scope:**   | global                                        |

This allows replacing the default instance value (server host name) by a more relevant value like a cluster identifier.

<a id="server-loki:loki.labels"></a>
`loki.labels`

Labels for a Loki log entry

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-loki:loki.labels)

| **Key:**    | `loki.labels`   |
|-------------|-----------------|
| **Type:**   | string          |
| **Scope:**  | global          |

Specify a comma-separated list of values that should be used as labels for a Loki log entry.

<a id="server-loki:loki.loglevel"></a>
`loki.loglevel`

Minimum log level to send to the Loki server

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-loki:loki.loglevel)

| **Key:**     | `loki.loglevel`   |
|--------------|-------------------|
| **Type:**    | string            |
| **Default:** | `info`            |
| **Scope:**   | global            |

<a id="server-loki:loki.types"></a>
`loki.types`

Events to send to the Loki server

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-loki:loki.types)

| **Key:**     | `loki.types`        |
|--------------|---------------------|
| **Type:**    | string              |
| **Default:** | `lifecycle,logging` |
| **Scope:**   | global              |

Specify a comma-separated list of events to send to the Loki server.
The events can be any combination of `lifecycle`, `logging`, `ovn`, and `security`.

<a id="server-options-misc"></a>

## Miscellaneous options

The following server options configure server-specific settings for [Instances](instances.md#instances), [OVN](reference/network_ovn.md#network-ovn) integration, [Backups](backup.md#backups) and [Storage](storage.md#storage):

<!-- Include content from [metadata.txt](metadata.txt) -->

<a id="server-miscellaneous:backups.compression_algorithm"></a>
`backups.compression_algorithm`

Compression algorithm to use for backups

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-miscellaneous:backups.compression_algorithm)

| **Key:**     | `backups.compression_algorithm`   |
|--------------|-----------------------------------|
| **Type:**    | string                            |
| **Default:** | `gzip`                            |
| **Scope:**   | global                            |

Possible values are `bzip2`, `gzip`, `lzma`, `xz`, or `none`.

<a id="server-miscellaneous:instances.migration.stateful"></a>
`instances.migration.stateful`

Whether to set `migration.stateful` to `true` for the instances

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-miscellaneous:instances.migration.stateful)

| **Key:**     | `instances.migration.stateful`   |
|--------------|----------------------------------|
| **Type:**    | bool                             |
| **Default:** | `false`                          |
| **Scope:**   | global                           |

You can override this setting for relevant instances, either in the instance-specific configuration or through a profile.

<a id="server-miscellaneous:instances.nic.host_name"></a>
`instances.nic.host_name`

How to set the host name for a NIC

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-miscellaneous:instances.nic.host_name)

| **Key:**     | `instances.nic.host_name`   |
|--------------|-----------------------------|
| **Type:**    | string                      |
| **Default:** | `random`                    |
| **Scope:**   | global                      |

Possible values are `random` and `mac`.

If set to `random`, use the random host interface name as the host name.
If set to `mac`, generate a host name in the form `lxd<mac_address>` (MAC without leading two digits).

<a id="server-miscellaneous:network.ovn.ca_cert"></a>
`network.ovn.ca_cert`

OVN SSL certificate authority

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-miscellaneous:network.ovn.ca_cert)

| **Key:**     | `network.ovn.ca_cert`                            |
|--------------|--------------------------------------------------|
| **Type:**    | string                                           |
| **Default:** | Content of `/etc/ovn/ovn-central.crt` if present |
| **Scope:**   | global                                           |

<a id="server-miscellaneous:network.ovn.client_cert"></a>
`network.ovn.client_cert`

OVN SSL client certificate

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-miscellaneous:network.ovn.client_cert)

| **Key:**     | `network.ovn.client_cert`                  |
|--------------|--------------------------------------------|
| **Type:**    | string                                     |
| **Default:** | Content of `/etc/ovn/cert_host` if present |
| **Scope:**   | global                                     |

<a id="server-miscellaneous:network.ovn.client_key"></a>
`network.ovn.client_key`

OVN SSL client key

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-miscellaneous:network.ovn.client_key)

| **Key:**     | `network.ovn.client_key`                  |
|--------------|-------------------------------------------|
| **Type:**    | string                                    |
| **Default:** | Content of `/etc/ovn/key_host` if present |
| **Scope:**   | global                                    |

<a id="server-miscellaneous:network.ovn.integration_bridge"></a>
`network.ovn.integration_bridge`

OVS integration bridge to use for OVN networks

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-miscellaneous:network.ovn.integration_bridge)

| **Key:**     | `network.ovn.integration_bridge`   |
|--------------|------------------------------------|
| **Type:**    | string                             |
| **Default:** | `br-int`                           |
| **Scope:**   | global                             |

<a id="server-miscellaneous:network.ovn.northbound_connection"></a>
`network.ovn.northbound_connection`

OVN northbound database connection string (default determined by environment)

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-miscellaneous:network.ovn.northbound_connection)

| **Key:**     | `network.ovn.northbound_connection`                         |
|--------------|-------------------------------------------------------------|
| **Type:**    | string                                                      |
| **Default:** | `unix:/var/run/ovn/ovnnb_db.sock` or MicroOVN configuration |
| **Scope:**   | global                                                      |

Specify a connection string for OVN Northbound database.
If value is not specified, LXD will determine the connection string based on the environment.
LXD snap will use the MicroOVN environment settings if connected to MicroOVN snap.
Otherwise, LXD will use `unix:/var/run/ovn/ovnnb_db.sock` as the connection string.

<a id="server-miscellaneous:storage.backups_volume"></a>
`storage.backups_volume`

Volume to use to store backup tarballs

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-miscellaneous:storage.backups_volume)

| **Key:**    | `storage.backups_volume`   |
|-------------|----------------------------|
| **Type:**   | string                     |
| **Scope:**  | local                      |

Specify the volume using the syntax `POOL/VOLUME`.

<a id="server-miscellaneous:storage.images_volume"></a>
`storage.images_volume`

Volume to use to store the image tarballs

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-miscellaneous:storage.images_volume)

| **Key:**    | `storage.images_volume`   |
|-------------|---------------------------|
| **Type:**   | string                    |
| **Scope:**  | local                     |

Specify the volume using the syntax `POOL/VOLUME`.

<a id="server-miscellaneous:storage.project.{name}.backups_volume"></a>
`storage.project.{name}.backups_volume`

Volume to use to store project-specific backup tarballs

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-miscellaneous:storage.project.{name}.backups_volume)

| **Key:**    | `storage.project.{name}.backups_volume`   |
|-------------|-------------------------------------------|
| **Type:**   | string                                    |
| **Scope:**  | local                                     |

Specify the volume using the syntax `POOL/VOLUME`.

<a id="server-miscellaneous:storage.project.{name}.images_volume"></a>
`storage.project.{name}.images_volume`

Volume to use to store project-specific image tarballs

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-miscellaneous:storage.project.{name}.images_volume)

| **Key:**    | `storage.project.{name}.images_volume`   |
|-------------|------------------------------------------|
| **Type:**   | string                                   |
| **Scope:**  | local                                    |

Specify the volume using the syntax `POOL/VOLUME`.

<a id="server-miscellaneous:user.instances.placement.scriptlet"></a>
`user.instances.placement.scriptlet`

Legacy storage for `instances.placement.scriptlet` (no effect)

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-miscellaneous:user.instances.placement.scriptlet)

| **Key:**    | `user.instances.placement.scriptlet`   |
|-------------|----------------------------------------|
| **Type:**   | string                                 |
| **Scope:**  | global                                 |

Stores the migrated value from the deprecated `instances.placement.scriptlet` configuration key. LXD ignores this key; changing it has no effect. It exists only to preserve previously stored data and may be removed in a future release.

<a id="server-miscellaneous:volatile.uuid"></a>
`volatile.uuid`

A random v7 UUID

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#server-miscellaneous:volatile.uuid)

| **Key:**    | `volatile.uuid`   |
|-------------|-------------------|
| **Type:**   | string            |
| **Scope:**  | global            |

This UUID is used as a stable identifier for the cluster. It cannot be changed.

## Related topics

How-to guides:

- [How to configure the LXD server](howto/server_configure.md#server-configure)


# index.html.md

<a id="backups"></a>

# How to back up a LXD server


            <p class="youtube_link">
              <a href="https://www.youtube.com/watch?v=IFOZpAxckPo" target="_blank">
                <span title="LXD backup and disaster recovery" class="play_icon">▶</span>
                <span title="LXD backup and disaster recovery">Watch on YouTube</span>
              </a>
            </p>
        
In a production setup, you should always back up the contents of your LXD server.

The LXD server contains a variety of different entities, and when choosing your backup strategy, you must decide which of these entities you want to back up and how frequently you want to save them.

## What to back up

The various contents of your LXD server are located on your file system and, in addition, recorded in the [LXD database](database.md#database).
Therefore, only backing up the database or only backing up the files on disk does not give you a full functional backup.

Your LXD server contains the following entities:

- Instances (database records and file systems)
- Images (database records, image files, and file systems)
- Networks (database records and state files)
- Profiles (database records)
- Storage volumes (database records and file systems)

Consider which of these you need to back up.
For example, if you don’t use custom images, you don’t need to back up your images since they are available on the image server.
If you use only the `default` profile, or only the standard `lxdbr0` network bridge, you might not need to worry about backing them up, because they can easily be re-created.

## Full backup

To create a full backup of all contents of your LXD server, back up the `/var/snap/lxd/common/lxd` (for snap users) or `/var/lib/lxd` (otherwise) directory.

This directory contains your local storage, the LXD database, and your configuration.
It does not contain separate storage devices, however.
That means that whether the directory also contains the data of your instances depends on the storage drivers that you use.

#### IMPORTANT
If your LXD server uses any external storage (for example, LVM volume groups, ZFS zpools, or any other resource that isn’t directly self-contained to LXD), you must back this up separately.

See [How to back up custom storage volumes](howto/storage_backup_volume.md#howto-storage-backup-volume) for instructions.

To back up your data, create a tarball of `/var/snap/lxd/common/lxd` (for snap users) or `/var/lib/lxd` (otherwise).
If you are not using the snap package and your source system has a `/etc/subuid` and `/etc/subgid` file, you should also back up these files.
Restoring them avoids needless shifting of instance file systems.

To restore your data, complete the following steps:

1. Stop LXD on your server (for example, with `sudo snap stop lxd`).
2. Delete the directory (`/var/snap/lxd/common/lxd` for snap users or `/var/lib/lxd` otherwise).
3. Restore the directory from the backup.
4. Delete and restore any external storage devices.
5. If you are not using the snap, restore the `/etc/subuid` and `/etc/subgid` files.
6. Restart LXD (for example, with `sudo snap start lxd` or by restarting your machine).

### Export a snapshot

If you are using the LXD snap, you can also create a full backup by exporting a snapshot of the snap:

1. Create a snapshot:
   ```none
   sudo snap save lxd
   ```

   Note down the ID of the snapshot (shown in the `Set` column).
2. Export the snapshot to a file:
   ```none
   sudo snap export-snapshot <ID> <output_file>
   ```

See [Create data snapshots](https://snapcraft.io/docs/how-to-guides/manage-snaps/create-data-snapshots/#how-to-guides-manage-snaps-create-data-snapshots) in the Snap documentation for details.

## Partial backup

If you decide to only back up specific entities, you have different options for how to do this.
You should consider doing some of these partial backups even if you are doing full backups in addition.
It can be easier and safer to, for example, restore a single instance or reconfigure a profile than to restore the full LXD server.

### Back up instances and volumes

Instances and storage volumes are backed up in a very similar way (because when backing up an instance, you basically back up its instance volume, see [Storage volume types](explanation/storage.md#storage-volume-types)).

See [How to back up instances](howto/instances_backup.md#instances-backup) and [How to back up custom storage volumes](howto/storage_backup_volume.md#howto-storage-backup-volume) for detailed information.
The following sections give a brief summary of the options you have for backing up instances and volumes.

<a id="secondary-backup-server"></a>

#### Secondary backup LXD server

LXD supports copying and moving instances and storage volumes between two hosts.
See [How to migrate LXD instances between servers](howto/instances_migrate.md#howto-instances-migrate) and [How to move or copy storage volumes](howto/storage_move_volume.md#howto-storage-move-volume) for instructions.

So if you have a spare server, you can regularly copy your instances and storage volumes to that secondary server to back them up.
Use the `--refresh` flag to update the copies (see [Optimized volume transfer](reference/storage_drivers.md#storage-optimized-volume-transfer) for the benefits).

If needed, you can either switch over to the secondary server or copy your instances or storage volumes back from it.

If you use the secondary server as a pure storage server, it doesn’t need to be as powerful as your main LXD server.

#### Export tarballs

You can use the `export` command to export instances and volumes to a backup tarball.
By default, those tarballs include all snapshots.

You can use an optimized export option, which is usually quicker and results in a smaller size of the tarball.
However, you must then use the same storage driver when restoring the backup tarball.

See [Use export files for instance backup](howto/instances_backup.md#instances-backup-export) and [Use export files for volume backup](howto/storage_backup_volume.md#storage-backup-export) for instructions.

#### Snapshots

Snapshots save the state of an instance or volume at a specific point in time.
However, they are stored in the same storage pool and are therefore likely to be lost if the original data is deleted or lost.
This means that while snapshots are very quick and easy to create and restore, they don’t constitute a secure backup.

See [Use snapshots for instance backup](howto/instances_backup.md#instances-snapshots) and [Use snapshots for volume backup](howto/storage_backup_volume.md#storage-backup-snapshots) for more information.

<a id="backup-database"></a>

### Back up the database

While there is no trivial method to restore the contents of the [LXD database](database.md#database), it can still be very convenient to keep a backup of its content.
Such a backup can make it much easier to re-create, for example, networks or profiles if the need arises.

Use the following command to dump the content of the local database to a file:

```none
lxd sql local .dump > <output_file>
```

Use the following command to dump the content of the global database to a file:

```none
lxd sql global .dump > <output_file>
```

You should include these two commands in your regular LXD backup.


# index.html.md

# Production setup

These how-to guides cover common operations to prepare an LXD server setup for production.

## Optimize performance

The `lxd-benchmark` tool measures the time to create instances in different configurations. In some scenarios, deployments can also be configured for increased bandwidth.

* [Benchmark performance](howto/benchmark_performance.md)
* [Increase bandwidth](howto/network_increase_bandwidth.md)

## Monitor metrics and logs

LXD collects metrics and logs that can be viewed as raw data or used with observability tools like Loki and Grafana.

* [Monitor metrics](metrics.md)
* [Monitor security events](howto/security_events.md)
* [Send logs to Loki](howto/logs_loki.md)
* [Set up Grafana](howto/grafana.md)

## Back up and recover

Full and partial server backups protect against data loss. Instance recovery and disaster recovery options are available for different failure scenarios.

* [Back up a server](backup.md)
* [Recover instances](howto/disaster_recovery.md)
* [Disaster recovery with storage replication](howto/disaster_recovery_replication.md)
* [Disaster recovery with replicators](howto/replicators_dr.md)

## Related topics

Explanation:

- [Performance tuning](explanation/performance_tuning.md#performance-tuning)

Reference:

- [Provided metrics](reference/provided_metrics.md#provided-metrics)
- [Server settings for a LXD production setup](reference/server_settings.md#server-settings)


# index.html.md

# Environment variables

The LXD client and daemon respect some environment variables to adapt to
the user’s environment and to turn some advanced features on and off.

#### NOTE
These environment variables are not available if you use the LXD snap.

## Common

| Name          | Description                                                                        |
|---------------|------------------------------------------------------------------------------------|
| `LXD_DIR`     | The LXD data directory                                                             |
| `PATH`        | List of paths to look into when resolving binaries                                 |
| `http_proxy`  | Proxy server URL for HTTP                                                          |
| `https_proxy` | Proxy server URL for HTTPS                                                         |
| `no_proxy`    | List of domains, IP addresses or CIDR ranges that don’t require the use of a proxy |

## Client environment variable

| Name              | Description                                                     |
|-------------------|-----------------------------------------------------------------|
| `EDITOR`          | What text editor to use                                         |
| `VISUAL`          | What text editor to use (if `EDITOR` isn’t set)                 |
| `LXD_CONF`        | Path to the LXC configuration directory                         |
| `LXD_GLOBAL_CONF` | Path to the global LXC configuration directory                  |
| `LXC_REMOTE`      | Name of the remote to use (overrides configured default remote) |

## Server environment variable

| Name                          | Description                                                                                                                                                                                                                                                                                       |
|-------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `LXD_EXEC_PATH`               | Full path to the LXD binary (used when forking subcommands)                                                                                                                                                                                                                                       |
| `LXD_LXC_TEMPLATE_CONFIG`     | Path to the LXC template configuration directory                                                                                                                                                                                                                                                  |
| `LXD_SECURITY_APPARMOR`       | If set to `false`, forces AppArmor off                                                                                                                                                                                                                                                            |
| `LXD_UNPRIVILEGED_ONLY`       | If set to `true`, enforces that only unprivileged containers can be created. Note that any privileged containers that have been created before setting LXD_UNPRIVILEGED_ONLY will continue to be privileged. To use this option effectively it should be set when the LXD daemon is first set up. |
| `LXD_OVMF_PATH`               | Path to an OVMF build including `OVMF_CODE.fd` and `OVMF_VARS.ms.fd` (deprecated, please use `LXD_QEMU_FW_PATH` instead)                                                                                                                                                                          |
| `LXD_QEMU_FW_PATH`            | Path (or `:` separated list of paths) to firmware (OVMF, SeaBIOS) to be used by QEMU                                                                                                                                                                                                              |
| `LXD_IDMAPPED_MOUNTS_DISABLE` | Disable idmapped mounts support (useful when testing traditional UID shifting)                                                                                                                                                                                                                    |
| `LXD_DEVMONITOR_DIR`          | Path to be monitored by the device monitor. This is primarily for testing.                                                                                                                                                                                                                        |
| `LXD_FSMONITOR_DRIVER`        | Driver to be used for file system monitoring. This is primarily for testing.                                                                                                                                                                                                                      |


# index.html.md

<a id="architectures"></a>

# Architectures

LXD can run on just about any architecture that is supported by the Linux kernel and by Go.

Some entities in LXD are tied to an architecture, for example, the instances, instance snapshots and images.

The following table lists all supported architectures including their unique identifier and the name used to refer to them.
The architecture names are typically aligned with the Linux kernel architecture names.

|   ID | Kernel name   | Description                 | Personalities       |
|------|---------------|-----------------------------|---------------------|
|    1 | `i686`        | 32bit Intel x86             |                     |
|    2 | `x86_64`      | 64bit Intel x86             | `x86`               |
|    3 | `armv7l`      | 32bit ARMv7 little-endian   |                     |
|    4 | `aarch64`     | 64bit ARMv8 little-endian   | `armv7l` (optional) |
|    5 | `ppc`         | 32bit PowerPC big-endian    |                     |
|    6 | `ppc64`       | 64bit PowerPC big-endian    | `powerpc`           |
|    7 | `ppc64le`     | 64bit PowerPC little-endian |                     |
|    8 | `s390x`       | 64bit ESA/390 big-endian    |                     |
|    9 | `mips`        | 32bit MIPS                  |                     |
|   10 | `mips64`      | 64bit MIPS                  | `mips`              |
|   11 | `riscv32`     | 32bit RISC-V little-endian  |                     |
|   12 | `riscv64`     | 64bit RISC-V little-endian  |                     |
|   13 | `armv6l`      | 32bit ARMv6 little-endian   |                     |
|   14 | `armv8l`      | 32bit ARMv8 little-endian   |                     |
|   15 | `loongarch64` | 64bit LoongArch             |                     |

#### NOTE
LXD cares only about the kernel architecture, not the particular userspace flavor as determined by the toolchain.

That means that LXD considers ARMv7 hard-float to be the same as ARMv7 soft-float and refers to both as `armv7l`.
If useful to the user, the exact userspace ABI may be set as an image and container property, allowing easy query.

## Virtual machine support

LXD only supports running virtual machines on the following host architectures:

- `x86_64`
- `aarch64`
- `ppc64le`
- `s390x`

The virtual machine guest architecture can usually be the 32bit personality of the host architecture,
so long as the virtual machine firmware is capable of booting it.


# index.html.md

<a id="authentication"></a>

# Remote API authentication

Remote communications with the LXD daemon happen using JSON over HTTPS.
This requires the LXD API to be exposed over the network; see [How to expose LXD to the network](howto/server_expose.md#server-expose) for instructions.

To be able to access the remote API, clients must authenticate with the LXD server.
The following authentication methods are supported:

- [TLS client certificates](#authentication-tls-certs)
- [OpenID Connect authentication](#authentication-openid)
- [Bearer token authentication](#authentication-bearer)

<a id="authentication-tls-certs"></a>

## TLS client certificates


            <p class="youtube_link">
              <a href="https://www.youtube.com/watch?v=4iNpiL-lrXU" target="_blank">
                <span title="LXD token based remote authentication" class="play_icon">▶</span>
                <span title="LXD token based remote authentication">Watch on YouTube</span>
              </a>
            </p>
        
When using  client certificates for authentication, both the client and the server will generate a key pair the first time they’re launched.
The server will use that key pair for all HTTPS connections to the LXD socket.
The client will use its certificate as a client certificate for any client-server communication.

To cause certificates to be regenerated, simply remove the old ones.
On the next connection, a new certificate is generated.

### Communication protocol

The supported protocol must be TLS 1.3 or better.

All communications must use perfect forward secrecy, and ciphers must be limited to strong elliptic curve ones (such as ECDHE-RSA or ECDHE-ECDSA).

Any generated key should be at least 4096 bit RSA, preferably 384 bit ECDSA.
When using signatures, only SHA-2 signatures should be trusted.

Since we control both client and server, there is no reason to support
any backward compatibility to broken protocol or ciphers.

<a id="authentication-trusted-clients"></a>

### Trusted TLS clients

The workflow to authenticate with the server is similar to that of SSH, where an initial connection to an unknown server triggers a prompt:

1. When the user adds a server with [`lxc remote add`](reference/manpages/lxc/remote/add.md#lxc-remote-add-md), the server is contacted over HTTPS, its certificate is downloaded and the fingerprint is shown to the user.
2. The user is asked to confirm that this is indeed the server’s fingerprint, which they can manually check by connecting to the server or by asking someone with access to the server to run the info command and compare the fingerprints.
3. The server attempts to authenticate the client:
   - If the client certificate is in the server’s trust store, the connection is granted.
   - If the client certificate is not in the server’s trust store, the server prompts the user for a token.
     If the provided token matches, the client certificate is added to the server’s trust store and the connection is granted.
     Otherwise, the connection is rejected.

See [How to expose LXD to the network](howto/server_expose.md#server-expose) and [Authenticate with the LXD server](howto/server_expose.md#server-authenticate) for instructions on how to configure TLS authentication and add trusted clients.

<a id="authentication-pki"></a>

### Using a PKI system

In a  setup, a system administrator manages a central PKI that issues client certificates for all the LXD clients and server certificates for all the LXD daemons.

In PKI mode, TLS authentication requires that client certificates are signed be the .
This requirement does not apply to clients that authenticate via [OIDC](#authentication-openid).

The steps for enabling PKI mode differ slightly depending on whether you use an ACME provider in addition (see [TLS server certificate](#authentication-server-certificate)).

Only PKI

If you use a PKI system, both the server and client certificates are issued by intermediate CA(s).
The `client.ca` file contains the certificate used by the client to verify the server certificate it receives when making a connection to a remote.
The `server.ca` file contains the certificate used by the server to verify the client certificate associated with an incoming connection.

Both files contain trust anchors used to evaluate if the received leaf certificate from the other end of the connection is to be trusted or not.
If the leaf certificate’s chain of trust leads to one of the trusted anchors it will be trusted (unless revoked).

1. Add the CA certificate to all machines:
   - Place the `client.ca` file in the clients’ configuration directories (`~/.config/lxc` or `~/snap/lxd/common/config` for snap users).
   - Place the `server.ca` file in the server’s configuration directory (`/var/lib/lxd` or `/var/snap/lxd/common/lxd` for snap users).

     #### NOTE
     In a cluster setup, the CA certificate  must be named `cluster.ca`, and the same file must be added to all cluster members.
2. Place the certificates issued by the CA in the clients’ configuration directories, replacing the automatically generated `client.crt` and `client.key` files.
3. If you want clients to automatically trust the server, place the certificates issued by the CA in the server’s configuration directory, replacing the automatically generated `server.crt` and `server.key` files.

   #### NOTE
   In a cluster setup, the certificate files must be named `cluster.crt` and `cluster.key`.
   They must be identical on all cluster members.

   When a client adds a PKI-enabled server or cluster as a remote, it checks the server certificate and prompts the user to trust the server certificate only if the certificate has not been signed by the CA.
4. Restart the LXD daemon.

PKI and ACME

If you use a PKI system alongside an ACME provider, the server certificates are issued by the ACME provider, and the client certificates are issued by a secondary CA.

1. Place the CA certificate for the server (`server.ca`) in the server’s configuration directory (`/var/lib/lxd` or `/var/snap/lxd/common/lxd` for snap users), so that the server can authenticate the clients.

   #### NOTE
   In a cluster setup, the CA certificate  must be named `cluster.ca`, and the same file must be added to all cluster members.
2. Place the certificates issued by the CA in the clients’ configuration directories, replacing the automatically generated `client.crt` and `client.key` files.
3. Restart the LXD daemon.

#### Trusting certificates

CA-signed client certificates are not automatically trusted.
You must still add them to the server in one of the ways described in [Trusted TLS clients](#authentication-trusted-clients).

To automatically trust CA-signed client certificates, set the [`core.trust_ca_certificates`](server.md#server-core:core.trust_ca_certificates) server configuration to true.
When `core.trust_ca_certificates` is enabled, any new clients with a CA-signed certificate will have full access to LXD.

<a id="authentication-revoke-certificates"></a>

#### Revoking certificates

To revoke certificates via the PKI, place a certificate revocation list in the server’s configuration directory as `ca.crl` and restart the LXD daemon.
A client with a CA-signed certificate that has been revoked, and is present in `ca.crl`, will not be able to authenticate with LXD, nor add LXD as a remote via [mutual TLS](#authentication-trusted-clients).

<a id="authentication-openid"></a>

## OpenID Connect authentication

LXD supports using [OpenID Connect](https://openid.net/developers/how-connect-works/) to authenticate users through an  Identity Provider.

To configure LXD to use OIDC authentication, set the [`oidc.*`](server.md#server-options-oidc) server configuration options.
See the [how-to guides](howto/oidc.md#howto-oidc) for more information.

Once configured, the LXD UI will display a Log in with SSO button which will redirect you to the Identity Provider to log in.

To use OIDC authentication in the LXD CLI, run [`lxc remote add <remote_name> <remote_address>`](reference/manpages/lxc/remote/add.md#lxc-remote-add-md).
This defaults to OIDC authentication if configured on the remote server.
You are then prompted to authenticate through your web browser, where you must confirm that the device code displayed in the browser matches the device code that is displayed in the terminal window.
The LXD client then retrieves and stores an access token, which it provides to LXD for all interactions.
The identity provider might also provide a refresh token.
In this case, the LXD client uses this refresh token to attempt to retrieve another access token when the current access token has expired.

When an OIDC client initially authenticates with LXD, it does not have access to the majority of the LXD API.
OIDC clients must be granted access by an administrator, see [Fine-grained authorization](explanation/authorization.md#fine-grained-authorization).

<a id="authentication-server-certificate"></a>

## TLS server certificate

LXD supports issuing server certificates using  services, for example, [Let’s Encrypt](https://letsencrypt.org/).

To enable this feature, set the following server configuration:

- [`acme.domain`](server.md#server-acme:acme.domain): The domain for which the certificate should be issued.
- [`acme.email`](server.md#server-acme:acme.email): The email address used for the account of the ACME service.
- [`acme.agree_tos`](server.md#server-acme:acme.agree_tos): Must be set to `true` to agree to the ACME service’s terms of service.
- [`acme.ca_url`](server.md#server-acme:acme.ca_url): The directory URL of the ACME service. By default, LXD uses “Let’s Encrypt”.

LXD currently only supports the [`HTTP-01 challenge`](https://letsencrypt.org/docs/challenge-types/#http-01-challenge), which requires handling incoming HTTP requests on port 80.
This can be achieved by using a reverse proxy such as [HAProxy](https://www.haproxy.org/).

The HAProxy configuration example below uses `lxd.example.net` as the domain.
After the certificate has been issued, LXD will be reachable from `https://lxd.example.net/`.
It applies filtering to minimize the amount of undesired traffic coming from the internet reaching the protected LXD cluster.

```default
# HAProxy
global
  log /dev/log local0
  log /dev/log local1 notice
  chroot /var/lib/haproxy
  stats socket /run/haproxy/admin.sock mode 660 level admin
  stats timeout 30s
  user haproxy
  group haproxy
  daemon
  maxconn 100000

defaults
  mode tcp
  log global
  option tcplog
  option dontlognull
  timeout connect 5s
  timeout client 30s
  timeout client-fin 30s
  timeout server 30s
  timeout tunnel 300s
  timeout http-request 5s
  timeout check 5s
  maxconn 80000

# Frontend for HTTP traffic - HTTP mode for ACME challenges redirection
frontend http_frontend
  bind *:80
  mode http
  option httplog

  # ACME challenges are very low traffic even with MPIC
  # (Multi-Perspective Issuance Corroboration) validation.
  maxconn 32

  # Only redirect ACME challenges for known hosts to HTTPS
  http-request deny unless { hdr(host) lxd.example.com }
  http-request deny unless { path_beg /.well-known/acme-challenge/ }
  redirect scheme https code 301

# Frontend for HTTPS traffic - TCP mode with SNI inspection
frontend https_frontend
  bind *:443

  # TCP request inspection for SNI and client filtering
  tcp-request inspect-delay 5s

  # Extract SNI from TLS handshake
  tcp-request content capture req.ssl_sni len 64

  # Reject unwanted traffic
  # non-TLS
  tcp-request content reject unless { req.ssl_hello_type 1 }

  # for unknown SNI hosts
  tcp-request content reject unless { req.ssl_sni lxd.example.com }

  # using too old TLS version
  # TLS 1.3 (SSL version 3.4) but it is hard to distinguish TLS 1.2
  # from 1.3 as TLS 1.3 tries to masquerade as a resumed TLS 1.2
  # connection to work around broken middleboxes. Reject anything
  # older than TLS 1.2.
  # See https://datatracker.ietf.org/doc/html/rfc8446#appendix-D.4
  tcp-request content reject if { req.ssl_ver lt 3.3 }

  # Rate limiting for LXD traffic (that passed above checks)
  stick-table type ip size 100k expire 30s store conn_rate(10s)
  tcp-request content track-sc0 src
  tcp-request content reject if { sc_conn_rate(0) gt 50 }

  # Route to backend
  default_backend lxd_cluster_tcp

# Additional frontend for LXD management on different port (optional)
frontend lxd_management
  bind *:8443

  # Network restrictions (only allow trusted networks)
  tcp-request connection reject unless { src 192.0.2.0/24 }

  # Route to backend
  default_backend lxd_cluster_tcp

# Backend for LXD cluster (TCP mode with TLS passthrough)
backend lxd_cluster_tcp
  balance roundrobin

  # Sticky sessions based on TLS session ID (extracted from handshake)
  stick-table type binary len 32 size 30k expire 30m
  acl clienthello req_ssl_hello_type 1
  acl serverhello rep_ssl_hello_type 2
  # use tcp content accepts to detects ssl client and server hello.
  tcp-request inspect-delay 5s
  tcp-request content accept if clienthello
  # no timeout on response inspect delay by default.
  tcp-response content accept if serverhello
  # SSL session ID (SSLID) may be present on a client or server hello.
  # Its length is coded on 1 byte at offset 43 and its value starts
  # at offset 44.
  # Match and learn on request if client hello.
  stick on payload_lv(43,1) if clienthello
  # Learn on response if server hello.
  stick store-response payload_lv(43,1) if serverhello

  # Health checks using simple TCP connect
  option tcp-check

  # Failed connections will be redispatched to another cluster member
  option redispatch

  # LXD cluster members with PROXY protocol and core.https_trusted_proxy
  server lxd-1 1.2.3.4:8443 check send-proxy
  server lxd-2 1.2.3.5:8443 check send-proxy
  server lxd-3 1.2.3.6:8443 check send-proxy
# EOF
```

<a id="authentication-bearer"></a>

## Bearer token authentication

LXD supports authenticating to the LXD API using bearer tokens. Bearer tokens provide a secure and temporary way to authenticate API requests without requiring client certificates.

Bearer tokens can be issued for identities of type `bearer`. The permissions associated with a token are derived from the identity it belongs to and are enforced through [Fine-grained authorization](explanation/authorization.md#fine-grained-authorization).

To authenticate an API request using a bearer token, include it in the `Authorization` header
as `Authorization: Bearer <token>`, where `<token>` represents an actual token value.

By default, bearer tokens expire after 24 hours, unless they are manually revoked.
The expiration time can be customized when issuing the token.

See [How to authenticate to the LXD API using bearer tokens](howto/auth_bearer.md#howto-auth-bearer) to learn how to issue and use bearer token in LXD.

## Failure scenarios

In the following scenarios, authentication is expected to fail.

### Server certificate changed

The server certificate might change in the following cases:

- The server was fully reinstalled and therefore got a new certificate.
- The connection is being intercepted ().

In such cases, the client will refuse to connect to the server because the certificate fingerprint does not match the fingerprint in the configuration for this remote.

It is then up to the user to contact the server administrator to check if the certificate did in fact change.
If it did, the certificate can be replaced by the new one, or the remote can be removed altogether and re-added.

### Server trust relationship revoked

The server trust relationship is revoked for a client if another trusted client or the local server administrator removes the trust entry for the client on the server.

In this case, the server still uses the same certificate, but all API calls return a 403 code with an error indicating that the client isn’t trusted.

## Related topics

How-to guides:

- [How to harden security for LXD](howto/security_harden.md#howto-security-harden)
- [How to expose LXD to the network](howto/server_expose.md#server-expose)

Explanation:

- [Security](explanation/security.md#exp-security)


# index.html.md

# API extensions

The changes below were introduced to the LXD API after the 1.0 API was finalized.

They are all backward compatible and can be detected by client tools by
looking at the `api_extensions` field in `GET /1.0`.

<a id="extension-storage-zfs-remove-snapshots"></a>

## `storage_zfs_remove_snapshots`

A [`zfs.remove_snapshots`](reference/storage_zfs.md#storage-zfs-volume-conf:zfs.remove_snapshots) daemon configuration key was introduced.

It’s a Boolean that defaults to `false` and that when set to `true` instructs LXD
to remove any needed snapshot when attempting to restore another.

This is needed as ZFS will only let you restore the latest snapshot.

<a id="extension-container-host-shutdown-timeout"></a>

## `container_host_shutdown_timeout`

A [`boot.host_shutdown_timeout`](reference/instance_options.md#instance-boot:boot.host_shutdown_timeout) container configuration key was introduced.

It’s an integer which indicates how long LXD should wait for the container
to stop before killing it.

Its value is only used on clean LXD daemon shutdown. It defaults to 30s.

<a id="extension-container-stop-priority"></a>

## `container_stop_priority`

A [`boot.stop.priority`](reference/instance_options.md#instance-boot:boot.stop.priority) container configuration key was introduced.

It’s an integer which indicates the priority of a container during shutdown.

Containers will shutdown starting with the highest priority level.

Containers with the same priority will shutdown in parallel.  It defaults to 0.

<a id="extension-container-syscall-filtering"></a>

## `container_syscall_filtering`

A number of new syscalls related container configuration keys were introduced.

* [`security.syscalls.deny_default`](reference/instance_options.md#instance-security:security.syscalls.deny_default)
* [`security.syscalls.deny_compat`](reference/instance_options.md#instance-security:security.syscalls.deny_compat)
* [`security.syscalls.deny`](reference/instance_options.md#instance-security:security.syscalls.deny)
* [`security.syscalls.allow`](reference/instance_options.md#instance-security:security.syscalls.allow)

See [Instance configuration](explanation/instance_config.md#instance-config) for how to use them.

#### NOTE
Initially, those configuration keys were (accidentally) introduced with
offensive names. They have since been renamed
(`container_syscall_filtering_allow_deny_syntax`), and the old names are no
longer accepted.

<a id="extension-auth-pki"></a>

## `auth_pki`

This indicates support for PKI authentication mode.

In this mode, the client and server both must use certificates issued by the same PKI.

See [Security](explanation/security.md#security) for details.

<a id="extension-container-last-used-at"></a>

## `container_last_used_at`

A `last_used_at` field was added to the `GET /1.0/instances/<name>` endpoint.

It is a timestamp of the last time the instance was started.

If an instance has been created but not started yet, `last_used_at` field
will be `1970-01-01T00:00:00Z`

<a id="extension-etag"></a>

## `etag`

Add support for the ETag header on all relevant endpoints.

This adds the following HTTP header on answers to GET:

* ETag (SHA-256 of user modifiable content)

And adds support for the following HTTP header on PUT requests:

* If-Match (ETag value retrieved through previous GET)

This makes it possible to GET a LXD object, modify it and PUT it without
risking to hit a race condition where LXD or another client modified the
object in the meantime.

<a id="extension-patch"></a>

## `patch`

Add support for the HTTP PATCH method.

PATCH allows for partial update of an object in place of PUT.

<a id="extension-usb-devices"></a>

## `usb_devices`

Add support for USB hotplug.

<a id="extension-https-allowed-credentials"></a>

## `https_allowed_credentials`

To use LXD API with all Web Browsers (via SPAs) you must send credentials
(certificate) with each XHR (in order for this to happen, you should set
[`withCredentials=true`](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials)
flag to each XHR Request).

Some browsers like Firefox and Safari can’t accept server response without
`Access-Control-Allow-Credentials: true` header. To ensure that the server will
return a response with that header, set [`core.https_allowed_credentials`](server.md#server-core:core.https_allowed_credentials) to `true`.

<a id="extension-image-compression-algorithm"></a>

## `image_compression_algorithm`

This adds support for a `compression_algorithm` property when creating an image (`POST /1.0/images`).

Setting this property overrides the server default value ([`images.compression_algorithm`](server.md#server-images:images.compression_algorithm)).

<a id="extension-directory-manipulation"></a>

## `directory_manipulation`

This allows for creating and listing directories via the LXD API, and exports
the file type via the X-LXD-type header, which can be either `file` or
`directory` right now.

<a id="extension-container-cpu-time"></a>

## `container_cpu_time`

This adds support for retrieving CPU time for a running container.

<a id="extension-storage-zfs-use-refquota"></a>

## `storage_zfs_use_refquota`

Introduces a new server property [`zfs.use_refquota`](reference/storage_zfs.md#storage-zfs-volume-conf:zfs.use_refquota) which instructs LXD
to set the `refquota` property instead of `quota` when setting a size limit
on a container. LXD will also then use `usedbydataset` in place of `used`
when being queried about disk utilization.

This effectively controls whether disk usage by snapshots should be
considered as part of the container’s disk space usage.

<a id="extension-storage-lvm-mount-options"></a>

## `storage_lvm_mount_options`

Adds a new `storage.lvm_mount_options` daemon configuration option
which defaults to `discard` and allows the user to set additional mount
options for the file system used by the LVM LV.

<a id="extension-network"></a>

## `network`

Network management API for LXD.

This includes:

* Addition of the `managed` property on `/1.0/networks` entries
* All the network configuration options (see [Network configuration](networks.md) for details)
* `POST /1.0/networks` (see [RESTful API](rest-api.md) for details)
* `PUT /1.0/networks/<entry>` (see [RESTful API](rest-api.md) for details)
* `PATCH /1.0/networks/<entry>` (see [RESTful API](rest-api.md) for details)
* `DELETE /1.0/networks/<entry>` (see [RESTful API](rest-api.md) for details)
* `ipv4.address` property on `nic` type devices (when `nictype` is `bridged`)
* `ipv6.address` property on `nic` type devices (when `nictype` is `bridged`)
* `security.mac_filtering` property on `nic` type devices (when `nictype` is `bridged`)

<a id="extension-profile-usedby"></a>

## `profile_usedby`

Adds a new `used_by` field to profile entries listing the instances that are using it.

<a id="extension-container-push"></a>

## `container_push`

When an instance is created in push mode, the client serves as a proxy between
the source and target server. This is useful in cases where the target server
is behind a NAT or firewall and cannot directly communicate with the source
server and operate in pull mode.

<a id="extension-container-exec-recording"></a>

## `container_exec_recording`

Introduces a new Boolean `record-output`, parameter to
`/1.0/instances/<name>/exec` which when set to `true` and combined with
with `wait-for-websocket` set to `false`, will record stdout and stderr to
disk and make them available through the logs interface.

The URL to the recorded output is included in the operation metadata
once the command is done running.

That output will expire similarly to other log files, typically after 48 hours.

<a id="extension-certificate-update"></a>

## `certificate_update`

Adds the following to the REST API:

* ETag header on GET of a certificate
* PUT of certificate entries
* PATCH of certificate entries

<a id="extension-container-exec-signal-handling"></a>

## `container_exec_signal_handling`

Adds support `/1.0/instances/<name>/exec` for forwarding signals sent to the
client to the processes executing in the instance. Currently SIGTERM and
SIGHUP are forwarded. Further signals that can be forwarded might be added
later.

<a id="extension-gpu-devices"></a>

## `gpu_devices`

Enables adding GPUs to a container.

<a id="extension-container-image-properties"></a>

## `container_image_properties`

Introduces a new `image` configuration key space. Read-only, includes the properties of the parent image.

<a id="extension-migration-progress"></a>

## `migration_progress`

Transfer progress is now exported as part of the operation, on both sending and receiving ends.
This shows up as a `fs_progress` attribute in the operation metadata.

<a id="extension-id-map"></a>

## `id_map`

Enables setting the [`security.idmap.isolated`](reference/instance_options.md#instance-security:security.idmap.isolated),
[`security.idmap.size`](reference/instance_options.md#instance-security:security.idmap.size), and [`raw.idmap`](reference/instance_options.md#instance-raw:raw.idmap) fields.

<a id="extension-network-firewall-filtering"></a>

## `network_firewall_filtering`

Add two new keys, [`ipv4.firewall`](reference/network_bridge.md#network-bridge-network-conf:ipv4.firewall) and [`ipv6.firewall`](reference/network_bridge.md#network-bridge-network-conf:ipv6.firewall) which if set to
`false` will turn off the generation of `iptables` FORWARDING rules. NAT
rules will still be added so long as the matching [`ipv4.nat`](reference/network_bridge.md#network-bridge-network-conf:ipv4.nat) or
[`ipv6.nat`](reference/network_bridge.md#network-bridge-network-conf:ipv6.nat) key is set to `true`.

Rules necessary for `dnsmasq` to work (DHCP/DNS) will always be applied if
`dnsmasq` is enabled on the bridge.

<a id="extension-network-routes"></a>

## `network_routes`

Introduces [`ipv4.routes`](reference/network_bridge.md#network-bridge-network-conf:ipv4.routes) and [`ipv6.routes`](reference/network_bridge.md#network-bridge-network-conf:ipv6.routes) which allow routing additional subnets to a LXD bridge.

<a id="extension-storage"></a>

## `storage`

Storage management API for LXD.

This includes:

* `GET /1.0/storage-pools`
* `POST /1.0/storage-pools` (see [RESTful API](rest-api.md) for details)
* `GET /1.0/storage-pools/<name>` (see [RESTful API](rest-api.md) for details)
* `POST /1.0/storage-pools/<name>` (see [RESTful API](rest-api.md) for details)
* `PUT /1.0/storage-pools/<name>` (see [RESTful API](rest-api.md) for details)
* `PATCH /1.0/storage-pools/<name>` (see [RESTful API](rest-api.md) for details)
* `DELETE /1.0/storage-pools/<name>` (see [RESTful API](rest-api.md) for details)
* `GET /1.0/storage-pools/<name>/volumes` (see [RESTful API](rest-api.md) for details)
* `GET /1.0/storage-pools/<name>/volumes/<volume_type>` (see [RESTful API](rest-api.md) for details)
* `POST /1.0/storage-pools/<name>/volumes/<volume_type>` (see [RESTful API](rest-api.md) for details)
* `GET /1.0/storage-pools/<pool>/volumes/<volume_type>/<name>` (see [RESTful API](rest-api.md) for details)
* `POST /1.0/storage-pools/<pool>/volumes/<volume_type>/<name>` (see [RESTful API](rest-api.md) for details)
* `PUT /1.0/storage-pools/<pool>/volumes/<volume_type>/<name>` (see [RESTful API](rest-api.md) for details)
* `PATCH /1.0/storage-pools/<pool>/volumes/<volume_type>/<name>` (see [RESTful API](rest-api.md) for details)
* `DELETE /1.0/storage-pools/<pool>/volumes/<volume_type>/<name>` (see [RESTful API](rest-api.md) for details)
* All storage configuration options (see [Storage configuration](storage.md) for details)

<a id="extension-file-delete"></a>

## `file_delete`

Implements `DELETE` in `/1.0/instances/<name>/files`

<a id="extension-file-append"></a>

## `file_append`

Implements the `X-LXD-write` header which can be one of `overwrite` or `append`.

<a id="extension-network-dhcp-expiry"></a>

## `network_dhcp_expiry`

Introduces [`ipv4.dhcp.expiry`](reference/network_bridge.md#network-bridge-network-conf:ipv4.dhcp.expiry) and [`ipv6.dhcp.expiry`](reference/network_bridge.md#network-bridge-network-conf:ipv6.dhcp.expiry) allowing to set the DHCP lease expiry time.

<a id="extension-storage-lvm-vg-rename"></a>

## `storage_lvm_vg_rename`

Introduces the ability to rename a volume group by setting [`lvm.vg_name`](reference/storage_lvm.md#storage-lvm-pool-conf:lvm.vg_name).

<a id="extension-storage-lvm-thinpool-rename"></a>

## `storage_lvm_thinpool_rename`

Introduces the ability to rename a thin pool name by setting [`lvm.thinpool_name`](reference/storage_lvm.md#storage-lvm-pool-conf:lvm.thinpool_name).

<a id="extension-network-vlan"></a>

## `network_vlan`

This adds a new [`vlan`](reference/devices_nic.md#device-nic-macvlan-device-conf:vlan) property to `macvlan` network devices.

When set, this will instruct LXD to attach to the specified VLAN. LXD
will look for an existing interface for that VLAN on the host. If one
can’t be found it will create one itself and then use that as the
macvlan parent.

<a id="extension-image-create-aliases"></a>

## `image_create_aliases`

Adds a new `aliases` field to `POST /1.0/images` allowing for aliases to
be set at image creation/import time.

<a id="extension-container-stateless-copy"></a>

## `container_stateless_copy`

This introduces a new `live` attribute in `POST /1.0/instances/<name>`.
Setting it to `false` tells LXD not to attempt running state transfer.

<a id="extension-container-only-migration"></a>

## `container_only_migration`

Introduces a new Boolean `container_only` attribute. When set to `true` only the
instance will be copied or moved.

<a id="extension-storage-zfs-clone-copy"></a>

## `storage_zfs_clone_copy`

Introduces a new Boolean [`zfs.clone_copy`](reference/storage_zfs.md#storage-zfs-pool-conf:zfs.clone_copy) property for ZFS storage
pools. When set to `false` copying an instance will be done through `zfs send` and
receive. This will make the target instance independent of its source
instance thus avoiding the need to keep dependent snapshots in the ZFS pool
around. However, this also entails less efficient storage usage for the
affected pool.
The default value for this property is `true`, i.e. space-efficient snapshots
will be used unless explicitly set to `false`.

<a id="extension-unix-device-rename"></a>

## `unix_device_rename`

Introduces the ability to rename the `unix-block`/`unix-char` device inside container by setting `path`,
and the `source` attribute is added to specify the device on host.
If `source` is set without a `path`, we should assume that `path` will be the same as `source`.
If `path` is set without `source` and `major`/`minor` isn’t set,
we should assume that `source` will be the same as `path`.
So at least one of them must be set.

<a id="extension-storage-lvm-use-thinpool"></a>

## `storage_lvm_use_thinpool`

Adds the [`lvm.use_thinpool`](reference/storage_lvm.md#storage-lvm-pool-conf:lvm.use_thinpool) configuration key, a Boolean that defaults to `true`.
When set to `false`, LXD creates plain logical volumes for storage entities instead of using an LVM thin pool.

<a id="extension-storage-rsync-bwlimit"></a>

## `storage_rsync_bwlimit`

When `rsync` has to be invoked to transfer storage entities setting `rsync.bwlimit`
places an upper limit on the amount of socket I/O allowed.

<a id="extension-network-vxlan-interface"></a>

## `network_vxlan_interface`

This introduces a new [`tunnel.NAME.interface`](reference/network_bridge.md#network-bridge-network-conf:tunnel.NAME.interface) option for networks.

This key control what host network interface is used for a VXLAN tunnel.

<a id="extension-storage-btrfs-mount-options"></a>

## `storage_btrfs_mount_options`

This introduces the [`btrfs.mount_options`](reference/storage_btrfs.md#storage-btrfs-pool-conf:btrfs.mount_options) property for Btrfs storage pools.

This key controls what mount options will be used for the Btrfs storage pool.

<a id="extension-entity-description"></a>

## `entity_description`

This adds descriptions to entities like instances, snapshots, networks, storage pools and volumes.

<a id="extension-image-force-refresh"></a>

## `image_force_refresh`

This allows forcing a refresh for an existing image.

<a id="extension-storage-lvm-lv-resizing"></a>

## `storage_lvm_lv_resizing`

This introduces the ability to resize logical volumes by setting the `size`
property in the instance root disk device.

<a id="extension-id-map-base"></a>

## `id_map_base`

This introduces a new [`security.idmap.base`](reference/instance_options.md#instance-security:security.idmap.base) allowing the user to skip the
map auto-selection process for isolated containers and specify what host
UID/GID to use as the base.

<a id="extension-file-symlinks"></a>

## `file_symlinks`

This adds support for transferring symlinks through the file API.
X-LXD-type can now be `symlink` with the request content being the target path.

<a id="extension-container-push-target"></a>

## `container_push_target`

This adds the `target` field to `POST /1.0/instances/<name>` which can be
used to have the source LXD host connect to the target during migration.

<a id="extension-network-vlan-physical"></a>

## `network_vlan_physical`

Allows use of [`vlan`](reference/network_physical.md#network-physical-network-conf:vlan) property with `physical` network devices.

When set, this will instruct LXD to attach to the specified VLAN on the `parent` interface.
LXD will look for an existing interface for that `parent` and VLAN on the host.
If one can’t be found it will create one itself.
Then, LXD will directly attach this interface to the container.

<a id="extension-storage-images-delete"></a>

## `storage_images_delete`

This enabled the storage API to delete storage volumes for images from
a specific storage pool.

<a id="extension-container-edit-metadata"></a>

## `container_edit_metadata`

This adds support for editing an instance `metadata.yaml` and related templates
via API, by accessing URLs under `/1.0/instances/<name>/metadata`. It can be used
to edit an instance before publishing an image from it.

<a id="extension-container-snapshot-stateful-migration"></a>

## `container_snapshot_stateful_migration`

This enables migrating stateful container snapshots to new containers.

<a id="extension-storage-driver-ceph"></a>

## `storage_driver_ceph`

This adds a Ceph storage driver.

<a id="extension-storage-ceph-user-name"></a>

## `storage_ceph_user_name`

This adds the ability to specify the Ceph user.

<a id="extension-resource-limits"></a>

## `resource_limits`

This adds the `instance_type` field to the container creation request.
Its value is expanded to LXD resource limits.

<a id="extension-storage-volatile-initial-source"></a>

## `storage_volatile_initial_source`

This records the actual source passed to LXD during storage pool creation.

<a id="extension-storage-ceph-force-osd-reuse"></a>

## `storage_ceph_force_osd_reuse`

This introduces the `ceph.osd.force_reuse` property for the Ceph storage
driver. When set to `true` LXD will reuse an OSD storage pool that is already in
use by another LXD instance.

<a id="extension-storage-block-filesystem-btrfs"></a>

## `storage_block_filesystem_btrfs`

This adds support for Btrfs as a storage volume file system, in addition to `ext4`
and `xfs`.

<a id="extension-resources"></a>

## `resources`

This adds support for querying a LXD daemon for the system resources it has
available.

<a id="extension-kernel-limits"></a>

## `kernel_limits`

This adds support for setting process limits such as maximum number of open
files for the container via `nofile`. The format is `limits.kernel.[limit name]`.

<a id="extension-storage-api-volume-rename"></a>

## `storage_api_volume_rename`

This adds support for renaming custom storage volumes.

<a id="extension-network-sriov"></a>

## `network_sriov`

This adds support for SR-IOV enabled network devices.

<a id="extension-console"></a>

## `console`

This adds support to interact with the container console device and console log.

<a id="extension-restrict-devlxd"></a>

## `restrict_devlxd`

A new [`security.devlxd`](reference/instance_options.md#instance-security:security.devlxd) container configuration key was introduced.
The key controls whether the `/dev/lxd` interface is made available to the instance.
If set to `false`, this effectively prevents the container from interacting with the LXD daemon.

<a id="extension-migration-pre-copy"></a>

## `migration_pre_copy`

This adds support for optimized memory transfer during live migration.

<a id="extension-infiniband"></a>

## `infiniband`

This adds support to use InfiniBand network devices.

<a id="extension-devlxd-events"></a>

## `devlxd_events`

This adds a WebSocket API to the `devlxd` socket.

When connecting to `/1.0/events` over the `devlxd` socket, you will now be
getting a stream of events over WebSocket.

<a id="extension-proxy"></a>

## `proxy`

This adds a new `proxy` device type to containers, allowing forwarding
of connections between the host and container.

<a id="extension-network-dhcp-gateway"></a>

## `network_dhcp_gateway`

Introduces a new [`ipv4.dhcp.gateway`](reference/network_bridge.md#network-bridge-network-conf:ipv4.dhcp.gateway) network configuration key to set an alternate gateway.

<a id="extension-file-get-symlink"></a>

## `file_get_symlink`

This makes it possible to retrieve symlinks using the file API.

<a id="extension-network-leases"></a>

## `network_leases`

Adds a new `/1.0/networks/NAME/leases` API endpoint to query the lease database on
bridges which run a LXD-managed DHCP server.

<a id="extension-unix-device-hotplug"></a>

## `unix_device_hotplug`

This adds support for the [`required`](reference/devices_unix_hotplug.md#device-unix-hotplug-device-conf:required) property for Unix devices.

<a id="extension-storage-api-local-volume-handling"></a>

## `storage_api_local_volume_handling`

This add the ability to copy and move custom storage volumes locally in the
same and between storage pools.

<a id="extension-operation-description"></a>

## `operation_description`

Adds a `description` field to all operations.

<a id="extension-clustering"></a>

## `clustering`

Clustering API for LXD.

This includes the following new endpoints (see [RESTful API](rest-api.md) for details):

* `GET /1.0/cluster`
* `UPDATE /1.0/cluster`
* `GET /1.0/cluster/members`
* `GET /1.0/cluster/members/<name>`
* `POST /1.0/cluster/members/<name>`
* `DELETE /1.0/cluster/members/<name>`

The following existing endpoints have been modified:

* `POST /1.0/instances` accepts a new `target` query parameter
* `POST /1.0/storage-pools` accepts a new `target` query parameter
* `GET /1.0/storage-pool/<name>` accepts a new `target` query parameter
* `POST /1.0/storage-pool/<pool>/volumes/<type>` accepts a new `target` query parameter
* `GET /1.0/storage-pool/<pool>/volumes/<type>/<name>` accepts a new `target` query parameter
* `POST /1.0/storage-pool/<pool>/volumes/<type>/<name>` accepts a new `target` query parameter
* `PUT /1.0/storage-pool/<pool>/volumes/<type>/<name>` accepts a new `target` query parameter
* `PATCH /1.0/storage-pool/<pool>/volumes/<type>/<name>` accepts a new `target` query parameter
* `DELETE /1.0/storage-pool/<pool>/volumes/<type>/<name>` accepts a new `target` query parameter
* `POST /1.0/networks` accepts a new `target` query parameter
* `GET /1.0/networks/<name>` accepts a new `target` query parameter

<a id="extension-event-lifecycle"></a>

## `event_lifecycle`

This adds a new `lifecycle` message type to the events API.

<a id="extension-storage-api-remote-volume-handling"></a>

## `storage_api_remote_volume_handling`

This adds the ability to copy and move custom storage volumes between remote.

<a id="extension-nvidia-runtime"></a>

## `nvidia_runtime`

Adds a [`nvidia.runtime`](reference/instance_options.md#instance-nvidia:nvidia.runtime) configuration option for containers, setting this to
`true` will have the NVIDIA runtime and CUDA libraries passed to the
container.

<a id="extension-container-mount-propagation"></a>

## `container_mount_propagation`

This adds a new [`propagation`](reference/devices_disk.md#device-disk-device-conf:propagation) option to the disk device type, allowing
the configuration of kernel mount propagation.

<a id="extension-container-backup"></a>

## `container_backup`

Add container backup support.

This includes the following new endpoints (see [RESTful API](rest-api.md) for details):

* `GET /1.0/instances/<name>/backups`
* `POST /1.0/instances/<name>/backups`
* `GET /1.0/instances/<name>/backups/<name>`
* `POST /1.0/instances/<name>/backups/<name>`
* `DELETE /1.0/instances/<name>/backups/<name>`
* `GET /1.0/instances/<name>/backups/<name>/export`

The following existing endpoint has been modified:

* `POST /1.0/instances` accepts the new source type `backup`

<a id="extension-devlxd-images"></a>

## `devlxd_images`

Adds a [`security.devlxd.images`](reference/instance_options.md#instance-security:security.devlxd.images) configuration option for containers which
controls the availability of a `/1.0/images/FINGERPRINT/export` API over
`devlxd`. This can be used by a container running nested LXD to access raw
images from the host.

<a id="extension-container-local-cross-pool-handling"></a>

## `container_local_cross_pool_handling`

This enables copying or moving containers between storage pools on the same LXD
instance.

<a id="extension-proxy-unix"></a>

## `proxy_unix`

Add support for both Unix sockets and abstract Unix sockets in proxy devices.
They can be used by specifying the address as `unix:/path/to/unix.sock` (normal
socket) or `unix:@/tmp/unix.sock` (abstract socket).

Supported connections are now:

* `TCP <-> TCP`
* `UNIX <-> UNIX`
* `TCP <-> UNIX`
* `UNIX <-> TCP`

<a id="extension-proxy-udp"></a>

## `proxy_udp`

Add support for UDP in proxy devices.

Supported connections are now:

* `TCP <-> TCP`
* `UNIX <-> UNIX`
* `TCP <-> UNIX`
* `UNIX <-> TCP`
* `UDP <-> UDP`
* `TCP <-> UDP`
* `UNIX <-> UDP`

<a id="extension-clustering-join"></a>

## `clustering_join`

This makes `GET /1.0/cluster` return information about which storage pools and
networks are required to be created by joining nodes and which node-specific
configuration keys they are required to use when creating them. Likewise the `PUT /1.0/cluster` endpoint now accepts the same format to pass information about
storage pools and networks to be automatically created before attempting to join
a cluster.

<a id="extension-proxy-tcp-udp-multi-port-handling"></a>

## `proxy_tcp_udp_multi_port_handling`

Adds support for forwarding traffic for multiple ports. Forwarding is allowed
between a range of ports if the port range is equal for source and target
(for example `1.2.3.4 0-1000 -> 5.6.7.8 1000-2000`) and between a range of source
ports and a single target port (for example `1.2.3.4 0-1000 -> 5.6.7.8 1000`).

<a id="extension-network-state"></a>

## `network_state`

Adds support for retrieving a network’s state.

This adds the following new endpoint (see [RESTful API](rest-api.md) for details):

* `GET /1.0/networks/<name>/state`

<a id="extension-proxy-unix-dac-properties"></a>

## `proxy_unix_dac_properties`

This adds support for GID, UID, and mode properties for non-abstract Unix
sockets.

<a id="extension-container-protection-delete"></a>

## `container_protection_delete`

Enables setting the [`security.protection.delete`](reference/instance_options.md#instance-security:security.protection.delete) field which prevents containers
from being deleted if set to `true`. Snapshots are not affected by this setting.

<a id="extension-unix-priv-drop"></a>

## `unix_priv_drop`

Adds [`security.uid`](reference/devices_proxy.md#device-proxy-device-conf:security.uid) and [`security.gid`](reference/devices_proxy.md#device-proxy-device-conf:security.gid) for the proxy devices, allowing
privilege dropping and effectively changing the UID/GID used for
connections to Unix sockets too.

<a id="extension-pprof-http"></a>

## `pprof_http`

This adds a new [`core.debug_address`](server.md#server-core:core.debug_address) configuration option to start a debugging HTTP server.

That server currently includes a `pprof` API and replaces the old
`cpu-profile`, `memory-profile` and `print-goroutines` debug options.

<a id="extension-proxy-haproxy-protocol"></a>

## `proxy_haproxy_protocol`

Adds a [`proxy_protocol`](reference/devices_proxy.md#device-proxy-device-conf:proxy_protocol) key to the proxy device which controls the use of the HAProxy PROXY protocol header.

<a id="extension-network-hwaddr"></a>

## `network_hwaddr`

Adds a [`bridge.hwaddr`](reference/network_bridge.md#network-bridge-network-conf:bridge.hwaddr) key to control the MAC address of the bridge.

<a id="extension-proxy-nat"></a>

## `proxy_nat`

This adds optimized UDP/TCP proxying. If the configuration allows, proxying
will be done via `iptables` instead of proxy devices.

<a id="extension-network-nat-order"></a>

## `network_nat_order`

This introduces the [`ipv4.nat.order`](reference/network_bridge.md#network-bridge-network-conf:ipv4.nat.order) and [`ipv6.nat.order`](reference/network_bridge.md#network-bridge-network-conf:ipv6.nat.order) configuration keys for LXD bridges.
Those keys control whether to put the LXD rules before or after any pre-existing rules in the chain.

<a id="extension-container-full"></a>

## `container_full`

This introduces a new `recursion=2` mode for `GET /1.0/instances` which allows for the retrieval of
all instance structs, including the state, snapshots and backup structs.

This effectively allows for [`lxc list`](reference/manpages/lxc/list.md#lxc-list-md) to get all it needs in one query.

<a id="extension-backup-compression"></a>

## `backup_compression`

This introduces a new [`backups.compression_algorithm`](server.md#server-miscellaneous:backups.compression_algorithm) configuration key which
allows configuration of backup compression.

<a id="extension-nvidia-runtime-config"></a>

## `nvidia_runtime_config`

This introduces a few extra configuration keys when using [`nvidia.runtime`](reference/instance_options.md#instance-nvidia:nvidia.runtime) and the `libnvidia-container` library.
Those keys translate pretty much directly to the matching NVIDIA container environment variables:

* [`nvidia.driver.capabilities`](reference/instance_options.md#instance-nvidia:nvidia.driver.capabilities) => `NVIDIA_DRIVER_CAPABILITIES`
* [`nvidia.require.cuda`](reference/instance_options.md#instance-nvidia:nvidia.require.cuda) => `NVIDIA_REQUIRE_CUDA`
* [`nvidia.require.driver`](reference/instance_options.md#instance-nvidia:nvidia.require.driver) => `NVIDIA_REQUIRE_DRIVER`

<a id="extension-storage-api-volume-snapshots"></a>

## `storage_api_volume_snapshots`

Add support for storage volume snapshots. They work like container snapshots,
only for volumes.

This adds the following new endpoint (see [RESTful API](rest-api.md) for details):

* `GET /1.0/storage-pools/<pool>/volumes/<type>/<name>/snapshots`
* `POST /1.0/storage-pools/<pool>/volumes/<type>/<name>/snapshots`
* `GET /1.0/storage-pools/<pool>/volumes/<type>/<volume>/snapshots/<name>`
* `PUT /1.0/storage-pools/<pool>/volumes/<type>/<volume>/snapshots/<name>`
* `POST /1.0/storage-pools/<pool>/volumes/<type>/<volume>/snapshots/<name>`
* `DELETE /1.0/storage-pools/<pool>/volumes/<type>/<volume>/snapshots/<name>`

<a id="extension-storage-unmapped"></a>

## `storage_unmapped`

Introduces a new `security.unmapped` Boolean on storage volumes.

Setting it to `true` will flush the current map on the volume and prevent
any further idmap tracking and remapping on the volume.

This can be used to share data between isolated containers after
attaching it to the container which requires write access.

<a id="extension-projects"></a>

## `projects`

Add a new project API, supporting creation, update and deletion of projects.

Projects can hold containers, profiles or images at this point and let
you get a separate view of your LXD resources by switching to it.

<a id="extension-network-vxlan-ttl"></a>

## `network_vxlan_ttl`

This adds a new [`tunnel.NAME.ttl`](reference/network_bridge.md#network-bridge-network-conf:tunnel.NAME.ttl) network configuration option which
makes it possible to raise the TTL on VXLAN tunnels.

<a id="extension-container-incremental-copy"></a>

## `container_incremental_copy`

This adds support for incremental container copy. When copying a container
using the `--refresh` flag, only the missing or outdated files will be
copied over. Should the target container not exist yet, a normal copy operation
is performed.

<a id="extension-usb-optional-vendorid"></a>

## `usb_optional_vendorid`

As the name implies, the [`vendorid`](reference/devices_usb.md#device-unix-usb-device-conf:vendorid) field on USB devices attached to
containers has now been made optional, allowing for all USB devices to
be passed to a container (similar to what’s done for GPUs).

<a id="extension-snapshot-scheduling"></a>

## `snapshot_scheduling`

This adds support for snapshot scheduling. It introduces three new
configuration keys: `snapshots.schedule`, `snapshots.schedule.stopped`, and
`snapshots.pattern`. Snapshots can be created automatically up to every minute.

<a id="extension-snapshot-schedule-aliases"></a>

## `snapshot_schedule_aliases`

Snapshot schedule can be configured by a comma-separated list of schedule aliases.
Available aliases are `<@hourly> <@daily> <@midnight> <@weekly> <@monthly> <@annually> <@yearly> <@startup>` for instances,
and `<@hourly> <@daily> <@midnight> <@weekly> <@monthly> <@annually> <@yearly>` for storage volumes.

<a id="extension-container-copy-project"></a>

## `container_copy_project`

Introduces a `project` field to the container source JSON object, allowing for
copy/move of containers between projects.

<a id="extension-clustering-server-address"></a>

## `clustering_server_address`

This adds support for configuring a server network address which differs from
the REST API client network address. When bootstrapping a new cluster, clients
can set the new [`cluster.https_address`](server.md#server-cluster:cluster.https_address) configuration key to specify the address of
the initial server. When joining a new server, clients can set the
[`core.https_address`](server.md#server-core:core.https_address) configuration key of the joining server to the REST API
address the joining server should listen at, and set the `server_address`
key in the `PUT /1.0/cluster` API to the address the joining server should
use for clustering traffic (the value of `server_address` will be
automatically copied to the `cluster.https_address` configuration key of the
joining server).

<a id="extension-clustering-image-replication"></a>

## `clustering_image_replication`

Enable image replication across the nodes in the cluster.
A new [`cluster.images_minimal_replica`](server.md#server-cluster:cluster.images_minimal_replica) configuration key was introduced can be used
to specify to the minimal numbers of nodes for image replication.

<a id="extension-container-protection-shift"></a>

## `container_protection_shift`

Enables setting the [`security.protection.shift`](reference/instance_options.md#instance-security:security.protection.shift) option which prevents containers
from having their file system shifted.

<a id="extension-snapshot-expiry"></a>

## `snapshot_expiry`

This adds support for snapshot expiration. The task is run minutely. The configuration
option [`snapshots.expiry`](reference/instance_options.md#instance-snapshots:snapshots.expiry) takes an expression in the form of `1M 2H 3d 4w 5m 6y` (1 minute, 2 hours, 3 days, 4 weeks, 5 months, 6 years), however not all
parts have to be used.

Snapshots which are then created will be given an expiry date based on the
expression. This expiry date, defined by `expires_at`, can be manually edited
using the API or [`lxc config edit`](reference/manpages/lxc/config/edit.md#lxc-config-edit-md). Snapshots with a valid expiry date will be
removed when the task in run. Expiry can be disabled by setting `expires_at` to
an empty string or `0001-01-01T00:00:00Z` (zero time). This is the default if
`snapshots.expiry` is not set.

This adds the following new endpoint (see [RESTful API](rest-api.md) for details):

* `PUT /1.0/instances/<name>/snapshots/<name>`

<a id="extension-container-backup-override-pool"></a>

## `container_backup_override_pool`

Adds the `PoolName` field to `InstanceBackupArgs`, sent as the `X-LXD-pool` header on `POST /1.0/instances`,
allowing the storage pool that an instance is restored into from a backup to be overridden instead of using
the pool recorded in the backup.

<a id="extension-snapshot-expiry-creation"></a>

## `snapshot_expiry_creation`

Adds `expires_at` to container creation, allowing for override of a
snapshot’s expiry at creation time.

<a id="extension-network-leases-location"></a>

## `network_leases_location`

Introduces a `Location` field in the leases list.
This is used when querying a cluster to show what node a particular
lease was found on.

<a id="extension-resources-cpu-socket"></a>

## `resources_cpu_socket`

Add Socket field to CPU resources in case we get out of order socket information.

<a id="extension-resources-gpu"></a>

## `resources_gpu`

Add a new GPU struct to the server resources, listing all usable GPUs on the system.

<a id="extension-resources-numa"></a>

## `resources_numa`

Shows the NUMA node for all CPUs and GPUs.

<a id="extension-kernel-features"></a>

## `kernel_features`

Exposes the state of optional kernel features through the server environment.

<a id="extension-id-map-current"></a>

## `id_map_current`

This introduces a new internal [`volatile.idmap.current`](reference/instance_options.md#instance-volatile:volatile.idmap.current) key which is
used to track the current mapping for the container.

This effectively gives us:

* [`volatile.last_state.idmap`](reference/instance_options.md#instance-volatile:volatile.last_state.idmap) => On-disk idmap
* [`volatile.idmap.current`](reference/instance_options.md#instance-volatile:volatile.idmap.current) => Current kernel map
* [`volatile.idmap.next`](reference/instance_options.md#instance-volatile:volatile.idmap.next) => Next on-disk idmap

This is required to implement environments where the on-disk map isn’t
changed but the kernel map is (e.g. `idmapped mounts`).

<a id="extension-event-location"></a>

## `event_location`

Expose the location of the generation of API events.

<a id="extension-storage-api-remote-volume-snapshots"></a>

## `storage_api_remote_volume_snapshots`

This allows migrating storage volumes including their snapshots.

<a id="extension-network-nat-address"></a>

## `network_nat_address`

This introduces the [`ipv4.nat.address`](reference/network_bridge.md#network-bridge-network-conf:ipv4.nat.address) and [`ipv6.nat.address`](reference/network_bridge.md#network-bridge-network-conf:ipv6.nat.address) configuration keys for LXD bridges.
Those keys control the source address used for outbound traffic from the bridge.

<a id="extension-container-nic-routes"></a>

## `container_nic_routes`

This introduces the [`ipv4.routes`](reference/devices_nic.md#device-nic-bridged-device-conf:ipv4.routes) and [`ipv6.routes`](reference/devices_nic.md#device-nic-bridged-device-conf:ipv6.routes) properties on `nic` type devices.
This allows adding static routes on host to container’s NIC.

<a id="extension-cluster-internal-copy"></a>

## `cluster_internal_copy`

This makes it possible to do a normal `POST /1.0/instances` to copy an
instance between cluster nodes with LXD internally detecting whether a
migration is required.

<a id="extension-seccomp-notify"></a>

## `seccomp_notify`

If the kernel supports `seccomp`-based syscall interception LXD can be notified
by a container that a registered syscall has been performed. LXD can then
decide to trigger various actions.

<a id="extension-lxc-features"></a>

## `lxc_features`

This introduces the `lxc_features` section output from the [`lxc info`](reference/manpages/lxc/info.md#lxc-info-md) command
via the `GET /1.0` route. It outputs the result of checks for key features being present in the
underlying LXC library.

<a id="extension-container-nic-ipvlan"></a>

## `container_nic_ipvlan`

This introduces the `ipvlan` `nic` device type.

<a id="extension-network-vlan-sriov"></a>

## `network_vlan_sriov`

This introduces VLAN ([`vlan`](reference/devices_nic.md#device-nic-sriov-device-conf:vlan)) and MAC filtering ([`security.mac_filtering`](reference/devices_nic.md#device-nic-sriov-device-conf:security.mac_filtering)) support for SR-IOV devices.

<a id="extension-storage-cephfs"></a>

## `storage_cephfs`

Add support for CephFS as a storage pool driver. This can only be used
for custom volumes, images and containers should be on Ceph (RBD)
instead.

<a id="extension-container-nic-ipfilter"></a>

## `container_nic_ipfilter`

This introduces container IP filtering ([`security.ipv4_filtering`](reference/devices_nic.md#device-nic-bridged-device-conf:security.ipv4_filtering) and [`security.ipv6_filtering`](reference/devices_nic.md#device-nic-bridged-device-conf:security.ipv6_filtering)) support for `bridged` NIC devices.

<a id="extension-resources-v2"></a>

## `resources_v2`

Rework the resources API at `/1.0/resources`, especially:

* CPU
  * Fix reporting to track sockets, cores and threads
  * Track NUMA node per core
  * Track base and turbo frequency per socket
  * Track current frequency per core
  * Add CPU cache information
  * Export the CPU architecture
  * Show online/offline status of threads
* Memory
  * Add huge-pages tracking
  * Track memory consumption per NUMA node too
* GPU
  * Split DRM information to separate struct
  * Export device names and nodes in DRM struct
  * Export device name and node in NVIDIA struct
  * Add SR-IOV VF tracking

<a id="extension-container-exec-user-group-cwd"></a>

## `container_exec_user_group_cwd`

Adds support for specifying `User`, `Group` and `Cwd` during `POST /1.0/instances/NAME/exec`.

<a id="extension-container-syscall-intercept"></a>

## `container_syscall_intercept`

Adds the `security.syscalls.intercept.*` configuration keys to control
what system calls will be intercepted by LXD and processed with
elevated permissions.

<a id="extension-container-disk-shift"></a>

## `container_disk_shift`

Adds the [`shift`](reference/devices_disk.md#device-disk-device-conf:shift) property on `disk` devices which controls the use of the `idmapped mounts` overlay.

<a id="extension-storage-shifted"></a>

## `storage_shifted`

Introduces a new `security.shifted` Boolean on storage volumes.

Setting it to `true` will allow multiple isolated containers to attach the
same storage volume while keeping the file system writable from all of
them.

This makes use of `idmapped mounts` as an overlay file system.

<a id="extension-resources-infiniband"></a>

## `resources_infiniband`

Export InfiniBand character device information (`issm`, `umad`, `uverb`) as part of the resources API.

<a id="extension-daemon-storage"></a>

## `daemon_storage`

This introduces two new configuration keys [`storage.images_volume`](server.md#server-miscellaneous:storage.images_volume) and
[`storage.backups_volume`](server.md#server-miscellaneous:storage.backups_volume) to allow for a storage volume on an existing
pool be used for storing the daemon-wide images and backups artifacts.

<a id="extension-instances"></a>

## `instances`

This introduces the concept of instances, of which currently the only type is `container`.

<a id="extension-image-types"></a>

## `image_types`

This introduces support for a new Type field on images, indicating what type of images they are.

<a id="extension-resources-disk-sata"></a>

## `resources_disk_sata`

Extends the disk resource API struct to include:

* Proper detection of SATA devices (type)
* Device path
* Drive RPM
* Block size
* Firmware version
* Serial number

<a id="extension-clustering-roles"></a>

## `clustering_roles`

This adds a new `roles` attribute to cluster entries, exposing a list of
roles that the member serves in the cluster.

<a id="extension-images-expiry"></a>

## `images_expiry`

This allows for editing of the expiry date on images.

<a id="extension-resources-network-firmware"></a>

## `resources_network_firmware`

Adds a `FirmwareVersion` field to network card entries.

<a id="extension-backup-compression-algorithm"></a>

## `backup_compression_algorithm`

This adds support for a `compression_algorithm` property when creating a backup (`POST /1.0/instances/<name>/backups`).

Setting this property overrides the server default value ([`backups.compression_algorithm`](server.md#server-miscellaneous:backups.compression_algorithm)).

<a id="extension-ceph-data-pool-name"></a>

## `ceph_data_pool_name`

This adds support for an optional argument ([`ceph.osd.data_pool_name`](reference/storage_ceph.md#storage-ceph-pool-conf:ceph.osd.data_pool_name)) when creating
storage pools using Ceph RBD, when this argument is used the pool will store it’s
actual data in the pool specified with `data_pool_name` while keeping the metadata
in the pool specified by `pool_name`.

<a id="extension-container-syscall-intercept-mount"></a>

## `container_syscall_intercept_mount`

Adds the [`security.syscalls.intercept.mount`](reference/instance_options.md#instance-security:security.syscalls.intercept.mount),
[`security.syscalls.intercept.mount.allowed`](reference/instance_options.md#instance-security:security.syscalls.intercept.mount.allowed), and
[`security.syscalls.intercept.mount.shift`](reference/instance_options.md#instance-security:security.syscalls.intercept.mount.shift) configuration keys to control whether
and how the `mount` system call will be intercepted by LXD and processed with
elevated permissions.

<a id="extension-compression-squashfs"></a>

## `compression_squashfs`

Adds support for importing/exporting of images/backups using SquashFS file system format.

<a id="extension-container-raw-mount"></a>

## `container_raw_mount`

This adds support for passing in raw mount options for disk devices.

<a id="extension-container-nic-routed"></a>

## `container_nic_routed`

This introduces the `routed` `nic` device type.

<a id="extension-container-syscall-intercept-mount-fuse"></a>

## `container_syscall_intercept_mount_fuse`

Adds the [`security.syscalls.intercept.mount.fuse`](reference/instance_options.md#instance-security:security.syscalls.intercept.mount.fuse) key. It can be used to
redirect file-system mounts to their fuse implementation. To this end, set e.g.
`security.syscalls.intercept.mount.fuse=ext4=fuse2fs`.

<a id="extension-container-disk-ceph"></a>

## `container_disk_ceph`

This allows for existing a Ceph RBD or CephFS to be directly connected to a LXD container.

<a id="extension-virtual-machines"></a>

## `virtual-machines`

Add virtual machine support.

<a id="extension-image-profiles"></a>

## `image_profiles`

Allows a list of profiles to be applied to an image when launching a new container.

<a id="extension-clustering-architecture"></a>

## `clustering_architecture`

This adds a new `architecture` attribute to cluster members which indicates a cluster
member’s architecture.

<a id="extension-resources-disk-id"></a>

## `resources_disk_id`

Add a new `device_id` field in the disk entries on the resources API.

<a id="extension-storage-lvm-stripes"></a>

## `storage_lvm_stripes`

This adds the ability to use LVM stripes on normal volumes and thin pool volumes.

<a id="extension-vm-boot-priority"></a>

## `vm_boot_priority`

Adds a `boot.priority` property on NIC and disk devices to control the boot order.

<a id="extension-unix-hotplug-devices"></a>

## `unix_hotplug_devices`

Adds support for Unix char and block device hotplugging.

<a id="extension-api-filtering"></a>

## `api_filtering`

Adds support for filtering the result of a GET request for instances and images.

<a id="extension-instance-nic-network"></a>

## `instance_nic_network`

Adds support for the `network` property on a NIC device to allow a NIC to be linked to a managed network.
This allows it to inherit some of the network’s settings and allows better validation of IP settings.

<a id="extension-clustering-sizing"></a>

## `clustering_sizing`

Support specifying a custom values for database voters and standbys.
The new [`cluster.max_voters`](server.md#server-cluster:cluster.max_voters) and [`cluster.max_standby`](server.md#server-cluster:cluster.max_standby) configuration keys were introduced
to specify to the ideal number of database voter and standbys.

<a id="extension-firewall-driver"></a>

## `firewall_driver`

Adds the `Firewall` property to the `ServerEnvironment` struct indicating the firewall driver being used.

<a id="extension-projects-limits"></a>

## `projects_limits`

Adds support for project-level resource limits, through the [`limits.cpu`](reference/projects.md#project-limits:limits.cpu),
[`limits.memory`](reference/projects.md#project-limits:limits.memory), [`limits.processes`](reference/projects.md#project-limits:limits.processes),
[`limits.containers`](reference/projects.md#project-limits:limits.containers), and [`limits.virtual-machines`](reference/projects.md#project-limits:limits.virtual-machines)
project configuration keys.

## `storage_lvm_vg_force_reuse`

Introduces the ability to create a storage pool from an existing non-empty volume group.
This option should be used with care, as LXD can then not guarantee that volume name conflicts won’t occur
with non-LXD created volumes in the same volume group.
This could also potentially lead to LXD deleting a non-LXD volume should name conflicts occur.

<a id="extension-container-syscall-intercept-hugetlbfs"></a>

## `container_syscall_intercept_hugetlbfs`

When mount syscall interception is enabled and `hugetlbfs` is specified as an
allowed file system type LXD will mount a separate `hugetlbfs` instance for the
container with the UID and GID mount options set to the container’s root UID
and GID. This ensures that processes in the container can use huge pages.

<a id="extension-limits-hugepages"></a>

## `limits_hugepages`

This allows to limit the number of huge pages a container can use through the
`hugetlb` cgroup. This means the `hugetlb` cgroup needs to be available. Note, that
limiting huge pages is recommended when intercepting the mount syscall for the
`hugetlbfs` file system to avoid allowing the container to exhaust the host’s
huge pages resources.

<a id="extension-container-nic-routed-gateway"></a>

## `container_nic_routed_gateway`

This introduces the [`ipv4.gateway`](reference/devices_nic.md#device-nic-routed-device-conf:ipv4.gateway) and [`ipv6.gateway`](reference/devices_nic.md#device-nic-routed-device-conf:ipv6.gateway) NIC configuration keys that can take a value of either `auto` or
`none`. The default value for the key if unspecified is `auto`. This will cause the current behavior of a default
gateway being added inside the container and the same gateway address being added to the host-side interface.
If the value is set to `none` then no default gateway nor will the address be added to the host-side interface.
This allows multiple routed NIC devices to be added to a container.

<a id="extension-projects-restrictions"></a>

## `projects_restrictions`

This introduces support for the [`restricted`](reference/projects.md#project-restricted:restricted) configuration key on project, which
can prevent the use of security-sensitive features in a project.

<a id="extension-custom-volume-snapshot-expiry"></a>

## `custom_volume_snapshot_expiry`

This allows custom volume snapshots to expiry.
Expiry dates can be set individually, or by setting the `snapshots.expiry` configuration key on the parent custom volume which then automatically applies to all created snapshots.

<a id="extension-volume-snapshot-scheduling"></a>

## `volume_snapshot_scheduling`

This adds support for custom volume snapshot scheduling. It introduces two new
configuration keys: `snapshots.schedule` and
`snapshots.pattern`. Snapshots can be created automatically up to every minute.

<a id="extension-trust-ca-certificates"></a>

## `trust_ca_certificates`

This allows for checking client certificates trusted by the provided CA (`server.ca`).
It can be enabled by setting [`core.trust_ca_certificates`](server.md#server-core:core.trust_ca_certificates) to `true`.
If enabled, it will perform the check, and bypass the trusted password if `true`.
An exception will be made if the connecting client certificate is in the provided CRL (`ca.crl`).
In this case, it will ask for the password.

<a id="extension-snapshot-disk-usage"></a>

## `snapshot_disk_usage`

This adds a new `size` field to the output of `/1.0/instances/<name>/snapshots/<snapshot>` which represents the disk usage of the snapshot.

<a id="extension-clustering-edit-roles"></a>

## `clustering_edit_roles`

This adds a writable endpoint for cluster members, allowing the editing of their roles.

<a id="extension-container-nic-routed-host-address"></a>

## `container_nic_routed_host_address`

This introduces the [`ipv4.host_address`](reference/devices_nic.md#device-nic-routed-device-conf:ipv4.host_address) and [`ipv6.host_address`](reference/devices_nic.md#device-nic-routed-device-conf:ipv6.host_address) NIC configuration keys that can be used to control the
host-side `veth` interface’s IP addresses. This can be useful when using multiple routed NICs at the same time and
needing a predictable next-hop address to use.

This also alters the behavior of [`ipv4.gateway`](reference/devices_nic.md#device-nic-routed-device-conf:ipv4.gateway) and [`ipv6.gateway`](reference/devices_nic.md#device-nic-routed-device-conf:ipv6.gateway) NIC configuration keys. When they are set to `auto`
the container will have its default gateway set to the value of `ipv4.host_address` or `ipv6.host_address` respectively.

The default values are:

`ipv4.host_address`: `169.254.0.1`
`ipv6.host_address`: `fe80::1`

This is backward compatible with the previous default behavior.

<a id="extension-container-nic-ipvlan-gateway"></a>

## `container_nic_ipvlan_gateway`

This introduces the [`ipv4.gateway`](reference/devices_nic.md#device-nic-ipvlan-device-conf:ipv4.gateway) and [`ipv6.gateway`](reference/devices_nic.md#device-nic-ipvlan-device-conf:ipv6.gateway) NIC configuration keys that can take a value of either `auto` or
`none`. The default value for the key if unspecified is `auto`. This will cause the current behavior of a default
gateway being added inside the container and the same gateway address being added to the host-side interface.
If the value is set to `none` then no default gateway nor will the address be added to the host-side interface.
This allows multiple IPVLAN NIC devices to be added to a container.

<a id="extension-resources-usb-pci"></a>

## `resources_usb_pci`

This adds USB and PCI devices to the output of `/1.0/resources`.

<a id="extension-resources-cpu-threads-numa"></a>

## `resources_cpu_threads_numa`

This indicates that the `numa_node` field is now recorded per-thread
rather than per core as some hardware apparently puts threads in
different NUMA domains.

<a id="extension-resources-cpu-core-die"></a>

## `resources_cpu_core_die`

Exposes the `die_id` information on each core.

<a id="extension-api-os"></a>

## `api_os`

This introduces two new fields in `/1.0`, `os` and `os_version`.

Those are taken from the OS-release data on the system.

<a id="extension-container-nic-routed-host-table"></a>

## `container_nic_routed_host_table`

This introduces the [`ipv4.host_table`](reference/devices_nic.md#device-nic-routed-device-conf:ipv4.host_table) and [`ipv6.host_table`](reference/devices_nic.md#device-nic-routed-device-conf:ipv6.host_table) NIC configuration keys that can be used to add static routes
for the instance’s IPs to a custom policy routing table by ID.

<a id="extension-container-nic-ipvlan-host-table"></a>

## `container_nic_ipvlan_host_table`

This introduces the [`ipv4.host_table`](reference/devices_nic.md#device-nic-ipvlan-device-conf:ipv4.host_table) and [`ipv6.host_table`](reference/devices_nic.md#device-nic-ipvlan-device-conf:ipv6.host_table) NIC configuration keys that can be used to add static routes
for the instance’s IPs to a custom policy routing table by ID.

<a id="extension-container-nic-ipvlan-mode"></a>

## `container_nic_ipvlan_mode`

This introduces the [`mode`](reference/devices_nic.md#device-nic-ipvlan-device-conf:mode) NIC configuration key that can be used to switch the `ipvlan` mode into either `l2` or `l3s`.
If not specified, the default value is `l3s` (which is the old behavior).

In `l2` mode the [`ipv4.address`](reference/devices_nic.md#device-nic-ipvlan-device-conf:ipv4.address) and [`ipv6.address`](reference/devices_nic.md#device-nic-ipvlan-device-conf:ipv6.address) keys will accept addresses in either CIDR or singular formats.
If singular format is used, the default subnet size is taken to be /24 and /64 for IPv4 and IPv6 respectively.

In `l2` mode the [`ipv4.gateway`](reference/devices_nic.md#device-nic-ipvlan-device-conf:ipv4.gateway) and [`ipv6.gateway`](reference/devices_nic.md#device-nic-ipvlan-device-conf:ipv6.gateway) keys accept only a singular IP address.

<a id="extension-resources-system"></a>

## `resources_system`

This adds system information to the output of `/1.0/resources`.

<a id="extension-images-push-relay"></a>

## `images_push_relay`

This adds the push and relay modes to image copy.
It also introduces the following new endpoint:

* `POST 1.0/images/<fingerprint>/export`

<a id="extension-network-dns-search"></a>

## `network_dns_search`

This introduces the `dns.search` configuration option on networks.

<a id="extension-container-nic-routed-limits"></a>

## `container_nic_routed_limits`

This introduces [`limits.ingress`](reference/devices_nic.md#device-nic-routed-device-conf:limits.ingress), [`limits.egress`](reference/devices_nic.md#device-nic-routed-device-conf:limits.egress) and [`limits.max`](reference/devices_nic.md#device-nic-routed-device-conf:limits.max) for routed NICs.

<a id="extension-instance-nic-bridged-vlan"></a>

## `instance_nic_bridged_vlan`

This introduces the [`vlan`](reference/devices_nic.md#device-nic-bridged-device-conf:vlan) and [`vlan.tagged`](reference/devices_nic.md#device-nic-bridged-device-conf:vlan.tagged) settings for `bridged` NICs.

`vlan` specifies the non-tagged VLAN to join, and `vlan.tagged` is a comma-delimited list of tagged VLANs to join.

<a id="extension-network-state-bond-bridge"></a>

## `network_state_bond_bridge`

This adds a `bridge` and `bond` section to the `/1.0/networks/NAME/state` API.

Those contain additional state information relevant to those particular types.

Bond:

* Mode
* Transmit hash
* Up delay
* Down delay
* MII frequency
* MII state
* Lower devices

Bridge:

* ID
* Forward delay
* STP mode
* Default VLAN
* VLAN filtering
* Upper devices

## `resources_cpu_isolated`

Add an `Isolated` property on CPU threads to indicate if the thread is
physically `Online` but is configured not to accept tasks.

<a id="extension-usedby-consistency"></a>

## `usedby_consistency`

This extension indicates that `UsedBy` should now be consistent with
suitable `?project=` and `?target=` when appropriate.

The 5 entities that have `UsedBy` are:

* Profiles
* Projects
* Networks
* Storage pools
* Storage volumes

<a id="extension-custom-block-volumes"></a>

## `custom_block_volumes`

This adds support for creating and attaching custom block volumes to instances.
It introduces the new `--type` flag when creating custom storage volumes, and accepts the values `fs` and `block`.

<a id="extension-clustering-failure-domains"></a>

## `clustering_failure_domains`

This extension adds a new `failure_domain` field to the `PUT /1.0/cluster/<node>` API,
which can be used to set the failure domain of a node.

<a id="extension-container-syscall-filtering-allow-deny-syntax"></a>

## `container_syscall_filtering_allow_deny_syntax`

A number of new syscalls related container configuration keys were updated.

* [`security.syscalls.deny_default`](reference/instance_options.md#instance-security:security.syscalls.deny_default)
* [`security.syscalls.deny_compat`](reference/instance_options.md#instance-security:security.syscalls.deny_compat)
* [`security.syscalls.deny`](reference/instance_options.md#instance-security:security.syscalls.deny)
* [`security.syscalls.allow`](reference/instance_options.md#instance-security:security.syscalls.allow)

Support for the offensively named variants was removed.

<a id="extension-resources-gpu-mdev"></a>

## `resources_gpu_mdev`

Expose available mediated device profiles and devices in `/1.0/resources`.

<a id="extension-console-vga-type"></a>

## `console_vga_type`

This extends the `/1.0/console` endpoint to take a `?type=` argument, which can
be set to `console` (default) or `vga` (the new type added by this extension).

When doing a `POST` to `/1.0/<instance name>/console?type=vga` the data WebSocket
returned by the operation in the metadata field will be a bidirectional proxy
attached to a SPICE Unix socket of the target virtual machine.

<a id="extension-projects-limits-disk"></a>

## `projects_limits_disk`

Add [`limits.disk`](reference/projects.md#project-limits:limits.disk) to the available project configuration keys. If set, it limits
the total amount of disk space that instances volumes, custom volumes and images
volumes can use in the project.

<a id="extension-network-type-macvlan"></a>

## `network_type_macvlan`

Adds support for additional network type `macvlan` and adds [`parent`](reference/network_macvlan.md#network-macvlan-network-conf:parent) configuration key for this network type to
specify which parent interface should be used for creating NIC device interfaces on top of.

Also adds [`network`](reference/devices_nic.md#device-nic-macvlan-device-conf:network) configuration key support for `macvlan` NICs to allow them to specify the associated network of
the same type that they should use as the basis for the NIC device.

<a id="extension-network-type-sriov"></a>

## `network_type_sriov`

Adds support for additional network type `sriov` and adds [`parent`](reference/network_sriov.md#network-sriov-network-conf:parent) configuration key for this network type to
specify which parent interface should be used for creating NIC device interfaces on top of.

Also adds [`network`](reference/devices_nic.md#device-nic-sriov-device-conf:network) configuration key support for `sriov` NICs to allow them to specify the associated network of
the same type that they should use as the basis for the NIC device.

<a id="extension-container-syscall-intercept-bpf-devices"></a>

## `container_syscall_intercept_bpf_devices`

This adds support to intercept the `bpf` syscall in containers. Specifically, it allows to manage device cgroup `bpf` programs.

<a id="extension-network-type-ovn"></a>

## `network_type_ovn`

Adds support for additional network type `ovn` with the ability to specify a `bridge` type network as the `parent`.

Introduces a new NIC device type of `ovn` which allows the `network` configuration key to specify which `ovn`
type network they should connect to.

Also introduces two new global configuration keys that apply to all `ovn` networks and NIC devices:

* [`network.ovn.integration_bridge`](server.md#server-miscellaneous:network.ovn.integration_bridge) - the OVS integration bridge to use.
* [`network.ovn.northbound_connection`](server.md#server-miscellaneous:network.ovn.northbound_connection) - the OVN northbound database connection string.

<a id="extension-projects-networks"></a>

## `projects_networks`

Adds the [`features.networks`](reference/projects.md#project-features:features.networks) configuration key to projects and the ability for a project to hold networks.

<a id="extension-projects-networks-restricted-uplinks"></a>

## `projects_networks_restricted_uplinks`

Adds the [`restricted.networks.uplinks`](reference/projects.md#project-restricted:restricted.networks.uplinks) project configuration key to indicate (as a comma-delimited list) which networks
the networks created inside the project can use as their uplink network.

<a id="extension-custom-volume-backup"></a>

## `custom_volume_backup`

Add custom volume backup support.

This includes the following new endpoints (see [RESTful API](rest-api.md) for details):

* `GET /1.0/storage-pools/<pool>/<type>/<volume>/backups`
* `POST /1.0/storage-pools/<pool>/<type>/<volume>/backups`
* `GET /1.0/storage-pools/<pool>/<type>/<volume>/backups/<name>`
* `POST /1.0/storage-pools/<pool>/<type>/<volume>/backups/<name>`
* `DELETE /1.0/storage-pools/<pool>/<type>/<volume>/backups/<name>`
* `GET /1.0/storage-pools/<pool>/<type>/<volume>/backups/<name>/export`

The following existing endpoint has been modified:

* `POST /1.0/storage-pools/<pool>/<type>/<volume>` accepts the new source type `backup`

<a id="extension-backup-override-name"></a>

## `backup_override_name`

Adds `Name` field to `InstanceBackupArgs` to allow specifying a different instance name when restoring a backup.

Adds `Name` and `PoolName` fields to `StoragePoolVolumeBackupArgs` to allow specifying a different volume name
when restoring a custom volume backup.

<a id="extension-storage-rsync-compression"></a>

## `storage_rsync_compression`

Adds `rsync.compression` configuration key to storage pools. This key can be used
to disable compression in `rsync` while migrating storage pools.

<a id="extension-network-type-physical"></a>

## `network_type_physical`

Adds support for additional network type `physical` that can be used as an uplink for `ovn` networks.

The interface specified by [`parent`](reference/network_physical.md#network-physical-network-conf:parent) on the `physical` network will be connected to the `ovn` network’s gateway.

<a id="extension-network-ovn-external-subnets"></a>

## `network_ovn_external_subnets`

Adds support for `ovn` networks to use external subnets from uplink networks.

Introduces the [`ipv4.routes`](reference/network_physical.md#network-physical-network-conf:ipv4.routes) and [`ipv6.routes`](reference/network_physical.md#network-physical-network-conf:ipv6.routes) setting on `physical` networks that defines the external routes
allowed to be used in child OVN networks in their [`ipv4.routes.external`](reference/devices_nic.md#device-nic-ovn-device-conf:ipv4.routes.external) and [`ipv6.routes.external`](reference/devices_nic.md#device-nic-ovn-device-conf:ipv6.routes.external) settings.

Introduces the [`restricted.networks.subnets`](reference/projects.md#project-restricted:restricted.networks.subnets) project setting that specifies which external subnets are allowed to
be used by OVN networks inside the project (if not set then all routes defined on the uplink network are allowed).

<a id="extension-network-ovn-nat"></a>

## `network_ovn_nat`

Adds support for [`ipv4.nat`](reference/network_ovn.md#network-ovn-network-conf:ipv4.nat) and [`ipv6.nat`](reference/network_ovn.md#network-ovn-network-conf:ipv6.nat) settings on `ovn` networks.

When creating the network if these settings are unspecified, and an equivalent IP address is being generated for
the subnet, then the appropriate NAT setting will added set to `true`.

If the setting is missing then the value is taken as `false`.

<a id="extension-network-ovn-external-routes-remove"></a>

## `network_ovn_external_routes_remove`

Removes the settings `ipv4.routes.external` and `ipv6.routes.external` from `ovn` networks.

The equivalent settings on the `ovn` NIC type can be used instead for this, rather than having to specify them
both at the network and NIC level.

<a id="extension-tpm-device-type"></a>

## `tpm_device_type`

This introduces the `tpm` device type.

<a id="extension-storage-zfs-clone-copy-rebase"></a>

## `storage_zfs_clone_copy_rebase`

This introduces `rebase` as a value for [`zfs.clone_copy`](reference/storage_zfs.md#storage-zfs-pool-conf:zfs.clone_copy) causing LXD to
track down any `image` dataset in the ancestry line and then perform
send/receive on top of that.

<a id="extension-gpu-mdev"></a>

## `gpu_mdev`

This adds support for virtual GPUs (vGPUs). It introduces the [`mdev`](reference/devices_gpu.md#device-gpu-mdev-device-conf:mdev) configuration key for GPU devices which takes
a supported `mdev` type, e.g. `i915-GVTg_V5_4`.

<a id="extension-resources-pci-iommu"></a>

## `resources_pci_iommu`

This adds the `IOMMUGroup` field for PCI entries in the resources API.

<a id="extension-resources-network-usb"></a>

## `resources_network_usb`

Adds the `usb_address` field to the network card entries in the resources API.

<a id="extension-resources-disk-address"></a>

## `resources_disk_address`

Adds the `usb_address` and `pci_address` fields to the disk entries in the resources API.

<a id="extension-network-physical-ovn-ingress-mode"></a>

## `network_physical_ovn_ingress_mode`

Adds [`ovn.ingress_mode`](reference/network_physical.md#network-physical-network-conf:ovn.ingress_mode) setting for `physical` networks.

Sets the method that OVN NIC external IPs will be advertised on uplink network.

Either `l2proxy` (proxy ARP/NDP) or `routed`.

<a id="extension-network-ovn-dhcp"></a>

## `network_ovn_dhcp`

Adds [`ipv4.dhcp`](reference/network_ovn.md#network-ovn-network-conf:ipv4.dhcp) and [`ipv6.dhcp`](reference/network_ovn.md#network-ovn-network-conf:ipv6.dhcp) settings for `ovn` networks.

Allows DHCP (and RA for IPv6) to be disabled. Defaults to on.

<a id="extension-network-physical-routes-anycast"></a>

## `network_physical_routes_anycast`

Adds [`ipv4.routes.anycast`](reference/network_physical.md#network-physical-network-conf:ipv4.routes.anycast) and [`ipv6.routes.anycast`](reference/network_physical.md#network-physical-network-conf:ipv6.routes.anycast) Boolean settings for `physical` networks. Defaults to `false`.

Allows OVN networks using physical network as uplink to relax external subnet/route overlap detection when used
with [`ovn.ingress_mode`](reference/network_physical.md#network-physical-network-conf:ovn.ingress_mode) set to `routed`.

<a id="extension-projects-limits-instances"></a>

## `projects_limits_instances`

Adds [`limits.instances`](reference/projects.md#project-limits:limits.instances) to the available project configuration keys. If set, it
limits the total number of instances (VMs and containers) that can be used in the project.

<a id="extension-network-state-vlan"></a>

## `network_state_vlan`

This adds a `vlan` section to the `/1.0/networks/NAME/state` API.

Those contain additional state information relevant to VLAN interfaces:

* `lower_device`
* `vid`

<a id="extension-instance-nic-bridged-port-isolation"></a>

## `instance_nic_bridged_port_isolation`

This adds the [`security.port_isolation`](reference/devices_nic.md#device-nic-bridged-device-conf:security.port_isolation) field for bridged NIC instances.

<a id="extension-instance-bulk-state-change"></a>

## `instance_bulk_state_change`

Adds the following endpoint for bulk state change (see [RESTful API](rest-api.md) for details):

* `PUT /1.0/instances`

<a id="extension-network-gvrp"></a>

## `network_gvrp`

This adds an optional `gvrp` property to `macvlan` and `physical` networks,
and to `ipvlan`, `macvlan`, `routed` and `physical` NIC devices.

When set, this specifies whether the VLAN should be registered using GARP VLAN
Registration Protocol. Defaults to `false`.

<a id="extension-instance-pool-move"></a>

## `instance_pool_move`

This adds a `pool` field to the `POST /1.0/instances/NAME` API,
allowing for easy move of an instance root disk between pools.

<a id="extension-gpu-sriov"></a>

## `gpu_sriov`

This adds support for SR-IOV enabled GPUs.
It introduces the `sriov` GPU type property.

<a id="extension-pci-device-type"></a>

## `pci_device_type`

This introduces the `pci` device type.

<a id="extension-storage-volume-state"></a>

## `storage_volume_state`

Add new `/1.0/storage-pools/POOL/volumes/VOLUME/state` API endpoint to get usage data on a volume.

<a id="extension-network-acl"></a>

## `network_acl`

This adds the concept of network ACLs to API under the API endpoint prefix `/1.0/network-acls`.

<a id="extension-migration-stateful"></a>

## `migration_stateful`

Add a new [`migration.stateful`](reference/instance_options.md#instance-migration:migration.stateful) configuration key.

<a id="extension-disk-state-quota"></a>

## `disk_state_quota`

This introduces the [`size.state`](reference/devices_disk.md#device-disk-device-conf:size.state) device configuration key on `disk` devices.

<a id="extension-storage-ceph-features"></a>

## `storage_ceph_features`

Adds a new [`ceph.rbd.features`](reference/storage_ceph.md#storage-ceph-pool-conf:ceph.rbd.features) configuration key on storage pools to control the RBD features used for new volumes.

<a id="extension-projects-compression"></a>

## `projects_compression`

Adds new [`backups.compression_algorithm`](reference/projects.md#project-specific:backups.compression_algorithm) and [`images.compression_algorithm`](reference/projects.md#project-specific:images.compression_algorithm) configuration keys which
allows configuration of backup and image compression per-project.

<a id="extension-projects-images-remote-cache-expiry"></a>

## `projects_images_remote_cache_expiry`

Add new [`images.remote_cache_expiry`](server.md#server-images:images.remote_cache_expiry) configuration key to projects,
allowing for set number of days after which an unused cached remote image will be flushed.

<a id="extension-certificate-project"></a>

## `certificate_project`

Adds a new `restricted` property to certificates in the API as well as
`projects` holding a list of project names that the certificate has
access to.

<a id="extension-network-ovn-acl"></a>

## `network_ovn_acl`

Adds a new `security.acls` property to OVN networks and OVN NICs, allowing Network ACLs to be applied.

<a id="extension-projects-images-auto-update"></a>

## `projects_images_auto_update`

Adds new [`images.auto_update_cached`](server.md#server-images:images.auto_update_cached) and [`images.auto_update_interval`](server.md#server-images:images.auto_update_interval) configuration keys which
allows configuration of images auto update in projects

<a id="extension-projects-restricted-cluster-target"></a>

## `projects_restricted_cluster_target`

Adds new [`restricted.cluster.target`](reference/projects.md#project-restricted:restricted.cluster.target) configuration key to project which prevent the user from using –target
to specify what cluster member to place a workload on or the ability to move a workload between members.

<a id="extension-images-default-architecture"></a>

## `images_default_architecture`

Adds new [`images.default_architecture`](server.md#server-images:images.default_architecture) global configuration key and matching per-project key which lets user tell LXD
what architecture to go with when no specific one is specified as part of the image request.

<a id="extension-network-ovn-acl-defaults"></a>

## `network_ovn_acl_defaults`

Adds new `security.acls.default.{in,e}gress.action` and `security.acls.default.{in,e}gress.logged` configuration keys for
OVN networks and NICs. This replaces the removed ACL `default.action` and `default.logged` keys.

<a id="extension-gpu-mig"></a>

## `gpu_mig`

This adds support for NVIDIA MIG. It introduces the `mig` GPU type and associated configuration keys.

<a id="extension-project-usage"></a>

## `project_usage`

Adds an API endpoint to get current resource allocations in a project.
Accessible at API `GET /1.0/projects/<name>/state`.

<a id="extension-network-bridge-acl"></a>

## `network_bridge_acl`

Adds a new [`security.acls`](reference/network_bridge.md#network-bridge-network-conf:security.acls) configuration key to `bridge` networks, allowing Network ACLs to be applied.

Also adds `security.acls.default.{in,e}gress.action` and `security.acls.default.{in,e}gress.logged` configuration keys for
specifying the default behavior for unmatched traffic.

<a id="extension-warnings"></a>

## `warnings`

Warning API for LXD.

This includes the following endpoints (see  [Restful API](rest-api.md) for details):

* `GET /1.0/warnings`
* `GET /1.0/warnings/<uuid>`
* `PUT /1.0/warnings/<uuid>`
* `DELETE /1.0/warnings/<uuid>`

<a id="extension-projects-restricted-backups-and-snapshots"></a>

## `projects_restricted_backups_and_snapshots`

Adds new [`restricted.backups`](reference/projects.md#project-restricted:restricted.backups) and [`restricted.snapshots`](reference/projects.md#project-restricted:restricted.snapshots) configuration keys to project which
prevents the user from creation of backups and snapshots.

<a id="extension-clustering-join-token"></a>

## `clustering_join_token`

Adds `POST /1.0/cluster/members` API endpoint for requesting a join token used when adding new cluster members
without using the trust password.

<a id="extension-clustering-description"></a>

## `clustering_description`

Adds an editable description to the cluster members.

<a id="extension-server-trusted-proxy"></a>

## `server_trusted_proxy`

This introduces support for [`core.https_trusted_proxy`](server.md#server-core:core.https_trusted_proxy) which has LXD
parse a HAProxy style connection header on such connections and if
present, will rewrite the request’s source address to that provided by
the proxy server.

<a id="extension-clustering-update-cert"></a>

## `clustering_update_cert`

Adds `PUT /1.0/cluster/certificate` endpoint for updating the cluster
certificate across the whole cluster

<a id="extension-storage-api-project"></a>

## `storage_api_project`

This adds support for copy/move custom storage volumes between projects.

<a id="extension-server-instance-driver-operational"></a>

## `server_instance_driver_operational`

This modifies the `driver` output for the `/1.0` endpoint to only include drivers which are actually supported and
operational on the server (as opposed to being included in LXD but not operational on the server).

<a id="extension-server-supported-storage-drivers"></a>

## `server_supported_storage_drivers`

This adds supported storage driver info to server environment info.

<a id="extension-event-lifecycle-requestor-address"></a>

## `event_lifecycle_requestor_address`

Adds a new address field to `lifecycle` requestor.

<a id="extension-resources-gpu-usb"></a>

## `resources_gpu_usb`

Add a new `USBAddress` (`usb_address`) field to `ResourcesGPUCard` (GPU entries) in the resources API.

<a id="extension-clustering-evacuation"></a>

## `clustering_evacuation`

Adds `POST /1.0/cluster/members/<name>/state` endpoint for evacuating and restoring cluster members.
It also adds the configuration keys [`cluster.evacuate`](reference/instance_options.md#instance-miscellaneous:cluster.evacuate) and [`volatile.evacuate.origin`](reference/instance_options.md#instance-volatile:volatile.evacuate.origin) for setting the evacuation method (`auto`, `stop` or `migrate`) and the origin of any migrated instance respectively.

<a id="extension-network-ovn-nat-address"></a>

## `network_ovn_nat_address`

This introduces the [`ipv4.nat.address`](reference/network_ovn.md#network-ovn-network-conf:ipv4.nat.address) and [`ipv6.nat.address`](reference/network_ovn.md#network-ovn-network-conf:ipv6.nat.address) configuration keys for LXD `ovn` networks.
Those keys control the source address used for outbound traffic from the OVN virtual network.
These keys can only be specified when the OVN network’s uplink network has [`ovn.ingress_mode`](reference/network_physical.md#network-physical-network-conf:ovn.ingress_mode) set to `routed`.

<a id="extension-network-bgp"></a>

## `network_bgp`

This introduces support for LXD acting as a BGP router to advertise
routes to `bridge` and `ovn` networks.

This comes with the addition to global configuration of:

* [`core.bgp_address`](server.md#server-core:core.bgp_address)
* [`core.bgp_asn`](server.md#server-core:core.bgp_asn)
* [`core.bgp_routerid`](server.md#server-core:core.bgp_routerid)

The following network configurations keys (`bridge` and `physical`):

* `bgp.peers.<name>.address`
* `bgp.peers.<name>.asn`
* `bgp.peers.<name>.password`

The `nexthop` configuration keys (`bridge`):

* [`bgp.ipv4.nexthop`](reference/network_bridge.md#network-bridge-network-conf:bgp.ipv4.nexthop)
* [`bgp.ipv6.nexthop`](reference/network_bridge.md#network-bridge-network-conf:bgp.ipv6.nexthop)

And the following NIC-specific configuration keys (`bridged` NIC type):

* [`ipv4.routes.external`](reference/devices_nic.md#device-nic-bridged-device-conf:ipv4.routes.external)
* [`ipv6.routes.external`](reference/devices_nic.md#device-nic-bridged-device-conf:ipv6.routes.external)

<a id="extension-network-forward"></a>

## `network_forward`

This introduces the networking address forward functionality. Allowing for `bridge` and `ovn` networks to define
external IP addresses that can be forwarded to internal IP(s) inside their respective networks.

<a id="extension-custom-volume-refresh"></a>

## `custom_volume_refresh`

Adds support for refresh during volume migration.

<a id="extension-network-counters-errors-dropped"></a>

## `network_counters_errors_dropped`

This adds the received and sent errors as well as inbound and outbound dropped packets to the network counters.

<a id="extension-metrics"></a>

## `metrics`

This adds metrics to LXD. It returns metrics of running instances using the OpenMetrics format.

This includes the following endpoints:

* `GET /1.0/metrics`

<a id="extension-image-source-project"></a>

## `image_source_project`

Adds a new `project` field to `POST /1.0/images` allowing for the source project
to be set at image copy time.

<a id="extension-clustering-config"></a>

## `clustering_config`

Adds new `config` property to cluster members with configurable key/value pairs.

<a id="extension-network-peer"></a>

## `network_peer`

This adds network peering to allow traffic to flow between OVN networks without leaving the OVN subsystem.

<a id="extension-linux-sysctl"></a>

## `linux_sysctl`

Adds new `linux.sysctl.*` configuration keys allowing users to modify certain kernel parameters
within containers.

<a id="extension-network-dns"></a>

## `network_dns`

Introduces a built-in DNS server and zones API to provide DNS records for LXD instances.

This introduces the following server configuration key:

* [`core.dns_address`](server.md#server-core:core.dns_address)

The following network configuration key:

* `dns.zone.forward`
* `dns.zone.reverse.ipv4`
* `dns.zone.reverse.ipv6`

And the following project configuration key:

* [`restricted.networks.zones`](reference/projects.md#project-restricted:restricted.networks.zones)

A new REST API is also introduced to manage DNS zones:

* `/1.0/network-zones` (GET, POST)
* `/1.0/network-zones/<name>` (GET, PUT, PATCH, DELETE)

<a id="extension-ovn-nic-acceleration"></a>

## `ovn_nic_acceleration`

Adds new [`acceleration`](reference/devices_nic.md#device-nic-ovn-device-conf:acceleration) configuration key to OVN NICs which can be used for enabling hardware acceleration.
It takes the values `none` or `sriov`.

<a id="extension-certificate-self-renewal"></a>

## `certificate_self_renewal`

This adds support for renewing a client’s own trust certificate.

<a id="extension-instance-project-move"></a>

## `instance_project_move`

This adds a `project` field to the `POST /1.0/instances/NAME` API,
allowing for easy move of an instance between projects.

<a id="extension-storage-volume-project-move"></a>

## `storage_volume_project_move`

This adds support for moving storage volume between projects.

<a id="extension-cloud-init"></a>

## `cloud_init`

This adds a new `cloud-init` configuration key namespace which contains the following keys:

* [`cloud-init.vendor-data`](reference/instance_options.md#instance-cloud-init:cloud-init.vendor-data)
* [`cloud-init.user-data`](reference/instance_options.md#instance-cloud-init:cloud-init.user-data)
* [`cloud-init.network-config`](reference/instance_options.md#instance-cloud-init:cloud-init.network-config)

It also adds a new endpoint `/1.0/devices` to `devlxd` which shows an instance’s devices.

<a id="extension-network-dns-nat"></a>

## `network_dns_nat`

This introduces `network.nat` as a configuration option on network zones (DNS).

It defaults to the current behavior of generating records for all
instances NICs but if set to `false`, it will instruct LXD to only
generate records for externally reachable addresses.

<a id="extension-database-leader"></a>

## `database_leader`

Adds new `database-leader` role which is assigned to cluster leader.

<a id="extension-instance-all-projects"></a>

## `instance_all_projects`

This adds support for displaying instances from all projects.

<a id="extension-clustering-groups"></a>

## `clustering_groups`

Add support for grouping cluster members.

This introduces the following new endpoints:

* `/1.0/cluster/groups` (GET, POST)
* `/1.0/cluster/groups/<name>` (GET, POST, PUT, PATCH, DELETE)

The following project restriction is added:

* [`restricted.cluster.groups`](reference/projects.md#project-restricted:restricted.cluster.groups)

<a id="extension-ceph-rbd-du"></a>

## `ceph_rbd_du`

Adds a new [`ceph.rbd.du`](reference/storage_ceph.md#storage-ceph-pool-conf:ceph.rbd.du) Boolean on Ceph storage pools which allows
disabling the use of the potentially slow `rbd du` calls.

<a id="extension-instance-get-full"></a>

## `instance_get_full`

This introduces a new `recursion=1` mode for `GET /1.0/instances/{name}` which allows for the retrieval of
all instance structs, including the state, snapshots and backup structs.

<a id="extension-qemu-metrics"></a>

## `qemu_metrics`

This adds a new [`security.agent.metrics`](reference/instance_options.md#instance-security:security.agent.metrics) Boolean which defaults to `true`.
When set to `false`, it doesn’t connect to the `lxd-agent` for metrics and other state information, but relies on stats from QEMU.

<a id="extension-gpu-mig-uuid"></a>

## `gpu_mig_uuid`

Adds support for the new MIG UUID format used by NVIDIA `470+` drivers (for example, `MIG-74c6a31a-fde5-5c61-973b-70e12346c202`),
the `MIG-` prefix can be omitted

This extension supersedes old `mig.gi` and `mig.ci` parameters which are kept for compatibility with old drivers and
cannot be set together.

<a id="extension-event-project"></a>

## `event_project`

Expose the project an API event belongs to.

<a id="extension-clustering-evacuation-live"></a>

## `clustering_evacuation_live`

This adds `live-migrate` as a configuration option to [`cluster.evacuate`](reference/instance_options.md#instance-miscellaneous:cluster.evacuate), which forces live-migration
of instances during cluster evacuation.

<a id="extension-instance-allow-inconsistent-copy"></a>

## `instance_allow_inconsistent_copy`

Adds `allow_inconsistent` field to instance source on `POST /1.0/instances`. If `true`, `rsync` will ignore the
`Partial transfer due to vanished source files` (code 24) error when creating an instance from a copy.

<a id="extension-network-state-ovn"></a>

## `network_state_ovn`

This adds an `ovn` section to the `/1.0/networks/NAME/state` API which contains additional state information relevant to
OVN networks:

* chassis

<a id="extension-storage-volume-api-filtering"></a>

## `storage_volume_api_filtering`

Adds support for filtering the result of a GET request for storage volumes.

<a id="extension-image-restrictions"></a>

## `image_restrictions`

This extension adds on to the image properties to include image restrictions/host requirements. These requirements
help determine the compatibility between an instance and the host system.

<a id="extension-storage-zfs-export"></a>

## `storage_zfs_export`

Introduces the ability to disable zpool export when unmounting pool by setting [`zfs.export`](reference/storage_zfs.md#storage-zfs-pool-conf:zfs.export).

<a id="extension-network-dns-records"></a>

## `network_dns_records`

This extends the network zones (DNS) API to add the ability to create and manage custom records.

This adds:

* `GET /1.0/network-zones/ZONE/records`
* `POST /1.0/network-zones/ZONE/records`
* `GET /1.0/network-zones/ZONE/records/RECORD`
* `PUT /1.0/network-zones/ZONE/records/RECORD`
* `PATCH /1.0/network-zones/ZONE/records/RECORD`
* `DELETE /1.0/network-zones/ZONE/records/RECORD`

<a id="extension-storage-zfs-reserve-space"></a>

## `storage_zfs_reserve_space`

Adds ability to set the `reservation`/`refreservation` ZFS property along with `quota`/`refquota`.

<a id="extension-network-acl-log"></a>

## `network_acl_log`

Adds a new `GET /1.0/networks-acls/NAME/log` API to retrieve ACL firewall logs.

<a id="extension-storage-zfs-blocksize"></a>

## `storage_zfs_blocksize`

Introduces a new [`zfs.blocksize`](reference/storage_zfs.md#storage-zfs-volume-conf:zfs.blocksize) property for ZFS storage volumes which allows to set volume block size.

<a id="extension-metrics-cpu-seconds"></a>

## `metrics_cpu_seconds`

This is used to detect whether LXD was fixed to output used CPU time in seconds rather than as milliseconds.

<a id="extension-instance-snapshot-never"></a>

## `instance_snapshot_never`

Adds a `@never` option to `snapshots.schedule` which allows disabling inheritance.

<a id="extension-certificate-token"></a>

## `certificate_token`

This adds token-based certificate addition to the trust store as a safer alternative to a trust password.

It adds the `token` field to `POST /1.0/certificates`.

<a id="extension-instance-nic-routed-neighbor-probe"></a>

## `instance_nic_routed_neighbor_probe`

This adds the ability to disable the `routed` NIC IP neighbor probing for availability on the parent network.

Adds the [`ipv4.neighbor_probe`](reference/devices_nic.md#device-nic-routed-device-conf:ipv4.neighbor_probe) and [`ipv6.neighbor_probe`](reference/devices_nic.md#device-nic-routed-device-conf:ipv6.neighbor_probe) NIC settings. Defaulting to `true` if not specified.

<a id="extension-event-hub"></a>

## `event_hub`

This adds support for `event-hub` cluster member role and the `ServerEventMode` environment field.

<a id="extension-agent-nic-config"></a>

## `agent_nic_config`

If set to `true`, on VM start-up the `lxd-agent` will apply NIC configuration to change the names and MTU of the instance NIC
devices.

<a id="extension-projects-restricted-intercept"></a>

## `projects_restricted_intercept`

Adds new [`restricted.containers.interception`](reference/projects.md#project-restricted:restricted.containers.interception) configuration key to allow usually safe system call interception options.

<a id="extension-metrics-authentication"></a>

## `metrics_authentication`

Introduces a new [`core.metrics_authentication`](server.md#server-core:core.metrics_authentication) server configuration option to
allow for the `/1.0/metrics` endpoint to be generally available without
client authentication.

<a id="extension-images-target-project"></a>

## `images_target_project`

Adds ability to copy image to a project different from the source.

<a id="extension-cluster-migration-inconsistent-copy"></a>

## `cluster_migration_inconsistent_copy`

Adds `allow_inconsistent` field to `POST /1.0/instances/<name>`. Set to `true` to allow inconsistent copying between cluster
members.

<a id="extension-cluster-ovn-chassis"></a>

## `cluster_ovn_chassis`

Introduces a new `ovn-chassis` cluster role which allows for specifying what cluster member should act as an OVN chassis.

<a id="extension-container-syscall-intercept-sched-setscheduler"></a>

## `container_syscall_intercept_sched_setscheduler`

Adds the [`security.syscalls.intercept.sched_setscheduler`](reference/instance_options.md#instance-security:security.syscalls.intercept.sched_setscheduler) to allow advanced process priority management in containers.

<a id="extension-storage-lvm-thinpool-metadata-size"></a>

## `storage_lvm_thinpool_metadata_size`

Introduces the ability to specify the thin pool metadata volume size via [`lvm.thinpool_metadata_size`](reference/storage_lvm.md#storage-lvm-pool-conf:lvm.thinpool_metadata_size).

If this is not specified then the default is to let LVM pick an appropriate thin pool metadata volume size.

<a id="extension-storage-volume-state-total"></a>

## `storage_volume_state_total`

This adds `total` field to the `GET /1.0/storage-pools/{name}/volumes/{type}/{volume}/state` API.

<a id="extension-instance-file-head"></a>

## `instance_file_head`

Implements HEAD on `/1.0/instances/NAME/file`.

<a id="extension-instances-nic-host-name"></a>

## `instances_nic_host_name`

This introduces the [`instances.nic.host_name`](server.md#server-miscellaneous:instances.nic.host_name) server configuration key that can take a value of either `random` or
`mac`. The default value for the key if unspecified is `random`. If it is set to random then use the random host interface names.
If it’s set to `mac`, then generate a name in the form `lxd1122334455`.

<a id="extension-image-copy-profile"></a>

## `image_copy_profile`

Adds ability to modify the set of profiles when image is copied.

<a id="extension-container-syscall-intercept-sysinfo"></a>

## `container_syscall_intercept_sysinfo`

Adds the [`security.syscalls.intercept.sysinfo`](reference/instance_options.md#instance-security:security.syscalls.intercept.sysinfo) to allow the `sysinfo` syscall to be populated with cgroup-based resource usage information.

<a id="extension-clustering-evacuation-mode"></a>

## `clustering_evacuation_mode`

This introduces a `mode` field to the evacuation request which allows
for overriding the evacuation mode traditionally set through
[`cluster.evacuate`](reference/instance_options.md#instance-miscellaneous:cluster.evacuate).

<a id="extension-resources-pci-vpd"></a>

## `resources_pci_vpd`

Adds a new VPD struct to the PCI resource entries.
This struct extracts vendor provided data including the full product name and additional key/value configuration pairs.

<a id="extension-qemu-raw-conf"></a>

## `qemu_raw_conf`

Introduces a [`raw.qemu.conf`](reference/instance_options.md#instance-raw:raw.qemu.conf) configuration key to override select sections of the generated `qemu.conf`.

<a id="extension-storage-cephfs-fscache"></a>

## `storage_cephfs_fscache`

Add support for `fscache`/`cachefilesd` on CephFS pools through a new [`cephfs.fscache`](reference/storage_cephfs.md#storage-cephfs-pool-conf:cephfs.fscache) configuration option.

<a id="extension-network-load-balancer"></a>

## `network_load_balancer`

This introduces the networking load balancer functionality. Allowing `ovn` networks to define port(s) on external
IP addresses that can be forwarded to one or more internal IP(s) inside their respective networks.

<a id="extension-vsock-api"></a>

## `vsock_api`

This introduces a bidirectional `vsock` interface which allows the `lxd-agent` and the LXD server to communicate better.

<a id="extension-instance-ready-state"></a>

## `instance_ready_state`

This introduces a new `Ready` state for instances which can be set using `devlxd`.

<a id="extension-network-bgp-holdtime"></a>

## `network_bgp_holdtime`

This introduces a new `bgp.peers.<name>.holdtime` configuration key to control the BGP hold time for a particular peer.

<a id="extension-storage-volumes-all-projects"></a>

## `storage_volumes_all_projects`

This introduces the ability to list storage volumes from all projects.

<a id="extension-metrics-memory-oom-total"></a>

## `metrics_memory_oom_total`

This introduces a new `lxd_memory_OOM_kills_total` metric to the `/1.0/metrics` API.
It reports the number of times the out of memory killer (`OOM`) has been triggered.

<a id="extension-storage-buckets"></a>

## `storage_buckets`

This introduces the storage bucket API. It allows the management of S3 object storage buckets for storage pools.

<a id="extension-storage-buckets-create-credentials"></a>

## `storage_buckets_create_credentials`

This updates the storage bucket API to return initial admin credentials at bucket creation time.

<a id="extension-metrics-cpu-effective-total"></a>

## `metrics_cpu_effective_total`

This introduces a new `lxd_cpu_effective_total` metric to the `/1.0/metrics` API.
It reports the total number of effective CPUs.

<a id="extension-projects-networks-restricted-access"></a>

## `projects_networks_restricted_access`

Adds the [`restricted.networks.access`](reference/projects.md#project-restricted:restricted.networks.access) project configuration key to indicate (as a comma-delimited list) which networks can be accessed inside the project.
If not specified, all networks are accessible (assuming it is also allowed by the [`restricted.devices.nic`](reference/projects.md#project-restricted:restricted.devices.nic) setting, described below).

This also introduces a change whereby network access is controlled by the project’s [`restricted.devices.nic`](reference/projects.md#project-restricted:restricted.devices.nic) setting:

* If `restricted.devices.nic` is set to `managed` (the default if not specified), only managed networks are accessible.
* If `restricted.devices.nic` is set to `allow`, all networks are accessible (dependent on the `restricted.networks.access` setting).
* If `restricted.devices.nic` is set to `block`, no networks are accessible.

<a id="extension-loki"></a>

## `loki`

This adds support for sending events to a Loki server.

It adds the following global configuration keys:

* [`loki.api.ca_cert`](server.md#server-loki:loki.api.ca_cert): CA certificate which can be used when sending events to the Loki server
* [`loki.api.url`](server.md#server-loki:loki.api.url): URL to the Loki server (protocol, name or IP and port)
* [`loki.auth.username`](server.md#server-loki:loki.auth.username) and [`loki.auth.password`](server.md#server-loki:loki.auth.password): Used if Loki is behind a reverse proxy with basic authentication enabled
* [`loki.labels`](server.md#server-loki:loki.labels): Comma-separated list of values which are to be used as labels for Loki events.
* [`loki.loglevel`](server.md#server-loki:loki.loglevel): Minimum log level for events sent to the Loki server.
* [`loki.types`](server.md#server-loki:loki.types): Types of events which are to be sent to the Loki server (any combination of `lifecycle`, `logging`, `ovn`, and `security`).

<a id="extension-acme"></a>

## `acme`

This adds ACME support, which allows [Let’s Encrypt](https://letsencrypt.org/) or other ACME services to issue certificates.

It adds the following global configuration keys:

* [`acme.domain`](server.md#server-acme:acme.domain): The domain for which the certificate should be issued.
* [`acme.email`](server.md#server-acme:acme.email): The email address used for the account of the ACME service.
* [`acme.ca_url`](server.md#server-acme:acme.ca_url): The directory URL of the ACME service, defaults to `https://acme-v02.api.letsencrypt.org/directory`.

It also adds the following endpoint, which is required for the HTTP-01 challenge:

* `/.well-known/acme-challenge/<token>`

<a id="extension-internal-metrics"></a>

## `internal_metrics`

This adds internal metrics to the list of metrics.
These include:

* Total running operations
* Total active warnings
* Daemon uptime in seconds
* Go memory stats
* Number of goroutines

<a id="extension-cluster-join-token-expiry"></a>

## `cluster_join_token_expiry`

This adds an expiry to cluster join tokens which defaults to 3 hours, but can be changed by setting the [`cluster.join_token_expiry`](server.md#server-cluster:cluster.join_token_expiry) configuration key.

<a id="extension-remote-token-expiry"></a>

## `remote_token_expiry`

This adds an expiry to remote add join tokens.
It can be set in the [`core.remote_token_expiry`](server.md#server-core:core.remote_token_expiry) configuration key, and defaults to 15 days.

<a id="extension-init-preseed"></a>

## `init_preseed`

Adds the `InitPreseed` type and related exported types (such as `InitLocalPreseed`, `InitClusterPreseed`, and
`InitNetworksProjectPost`) to `shared/api`, formalizing the YAML structure accepted by `lxd init --preseed` so
that it can be generated and parsed by other tools.

<a id="extension-storage-volumes-created-at"></a>

## `storage_volumes_created_at`

This change adds support for storing the creation date and time of storage volumes and their snapshots.

This adds the `CreatedAt` field to the `StorageVolume` and `StorageVolumeSnapshot` API types.

<a id="extension-cpu-hotplug"></a>

## `cpu_hotplug`

This adds CPU hotplugging for VMs.
Hotplugging is disabled when using CPU pinning, because this would require hotplugging NUMA devices as well, which is not possible.

<a id="extension-projects-networks-zones"></a>

## `projects_networks_zones`

This adds support for the [`features.networks.zones`](reference/projects.md#project-features:features.networks.zones) project feature, which changes which project network zones are
associated with when they are created. Previously network zones were tied to the value of [`features.networks`](reference/projects.md#project-features:features.networks),
meaning they were created in the same project as networks were.

Now this has been decoupled from [`features.networks`](reference/projects.md#project-features:features.networks) to allow projects that share a network in the default project
(i.e those with `features.networks=false`) to have their own project level DNS zones that give a project oriented
“view” of the addresses on that shared network (which only includes addresses from instances in their project).

This also introduces a change to the network `dns.zone.forward` setting, which now accepts a comma-separated of
DNS zone names (a maximum of one per project) in order to associate a shared network with multiple zones.

No change to the `dns.zone.reverse.*` settings have been made, they still only allow a single DNS zone to be set.
However the resulting zone content that is generated now includes `PTR` records covering addresses from all
projects that are referencing that network via one of their forward zones.

Existing projects that have `features.networks=true` will have `features.networks.zones=true` set automatically,
but new projects will need to specify this explicitly.

<a id="extension-network-txqueuelen"></a>

## `network_txqueuelen`

Adds a `txqueuelen` key to control the `txqueuelen` parameter of the NIC device.

<a id="extension-cluster-member-state"></a>

## `cluster_member_state`

Adds `GET /1.0/cluster/members/<member>/state` API endpoint and associated `ClusterMemberState` API response type.

<a id="extension-storage-pool-source-wipe"></a>

## `storage_pool_source_wipe`

Adds support for a `source.wipe` Boolean on the storage pool, indicating
that LXD should wipe partition headers off the requested disk rather
than potentially fail due to pre-existing file systems.

<a id="extension-zfs-block-mode"></a>

## `zfs_block_mode`

This adds support for using ZFS block <spellexception>filesystem</spellexception> volumes allowing the use of different file systems on top of ZFS.

This adds the following new configuration options for ZFS storage pools:

* `volume.zfs.block_mode`
* `volume.block.mount_options`
* `volume.block.filesystem`

<a id="extension-instance-generation-id"></a>

## `instance_generation_id`

Adds support for instance generation ID. The VM or container generation ID will change whenever the instance’s place in time moves backwards. As of now, the generation ID is only exposed through to VM type instances. This allows for the VM guest OS to reinitialize any state it needs to avoid duplicating potential state that has already occurred:

* [`volatile.uuid.generation`](reference/instance_options.md#instance-volatile:volatile.uuid.generation)

<a id="extension-disk-io-cache"></a>

## `disk_io_cache`

This introduces a new [`io.cache`](reference/devices_disk.md#device-disk-device-conf:io.cache) property to disk devices which can be used to override the VM caching behavior.

<a id="extension-amd-sev"></a>

## `amd_sev`

Adds support for AMD SEV (Secure Encrypted Virtualization) that can be used to encrypt the memory of a guest VM.

This adds the following new configuration options for SEV encryption:

* [`security.sev`](reference/instance_options.md#instance-security:security.sev) : (bool) is SEV enabled for this VM
* [`security.sev.policy.es`](reference/instance_options.md#instance-security:security.sev.policy.es) : (bool) is SEV-ES enabled for this VM
* [`security.sev.session.dh`](reference/instance_options.md#instance-security:security.sev.session.dh) : (string) guest owner’s `base64`-encoded Diffie-Hellman key
* [`security.sev.session.data`](reference/instance_options.md#instance-security:security.sev.session.data) : (string) guest owner’s `base64`-encoded session blob

<a id="extension-storage-pool-loop-resize"></a>

## `storage_pool_loop_resize`

This allows growing loop file backed storage pools by changing the `size` setting of the pool.

<a id="extension-migration-vm-live"></a>

## `migration_vm_live`

This adds support for performing VM QEMU to QEMU live migration for both shared storage (clustered Ceph) and
non-shared storage pools.

This also adds the `CRIUType_VM_QEMU` value of `3` for the migration `CRIUType` `protobuf` field.

<a id="extension-ovn-nic-nesting"></a>

## `ovn_nic_nesting`

This adds support for nesting an `ovn` NIC inside another `ovn` NIC on the same instance.
This allows for an OVN logical switch port to be tunneled inside another OVN NIC using VLAN tagging.

This feature is configured by specifying the parent NIC name using the [`nested`](reference/devices_nic.md#device-nic-ovn-device-conf:nested) property and the VLAN ID to use for tunneling with the [`vlan`](reference/devices_nic.md#device-nic-ovn-device-conf:vlan) property.

<a id="extension-oidc"></a>

## `oidc`

This adds support for OpenID Connect (OIDC) authentication.

This adds the following new configuration keys:

* [`oidc.issuer`](server.md#server-oidc:oidc.issuer)
* [`oidc.client.id`](server.md#server-oidc:oidc.client.id)
* [`oidc.audience`](server.md#server-oidc:oidc.audience)

<a id="extension-network-ovn-l3only"></a>

## `network_ovn_l3only`

This adds the ability to set an `ovn` network into “layer 3 only” mode.
This mode can be enabled at IPv4 or IPv6 level using [`ipv4.l3only`](reference/network_ovn.md#network-ovn-network-conf:ipv4.l3only) and [`ipv6.l3only`](reference/network_ovn.md#network-ovn-network-conf:ipv6.l3only) configuration options respectively.

With this mode enabled the following changes are made to the network:

* The virtual router’s internal port address will be configured with a single host netmask (e.g. /32 for IPv4 or /128 for IPv6).
* Static routes for active instance NIC addresses will be added to the virtual router.
* A discard route for the entire internal subnet will be added to the virtual router to prevent packets destined for inactive addresses from escaping to the uplink network.
* The DHCPv4 server will be configured to indicate that a netmask of 255.255.255.255 be used for instance configuration.

<a id="extension-ovn-nic-acceleration-vdpa"></a>

## `ovn_nic_acceleration_vdpa`

This updates the `ovn_nic_acceleration` API extension. The [`acceleration`](reference/devices_nic.md#device-nic-ovn-device-conf:acceleration) configuration key for OVN NICs can now takes the value `vdpa` to support Virtual Data Path Acceleration (VDPA).

<a id="extension-cluster-healing"></a>

## `cluster_healing`

This adds cluster healing which automatically evacuates offline cluster members.

This adds the following new configuration key:

* [`cluster.healing_threshold`](server.md#server-cluster:cluster.healing_threshold)

The configuration key takes an integer, and can be disabled by setting it to 0 (default). If set, the value represents the threshold after which an offline cluster member is to be evacuated. In case the value is lower than [`cluster.offline_threshold`](server.md#server-cluster:cluster.offline_threshold), that value will be used instead.

When the offline cluster member is evacuated, only remote-backed instances will be migrated. Local instances will be ignored as there is no way of migrating them once the cluster member is offline.

<a id="extension-instances-state-total"></a>

## `instances_state_total`

This extension adds a new `total` field to `InstanceStateDisk` and `InstanceStateMemory`, both part of the instance’s state API.

<a id="extension-auth-user"></a>

## `auth_user`

Add current user details to the main API endpoint.

This introduces:

* `auth_user_name`
* `auth_user_method`

<a id="extension-security-csm"></a>

## `security_csm`

Introduce a new `instance-security:security.csm` configuration key to control the use of
`CSM` (Compatibility Support Module) to allow legacy operating systems to
be run in LXD VMs.

#### NOTE
The `security.csm` key has been replaced by `boot.mode`. See [instance_boot_mode](#extension-instance-boot-mode).

<a id="extension-instances-rebuild"></a>

## `instances_rebuild`

This extension adds the ability to rebuild an instance with the same origin image, alternate image or as empty. A new `POST /1.0/instances/<name>/rebuild?project=<project>` API endpoint has been added as well as a new CLI command [`lxc rebuild`](reference/manpages/lxc/rebuild.md#lxc-rebuild-md).

<a id="extension-numa-cpu-placement"></a>

## `numa_cpu_placement`

This adds the possibility to place a set of CPUs in a desired set of NUMA nodes.

This adds the following new configuration key:

* [`limits.cpu.nodes`](reference/instance_options.md#instance-resource-limits:limits.cpu.nodes) : (string) comma-separated list of NUMA node IDs or NUMA node ID ranges to place the CPUs (chosen with a dynamic value of [`limits.cpu`](reference/instance_options.md#instance-resource-limits:limits.cpu)) in.

<a id="extension-custom-volume-iso"></a>

## `custom_volume_iso`

This adds the possibility to import ISO images as custom storage volumes.

This adds the `--type` flag to [`lxc storage volume import`](reference/manpages/lxc/storage/volume/import.md#lxc-storage-volume-import-md).

<a id="extension-network-allocations"></a>

## `network_allocations`

This adds the possibility to list a LXD deployment’s network allocations.

Through the [`lxc network list-allocations`](reference/manpages/lxc/network/list-allocations.md#lxc-network-list-allocations-md) command and the `--project <PROJECT> | --all-projects` flags,
you can list all the used IP addresses, hardware addresses (for instances), resource URIs and whether it uses NAT for
each `instance`, `network`, `network forward` and `network load-balancer`.

<a id="extension-storage-api-remote-volume-snapshot-copy"></a>

## `storage_api_remote_volume_snapshot_copy`

This allows copying storage volume snapshots to and from remotes.

<a id="extension-zfs-delegate"></a>

## `zfs_delegate`

This implements a new [`zfs.delegate`](reference/storage_zfs.md#storage-zfs-volume-conf:zfs.delegate) volume Boolean for volumes on a ZFS storage driver.
When enabled and a suitable system is in use (requires ZFS 2.2 or higher), the ZFS dataset will be delegated to the container, allowing for its use through the `zfs` command line tool.

<a id="extension-operations-get-query-all-projects"></a>

## `operations_get_query_all_projects`

This introduces support for the `all-projects` query parameter for the GET API calls to both `/1.0/operations` and `/1.0/operations?recursion=1`.
This parameter allows bypassing the project name filter.

<a id="extension-metadata-configuration"></a>

## `metadata_configuration`

Adds the `GET /1.0/metadata/configuration` API endpoint to retrieve the generated metadata configuration in a JSON format. The JSON structure adopts the structure `"configs" > `ENTITY` > `ENTITY_SECTION` > "keys" > [<CONFIG_OPTION_0>, <CONFIG_OPTION_1>, ...]`.
Check the list of [configuration options](config-options.md) to see which configuration options are included.

<a id="extension-syslog-socket"></a>

## `syslog_socket`

This introduces a syslog socket that can receive syslog formatted log messages. These can be viewed in the events API and `lxc monitor`, and can be forwarded to Loki. To enable this feature, set [`core.syslog_socket`](server.md#server-core:core.syslog_socket) to `true`.

<a id="extension-event-lifecycle-name-and-project"></a>

## `event_lifecycle_name_and_project`

This adds the fields `Name` and `Project` to `lifecycle` events.

<a id="extension-instances-nic-limits-priority"></a>

## `instances_nic_limits_priority`

This introduces a new per-NIC `limits.priority` option that works with both cgroup1 and cgroup2 unlike the deprecated `limits.network.priority` instance setting, which only worked with cgroup1.

<a id="extension-disk-initial-volume-configuration"></a>

## `disk_initial_volume_configuration`

This API extension provides the capability to set initial volume configurations for instance root devices.
Initial volume configurations are prefixed with `initial.` and can be specified either through profiles or directly
during instance initialization using the `--device` flag.

Note that these configuration are applied only at the time of instance creation and subsequent modifications have
no effect on existing devices.

<a id="extension-operation-wait"></a>

## `operation_wait`

This API extension indicates that the `/1.0/operations/{id}/wait` endpoint exists on the server. This indicates to the client
that the endpoint can be used to wait for an operation to complete rather than waiting for an operation event via the
`/1.0/events` endpoint.

<a id="extension-cluster-internal-custom-volume-copy"></a>

## `cluster_internal_custom_volume_copy`

This extension adds support for copying and moving custom storage volumes within a cluster with a single API call.
Calling `POST /1.0/storage-pools/<pool>/custom?target=<target>` will copy the custom volume specified in the `source` part of the request.
Calling `POST /1.0/storage-pools/<pool>/custom/<volume>?target=<target>` will move the custom volume from the source, specified in the `source` part of the request, to the target.

<a id="extension-disk-io-bus"></a>

## `disk_io_bus`

This introduces a new [`io.bus`](reference/devices_disk.md#device-disk-device-conf:io.bus) property to disk devices which can be used to override the bus the disk is attached to.

<a id="extension-storage-cephfs-create-missing"></a>

## `storage_cephfs_create_missing`

This introduces the configuration keys [`cephfs.create_missing`](reference/storage_cephfs.md#storage-cephfs-pool-conf:cephfs.create_missing), [`cephfs.osd_pg_num`](reference/storage_cephfs.md#storage-cephfs-pool-conf:cephfs.osd_pg_num), [`cephfs.meta_pool`](reference/storage_cephfs.md#storage-cephfs-pool-conf:cephfs.meta_pool) and [`cephfs.data_pool`](reference/storage_cephfs.md#storage-cephfs-pool-conf:cephfs.data_pool) to be used when adding a `cephfs` storage pool to instruct LXD to create the necessary entities for the storage pool, if they do not exist.

<a id="extension-instance-move-config"></a>

## `instance_move_config`

This API extension provides the ability to use flags `--profile`, `--no-profile`, `--device`, and `--config`
when moving an instance between projects and/or storage pools.

<a id="extension-ovn-ssl-config"></a>

## `ovn_ssl_config`

This introduces new server configuration keys to provide the SSL CA and client key pair to access the OVN databases.
The new configuration keys are [`network.ovn.ca_cert`](server.md#server-miscellaneous:network.ovn.ca_cert), [`network.ovn.client_cert`](server.md#server-miscellaneous:network.ovn.client_cert) and [`network.ovn.client_key`](server.md#server-miscellaneous:network.ovn.client_key).

<a id="extension-init-preseed-storage-volumes"></a>

## `init_preseed_storage_volumes`

This API extension provides the ability to configure storage volumes in preseed init.

<a id="extension-metrics-instances-count"></a>

## `metrics_instances_count`

This extends the metrics to include the containers and virtual machines counts. Instances are counted irrespective of their state.

<a id="extension-server-instance-type-info"></a>

## `server_instance_type_info`

This API extension enables querying a server’s supported instance types.
When querying the `/1.0` endpoint, a new field named `instance_types` is added to the retrieved data.
This field indicates which instance types are supported by the server.

<a id="extension-resources-disk-mounted"></a>

## `resources_disk_mounted`

Adds a `mounted` field to disk resources that LXD discovers on the system, reporting whether that disk or partition is
mounted.

<a id="extension-server-version-lts"></a>

## `server_version_lts`

The API extension adds indication whether the LXD version is an LTS release.
This is indicated when command `lxc version` is executed or when `/1.0` endpoint is queried.

<a id="extension-oidc-groups-claim"></a>

## `oidc_groups_claim`

This API extension enables setting an [`oidc.groups.claim`](server.md#server-oidc:oidc.groups.claim) configuration key.
If OIDC authentication is configured and this claim is set, LXD will request this claim in the scope of OIDC flow.
The value of the claim will be extracted and might be used to make authorization decisions.

<a id="extension-loki-config-instance"></a>

## `loki_config_instance`

Adds a new [`loki.instance`](server.md#server-loki:loki.instance) server configuration key to customize the `instance` field in Loki events.
This can be used to expose the name of the cluster rather than the individual system name sending
the event as that’s usually already covered by the `location` field.

<a id="extension-storage-volatile-uuid"></a>

## `storage_volatile_uuid`

Adds a new `volatile.uuid` configuration key to all storage volumes, snapshots and buckets.
This information can be used by storage drivers as a separate identifier besides the name
when working with volumes.

<a id="extension-import-instance-devices"></a>

## `import_instance_devices`

This API extension provides the ability to use flags `--device` when importing an instance to override instance’s devices.

<a id="extension-instances-uefi-vars"></a>

## `instances_uefi_vars`

This API extension indicates that the `/1.0/instances/{name}/uefi-vars` endpoint is supported on the server. This endpoint allows to get the full list of UEFI variables (HTTP method GET) or replace the entire set of UEFI variables (HTTP method PUT).

<a id="extension-instances-migration-stateful"></a>

## `instances_migration_stateful`

This API extension allows newly created VMs to have their [`migration.stateful`](reference/instance_options.md#instance-migration:migration.stateful) configuration key automatically set
through the new server-level configuration key [`instances.migration.stateful`](server.md#server-miscellaneous:instances.migration.stateful). If `migration.stateful` is already set at the profile or instance level then `instances.migration.stateful` is not applied.

<a id="extension-access-management"></a>

## `access_management`

Adds new APIs under `/1.0/auth` for viewing and managing identities, groups, and permissions.
Adds an embedded OpenFGA authorization driver for enforcing fine-grained permissions.

#### IMPORTANT
Prior to the addition of this extension, all OIDC clients were given full access to LXD (equivalent to Unix socket access).
This extension revokes access to all OIDC clients.
To regain access, a user must:

1. Make a call to the OIDC enabled LXD remote (e.g. `lxc info`) to ensure that their OIDC identity is added to the LXD database.
2. Create a group: `lxc auth group create <group_name>`
3. Grant the group a suitable permission.
   As all OIDC clients prior to this extension have had full access to LXD, the corresponding permission is `admin` on `server`.
   To grant this permission to your group, run: `lxc auth group permission add <group_name> server admin`
4. Add themselves to the group. To do this, run: `lxc auth identity group add oidc/<email_address> <group_name>`

Steps 2 to 4 above cannot be performed via OIDC authentication (access has been revoked).
They must be performed by a sufficiently privileged user, either via Unix socket or unrestricted TLS client certificate.

For more information on access control for OIDC clients, see [Fine-grained authorization](explanation/authorization.md#fine-grained-authorization).

<a id="extension-vm-disk-io-limits"></a>

## `vm_disk_io_limits`

Adds the ability to limit disk I/O for virtual machines.

<a id="extension-storage-volumes-all"></a>

## `storage_volumes_all`

This API extension adds support for listing storage volumes from all storage pools via `/1.0/storage-volumes` or `/1.0/storage-volumes/{type}` to filter by volume type. Also adds a `pool` field to storage volumes.

<a id="extension-instances-files-modify-permissions"></a>

## `instances_files_modify_permissions`

Adds the ability for `POST /1.0/instances/{name}/files` to modify the permissions of files that already exist via the `X-LXD-modify-perm` header.

`X-LXD-modify-perm` should be a comma-separated list of 0 or more of `mode`, `uid`, and `gid`.

<a id="extension-image-restriction-nesting"></a>

## `image_restriction_nesting`

This extension adds a new image restriction, `requirements.nesting` which when `true` indicates that an image cannot be run without nesting.

<a id="extension-container-syscall-intercept-finit-module"></a>

## `container_syscall_intercept_finit_module`

Adds the [`linux.kernel_modules.load`](reference/instance_options.md#instance-miscellaneous:linux.kernel_modules.load) container configuration option. If the option is set to `ondemand`, the `finit_modules()` syscall is intercepted and a privileged user in the container’s user namespace can load the Linux kernel modules specified in the
allow list [`linux.kernel_modules`](reference/instance_options.md#instance-miscellaneous:linux.kernel_modules).

<a id="extension-device-usb-serial"></a>

## `device_usb_serial`

This adds new configuration keys [`serial`](reference/devices_usb.md#device-unix-usb-device-conf:serial), [`busnum`](reference/devices_usb.md#device-unix-usb-device-conf:busnum) and [`devnum`](reference/devices_usb.md#device-unix-usb-device-conf:devnum) for [device type `usb`](reference/devices_usb.md#devices-usb).
The feature has been added to make it possible to distinguish between devices with identical [`vendorid`](reference/devices_usb.md#device-unix-usb-device-conf:vendorid) and [`productid`](reference/devices_usb.md#device-unix-usb-device-conf:productid).

<a id="extension-network-allocate-external-ips"></a>

## `network_allocate_external_ips`

Adds the ability to use an unspecified IPv4 (`0.0.0.0`) or IPv6 (`::`) address in the `listen_address` field of the request body for `POST /1.0/networks/{networkName}/load-balancers` and `POST /1.0/networks/{networkName}/forwards`.
If an unspecified IP address is used, supported drivers will allocate an available listen address automatically.
Allocation of external IP addresses is currently supported by the OVN network driver.
The OVN driver will allocate IP addresses from the subnets specified in the uplink network’s `ipv4.routes` and `ipv6.routes` configuration options.

<a id="extension-explicit-trust-token"></a>

## `explicit_trust_token`

Adds the ability to explicitly specify a trust token when creating a certificate
and joining an existing cluster.

<a id="extension-shared-custom-block-volumes"></a>

## `shared_custom_block_volumes`

This adds a configuration key `security.shared` to custom block volumes.
If unset or `false`, the custom block volume cannot be attached to multiple instances.
This feature was added to prevent data loss which can happen when custom block volumes are attached to multiple instances at once.

<a id="extension-instance-import-conversion"></a>

## `instance_import_conversion`

Adds the ability to convert images from different formats (e.g. VMDK or QCow2) into RAW image format and import them as LXD instances.

<a id="extension-instance-create-start"></a>

## `instance_create_start`

Adds a `start` field to the `POST /1.0/instances` API which when set
to `true` will have the instance automatically start upon creation.

In this scenario, the creation and startup is part of a single background operation.

<a id="extension-instance-protection-start"></a>

## `instance_protection_start`

Enables setting the [`security.protection.start`](reference/instance_options.md#instance-security:security.protection.start) field which prevents instances
from being started if set to `true`.

<a id="extension-devlxd-images-vm"></a>

## `devlxd_images_vm`

Enables the [`security.devlxd.images`](reference/instance_options.md#instance-security:security.devlxd.images) configuration option for virtual machines.
This controls the availability of a `/1.0/images/FINGERPRINT/export` API over `devlxd`.
This can be used by a virtual machine running LXD to access raw images from the host.

<a id="extension-disk-io-bus-virtio-blk"></a>

## `disk_io_bus_virtio_blk`

Adds a new `virtio-blk` value for `io.bus` on `disk` devices which allows
for the attached disk to be connected to the `virtio-blk` bus.

<a id="extension-metrics-api-requests"></a>

## `metrics_api_requests`

Adds the following internal metrics:

* Total completed requests
* Number of ongoing requests

<a id="extension-projects-limits-disk-pool"></a>

## `projects_limits_disk_pool`

This introduces per-pool project disk limits, introducing a `limits.disk.pool.NAME`
configuration option to the project limits. When `limits.disk.pool.POOLNAME: 0`
for a project, the pool is excluded from `lxc storage list` in that project.

<a id="extension-ubuntu-pro-guest-attach"></a>

## `ubuntu_pro_guest_attach`

Adds a new [`ubuntu_pro.guest_attach`](reference/instance_options.md#instance-miscellaneous:ubuntu_pro.guest_attach) configuration option for instances.
When set to `on`, if the host has guest attachment enabled, the guest can request a guest token for Ubuntu Pro via `devlxd`.

For more information, see: [How to configure Ubuntu Pro guest attachment](howto/instances_ubuntu_pro_attach.md#instances-ubuntu-pro-attach).

<a id="extension-metadata-configuration-entity-types"></a>

## `metadata_configuration_entity_types`

This adds entity type metadata to `GET /1.0/metadata/configuration`.
The entity type metadata is a JSON object under the `entities` key.

<a id="extension-access-management-tls"></a>

## `access_management_tls`

Expands APIs under `/1.0/auth` to include:

1. Creation of fine-grained TLS identities, whose permissions are managed via group membership.
   This is performed via `POST /1.0/auth/identities/tls`.
   If the request body contains `{"token": true}`, a token will be returned that may be used by a non-authenticated caller to gain trust with the LXD server (the caller must send their certificate during the TLS handshake).
   If the request body contains `{"certificate": "<base64 encoded x509 certificate>"}"`, the identity will be created directly.
   The request body may also specify an array of group names.
   The caller must have `can_create_identities` on `server`.
2. Deletion of OIDC and fine-grained TLS identities.
   This is performed via `DELETE /1.0/auth/identities/tls/{nameOrFingerprint}` or `DELETE /1.0/auth/identities/oidc/{nameOrEmailAddress}`.
   The caller must have `can_delete` on the identity. All identities may delete their own identity.
   For OIDC identities this revokes all access but does not revoke trust (authentication is performed by the identity provider).
   For fine-grained TLS identities, this revokes all access and revokes trust.
3. Functionality to update the certificate of a fine-grained TLS identity.
   This is performed via `PUT /1.0/auth/identities/tls/{nameOrFingerprint}` or `PATCH /1.0/auth/identities/tls/{nameOrFingerprint}`.
   The caller must provide a base64 encoded x509 certificate in the `certificate` field of the request body.
   Fine-grained TLS identities may update their own certificate.
   To update the certificate of another identity, the caller must have `can_edit` on the identity.

<a id="extension-network-allocations-ovn-uplink"></a>

## `network_allocations_ovn_uplink`

Includes OVN virtual routers external IPs to `/1.0/network-allocations` responses with the type `uplink`.
Introduces the `network` field on each allocation, indicating to which network each allocated address belongs.
And lastly, adds a `project` field on leases, leases can be retrieved via `/1.0/networks/<network>/leases`.

<a id="extension-network-ovn-uplink-vlan"></a>

## `network_ovn_uplink_vlan`

Adds support for using a bridge network with a specified VLAN ID as an OVN uplink.

<a id="extension-state-logical-cpus"></a>

## `state_logical_cpus`

Adds `logical_cpus` field to `GET /1.0/cluster/members/{name}/state` which
contains the total available logical CPUs available when LXD started.

<a id="extension-vm-limits-cpu-pin-strategy"></a>

## `vm_limits_cpu_pin_strategy`

Adds a new [`limits.cpu.pin_strategy`](reference/instance_options.md#instance-resource-limits:limits.cpu.pin_strategy) configuration option for virtual machines. This option controls the CPU pinning strategy. When set to `none`, CPU auto pinning is disabled. When set to `auto`, CPU auto pinning is enabled.

<a id="extension-gpu-cdi"></a>

## `gpu_cdi`

Adds support for using the Container Device Interface (CDI) specification to configure GPU passthrough in LXD containers. The `id` field of GPU devices now accepts CDI identifiers (for example, `{VENDOR_DOMAIN_NAME}/gpu=gpu{INDEX}`) for containers, in addition to DRM card IDs. This enables GPU passthrough for devices that don’t use PCI addressing (like NVIDIA Tegra iGPUs) and provides a more flexible way to identify and configure GPU devices.

<a id="extension-images-all-projects"></a>

## `images_all_projects`

This adds support for listing images across all projects using the `all-projects` parameter in `GET /1.0/images` requests.

<a id="extension-metadata-configuration-scope"></a>

## `metadata_configuration_scope`

This adds scope metadata to `GET /1.0/metadata/configuration`. Options marked with a `global` scope are applied to all cluster members. Options with a `local` scope must be set on a per-member basis.

<a id="extension-unix-device-hotplug-ownership-inherit"></a>

## `unix_device_hotplug_ownership_inherit`

Adds a new [`ownership.inherit`](reference/devices_unix_hotplug.md#device-unix-hotplug-device-conf:ownership.inherit) configuration option for `unix-hotplug` devices. This option controls whether the device inherits ownership (GID and/or UID) from the host. When set to `true` and GID and/or UID are unset, host ownership is inherited. When set to `false`, host ownership is not inherited and ownership can be configured by setting [`gid`](reference/devices_unix_hotplug.md#device-unix-hotplug-device-conf:gid) and [`uid`](reference/devices_unix_hotplug.md#device-unix-hotplug-device-conf:uid).

<a id="extension-unix-device-hotplug-subsystem-device-option"></a>

## `unix_device_hotplug_subsystem_device_option`

Adds a new [`subsystem`](reference/devices_unix_hotplug.md#device-unix-hotplug-device-conf:subsystem) configuration option for `unix-hotplug` devices. This adds support for detecting `unix-hotplug` devices by subsystem, and can be used in conjunction with [`productid`](reference/devices_unix_hotplug.md#device-unix-hotplug-device-conf:productid) and [`vendorid`](reference/devices_unix_hotplug.md#device-unix-hotplug-device-conf:vendorid).

<a id="extension-storage-ceph-osd-pool-size"></a>

## `storage_ceph_osd_pool_size`

This introduces the configuration keys [`ceph.osd.pool_size`](reference/storage_ceph.md#storage-ceph-pool-conf:ceph.osd.pool_size), and [`cephfs.osd_pool_size`](reference/storage_cephfs.md#storage-cephfs-pool-conf:cephfs.osd_pool_size) to be used when adding or updating a `ceph` or `cephfs` storage pool to instruct LXD to create set the replication size for the underlying OSD pools.

<a id="extension-network-get-target"></a>

## `network_get_target`

Adds optional `target` parameter to `GET /1.0/network`. When target is set, forward the request to the specified cluster member and return the non-managed interfaces from that member.

<a id="extension-network-zones-all-projects"></a>

## `network_zones_all_projects`

This adds support for listing network zones across all projects using the `all-projects` parameter in `GET /1.0/network-zones` requests.

<a id="extension-vm-root-volume-attachment"></a>

## `vm_root_volume_attachment`

Adds support for virtual-machine root volumes and snapshots to be attached to other instances as disk devices. Introduces the `source.type` and `source.snapshot` keys for disk devices.

<a id="extension-projects-limits-uplink-ips"></a>

## `projects_limits_uplink_ips`

Introduces per-project uplink IP limits for each available uplink network, adding `limits.networks.uplink_ips.ipv4.NETWORK_NAME` and `limits.networks.uplink_ips.ipv6.NETWORK_NAME` configuration keys for projects with `features.networks` enabled.
These keys define the maximum value of IPs made available on a network named NETWORK_NAME to be assigned as uplink IPs for entities inside a certain project. These entities can be other networks, network forwards or load balancers.

<a id="extension-entities-with-entitlements"></a>

## `entities_with_entitlements`

Adds `fine_grained` field to `GET /1.0/auth/identities/current` to indicate if the current identity
interacting with the LXD API is fine-grained (that is, associated permissions are managed via group membership).
Allows LXD entities to be returned with an `access_entitlements` field if the current identity is fine-grained and the
GET request to fetch the LXD entities has the `with-access-entitlements=<comma_separated_list_of_candidate_entitlements>` query parameter.

<a id="extension-profiles-all-projects"></a>

## `profiles_all_projects`

This adds support for listing profiles across all projects using the `all-projects` parameter in `GET /1.0/profiles` requests.

<a id="extension-storage-driver-powerflex"></a>

## `storage_driver_powerflex`

Adds a new `powerflex` storage driver which allows the consumption of storage volumes from a Dell PowerFlex storage array using NVMe/TCP and SDC.
The following new pool level configuration keys have been added:

1. [`powerflex.snapshot_copy`](reference/storage_powerflex.md#storage-powerflex-pool-conf:powerflex.snapshot_copy)
2. [`powerflex.domain`](reference/storage_powerflex.md#storage-powerflex-pool-conf:powerflex.domain)
3. [`powerflex.gateway`](reference/storage_powerflex.md#storage-powerflex-pool-conf:powerflex.gateway)
4. [`powerflex.gateway.verify`](reference/storage_powerflex.md#storage-powerflex-pool-conf:powerflex.gateway.verify)
5. [`powerflex.mode`](reference/storage_powerflex.md#storage-powerflex-pool-conf:powerflex.mode)
6. [`powerflex.pool`](reference/storage_powerflex.md#storage-powerflex-pool-conf:powerflex.pool)
7. [`powerflex.sdt`](reference/storage_powerflex.md#storage-powerflex-pool-conf:powerflex.sdt)
8. [`powerflex.user.name`](reference/storage_powerflex.md#storage-powerflex-pool-conf:powerflex.user.name)
9. [`powerflex.user.password`](reference/storage_powerflex.md#storage-powerflex-pool-conf:powerflex.user.password)

The following configuration keys have been added for volumes backed by PowerFlex:

1. [`block.type`](reference/storage_powerflex.md#storage-powerflex-volume-conf:block.type)

<a id="extension-storage-driver-pure"></a>

## `storage_driver_pure`

Adds a new `pure` storage driver which allows the consumption of storage volumes from a Pure Storage storage array using either iSCSI or NVMe/TCP.

The following pool level configuration keys have been added:

1. [`pure.gateway`](reference/storage_pure.md#storage-pure-pool-conf:pure.gateway)
2. [`pure.gateway.verify`](reference/storage_pure.md#storage-pure-pool-conf:pure.gateway.verify)
3. [`pure.api.token`](reference/storage_pure.md#storage-pure-pool-conf:pure.api.token)
4. [`pure.mode`](reference/storage_pure.md#storage-pure-pool-conf:pure.mode)
5. [`pure.target`](reference/storage_pure.md#storage-pure-pool-conf:pure.target)

<a id="extension-cloud-init-ssh-keys"></a>

## `cloud_init_ssh_keys`

Adds support for injecting additional SSH public keys into instances through [cloud-init](reference/instance_options.md#instance-options-cloud-init) without conflicting with any configuration present on [`cloud-init.vendor-data`](reference/instance_options.md#instance-cloud-init:cloud-init.vendor-data) or [`cloud-init.user-data`](reference/instance_options.md#instance-cloud-init:cloud-init.user-data).

To achieve this, the `cloud-init.ssh-keys.KEYNAME` configuration key is added for both instances and profiles. This key is used to define a public key to be injected. `KEYNAME` can be any arbitrary name for the injected key.

The value for `cloud-init.ssh-keys.KEYNAME` should be `<user>:<key>`, where `<user>` is the name of the user for whom to inject the key. For `<key>`, provide either the public key or a `cloud-init` import ID for a key hosted elsewhere. Example valid values for `cloud-init.ssh-keys.KEYNAME` are `root:gh:githubUser` or `myUser:ssh-keyAlg base64PublicKey`.

<a id="extension-oidc-scopes"></a>

## `oidc_scopes`

This API extension enables setting an [`oidc.scopes`](server.md#server-oidc:oidc.scopes) configuration key, which accepts a space-separated list of OIDC scopes to request from the identity provider.
This configuration option can be used to request additional scopes that might be required for retrieving [identity provider groups](explanation/authorization.md#identity-provider-groups) from the identity provider.
Additionally, the optional scopes `profile` and `offline_access` can be unset via this setting.
Note that the `openid` and `email` scopes are always required.

<a id="extension-project-default-network-and-storage"></a>

## `project_default_network_and_storage`

Adds flags –network and –storage. The –network flag adds a network device connected to the specified network to the default profile. The –storage flag adds a root disk device using the specified storage pool to the default profile.

<a id="extension-client-cert-presence"></a>

## `client_cert_presence`

Adds the field `client_certificate` to `GET /1.0` to indicate if the current request has a client certificate in it. This is for informational purposes only and does not affect the behavior of the API.

<a id="extension-clustering-groups-used-by"></a>

## `clustering_groups_used_by`

This API extension adds a `used_by` field to the API response for a [cluster group](explanation/clusters.md#cluster-groups).
Deletion of a cluster group is disallowed if the cluster group is referenced by project configuration (see [`restricted.cluster.groups`](reference/projects.md#project-restricted:restricted.cluster.groups)).

<a id="extension-container-bpf-delegation"></a>

## `container_bpf_delegation`

Adds new [`security.delegate_bpf`](reference/instance_options.md#instance-security:security.delegate_bpf).\* group of options in order to support eBPF delegation using BPF Token mechanism. See [Privilege delegation using BPF Token](explanation/bpf.md#bpf-delegation-token) for more information.

<a id="extension-override-snapshot-profiles-on-copy"></a>

## `override_snapshot_profiles_on_copy`

This adds a request option to set snapshot’s target profile on instance copy to be inherited from target instance.

<a id="extension-resources-device-fs-uuid"></a>

## `resources_device_fs_uuid`

Adds the field `device_fs_uuid` including the respective UUID to each disk and partition indicating whether or not a filesystem is located on the device.

<a id="extension-backup-metadataversion"></a>

<a id="extension-backup-metadata-version"></a>

## `backup_metadata_version`

Adds the field `version` when exporting instances and custom storage volumes to define the backup file format.
In case the field is omitted, the server’s default version is used.
This maintains backwards compatibility with older clients.

When exporting an instance, the specific version can be provided using the `--export-version` flag:

`lxc export v1 --export-version 2`

The same applies when exporting a custom storage volume:

`lxc storage volume export pool1 vol1 --export-version 2`

<a id="extension-storage-buckets-all-projects"></a>

## `storage_buckets_all_projects`

This adds support for listing storage buckets across all projects using the `all-projects` parameter in `GET /1.0/storage-pools/POOL/buckets` requests.

<a id="extension-network-acls-all-projects"></a>

## `network_acls_all_projects`

This adds support for listing network ACLs across all projects using the `all-projects` parameter in `GET /1.0/network-acls` requests.

<a id="extension-networks-all-projects"></a>

## `networks_all_projects`

This adds support for listing networks across all projects using the `all-projects` parameter in `GET /1.0/networks` requests.

<a id="extension-clustering-restore-skip-mode"></a>

## `clustering_restore_skip_mode`

Adds a `skip` mode to the restore request. This mode restores a cluster member’s status to `ONLINE` without restarting any of its stopped local instances or migrating back instances that were evacuated to other cluster members.

<a id="extension-disk-io-threads-virtiofsd"></a>

## `disk_io_threads_virtiofsd`

Adds the [`io.threads`](reference/devices_disk.md#device-disk-device-conf:io.threads) option on `disk` devices which is used to control the `virtiofsd` thread pool size when sharing file systems into VMs. This can help improve I/O performance.

<a id="extension-oidc-client-secret"></a>

## `oidc_client_secret`

This adds support for the [`oidc.client.secret`](server.md#server-oidc:oidc.client.secret) configuration key.
If set, the LXD server will use this value in the OpenID Connect (OIDC) authorization code flow, which is used by LXD UI.
This configuration value is not shared with other LXD clients (such as the LXD CLI).

<a id="extension-pci-hotplug"></a>

## `pci_hotplug`

This adds PCI device hotplugging for VMs.

<a id="extension-device-patch-removal"></a>

## `device_patch_removal`

The `PATCH /1.0/instances/{name}` endpoint allows removing an instance device by setting its value to `null` in the devices map.

<a id="extension-daemon-storage-per-project"></a>

## `daemon_storage_per_project`

This introduces two new configuration keys [`storage.project.{name}.images_volume`](server.md#server-miscellaneous:storage.project.{name}.images_volume) and
[`storage.project.{name}.backups_volume`](server.md#server-miscellaneous:storage.project.{name}.backups_volume) per each project to allow for a storage volume on an existing
pool be used for storing the project-specific images and backups artifacts.

<a id="extension-ovn-internal-load-balancer"></a>

## `ovn_internal_load_balancer`

This introduces support for internal OVN load balancers and network forwards. This approach allows `ovn` networks to define ports on internal IP addresses that can be forwarded to other internal IPs inside their respective networks.
This change removes the previous limitation on `ovn` networks that load balancers and network forwards could only use external IP addresses to forward to internal IPs.

<a id="extension-auth-bearer-devlxd"></a>

## `auth_bearer_devlxd`

Adds a new `bearer` authentication method and enables authentication to the DevLXD API.
See [DevLXD bearer tokens](dev-lxd.md#devlxd-authentication-bearer).

<a id="extension-devlxd-volume-management"></a>

## `devlxd_volume_management`

Enables additional DevLXD endpoints for managing custom storage volumes and instance devices when `security.devlxd.management.volumes` is set to true.
These endpoints are primarily intended for use by the LXD CSI driver.

Management is limited to custom storage volumes.
Additionally, the client is required to authenticate using DevLXD identity, which is used to track storage volume and instance device owner.
Volumes and instance devices created through the DevLXD are marked as owned by the authenticated identity and can later be modified or removed through DevLXD only by the same identity.

New DevLXD endpoints:

* `GET /1.0/storage-pools/{pool}` — Retrieve a storage pool.
* `GET /1.0/storage-pools/{pool}/volumes` — List owned custom volumes in a pool.
* `GET /1.0/storage-pools/{pool}/volumes/{volume}` — Retrieve an owned custom volume.
* `POST /1.0/storage-pools/{pool}/volumes` — Create a new owned custom volume in a pool.
* `PUT /1.0/storage-pools/{pool}/volumes/{volume}` — Update an owned custom volume.
* `DELETE /1.0/storage-pools/{pool}/volumes/{volume}` — Delete an owned custom volume.
* `GET /1.0/instances/{inst}` — Retrieve an instance and its owned devices.
* `PATCH /1.0/instances/{inst}` — Add new instance devices or modify owned devices.

Changes to existing DevLXD endpoints:

* `GET /1.0` — Adds a `supported_storage_drivers` field to the response, which is populated when `security.devlxd.management.volumes` is enabled.

<a id="extension-storage-driver-alletra"></a>

## `storage_driver_alletra`

Adds a new `alletra` storage driver for the consumption of storage volumes from an HPE Alletra storage array.

The following pool-level configuration keys have been added:

1. [`alletra.wsapi`](reference/storage_alletra.md#storage-alletra-pool-conf:alletra.wsapi)
2. [`alletra.wsapi.verify`](reference/storage_alletra.md#storage-alletra-pool-conf:alletra.wsapi.verify)
3. [`alletra.user.name`](reference/storage_alletra.md#storage-alletra-pool-conf:alletra.user.name)
4. [`alletra.user.password`](reference/storage_alletra.md#storage-alletra-pool-conf:alletra.user.password)
5. [`alletra.cpg`](reference/storage_alletra.md#storage-alletra-pool-conf:alletra.cpg)
6. [`alletra.target`](reference/storage_alletra.md#storage-alletra-pool-conf:alletra.target)
7. [`alletra.mode`](reference/storage_alletra.md#storage-alletra-pool-conf:alletra.mode)

<a id="extension-resources-disk-used-by"></a>

## `resources_disk_used_by`

Adds the field `used_by` to potential storage disk returned by the resources end point to indicate its use by any virtual parent device, e.g. `bcache`.

<a id="extension-ovn-dhcp-ranges"></a>

## `ovn_dhcp_ranges`

This introduces support for the [`ipv4.dhcp.ranges`](reference/network_ovn.md#network-ovn-network-conf:ipv4.dhcp.ranges) configuration key for `ovn` networks. This key allows specifying a list of IPv4 ranges
reserved for dynamic allocation using DHCP.

<a id="extension-operation-requestor"></a>

## `operation_requestor`

This adds a new `requestor` field to operations, which contains information about the caller that initiated the operation.

<a id="extension-import-custom-volume-tar"></a>

## `import_custom_volume_tar`

This adds new option `tar` for parameter `--type` in `POST /1.0/storage-pools/{poolName}/volumes/{type}` API call.

<a id="extension-projects-force-delete"></a>

## `projects_force_delete`

Adds support for force deleting projects and their entities (instances, profiles, images, networks, network ACLs, network zones, storage volumes, and storage buckets) by setting the `force` query parameter on `DELETE /1.0/projects/{name}` requests.

<a id="extension-auth-oidc-sessions"></a>

## `auth_oidc_sessions`

Adds session support for OIDC authentication. This enables compatibility with identity providers that issue opaque access tokens.

When a session expires, LXD will re-verify the login with the identity provider.
The duration of OIDC sessions defaults to one week and can be configured via the [`oidc.session.expiry`](server.md#server-oidc:oidc.session.expiry) configuration key.

Verification of an OIDC session depends on a new, cluster-wide core secret.
The OIDC session expiry can never be greater than the expiry of the core secret.
The [`core.auth_secret_expiry`](server.md#server-core:core.auth_secret_expiry) configuration option can set to define how long a given secret can be used for before it expires.

<a id="extension-instance-snapshots-multi-volume"></a>

## `instance_snapshots_multi_volume`

Enables the creation of a multi-volume snapshot and the restoration of an instance together with its attached volumes, while ensuring crash consistency across volumes.

Adds `DiskVolumesMode` to `POST /1.0/instances/{name}/snapshots` and `RestoreDiskVolumesMode` to `PUT /1.0/instances/{name}` to select which attached volumes are included in snapshots/restores: “root” includes only the instance’s root disk; “all-exclusive” includes the root disk and any exclusively attached (non-shared) volumes. Defaults to “root”.

This extension also introduces a new volatile configuration key, [`volatile.attached_volumes`](reference/instance_options.md#instance-volatile:volatile.attached_volumes), in the configuration of supported storage drivers for instance snapshots. This key contains a JSON-serialized map of attached volume UUIDs to the UUIDs of their corresponding snapshots. Example value: `{<volume1-uuid>: <snapshot1-uuid>,<volume2-uuid>: <snapshot2-uuid>}`.

<a id="extension-vm-persistent-bus"></a>

## `vm_persistent_bus`

Adds support for persistently recording VM PCIe bus allocations in volatile configuration keys.

This introduces two new volatile VM configuration keys:

* [`volatile.<name>.bus`](reference/instance_options.md#instance-volatile:volatile.<name>.bus) - records the bus number for the device.
* [`volatile.bus.mode`](reference/instance_options.md#instance-volatile:volatile.bus.mode) - records whether “persistent” mode is being used for a VM.

<a id="extension-instance-placement-groups"></a>

## `instance_placement_groups`

Placement groups define how instances are scheduled across cluster members according to a configurable placement policy (`spread` or `compact`) and rigor (`strict` or `permissive`). They can be referenced in instance and profile configuration through the [`placement.group`](reference/instance_options.md#instance-placement:placement.group) key to control placement behavior during instance creation and migration.

New API endpoints:

1. `GET /1.0/placement-groups` — List all placement groups
2. `POST /1.0/placement-groups` — Create a new placement group
3. `GET /1.0/placement-groups/{name}` — Retrieve details for a specific placement group
4. `PUT /1.0/placement-groups/{name}` — Replace a placement group definition
5. `PATCH /1.0/placement-groups/{name}` — Update selected properties of a placement group
6. `DELETE /1.0/placement-groups/{name}` — Delete a placement group

<a id="extension-ovn-nic-acceleration-parent"></a>

## `ovn_nic_acceleration_parent`

Adds support for specifying the OVN NIC acceleration physical function interfaces to allocate virtual functions from.

This avoids the need for adding physical function interfaces to the OVN integration bridge.

This introduces a new `ovn` network and `ovn` NIC configuration key:

* [`acceleration.parent`](reference/devices_nic.md#device-nic-ovn-device-conf:acceleration.parent) - Comma separated list of physical function (PF) interfaces to allocate virtual functions (VFs) from for hardware acceleration when [`acceleration`](reference/devices_nic.md#device-nic-ovn-device-conf:acceleration) is enabled.

<a id="extension-storage-and-profile-operations"></a>

## `storage_and_profile_operations`

Certain storage and profile endpoints that were previously synchronous now return an operation and behave asynchronously.

Newer LXD Go clients detect the presence of this API extension. When it is available, the client receives an operation object directly from the LXD server.
If the extension is not present, the server response is wrapped in a completed operation, allowing the caller to handle it as an operation while lacking a retrievable operation ID.

Older LXD Go clients are incompatible with servers that include this extension.
Instead of returning a successful response, they will receive an operation response.

Endpoints converted to asynchronous behavior:

* `POST /storage-pools/{pool}/volumes/{type}` - Create storage volume
* `PUT /storage-pools/{pool}/volumes/{type}/{vol}` - Update storage volume
* `PATCH /storage-pools/{pool}/volumes/{type}/{vol}` - Patch storage volume
* `POST /storage-pools/{pool}/volumes/{type}/{vol}` - Rename storage volume
* `DELETE /storage-pools/{pool}/volumes/{type}/{vol}` - Delete storage volume
* `PUT /storage-pools/{pool}/volumes/{type}/{vol}/snapshots/{snap}` - Update storage volume snapshot
* `PATCH /storage-pools/{pool}/volumes/{type}/{vol}/snapshots/{snap}` - Patch storage volume snapshot
* `PUT /1.0/profiles/{name}` - Update profile
* `PATCH /1.0/profiles/{name}` - Patch profile

<a id="extension-storage-source-recover"></a>

## `storage_source_recover`

As part of the recovery process it might be necessary to recover existing storage pools previously created by LXD.

Before this was only partially possible for some of the drivers (e.g. by using `lvm.vg.force_reuse`), but not directly supported.
The new pool `source.recover` configuration key can be set per cluster member to allow reuse of an existing pool `source`.
What it does not allow is reusing the same source for multiple storage pools.
The LVM storage driver has the specific `lvm.vg.force_reuse` configuration key for this purpose.

<a id="extension-instance-force-delete"></a>

## `instance_force_delete`

This adds support for a `force` query parameter to the `DELETE /1.0/instances/{name}` endpoint. When set, running instances will be forcibly stopped before deletion.

<a id="extension-operation-metadata-entity-name"></a>

<a id="extension-operation-metadata-entity-url"></a>

## `operation_metadata_entity_url`

Each [operation event](events.md#ref-events-operation) has a `resources` field that contains URLs of LXD entities that the operation depends on.

When an instance, instance backup, or storage volume backup is created, it is not strictly required for the caller to provide the name of the new resource.
In this case, the URL of the expected resource is added to the resources map for clients to inspect and use.
The `resources` field then contains both a dependency of the operation, and the newly created resource (which may not exist yet).

To improve consistency, this API extension adds an `entity_url` field to operation metadata.
The field contains the expected URL of the created entity.
The field is only included when a resource is being created asynchronously (operation response), and where it is not required for the entity name to be specified by the client.
For synchronous resource creation, clients should inspect the `Location` header.

The `resources` field should no longer be relied upon for this information.

<a id="extension-instance-boot-mode"></a>

## `instance_boot_mode`

Introduces the new [`boot.mode`](reference/instance_options.md#instance-boot:boot.mode) configuration key to control the VM boot firmware mode.
This replaces the removed `security.csm` and `security.secureboot` settings.

The new setting accepts:

* `uefi-secureboot` (default) - Use UEFI firmware with secure boot enabled
* `uefi-nosecureboot` - Use UEFI firmware with secure boot disabled
* `bios` - Use legacy BIOS firmware (SeaBIOS), `x86_64` (`amd64`) only

<a id="extension-auth-bearer-lxd"></a>

<a id="extension-auth-bearer"></a>

## `auth_bearer`

Adds new identity type `bearer` that allows authentication with the LXD API using bearer tokens.
See [LXD bearer tokens](authentication.md#authentication-bearer).

If applicable, the endpoint `/1.0/auth/identities/current` now also exposes the credential expiration time.
The `expires_at` field is set when the current identity is trusted and the authentication method is either `bearer` or `tls`.
In these cases, it reports the expiration time of the bearer token or the TLS certificate, respectively.

<a id="extension-vm-limits-max-bus-ports"></a>

## `vm_limits_max_bus_ports`

This introduces support for the [`limits.max_bus_ports`](reference/instance_options.md#instance-resource-limits:limits.max_bus_ports) configuration key for virtual machines. This option controls the maximum allowed number of user configurable devices requiring a dedicated PCI/PCIe port for a virtual machine.
This number includes both the devices attached before the instance start and the devices hotplugged at runtime.

<a id="extension-instances-state-selective-recursion"></a>

## `instances_state_selective_recursion`

Adds support for selective recursion when querying instances.

The API now supports selective state field fetching using semicolon-separated syntax in the `recursion` parameter:

* `recursion=2;fields=state.disk` - Fetch only disk information
* `recursion=2;fields=state.network` - Fetch only network information
* `recursion=2;fields=state.disk,state.network` - Fetch both disk and network
* `recursion=2;fields=` - Fetch no expensive state fields (disk and network skipped)
* `recursion=2` - Fetch all fields (default behavior)

The semicolon and equals signs must be URL-encoded when used in HTTP requests (`%3B` for `;` and `%3D` for `=`).

The `lxc list` command automatically optimizes queries based on requested columns.

<a id="extension-project-delete-operation"></a>

## `project_delete_operation`

The [forced project deletion](#extension-projects-force-delete) API extension added support for forcibly deleting a project and all of its contents.
This can take a long time, but the `DELETE /1.0/projects/{name}` endpoint still returned a synchronous response.

This extension converts this endpoint to an asynchronous operation response.
As with the [storage and profile operation extension](#extension-storage-and-profile-operations), this extension is forward compatible only.

<a id="extension-gpu-cdi-amd"></a>

## `gpu_cdi_amd`

Adds support for using the Container Device Interface (CDI) specification to configure AMD GPU passthrough in LXD containers. The `id` field of GPU devices now accepts CDI identifiers (for example, `amd.com/gpu=gpu{INDEX}`) for containers, in addition to DRM card IDs.

<a id="extension-instance-refresh-config"></a>

## `instance_refresh_config`

Ensures that instance `copy --refresh` operations apply target config/profile/device updates server-side.

This applies to both direct copies and migration-based refresh operations.

During refresh, the server applies the target instance configuration from the request (including config, devices, and profiles) before the data transfer completes.
The request payload is treated as the full desired writable target configuration for the refresh update.
The server does not merge or preserve omitted target keys automatically.
Clients must include any target values that should remain on the destination after refresh.

<a id="extension-clustering-control-plane"></a>

## `clustering_control_plane`

Adds a new `control-plane` cluster member role that can be manually assigned to designate which members participate in Raft consensus. Control plane mode is inactive by default until the number of members assigned the `control-plane` role reaches 3 or more. During this inactive period, all cluster members are eligible for automatic promotion to database roles. Once control plane mode activates, only members with the `control-plane` role are eligible to become voters, standbys, or the database leader. Members without the `control-plane` role are automatically assigned the `RAFT_SPARE` role and are excluded from automatic promotion to database roles, enabling safe scaling of cluster members without affecting quorum.

If fewer than 3 members are assigned the `control-plane` role, all members remain eligible for automatic promotion to database roles, maintaining backwards compatibility with existing cluster behavior.

The `control-plane` role is displayed alongside the database role (`database-leader`, `database-voter`, `database-standby`) for members participating in Raft.

The role also controls internal event routing:

- When control plane mode is active, members with the `control-plane` role act as event hubs.
- When control plane mode is inactive, the cluster uses full-mesh event connectivity.

These behaviors are applied asynchronously on heartbeat. Role changes are detected on the next heartbeat cycle, and control-plane mode activation or deactivation triggers automatic role rebalancing.

The `event-hub` role is deprecated in favor of the functionally equivalent `control-plane` role.

For more information, see [LXD cluster roles](reference/dqlite-internals.md#dqlite-internals-lxd-cluster-roles) and [Use control plane mode](howto/cluster_manage.md#cluster-manage-control-plane).

<a id="extension-storage-remote-drop-source"></a>

## `storage_remote_drop_source`

Starting with this extension, support for the `source` configuration key in both the Ceph RBD `ceph` and CephFS `cephfs` drivers is dropped.
This ensures the storage pool configuration is done consistently across all remote drivers.

For Ceph RBD use the `ceph.osd.pool_name` configuration key.
For CephFS use the `cephfs.path` configuration key.

<a id="extension-storage-ceph-use-rbd-defaults"></a>

## `storage_ceph_use_rbd_defaults`

Starting with this extension, new volumes (and clones) in Ceph RBD (`ceph`) pools are no longer created with only `--image-feature layering`.
Instead the default RBD features of the respective Ceph cluster are used implicitly.
This also applies to new volumes in already existing Ceph RBD storage pools.

In case the `ceph.rbd.features` configuration key is already set the pool, new volumes continue using this list of features and won’t
use the defaults set in the Ceph cluster.

<a id="extension-bulk-operations"></a>

## `bulk_operations`

Adds a `recursion=2` mode to `GET /1.0/operations`, enabling retrieval of parent-child relationships between operations. The parent-child operations are now also returned by the `GET /1.0/operations/{id}` endpoint when `recursion=1` is specified.

<a id="extension-ovn-dynamic-northbound-connection"></a>

## `ovn_dynamic_northbound_connection`

Starting with this extension, if the [`network.ovn.northbound_connection`](server.md#server-miscellaneous:network.ovn.northbound_connection) server configuration is not specified, LXD dynamically determines the OVN Northbound database connection string based on the environment.
If the MicroOVN snap is used, LXD reads the configuration from the MicroOVN `ovn.env` file. Otherwise, it defaults to using the `unix:/var/run/ovn/ovnnb_db.sock` socket.

<a id="extension-storage-zfs-promote"></a>

## `storage_zfs_promote`

A [`zfs.promote`](reference/storage_zfs.md#storage-zfs-volume-conf:zfs.promote) configuration key was introduced.

It’s a Boolean that defaults to `false` and that when set to `true` instructs LXD to ZFS promote the volume being created (or re-created) from a clone.

This is primarily useful when combined with the `initial.` `disk` device configuration options, as it allows controlling ZFS promotion when creating instances from other instances.

<a id="extension-storage-and-network-operations"></a>

## `storage_and_network_operations`

Storage pool and network endpoints that were previously synchronous now return background operations. This affects create, update, delete, and rename actions on storage pools, networks, network ACLs, network zones, network zone records, network forwards, network load balancers, network peers, and storage buckets (including bucket keys).

Clients should check for this extension and handle the asynchronous response by waiting on the returned operation. Operation metadata may include additional data, such as storage bucket admin credentials on bucket creation.

<a id="extension-gpu-cdi-hotplug"></a>

## `gpu_cdi_hotplug`

Adds support for hotplugging GPU devices into containers when using [CDI mode](reference/devices_gpu.md#gpu-physical-cdi).

<a id="extension-image-extended-metadata"></a>

## `image_extended_metadata`

Adds `release_codename` and `release_title` fields to the `api.Image` struct. These fields are optional and are populated from the SimpleStreams index when available.

Also updates the generated image description for SimpleStreams images to include variant if available. The image creation date and architecture are no longer used for image description.

<a id="extension-cluster-links"></a>

## `cluster_links`

Cluster links enable secure, authenticated communication between separate LXD clusters using mutual TLS certificates.
See [Cluster links](explanation/clusters.md#exp-cluster-links) for more information.

This introduces the cluster links API and identity type.

This includes the following new endpoints (see [REST API](rest-api.md#rest-api) for details):

* [`GET /1.0/cluster/links/<name>`](/api/#/cluster-links/cluster_link_get)
* [`GET /1.0/cluster/links`](/api/#/cluster-links/cluster_links_get)
* [`GET /1.0/cluster/links/<name>/state`](/api/#/cluster-links/cluster_link_state_get)
* [`PUT /1.0/cluster/links/<name>`](/api/#/cluster-links/cluster_link_put)
* [`PATCH /1.0/cluster/links/<name>`](/api/#/cluster-links/cluster_link_patch)
* [`POST /1.0/cluster/links`](/api/#/cluster-links/cluster_links_post)
* [`POST /1.0/cluster/links/<name>`](/api/#/cluster-links/cluster_link_post)
* [`DELETE /1.0/cluster/links/<name>`](/api/#/cluster-links/cluster_link_delete)

<a id="extension-replicators"></a>

## replicators

This introduces the replicators API. Replicators are used to replicate project instances across clusters.

This includes the following new endpoints (see [REST API](rest-api.md#rest-api) for details):

* [`GET /1.0/replicators`](/api/#/replicators/replicators_get)
* [`GET /1.0/replicators/<name>`](/api/#/replicators/replicator_get)
* [`POST /1.0/replicators`](/api/#/replicators/replicators_post)
* [`PUT /1.0/replicators/<name>`](/api/#/replicators/replicator_put)
* [`PATCH /1.0/replicators/<name>`](/api/#/replicators/replicator_patch)
* [`POST /1.0/replicators/<name>`](/api/#/replicators/replicator_post)
* [`DELETE /1.0/replicators/<name>`](/api/#/replicators/replicator_delete)
* [`GET /1.0/replicators/<name>/state`](/api/#/replicators/replicator_state_get)

<a id="extension-event-security"></a>

## `event_security`

Adds a new `security` event type conforming to OWASP security event logging guidelines.
Security events are accessible via `GET /1.0/events?type=security` and can be routed to Grafana Loki by adding `security` to the `loki.types` server configuration.

<a id="extension-storage-driver-powerstore"></a>

## `storage_driver_powerstore`

Adds a new `powerstore` storage driver which allows the consumption of storage volumes from a PowerStore storage array using iSCSI or Fibre Channel (FC).

The following pool level configuration keys have been added:

1. [`powerstore.gateway`](reference/storage_powerstore.md#storage-powerstore-pool-conf:powerstore.gateway)
2. [`powerstore.gateway.verify`](reference/storage_powerstore.md#storage-powerstore-pool-conf:powerstore.gateway.verify)
3. [`powerstore.user.name`](reference/storage_powerstore.md#storage-powerstore-pool-conf:powerstore.user.name)
4. [`powerstore.user.password`](reference/storage_powerstore.md#storage-powerstore-pool-conf:powerstore.user.password)
5. [`powerstore.mode`](reference/storage_powerstore.md#storage-powerstore-pool-conf:powerstore.mode)
6. [`powerstore.target`](reference/storage_powerstore.md#storage-powerstore-pool-conf:powerstore.target)

<a id="extension-oidc-device-client-id"></a>

## `oidc_device_client_id`

The [OIDC client secret configuration extension](#extension-oidc-client-secret) is used to configure LXD to send a
secret to the identity provider for authentication. It is not secure to make this secret public for consumption by the
LXD CLI (`lxc`). For this reason, if the client configured for LXD in the identity provider requires a secret, that
client cannot be used by CLI users.

This extension adds a new [`oidc.device.client.id`](server.md#server-oidc:oidc.device.client.id) configuration key for the CLI to use. An
administrator can create two clients in the identity provider, one for LXD UI requiring a secret (and ),
and one for the CLI that enables the device authorization grant and does not require a secret. The device client ID will
be public to the CLI, falling back to [`oidc.client.id`](server.md#server-oidc:oidc.client.id). This configuration option cannot be
set unless [`oidc.client.id`](server.md#server-oidc:oidc.client.id) is set.

<a id="extension-storage-nvme-tcp"></a>

## `storage_nvme_tcp`

Renames storage pool NVMe/TCP mode from `nvme` to `nvme/tcp`.

<a id="extension-project-replica-mode"></a>

## `project_replica_mode`

Adds a `replica_mode` field to projects and a new `PUT /1.0/projects/<name>/state` endpoint for promoting and demoting projects between leader and standby modes for replication.

<a id="extension-cluster-links-used-by"></a>

## `cluster_links_used_by`

Adds a `used_by` field to `ClusterLink` resources, returned by `GET /1.0/cluster/links` (with `recursion=1`) and `GET /1.0/cluster/links/{name}`. The field lists URLs of entities that reference the cluster link, filtered by the caller’s view permissions.

<a id="extension-network-load-balancer-pool"></a>

## `network_load_balancer_pool`

This introduces the load balancer pools for OVN networks.
Pools are used to group instances to which a load balancer forwards traffic.

This includes the following new endpoints (see [REST API](rest-api.md#rest-api) for details):

* [`GET /1.0/networks/{networkName}/load-balancer-pools`](/api/#/network-load-balancer-pools/network_load_balancer_pools_get)
* [`POST /1.0/networks/{networkName}/load-balancer-pools`](/api/#/network-load-balancer-pools/network_load_balancer_pools_post)
* [`GET /1.0/networks/{networkName}/load-balancer-pools/{poolName}`](/api/#/network-load-balancer-pools/network_load_balancer_pool_get)
* [`PUT /1.0/networks/{networkName}/load-balancer-pools/{poolName}`](/api/#/network-load-balancer-pools/network_load_balancer_pool_put)
* [`DELETE /1.0/networks/{networkName}/load-balancer-pools/{poolName}`](/api/#/network-load-balancer-pools/network_load_balancer_pool_delete)

<a id="extension-clustering-evacuation-force"></a>

## `clustering_evacuation_force`

Adds a `force` field to `POST /1.0/cluster/members/{name}/state` when performing an `evacuate` action.

When `force` is set to `true`, LXD skips the quorum safety check that otherwise would not allow you to evacuate an online raft voter when the remaining online voters would fall below the required majority.


# index.html.md

<a id="projects"></a>

# Projects

LXD projects enable grouping related instances together, as well as setting up multi-user environments where users are restricted to certain projects.

* [Create and configure projects](howto/projects_create.md)
* [Work with projects](howto/projects_work.md)
* [Confine users to projects](howto/projects_confine.md)

## Related topics

Explanation:

- [Instances grouping with projects](explanation/projects.md#exp-projects)

Reference:

- [Project configuration](reference/projects.md#ref-projects)


# index.html.md

<a id="run-commands"></a>

# How to run commands in an instance

LXD allows to run commands inside an instance using the LXD client or the API, without needing to access the instance through the network.

For containers, this always works and is handled directly by LXD.
For virtual machines, the `lxd-agent` process must be running inside of the virtual machine for this to work.

#### NOTE
The UI does not currently support sending commands to an instance.
However, it provides a terminal that gives you [shell access to your instance](#run-commands-shell).

## Run commands inside your instance

CLI

To run a single command from the terminal of the host machine, use the [`lxc exec`](reference/manpages/lxc/exec.md#lxc-exec-md) command:

```none
lxc exec <instance_name> -- <command>
```

For example, enter the following command to update the package list on your container:

```none
lxc exec my-instance -- apt-get update
```

API

Send a POST request to the instance’s `exec` endpoint to run a single command from the terminal of the host machine:

```none
lxc query --request POST /1.0/instances/<instance_name>/exec --data '{
  "command": [ "<command>" ]
}'
```

For example, enter the following command to update the package list on your container:

```none
lxc query --request POST /1.0/instances/my-instance/exec --data '{
  "command": [ "apt-get", "update" ]
}'
```

See [`POST /1.0/instances/{name}/exec`](/api/#/instances/instance_exec_post) for more information.

### Execution mode

LXD can execute commands either interactively or non-interactively.

CLI

In interactive mode, a pseudo-terminal device (PTS) is used to handle input (stdin) and output (stdout, stderr).
This mode is automatically selected by the CLI if connected to a terminal emulator (and not run from a script).
To force interactive mode, add either `--force-interactive` or `--mode interactive` to the command.

In non-interactive mode, pipes are allocated instead (one for each of stdin, stdout and stderr).
This method allows running a command and properly getting separate stdin, stdout and stderr as required by many scripts.
To force non-interactive mode, add either `--force-noninteractive` or `--mode non-interactive` to the command.

API

In both modes, the operation creates a control socket that can be used for out-of-band communication with LXD.
You can send signals and window sizing information through this socket.

Interactive mode
: In interactive mode, the operation creates an additional single bi-directional WebSocket.
  To force interactive mode, add `"interactive": true` and `"wait-for-websocket": true` to the request data.
  For example:
  <br/>
  ```none
  lxc query --request POST /1.0/instances/my-instance/exec --data '{
    "command": [ "/bin/bash" ],
    "interactive": true,
    "wait-for-websocket": true
  }'
  ```

Non-interactive mode
: In non-interactive mode, the operation creates three additional WebSockets: one each for stdin, stdout, and stderr.
  To force non-interactive mode, add `"interactive": false` to the request data.
  <br/>
  When running a command in non-interactive mode, you can instruct LXD to record the output of the command.
  To do so, add `"record-output": true` to the request data.
  You can then send a request to the `exec-output` endpoint to retrieve the list of files that contain command output:
  <br/>
  ```none
  lxc query --request GET /1.0/instances/<instance_name>/logs/exec-output
  ```
  <br/>
  To display the output of one of the files, send a request to one of the files:
  <br/>
  ```none
  lxc query --request GET /1.0/instances/<instance_name>/logs/exec-output/<record-output-file>
  ```
  <br/>
  When you don’t need the command output anymore, you can delete it:
  <br/>
  ```none
  lxc query --request DELETE /1.0/instances/<instance_name>/logs/exec-output/<record-output-file>
  ```
  <br/>
  See [`GET /1.0/instances/{name}/logs/exec-output`](/api/#/instances/instance_exec-output_get), [`GET /1.0/instances/{name}/logs/exec-output/{filename}`](/api/#/instances/instance_exec-output_get), and [`DELETE /1.0/instances/{name}/logs/exec-output/{filename}`](/api/#/instances/instance_exec-output_delete) for more information.

### User, groups and working directory

LXD has a policy not to read data from within the instances or trust anything that can be found in the instance.
Therefore, LXD does not parse files like `/etc/passwd`, `/etc/group` or `/etc/nsswitch.conf` to handle user and group resolution.

As a result, LXD doesn’t know the home directory for the user or the supplementary groups the user is in.

By default, LXD runs commands as `root` (UID 0) with the default group (GID 0) and the working directory set to `/root`.
You can override the user, group and working directory by specifying absolute values.

CLI

You can override the default settings by adding the following flags to the [`lxc exec`](reference/manpages/lxc/exec.md#lxc-exec-md) command:

- `--user` - the user ID for running the command
- `--group` - the group ID for running the command
- `--cwd` - the directory in which the command should run

API

You can override the default settings by adding the following fields to the request data:

- `"user": <user_ID>` - the user ID for running the command
- `"group": <group_ID>` - the group ID for running the command
- `"cwd": "<directory>"` - the directory in which the command should run

### Environment

You can pass environment variables to an exec session in the following two ways:

Set environment variables as instance options
: CLI
  <br/>
  To set the `<ENVVAR>` environment variable to `<value>` in the instance, set the `environment.<ENVVAR>` instance option (see [`environment.*`](reference/instance_options.md#instance-miscellaneous:environment.*)):
  <br/>
  ```none
  lxc config set <instance_name> environment.<ENVVAR>=<value>
  ```
  <br/>
  API
  <br/>
  To set the `<ENVVAR>` environment variable to `<value>` in the instance, set the `environment.<ENVVAR>` instance option (see [`environment.*`](reference/instance_options.md#instance-miscellaneous:environment.*)):
  <br/>
  ```none
  lxc query --request PATCH /1.0/instances/<instance_name> --data '{
    "config": {
      "environment.<ENVVAR>": "<value>"
    }
  }'
  ```
  <br/>
  UI
  <br/>
  To set the `<ENVVAR>` environment variable to `<value>` in the instance, go to the instance detail page, switch to the Configuration tab and select YAML configuration.
  Then click Edit instance.
  <br/>
  Add the `environment.<ENVVAR>` configuration under the `config` section.
  For example:
  <br/>
  ```none
  config:
    environment.<ENVVAR>: "<value>"
  ```
  <br/>
  Click Save changes.

Pass environment variables to the exec command
: CLI
  <br/>
  To pass an environment variable to the exec command, use the `--env` flag.
  For example:
  <br/>
  ```none
  lxc exec <instance_name> --env <ENVVAR>=<value> -- <command>
  ```
  <br/>
  API
  <br/>
  To pass an environment variable to the exec command, add an `environment` field to the request data.
  For example:
  <br/>
  ```none
  lxc query --request POST /1.0/instances/<instance_name>/exec --data '{
    "command": [ "<command>" ],
    "environment": {
      "<ENVVAR>": "<value>"
    }
  }'
  ```

In addition, LXD sets the following default values (unless they are passed in one of the ways described above):

| Variable name   | Condition               | Value                                                                                                                                                                                                |
|-----------------|-------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `PATH`          | -                       | Concatenation of:<br/><br/>- `/usr/local/sbin`<br/>- `/usr/local/bin`<br/>- `/usr/sbin`<br/>- `/usr/bin`<br/>- `/sbin`<br/>- `/bin`<br/>- `/snap` (if applicable)<br/>- `/etc/NIXOS` (if applicable) |
| `LANG`          | -                       | `C.UTF-8`                                                                                                                                                                                            |
| `HOME`          | running as root (UID 0) | `/root`                                                                                                                                                                                              |
| `USER`          | running as root (UID 0) | `root`                                                                                                                                                                                               |

<a id="run-commands-shell"></a>

## Get shell access to your instance

If you want to run commands directly in your instance, run a shell command inside it.

CLI

Enter the following command (assuming that the `/bin/bash` command exists in your instance):

```none
lxc exec <instance_name> -- /bin/bash
```

API

Enter the following command (assuming that the `/bin/bash` command exists in your instance):

```none
lxc query --request POST /1.0/instances/<instance_name>/exec --data '{
  "command": [ "/bin/bash" ]
}'
```

UI

Navigate to the instance detail page and switch to the Terminal tab to access the shell.

By default, you are logged in as the `root` user.
If you want to log in as a different user, enter the following command:

CLI

```none
lxc exec <instance_name> -- su --login <user_name>
```

To exit the instance shell, enter `exit` or press `Ctrl`+`d`.

API

```none
lxc query --request POST /1.0/instances/<instance_name>/exec --data '{
  "command": [ "su", "--login", "<user_name>" ]
}'
```

UI

```none
su --login <user_name>
```

To exit the user shell and go back to the root shell, enter `exit` or press `Ctrl`+`d`.

#### NOTE
Depending on the operating system that you run in your instance, you might need to create a user first.


# index.html.md

<a id="devices-unix-hotplug"></a>

# Type: `unix-hotplug`


            <p class="youtube_link">
              <a href="https://www.youtube.com/watch?v=C2e3LD5wLI8" target="_blank">
                <span title="LXD Unix devices - YouTube" class="play_icon">▶</span>
                <span title="LXD Unix devices - YouTube">Watch on YouTube</span>
              </a>
            </p>
        
#### NOTE
The `unix-hotplug` device type is supported for containers.
It supports hotplugging.

Unix hotplug devices make the requested Unix device appear as a device in the container (under `/dev`).
If the device exists on the host system, you can read from it and write to it.

The implementation depends on `systemd-udev` to be run on the host.

## Device options

`unix-hotplug` devices have the following device options:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="device-unix-hotplug-device-conf:gid"></a>
`gid`

GID of the device owner in the container

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-unix-hotplug-device-conf:gid)

| **Key:**     | `gid`   |
|--------------|---------|
| **Type:**    | integer |
| **Default:** | `0`     |

<a id="device-unix-hotplug-device-conf:mode"></a>
`mode`

Mode of the device in the container

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-unix-hotplug-device-conf:mode)

| **Key:**     | `mode`   |
|--------------|----------|
| **Type:**    | integer  |
| **Default:** | `0660`   |

<a id="device-unix-hotplug-device-conf:ownership.inherit"></a>
`ownership.inherit`

Whether this device inherits ownership (GID and/or UID) from the host

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-unix-hotplug-device-conf:ownership.inherit)

| **Key:**     | `ownership.inherit`   |
|--------------|-----------------------|
| **Type:**    | bool                  |
| **Default:** | `false`               |

<a id="device-unix-hotplug-device-conf:productid"></a>
`productid`

Product ID of the Unix device

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-unix-hotplug-device-conf:productid)

| **Key:**    | `productid`   |
|-------------|---------------|
| **Type:**   | string        |

<a id="device-unix-hotplug-device-conf:required"></a>
`required`

Whether this device is required to start the container

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-unix-hotplug-device-conf:required)

| **Key:**     | `required`   |
|--------------|--------------|
| **Type:**    | bool         |
| **Default:** | `false`      |

The default is `false`, which means that all devices can be hotplugged.

<a id="device-unix-hotplug-device-conf:subsystem"></a>
`subsystem`

Subsystem of the Unix device

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-unix-hotplug-device-conf:subsystem)

| **Key:**    | `subsystem`   |
|-------------|---------------|
| **Type:**   | string        |

<a id="device-unix-hotplug-device-conf:uid"></a>
`uid`

UID of the device owner in the container

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-unix-hotplug-device-conf:uid)

| **Key:**     | `uid`   |
|--------------|---------|
| **Type:**    | integer |
| **Default:** | `0`     |

<a id="device-unix-hotplug-device-conf:vendorid"></a>
`vendorid`

Vendor ID of the Unix device

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-unix-hotplug-device-conf:vendorid)

| **Key:**    | `vendorid`   |
|-------------|--------------|
| **Type:**   | string       |

## Configuration examples

Add a `unix-hotplug` device to an instance by specifying its vendor ID, product ID, and/or subsystem:

```none
lxc config device add <instance_name> <device_name> unix-hotplug vendorid=<vendor_ID> productid=<product_ID> subsystem=<subsystem>
```

See [Configure devices](../howto/instances_configure.md#instances-configure-devices) for more information.


# index.html.md

<a id="storage-drivers"></a>

# Storage drivers

LXD supports several storage drivers for storing images, instances, and custom volumes. Where possible, LXD uses the advanced features of each driver to optimize operations.

Storage drivers are divided into local and non-local storage, based on their accessibility.

<a id="storage-drivers-features"></a>

## Feature comparison

Legend: ✅ supported, ❌ not supported, ➖ not applicable

<a id="storage-drivers-features-local"></a>

### Local storage features

| Feature                                                                         | Directory             | Btrfs   | LVM                   | ZFS                   |
|---------------------------------------------------------------------------------|-----------------------|---------|-----------------------|-----------------------|
| [Optimized image storage](#storage-optimized-image-storage)                     | ❌                     | ✅       | ✅                     | ✅                     |
| [Optimized instance creation](#storage-optimized-instance-creation)             | ❌                     | ✅       | ✅                     | ✅                     |
| [Optimized snapshot creation](#storage-optimized-snapshot-creation)             | ❌                     | ✅       | ✅                     | ✅                     |
| [Optimized backup (import/export)](#storage-optimized-backup)                   | ❌                     | ✅       | ❌                     | ✅                     |
| [Optimized volume transfer](#storage-optimized-volume-transfer)                 | ❌                     | ✅       | ❌                     | ✅                     |
| [Optimized volume refresh](#storage-optimized-volume-refresh)                   | ❌                     | ✅       | ✅<sup>[1](#id5)</sup> | ✅                     |
| [Copy-on-write](#storage-copy-on-write)                                         | ❌                     | ✅       | ✅                     | ✅                     |
| [Block-based](#storage-block-based)                                             | ❌                     | ❌       | ✅                     | ❌                     |
| [Instant cloning](#storage-instant-cloning)                                     | ❌                     | ✅       | ✅                     | ✅                     |
| [Storage driver usable inside a container](#storage-driver-usable-in-container) | ✅                     | ✅       | ❌                     | ✅<sup>[2](#id6)</sup> |
| [Restore from older snapshots (not latest)](#storage-restore-older-snapshots)   | ✅                     | ✅       | ✅                     | ❌                     |
| [Storage quotas](#storage-quotas)                                               | ✅<sup>[3](#id7)</sup> | ✅       | ✅                     | ✅                     |
| [Available on lxd init](#storage-available-init)                                | ✅                     | ✅       | ✅                     | ✅                     |
| [Volume recovery](#storage-volume-recovery)                                     | ✅                     | ✅       | ✅                     | ✅                     |

<a id="storage-drivers-features-nonlocal"></a>

### Non-local storage features

| Feature                                                                         | Ceph RBD               | CephFS   | Ceph Object   | Dell PowerFlex         | Dell PowerStore        | Pure Storage           | HPE Alletra            |
|---------------------------------------------------------------------------------|------------------------|----------|---------------|------------------------|------------------------|------------------------|------------------------|
| [Optimized image storage](#storage-optimized-image-storage)                     | ✅                      | ➖        | ➖             | ❌                      | ✅                      | ✅                      | ✅                      |
| [Optimized instance creation](#storage-optimized-instance-creation)             | ✅                      | ➖        | ➖             | ❌                      | ✅                      | ✅                      | ✅                      |
| [Optimized snapshot creation](#storage-optimized-snapshot-creation)             | ✅                      | ✅        | ➖             | ✅                      | ✅                      | ✅                      | ✅                      |
| [Optimized backup (import/export)](#storage-optimized-backup)                   | ❌                      | ➖        | ➖             | ❌                      | ❌                      | ❌                      | ❌                      |
| [Optimized volume transfer](#storage-optimized-volume-transfer)                 | ✅<sup>[4](#id15)</sup> | ➖        | ➖             | ❌                      | ❌                      | ❌                      | ❌                      |
| [Optimized volume refresh](#storage-optimized-volume-refresh)                   | ✅<sup>[5](#id16)</sup> | ➖        | ➖             | ❌                      | ✅<sup>[6](#id17)</sup> | ✅<sup>[6](#id17)</sup> | ✅<sup>[6](#id17)</sup> |
| [Copy-on-write](#storage-copy-on-write)                                         | ✅                      | ✅        | ➖             | ✅                      | ✅                      | ✅                      | ✅                      |
| [Block-based](#storage-block-based)                                             | ✅                      | ❌        | ➖             | ✅                      | ✅                      | ✅                      | ✅                      |
| [Instant cloning](#storage-instant-cloning)                                     | ✅                      | ✅        | ➖             | ❌                      | ✅                      | ✅                      | ❌                      |
| [Storage driver usable inside a container](#storage-driver-usable-in-container) | ❌                      | ➖        | ➖             | ❌                      | ❌                      | ❌                      | ❌                      |
| [Restore from older snapshots (not latest)](#storage-restore-older-snapshots)   | ✅                      | ✅        | ➖             | ✅                      | ✅                      | ✅                      | ✅                      |
| [Storage quotas](#storage-quotas)                                               | ✅                      | ✅        | ✅             | ✅                      | ✅                      | ✅                      | ✅                      |
| [Available on lxd init](#storage-available-init)                                | ✅                      | ❌        | ❌             | ❌                      | ❌                      | ❌                      | ❌                      |
| [Object storage](#storage-object-storage)                                       | ❌                      | ❌        | ✅             | ❌                      | ❌                      | ❌                      | ❌                      |
| [Volume recovery](#storage-volume-recovery)                                     | ✅                      | ✅        | ✅             | ✅<sup>[7](#id18)</sup> | ❌                      | ✅<sup>[7](#id18)</sup> | ❌                      |

For driver-specific information and configuration options, see the pages for the individual drivers, linked below.

<a id="storage-drivers-local"></a>

## Local

LXD provides drivers for the following types of local storage:

* [Directory - `dir`](storage_dir.md)
* [Btrfs - `btrfs`](storage_btrfs.md)
* [LVM - `lvm`](storage_lvm.md)
* [ZFS - `zfs`](storage_zfs.md)

A local volume resides on the storage pool of a single LXD server and is only accessible to instances running on that server. In a cluster, other members cannot access local volumes directly.

<a id="storage-drivers-nonlocal"></a>

## Non-local

LXD supports three categories of non-local storage drivers, described below.

<a id="storage-drivers-remote"></a>

### Remote

LXD provides drivers for the following types of remote storage:

* [Ceph RBD - `ceph`](storage_ceph.md)
* [Dell PowerFlex - `powerflex`](storage_powerflex.md)
* [Dell PowerStore - `powerstore`](storage_powerstore.md)
* [Pure Storage - `pure`](storage_pure.md)
* [HPE Alletra - `alletra`](storage_alletra.md)

A remote volume is stored on a storage backend that supports cluster-wide access. It is a block volume rather than a shared file system. A remote volume can be attached from any cluster member, but concurrent access by multiple instances or members is not allowed by default and not considered safe. Even when concurrent attachment is allowed (for example, with the volume’s `security.shared` option enabled), it can still risk data corruption.

Compared to local storage, remote pools make [instance migration](../howto/instances_migrate.md#howto-instances-migrate) faster because the instance’s root volume can be re-attached from another cluster member without copying the disk data. With local storage, the root disk must be transferred over the network during migration, which takes more time.

<a id="storage-drivers-shared"></a>

### Shared

LXD provides the following driver for shared storage:

* [CephFS - `cephfs`](storage_cephfs.md)

Like remote volumes, shared volumes are accessible cluster-wide. Unlike remote volumes, shared volumes can be mounted concurrently by multiple instances or cluster members while remaining safe for concurrent access. Shared pools only support custom filesystem volumes; they cannot host instance root volumes or custom block volumes.

<a id="storage-drivers-object"></a>

### Object storage backend

LXD provides the following driver for an object storage backend:

* [Ceph Object - `cephobject`](storage_cephobject.md)

Ceph Object is a dedicated object storage backend that exposes buckets over HTTP(S). It uses the S3-compatible API and stores data as discrete objects instead of mounted volumes. Like shared storage, using an object storage backend allows concurrent access by multiple instances across the cluster.

<a id="storage-drivers-recommended-setup"></a>

## Recommended setup

The two best options for use with LXD are ZFS (local) and Ceph (non-local).

Whenever possible, dedicate a full disk or partition to your LXD storage pool. LXD allows you to create loop-based storage, but this isn’t recommended for production use. See [Data storage location](../explanation/storage.md#storage-location) for more information.

The [Directory](storage_dir.md#storage-dir) backend should be considered as a last resort option. It supports all main LXD features, but is slow and inefficient because it cannot perform instant copies or snapshots. Therefore, it constantly copies the instance’s full storage.

<a id="storage-drivers-security"></a>

## Security considerations

Currently, the Linux kernel might silently ignore mount options and not apply them when a block-based file system (for example, `ext4`) is already mounted with different mount options.

This means when dedicated disk devices are shared between different storage pools with different mount options set, the second mount might not have the expected mount options.

This becomes security relevant when, for example, one storage pool is supposed to provide `acl` support and the second one is supposed to not provide `acl` support.

For this reason, it is currently recommended to either have dedicated disk devices per storage pool or to ensure that all storage pools that share the same dedicated disk device use the same mount options.

<a id="storage-drivers-features-reference"></a>

## Features reference

<a id="storage-optimized-image-storage"></a>

### Optimized image storage

Most LXD storage drivers provide an optimized image storage format. To make instance creation near instantaneous, LXD clones a pre-made image volume when creating an instance rather than unpacking the image tarball from scratch.

To prevent preparing such a volume on a storage pool that might never be used with that image, the volume is generated on demand. Therefore, the first instance takes longer to create than subsequent ones.

<a id="storage-optimized-instance-creation"></a>

### Optimized instance creation

Some storage drivers can create instances by cloning an existing volume rather than copying all data, which reduces the amount of data that must be written.

<a id="storage-optimized-snapshot-creation"></a>

### Optimized snapshot creation

Some storage drivers can create snapshots without copying full volumes. This optimizes speed and resources compared to full-copy snapshots.

<a id="storage-optimized-backup"></a>

### Optimized backup (import/export)

Some storage drivers support LXD’s optimized backup path when exporting and importing instance or volume backups. Optimized exports are usually faster, and snapshots are stored as deltas from the main volume.

<a id="storage-optimized-volume-transfer"></a>

### Optimized volume transfer

Btrfs, ZFS, and Ceph RBD have an internal send/receive mechanism that allows for optimized volume transfer.

LXD uses this optimized transfer when transferring instances and snapshots between storage pools that use the same storage driver, if the storage driver supports optimized transfer and the optimized transfer is actually quicker.
Otherwise, LXD uses `rsync` to transfer container and file system volumes, or raw block transfer to transfer virtual machine and custom block volumes.

The optimized transfer uses the underlying storage driver’s native functionality for transferring data, which is usually faster than using `rsync` or raw block transfer.

<a id="storage-optimized-volume-refresh"></a>

### Optimized volume refresh

The full potential of the optimized transfer becomes apparent when refreshing a copy of an instance or custom volume that uses periodic snapshots.
If the optimized transfer isn’t supported by the driver or its implementation of volume refresh, instead of the delta, the entire volume including its snapshot(s) will be copied using either `rsync` or raw block transfer. LXD will try to keep the overhead low by transferring only the volume itself or any snapshots that are missing on the target.

When optimized refresh is available for an instance or custom volume, LXD bases the refresh on the latest snapshot, which means:

- When you take a first snapshot and refresh the copy, the transfer will take roughly the same time as a full copy.
  LXD transfers the new snapshot and the difference between the snapshot and the main volume.
- For subsequent snapshots, the transfer is considerably faster.
  LXD does not transfer the full new snapshot, but only the difference between the new snapshot and the latest snapshot that already exists on the target.
- When refreshing without a new snapshot, LXD transfers only the differences between the main volume and the latest snapshot on the target.
  This transfer is usually faster than using `rsync` (as long as the latest snapshot is not too outdated).

On the other hand, refreshing copies of instances without snapshots (either because the instance doesn’t have any snapshots or because the refresh uses the `--instance-only` flag) would actually be slower than using `rsync` or raw block transfer.
In such cases, the optimized transfer would transfer the difference between the (non-existent) latest snapshot and the main volume, thus the full volume.
Therefore, LXD uses `rsync` or raw block transfer instead of the optimized transfer for refreshes without snapshots.

<a id="storage-copy-on-write"></a>

### Copy-on-write

Copy-on-write (CoW) means the storage driver can share unchanged data between a volume and its snapshots. Only changed blocks are written to new locations, which reduces duplication and can improve snapshot performance.

<a id="storage-block-based"></a>

### Block-based

Block-based storage presents volumes as block devices rather than mounted file systems. If a file system is needed, LXD can format the block volume for containers and custom file system volumes, or the instance can format it (for example, for virtual machines). See [Pure Storage](storage_pure.md#storage-pure), [HPE Alletra](storage_alletra.md#storage-alletra), and [Ceph RBD](storage_ceph.md#storage-ceph) for driver-specific details.

<a id="storage-instant-cloning"></a>

### Instant cloning

Instant cloning means LXD can quickly create a new volume by cloning an existing one without copying all data.

<a id="storage-driver-usable-in-container"></a>

### Storage driver usable inside a container

Some storage drivers can be used when LXD itself is running inside a container. Drivers that cannot be used inside a container often need access to host capabilities or devices that containers normally don’t have, and other container limits can also apply.

<a id="storage-restore-older-snapshots"></a>

### Restore from older snapshots (not latest)

Indicates whether LXD can restore a volume or instance to a snapshot older than the most recent one. Some drivers only allow restoring to the latest snapshot.

<a id="storage-quotas"></a>

### Storage quotas

Shows whether the storage driver supports enforcing size limits on storage volumes.

<a id="storage-available-init"></a>

### Available on `lxd init`

Shows whether the storage driver can be selected during `lxd init` (interactive or preseed). Drivers that depend on external storage systems require those systems to be set up first.

<a id="storage-object-storage"></a>

### Object storage

Object storage provides access to data over HTTP(S). It stores data as discrete objects within buckets, making it ideal for unstructured data such as backups, images, and logs. Unlike volumes, object storage is not mounted to instances but accessed through APIs.

<a id="storage-volume-recovery"></a>

### Volume recovery

Shows whether [lxd recover](../howto/disaster_recovery.md#disaster-recovery) can re-discover and import existing volumes for the driver after a database loss. Some non-local storage drivers have limitations (see the table footnotes).

## Related topics

How-to guides:

- [Storage](../storage.md#storage)

Explanation:

- [Storage pools, volumes, and buckets](../explanation/storage.md#exp-storage)

---
* <a id='id5'>**[1]**</a> Requires [`lvm.use_thinpool`](storage_lvm.md#storage-lvm-pool-conf:lvm.use_thinpool) to be enabled. Only when refreshing local volumes.
* <a id='id6'>**[2]**</a> Requires [`zfs.delegate`](storage_zfs.md#storage-zfs-volume-conf:zfs.delegate) to be enabled.
* <a id='id7'>**[3]**</a> <!-- Include content from [storage_dir.md](storage_dir.md) -->  The `dir` driver supports storage quotas when running on either ext4 or XFS with project quotas enabled at the file system level.
* <a id='id15'>**[4]**</a> Volumes of type `block` will fall back to non-optimized transfer when migrating to an older LXD server that doesn’t yet support the `RBD_AND_RSYNC` migration type.
* <a id='id16'>**[5]**</a> Only for volumes of type `block`.
* <a id='id17'>**[6]**</a> Only when refreshing volumes on the same LXD server using the same storage array.
* <a id='id18'>**[7]**</a> Custom volumes can only be recovered when attached to an instance due to the use of transformed volume names.


# index.html.md

<a id="image-format"></a>

# Image format

Images contain a root file system and a metadata file that describes the image.
They can also contain templates for creating files inside an instance that uses the image.

Images can be packaged as either a unified image (single file) or a split image (two files).

## Content

Images for containers have the following directory structure:

```default
metadata.yaml
rootfs/
templates/
```

Images for VMs have the following directory structure:

```default
metadata.yaml
rootfs.img
templates/
```

For both instance types, the `templates/` directory is optional.

### Metadata

The `metadata.yaml` file contains information that is relevant to running the image in LXD.
It includes the following information:

```yaml
architecture: x86_64
creation_date: 1424284563
properties:
  description: Ubuntu 24.04 LTS Intel 64bit
  os: Ubuntu
  release: noble 24.04
templates:
  ...
```

The `architecture` and `creation_date` fields are mandatory.
The `properties` field contains a set of default properties for the image.
The `os`, `release`, `name` and `description` fields are commonly used, but are not mandatory.

The `templates` field is optional.
See [Templates (optional)](#image-format-templates) for information on how to configure templates.

### Root file system

For containers, the `rootfs/` directory contains a full file system tree of the root directory (`/`) in the container.

Virtual machines use a `rootfs.img` `qcow2` file instead of a `rootfs/` directory.
This file becomes the main disk device.

<a id="image-format-templates"></a>

### Templates (optional)

You can use templates to dynamically create files inside an instance.
To do so, configure template rules in the `metadata.yaml` file and place the template files in a `templates/` directory.

As a general rule, you should never template a file that is owned by a package or is otherwise expected to be overwritten by normal operation of an instance.

#### Template rules

For each file that should be generated, create a rule in the `metadata.yaml` file.
For example:

```yaml
templates:
  /etc/hosts:
    when:
      - create
      - rename
    template: hosts.tpl
    properties:
      foo: bar
  /etc/hostname:
    when:
      - start
    template: hostname.tpl
  /etc/network/interfaces:
    when:
      - create
    template: interfaces.tpl
    create_only: true
```

The `when` key can be one or more of:

- `create` - run at the time a new instance is created from the image
- `copy` - run when an instance is created from an existing one
- `start` - run every time the instance is started

The `template` key points to the template file in the `templates/` directory.

You can pass user-defined template properties to the template file through the `properties` key.

Set the `create_only` key if you want LXD to create the file if it doesn’t exist, but not overwrite an existing file.

#### Template files

Template files use the [Pongo2](https://www.schlachter.tech/solutions/pongo2-template-engine/) format.

They always receive the following context:

| Variable     | Type                           | Description                                                                         |
|--------------|--------------------------------|-------------------------------------------------------------------------------------|
| `trigger`    | `string`                       | Name of the event that triggered the template                                       |
| `path`       | `string`                       | Path of the file that uses the template                                             |
| `instance`   | `map[string]string`            | Key/value map of instance properties (name, architecture, privileged and ephemeral) |
| `config`     | `map[string]string`            | Key/value map of the instance’s configuration                                       |
| `devices`    | `map[string]map[string]string` | Key/value map of the devices assigned to the instance                               |
| `properties` | `map[string]string`            | Key/value map of the template properties specified in `metadata.yaml`               |

For convenience, the following functions are exported to the Pongo2 templates:

- `config_get("user.foo", "bar")` - Returns the value of `user.foo`, or `"bar"` if not set.

<a id="image-format-tarballs"></a>

## Image tarballs

LXD supports two LXD-specific image formats: a unified tarball and split tarballs.

These tarballs can be compressed.
LXD supports a wide variety of compression algorithms for tarballs.
However, for compatibility purposes, you should use `gzip` or `xz`.

<a id="image-format-unified"></a>

### Unified tarball

A unified tarball is a single tarball (usually `*.tar.xz`) that contains the full content of the image, including the metadata, the root file system and optionally the template files.

This is the format that LXD itself uses internally when publishing images.
It is usually easier to work with; therefore, you should use the unified format when creating LXD-specific images.

The image identifier for such images is the SHA-256 of the tarball.

<a id="image-format-split"></a>

### Split tarballs

A split image consists of two separate tarballs.
One tarball contains the metadata and optionally the template files (usually `*.tar.xz`), and the other contains the root file system (usually `*.squashfs` for containers or `*.qcow2` for virtual machines).

For containers, the root file system tarball can be SquashFS-formatted.
For virtual machines, the `rootfs.img` file always uses the `qcow2` format.
It can optionally be compressed using `qcow2`’s native compression.

This format is designed to allow for easy image building from existing non-LXD rootfs tarballs that are already available.
You should also use this format if you want to create images that can be consumed by both LXD and other tools.

The image identifier for such images is the SHA-256 of the concatenation of the metadata and root file system tarball (in that order).

## Related topics

How-to guides:

- [Images](../images.md#images)

Explanation:

- [Local and remote images](../image-handling.md#about-images)


# index.html.md

<a id="network-bridge"></a>

# Bridge network

As one of the possible network configuration types under LXD, LXD supports creating and managing network bridges.

<!-- Include start bridge intro -->

A network bridge creates a virtual L2 Ethernet switch that instance NICs can connect to, making it possible for them to communicate with each other and the host.
LXD bridges can leverage underlying native Linux bridges and Open vSwitch.

<!-- Include end bridge intro -->

The `bridge` network type allows to create an L2 bridge that connects the instances that use it together into a single network L2 segment.
Bridges created by LXD are managed, which means that in addition to creating the bridge interface itself, LXD also sets up a local `dnsmasq` process to provide DHCP, IPv6 route announcements and DNS services to the network.
By default, it also performs NAT for the bridge.

See [How to configure your firewall](../howto/network_bridge_firewalld.md#network-bridge-firewall) for instructions on how to configure your firewall to work with LXD bridge networks.

<!-- Include start MAC identifier note -->

#### NOTE
Static DHCP assignments depend on the client using its MAC address as the DHCP identifier.
This method prevents conflicting leases when copying an instance, and thus makes statically assigned leases work properly.

<!-- Include end MAC identifier note -->

## IPv6 prefix size

If you’re using IPv6 for your bridge network, you should use a prefix size of 64.

Larger subnets (i.e., using a prefix smaller than 64) should work properly too, but they aren’t typically that useful for .

Smaller subnets are in theory possible (when using stateful DHCPv6 for IPv6 allocation), but they aren’t properly supported by `dnsmasq` and might cause problems.
If you must create a smaller subnet, use static allocation or another standalone router advertisement daemon.

<a id="network-bridge-options"></a>

## Configuration options

The following configuration key namespaces are currently supported for the `bridge` network type:

- `bgp` (BGP peer configuration)
- `bridge` (L2 interface configuration)
- `dns` (DNS server and resolution configuration)
- `fan` (configuration specific to the Ubuntu FAN overlay)
- `ipv4` (L3 IPv4 configuration)
- `ipv6` (L3 IPv6 configuration)
- `security` (network ACL configuration)
- `raw` (raw configuration file content)
- `tunnel` (cross-host tunneling configuration)
- `user` (free-form key/value for user metadata)

#### NOTE
LXD uses the [CIDR notation](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing) where network subnet information is required, for example, `192.0.2.0/24` or `2001:db8::/32`. This does not apply to cases where a single address is required, for example, local/remote addresses of tunnels, NAT addresses or specific addresses to apply to an instance.

The following configuration options are available for the `bridge` network type:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="network-bridge-network-conf:bgp.ipv4.nexthop"></a>
`bgp.ipv4.nexthop`

Override the IPv4 next-hop for advertised prefixes

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:bgp.ipv4.nexthop)

| **Key:**       | `bgp.ipv4.nexthop`   |
|----------------|----------------------|
| **Type:**      | string               |
| **Default:**   | local address        |
| **Condition:** | BGP server           |
| **Scope:**     | local                |

<a id="network-bridge-network-conf:bgp.ipv6.nexthop"></a>
`bgp.ipv6.nexthop`

Override the IPv6 next-hop for advertised prefixes

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:bgp.ipv6.nexthop)

| **Key:**       | `bgp.ipv6.nexthop`   |
|----------------|----------------------|
| **Type:**      | string               |
| **Default:**   | local address        |
| **Condition:** | BGP server           |
| **Scope:**     | local                |

<a id="network-bridge-network-conf:bgp.peers.NAME.address"></a>
`bgp.peers.NAME.address`

Peer address (IPv4 or IPv6)

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:bgp.peers.NAME.address)

| **Key:**       | `bgp.peers.NAME.address`   |
|----------------|----------------------------|
| **Type:**      | string                     |
| **Condition:** | BGP server                 |
| **Scope:**     | global                     |

<a id="network-bridge-network-conf:bgp.peers.NAME.asn"></a>
`bgp.peers.NAME.asn`

Peer AS number

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:bgp.peers.NAME.asn)

| **Key:**       | `bgp.peers.NAME.asn`   |
|----------------|------------------------|
| **Type:**      | integer                |
| **Condition:** | BGP server             |
| **Scope:**     | global                 |

<a id="network-bridge-network-conf:bgp.peers.NAME.holdtime"></a>
`bgp.peers.NAME.holdtime`

Peer session hold time

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:bgp.peers.NAME.holdtime)

| **Key:**       | `bgp.peers.NAME.holdtime`   |
|----------------|-----------------------------|
| **Type:**      | integer                     |
| **Default:**   | `180`                       |
| **Condition:** | BGP server                  |
| **Required:**  | no                          |
| **Scope:**     | global                      |

Specify the hold time in seconds.

<a id="network-bridge-network-conf:bgp.peers.NAME.password"></a>
`bgp.peers.NAME.password`

Peer session password

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:bgp.peers.NAME.password)

| **Key:**       | `bgp.peers.NAME.password`   |
|----------------|-----------------------------|
| **Type:**      | string                      |
| **Default:**   | (no password)               |
| **Condition:** | BGP server                  |
| **Required:**  | no                          |
| **Scope:**     | global                      |

<a id="network-bridge-network-conf:bridge.driver"></a>
`bridge.driver`

Bridge driver

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:bridge.driver)

| **Key:**     | `bridge.driver`   |
|--------------|-------------------|
| **Type:**    | string            |
| **Default:** | `native`          |
| **Scope:**   | global            |

Possible values are `native` and `openvswitch`.

<a id="network-bridge-network-conf:bridge.external_interfaces"></a>
`bridge.external_interfaces`

Unconfigured network interfaces to include in the bridge

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:bridge.external_interfaces)

| **Key:**    | `bridge.external_interfaces`   |
|-------------|--------------------------------|
| **Type:**   | string                         |
| **Scope:**  | local                          |

Specify a comma-separated list of unconfigured network interfaces to include in the bridge.

<a id="network-bridge-network-conf:bridge.hwaddr"></a>
`bridge.hwaddr`

MAC address for the bridge

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:bridge.hwaddr)

| **Key:**    | `bridge.hwaddr`   |
|-------------|-------------------|
| **Type:**   | string            |
| **Scope:**  | global            |

<a id="network-bridge-network-conf:bridge.mode"></a>
`bridge.mode`

Bridge operation mode

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:bridge.mode)

| **Key:**     | `bridge.mode`   |
|--------------|-----------------|
| **Type:**    | string          |
| **Default:** | `standard`      |
| **Scope:**   | global          |

Possible values are `standard` and `fan`.

<a id="network-bridge-network-conf:bridge.mtu"></a>
`bridge.mtu`

Bridge MTU

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:bridge.mtu)

| **Key:**     | `bridge.mtu`                                                                                                  |
|--------------|---------------------------------------------------------------------------------------------------------------|
| **Type:**    | integer                                                                                                       |
| **Default:** | `1400` when tunnels are configured, otherwise `1500` if `bridge.mode=standard` or `1450` if `bridge.mode=fan` |
| **Scope:**   | global                                                                                                        |

The default value varies depending on whether the bridge uses a tunnel or a fan setup.

<a id="network-bridge-network-conf:dns.domain"></a>
`dns.domain`

Domain to advertise to DHCP clients and use for DNS resolution

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:dns.domain)

| **Key:**     | `dns.domain`   |
|--------------|----------------|
| **Type:**    | string         |
| **Default:** | `lxd`          |
| **Scope:**   | global         |

<a id="network-bridge-network-conf:dns.mode"></a>
`dns.mode`

DNS registration mode

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:dns.mode)

| **Key:**     | `dns.mode`   |
|--------------|--------------|
| **Type:**    | string       |
| **Default:** | `managed`    |
| **Scope:**   | global       |

Possible values are `none` for no DNS record, `managed` for LXD-generated static records, and `dynamic` for client-generated records.

<a id="network-bridge-network-conf:dns.search"></a>
`dns.search`

Full domain search list

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:dns.search)

| **Key:**     | `dns.search`       |
|--------------|--------------------|
| **Type:**    | string             |
| **Default:** | `dns.domain` value |
| **Scope:**   | global             |

Specify a comma-separated list of domains.

<a id="network-bridge-network-conf:dns.zone.forward"></a>
`dns.zone.forward`

DNS zone names for forward DNS records

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:dns.zone.forward)

| **Key:**    | `dns.zone.forward`   |
|-------------|----------------------|
| **Type:**   | string               |
| **Scope:**  | global               |

Specify a comma-separated list of DNS zone names.

<a id="network-bridge-network-conf:dns.zone.reverse.ipv4"></a>
`dns.zone.reverse.ipv4`

DNS zone name for IPv4 reverse DNS records

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:dns.zone.reverse.ipv4)

| **Key:**    | `dns.zone.reverse.ipv4`   |
|-------------|---------------------------|
| **Type:**   | string                    |
| **Scope:**  | global                    |

<a id="network-bridge-network-conf:dns.zone.reverse.ipv6"></a>
`dns.zone.reverse.ipv6`

DNS zone name for IPv6 reverse DNS records

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:dns.zone.reverse.ipv6)

| **Key:**    | `dns.zone.reverse.ipv6`   |
|-------------|---------------------------|
| **Type:**   | string                    |
| **Scope:**  | global                    |

<a id="network-bridge-network-conf:fan.overlay_subnet"></a>
`fan.overlay_subnet`

Subnet to use as the overlay for the FAN

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:fan.overlay_subnet)

| **Key:**       | `fan.overlay_subnet`   |
|----------------|------------------------|
| **Type:**      | string                 |
| **Default:**   | `240.0.0.0/8`          |
| **Condition:** | fan mode               |
| **Scope:**     | global                 |

Use CIDR notation.

<a id="network-bridge-network-conf:fan.underlay_subnet"></a>
`fan.underlay_subnet`

Subnet to use as the underlay for the FAN

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:fan.underlay_subnet)

| **Key:**       | `fan.underlay_subnet`             |
|----------------|-----------------------------------|
| **Type:**      | string                            |
| **Default:**   | initial value on creation: `auto` |
| **Condition:** | fan mode                          |
| **Scope:**     | global                            |

Use CIDR notation.

You can set the option to `auto` to use the default gateway subnet.

<a id="network-bridge-network-conf:ipv4.address"></a>
`ipv4.address`

IPv4 address for the bridge

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:ipv4.address)

| **Key:**       | `ipv4.address`                    |
|----------------|-----------------------------------|
| **Type:**      | string                            |
| **Default:**   | initial value on creation: `auto` |
| **Condition:** | standard mode                     |
| **Scope:**     | global                            |

Use CIDR notation.

You can set the option to `none` to turn off IPv4, or to `auto` to generate a new random unused subnet.

<a id="network-bridge-network-conf:ipv4.dhcp"></a>
`ipv4.dhcp`

Whether to allocate IPv4 addresses using DHCP

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:ipv4.dhcp)

| **Key:**       | `ipv4.dhcp`   |
|----------------|---------------|
| **Type:**      | bool          |
| **Default:**   | `true`        |
| **Condition:** | IPv4 address  |
| **Scope:**     | global        |

<a id="network-bridge-network-conf:ipv4.dhcp.expiry"></a>
`ipv4.dhcp.expiry`

When to expire DHCP leases

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:ipv4.dhcp.expiry)

| **Key:**       | `ipv4.dhcp.expiry`   |
|----------------|----------------------|
| **Type:**      | string               |
| **Default:**   | `1h`                 |
| **Condition:** | IPv4 DHCP            |
| **Scope:**     | global               |

<a id="network-bridge-network-conf:ipv4.dhcp.gateway"></a>
`ipv4.dhcp.gateway`

Address of the gateway for the IPv4 subnet

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:ipv4.dhcp.gateway)

| **Key:**       | `ipv4.dhcp.gateway`   |
|----------------|-----------------------|
| **Type:**      | string                |
| **Default:**   | IPv4 address          |
| **Condition:** | IPv4 DHCP             |
| **Scope:**     | global                |

<a id="network-bridge-network-conf:ipv4.dhcp.ranges"></a>
`ipv4.dhcp.ranges`

IPv4 ranges to use for DHCP

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:ipv4.dhcp.ranges)

| **Key:**       | `ipv4.dhcp.ranges`   |
|----------------|----------------------|
| **Type:**      | string               |
| **Default:**   | all addresses        |
| **Condition:** | IPv4 DHCP            |
| **Scope:**     | global               |

Specify a comma-separated list of IPv4 ranges in FIRST-LAST format.

<a id="network-bridge-network-conf:ipv4.firewall"></a>
`ipv4.firewall`

Whether to generate filtering firewall rules for this network

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:ipv4.firewall)

| **Key:**       | `ipv4.firewall`   |
|----------------|-------------------|
| **Type:**      | bool              |
| **Default:**   | `true`            |
| **Condition:** | IPv4 address      |
| **Scope:**     | global            |

<a id="network-bridge-network-conf:ipv4.nat"></a>
`ipv4.nat`

Whether to use NAT for IPv4

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:ipv4.nat)

| **Key:**       | `ipv4.nat`                                                                     |
|----------------|--------------------------------------------------------------------------------|
| **Type:**      | bool                                                                           |
| **Default:**   | `false` (initial value on creation if `ipv4.address` is set to `auto`: `true`) |
| **Condition:** | IPv4 address                                                                   |
| **Scope:**     | global                                                                         |

<a id="network-bridge-network-conf:ipv4.nat.address"></a>
`ipv4.nat.address`

Source address used for outbound traffic from the bridge

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:ipv4.nat.address)

| **Key:**       | `ipv4.nat.address`   |
|----------------|----------------------|
| **Type:**      | string               |
| **Condition:** | IPv4 address         |
| **Scope:**     | global               |

<a id="network-bridge-network-conf:ipv4.nat.order"></a>
`ipv4.nat.order`

Where to add the required NAT rules

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:ipv4.nat.order)

| **Key:**       | `ipv4.nat.order`   |
|----------------|--------------------|
| **Type:**      | string             |
| **Default:**   | `before`           |
| **Condition:** | IPv4 address       |
| **Scope:**     | global             |

Set this option to `before` to add the NAT rules before any pre-existing rules, or to `after` to add them after the pre-existing rules.

<a id="network-bridge-network-conf:ipv4.ovn.ranges"></a>
`ipv4.ovn.ranges`

IPv4 ranges to use for child OVN network routers

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:ipv4.ovn.ranges)

| **Key:**    | `ipv4.ovn.ranges`   |
|-------------|---------------------|
| **Type:**   | string              |
| **Scope:**  | global              |

Specify a comma-separated list of IPv4 ranges in FIRST-LAST format.

<a id="network-bridge-network-conf:ipv4.routes"></a>
`ipv4.routes`

Additional IPv4 CIDR subnets to route to the bridge

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:ipv4.routes)

| **Key:**       | `ipv4.routes`   |
|----------------|-----------------|
| **Type:**      | string          |
| **Condition:** | IPv4 address    |
| **Scope:**     | global          |

Specify a comma-separated list of IPv4 CIDR subnets.

<a id="network-bridge-network-conf:ipv4.routing"></a>
`ipv4.routing`

Whether to route IPv4 traffic in and out of the bridge

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:ipv4.routing)

| **Key:**       | `ipv4.routing`   |
|----------------|------------------|
| **Type:**      | bool             |
| **Default:**   | `true`           |
| **Condition:** | IPv4 address     |
| **Scope:**     | global           |

<a id="network-bridge-network-conf:ipv6.address"></a>
`ipv6.address`

IPv6 address for the bridge

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:ipv6.address)

| **Key:**       | `ipv6.address`                    |
|----------------|-----------------------------------|
| **Type:**      | string                            |
| **Default:**   | initial value on creation: `auto` |
| **Condition:** | standard mode                     |
| **Scope:**     | global                            |

Use CIDR notation.

You can set the option to `none` to turn off IPv6, or to `auto` to generate a new random unused subnet.

<a id="network-bridge-network-conf:ipv6.dhcp"></a>
`ipv6.dhcp`

Whether to provide additional network configuration over DHCP

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:ipv6.dhcp)

| **Key:**       | `ipv6.dhcp`   |
|----------------|---------------|
| **Type:**      | bool          |
| **Default:**   | `true`        |
| **Condition:** | IPv6 address  |
| **Scope:**     | global        |

<a id="network-bridge-network-conf:ipv6.dhcp.expiry"></a>
`ipv6.dhcp.expiry`

When to expire DHCP leases

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:ipv6.dhcp.expiry)

| **Key:**       | `ipv6.dhcp.expiry`   |
|----------------|----------------------|
| **Type:**      | string               |
| **Default:**   | `1h`                 |
| **Condition:** | IPv6 DHCP            |
| **Scope:**     | global               |

<a id="network-bridge-network-conf:ipv6.dhcp.ranges"></a>
`ipv6.dhcp.ranges`

IPv6 ranges to use for DHCP

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:ipv6.dhcp.ranges)

| **Key:**       | `ipv6.dhcp.ranges`   |
|----------------|----------------------|
| **Type:**      | string               |
| **Default:**   | all addresses        |
| **Condition:** | IPv6 stateful DHCP   |
| **Scope:**     | global               |

Specify a comma-separated list of IPv6 ranges in FIRST-LAST format.

<a id="network-bridge-network-conf:ipv6.dhcp.stateful"></a>
`ipv6.dhcp.stateful`

Whether to allocate IPv6 addresses using DHCP

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:ipv6.dhcp.stateful)

| **Key:**       | `ipv6.dhcp.stateful`   |
|----------------|------------------------|
| **Type:**      | bool                   |
| **Default:**   | `false`                |
| **Condition:** | IPv6 DHCP              |
| **Scope:**     | global                 |

<a id="network-bridge-network-conf:ipv6.firewall"></a>
`ipv6.firewall`

Whether to generate filtering firewall rules for this network

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:ipv6.firewall)

| **Key:**       | `ipv6.firewall`   |
|----------------|-------------------|
| **Type:**      | bool              |
| **Default:**   | `true`            |
| **Condition:** | IPv6 DHCP         |
| **Scope:**     | global            |

<a id="network-bridge-network-conf:ipv6.nat"></a>
`ipv6.nat`

Whether to use NAT for IPv6

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:ipv6.nat)

| **Key:**       | `ipv6.nat`                                                                     |
|----------------|--------------------------------------------------------------------------------|
| **Type:**      | bool                                                                           |
| **Default:**   | `false` (initial value on creation if `ipv6.address` is set to `auto`: `true`) |
| **Condition:** | IPv6 address                                                                   |
| **Scope:**     | global                                                                         |

<a id="network-bridge-network-conf:ipv6.nat.address"></a>
`ipv6.nat.address`

Source address used for outbound traffic from the bridge

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:ipv6.nat.address)

| **Key:**       | `ipv6.nat.address`   |
|----------------|----------------------|
| **Type:**      | string               |
| **Condition:** | IPv6 address         |
| **Scope:**     | global               |

<a id="network-bridge-network-conf:ipv6.nat.order"></a>
`ipv6.nat.order`

Where to add the required NAT rules

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:ipv6.nat.order)

| **Key:**       | `ipv6.nat.order`   |
|----------------|--------------------|
| **Type:**      | string             |
| **Default:**   | `before`           |
| **Condition:** | IPv6 address       |
| **Scope:**     | global             |

Set this option to `before` to add the NAT rules before any pre-existing rules, or to `after` to add them after the pre-existing rules.

<a id="network-bridge-network-conf:ipv6.ovn.ranges"></a>
`ipv6.ovn.ranges`

IPv6 ranges to use for child OVN network routers

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:ipv6.ovn.ranges)

| **Key:**    | `ipv6.ovn.ranges`   |
|-------------|---------------------|
| **Type:**   | string              |
| **Scope:**  | global              |

Specify a comma-separated list of IPv6 ranges in FIRST-LAST format.

<a id="network-bridge-network-conf:ipv6.routes"></a>
`ipv6.routes`

Additional IPv6 CIDR subnets to route to the bridge

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:ipv6.routes)

| **Key:**       | `ipv6.routes`   |
|----------------|-----------------|
| **Type:**      | string          |
| **Condition:** | IPv6 address    |
| **Scope:**     | global          |

Specify a comma-separated list of IPv6 CIDR subnets.

<a id="network-bridge-network-conf:ipv6.routing"></a>
`ipv6.routing`

Whether to route IPv6 traffic in and out of the bridge

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:ipv6.routing)

| **Key:**       | `ipv6.routing`   |
|----------------|------------------|
| **Type:**      | bool             |
| **Condition:** | IPv6 address     |
| **Scope:**     | global           |

<a id="network-bridge-network-conf:raw.dnsmasq"></a>
`raw.dnsmasq`

Additional `dnsmasq` configuration to append to the configuration file

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:raw.dnsmasq)

| **Key:**    | `raw.dnsmasq`   |
|-------------|-----------------|
| **Type:**   | string          |
| **Scope:**  | global          |

<a id="network-bridge-network-conf:security.acls"></a>
`security.acls`

Network ACLs to apply to NICs connected to this network

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:security.acls)

| **Key:**    | `security.acls`   |
|-------------|-------------------|
| **Type:**   | string            |
| **Scope:**  | global            |

Specify a comma-separated list of network ACLs.

Also see [Bridge limitations](../howto/network_acls.md#network-acls-bridge-limitations).

<a id="network-bridge-network-conf:security.acls.default.egress.action"></a>
`security.acls.default.egress.action`

Default action to use for egress traffic

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:security.acls.default.egress.action)

| **Key:**       | `security.acls.default.egress.action`   |
|----------------|-----------------------------------------|
| **Type:**      | string                                  |
| **Condition:** | `security.acls`                         |
| **Scope:**     | global                                  |

The specified action is used for all egress traffic that doesn’t match any ACL rule.

<a id="network-bridge-network-conf:security.acls.default.egress.logged"></a>
`security.acls.default.egress.logged`

Whether to log egress traffic that doesn’t match any ACL rule

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:security.acls.default.egress.logged)

| **Key:**       | `security.acls.default.egress.logged`   |
|----------------|-----------------------------------------|
| **Type:**      | bool                                    |
| **Condition:** | `security.acls`                         |
| **Scope:**     | global                                  |

<a id="network-bridge-network-conf:security.acls.default.ingress.action"></a>
`security.acls.default.ingress.action`

Default action to use for ingress traffic

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:security.acls.default.ingress.action)

| **Key:**       | `security.acls.default.ingress.action`   |
|----------------|------------------------------------------|
| **Type:**      | string                                   |
| **Condition:** | `security.acls`                          |
| **Scope:**     | global                                   |

The specified action is used for all ingress traffic that doesn’t match any ACL rule.

<a id="network-bridge-network-conf:security.acls.default.ingress.logged"></a>
`security.acls.default.ingress.logged`

Whether to log ingress traffic that doesn’t match any ACL rule

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:security.acls.default.ingress.logged)

| **Key:**       | `security.acls.default.ingress.logged`   |
|----------------|------------------------------------------|
| **Type:**      | bool                                     |
| **Condition:** | `security.acls`                          |
| **Scope:**     | global                                   |

<a id="network-bridge-network-conf:tunnel.NAME.group"></a>
`tunnel.NAME.group`

Multicast address for `vxlan`

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:tunnel.NAME.group)

| **Key:**       | `tunnel.NAME.group`   |
|----------------|-----------------------|
| **Type:**      | string                |
| **Condition:** | `vxlan`               |

This address is used if [`tunnel.NAME.local`](#network-bridge-network-conf:tunnel.NAME.local) and [`tunnel.NAME.remote`](#network-bridge-network-conf:tunnel.NAME.remote) aren’t set.

<a id="network-bridge-network-conf:tunnel.NAME.id"></a>
`tunnel.NAME.id`

Specific tunnel ID to use for the `vxlan` tunnel

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:tunnel.NAME.id)

| **Key:**       | `tunnel.NAME.id`   |
|----------------|--------------------|
| **Type:**      | integer            |
| **Condition:** | `vxlan`            |

<a id="network-bridge-network-conf:tunnel.NAME.interface"></a>
`tunnel.NAME.interface`

Specific host interface to use for the tunnel

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:tunnel.NAME.interface)

| **Key:**       | `tunnel.NAME.interface`   |
|----------------|---------------------------|
| **Type:**      | string                    |
| **Condition:** | `vxlan`                   |

<a id="network-bridge-network-conf:tunnel.NAME.local"></a>
`tunnel.NAME.local`

Local address for the tunnel

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:tunnel.NAME.local)

| **Key:**       | `tunnel.NAME.local`                |
|----------------|------------------------------------|
| **Type:**      | string                             |
| **Condition:** | `gre` or `vxlan`                   |
| **Required:**  | not required for multicast `vxlan` |

<a id="network-bridge-network-conf:tunnel.NAME.port"></a>
`tunnel.NAME.port`

Specific port to use for the `vxlan` tunnel

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:tunnel.NAME.port)

| **Key:**       | `tunnel.NAME.port`   |
|----------------|----------------------|
| **Type:**      | integer              |
| **Default:**   | `0`                  |
| **Condition:** | `vxlan`              |

<a id="network-bridge-network-conf:tunnel.NAME.protocol"></a>
`tunnel.NAME.protocol`

Tunneling protocol

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:tunnel.NAME.protocol)

| **Key:**       | `tunnel.NAME.protocol`   |
|----------------|--------------------------|
| **Type:**      | string                   |
| **Condition:** | standard mode            |

Possible values are `vxlan` and `gre`.

<a id="network-bridge-network-conf:tunnel.NAME.remote"></a>
`tunnel.NAME.remote`

Remote address for the tunnel

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:tunnel.NAME.remote)

| **Key:**       | `tunnel.NAME.remote`               |
|----------------|------------------------------------|
| **Type:**      | string                             |
| **Condition:** | `gre` or `vxlan`                   |
| **Required:**  | not required for multicast `vxlan` |

<a id="network-bridge-network-conf:tunnel.NAME.ttl"></a>
`tunnel.NAME.ttl`

Specific TTL to use for multicast routing topologies

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:tunnel.NAME.ttl)

| **Key:**       | `tunnel.NAME.ttl`   |
|----------------|---------------------|
| **Type:**      | string              |
| **Default:**   | `1`                 |
| **Condition:** | `vxlan`             |

<a id="network-bridge-network-conf:user.*"></a>
`user.*`

User-provided free-form key/value pairs

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-bridge-network-conf:user.*)

| **Key:**    | `user.*`   |
|-------------|------------|
| **Type:**   | string     |
| **Scope:**  | global     |

<a id="network-bridge-features"></a>

## Supported features

The following features are supported for the `bridge` network type:

- [How to configure network ACLs](../howto/network_acls.md#network-acls)
- [How to configure network forwards](../howto/network_forwards.md#network-forwards)
- [How to configure network zones](../howto/network_zones.md#network-zones)
- [How to configure LXD as a BGP server](../howto/network_bgp.md#network-bgp)
- [How to integrate with `systemd-resolved`](../howto/network_bridge_resolved.md#network-bridge-resolved)

## Firewall issues

See [How to configure your firewall](../howto/network_bridge_firewalld.md#network-bridge-firewall) for instructions on how to troubleshoot firewall issues.


# index.html.md

<a id="devices-unix-char"></a>

# Type: `unix-char`


            <p class="youtube_link">
              <a href="https://www.youtube.com/watch?v=C2e3LD5wLI8" target="_blank">
                <span title="LXD Unix devices - YouTube" class="play_icon">▶</span>
                <span title="LXD Unix devices - YouTube">Watch on YouTube</span>
              </a>
            </p>
        
#### NOTE
The `unix-char` device type is supported for containers.
It supports hotplugging.

Unix character devices make the specified character device appear as a device in the container (under `/dev`).
You can read from the device and write to it.

## Device options

`unix-char` devices have the following device options:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="device-unix-char-device-conf:gid"></a>
`gid`

GID of the device owner in the container

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-unix-char-device-conf:gid)

| **Key:**     | `gid`   |
|--------------|---------|
| **Type:**    | integer |
| **Default:** | `0`     |

<a id="device-unix-char-device-conf:major"></a>
`major`

Device major number

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-unix-char-device-conf:major)

| **Key:**     | `major`        |
|--------------|----------------|
| **Type:**    | integer        |
| **Default:** | device on host |

<a id="device-unix-char-device-conf:minor"></a>
`minor`

Device minor number

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-unix-char-device-conf:minor)

| **Key:**     | `minor`        |
|--------------|----------------|
| **Type:**    | integer        |
| **Default:** | device on host |

<a id="device-unix-char-device-conf:mode"></a>
`mode`

Mode of the device in the container

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-unix-char-device-conf:mode)

| **Key:**     | `mode`   |
|--------------|----------|
| **Type:**    | integer  |
| **Default:** | `0660`   |

<a id="device-unix-char-device-conf:path"></a>
`path`

Path inside the container

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-unix-char-device-conf:path)

| **Key:**      | `path`                                |
|---------------|---------------------------------------|
| **Type:**     | string                                |
| **Required:** | either `source` or `path` must be set |

<a id="device-unix-char-device-conf:required"></a>
`required`

Whether this device is required to start the container

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-unix-char-device-conf:required)

| **Key:**     | `required`   |
|--------------|--------------|
| **Type:**    | bool         |
| **Default:** | `true`       |

See [Hotplugging](#devices-unix-char-hotplugging) for more information.

<a id="device-unix-char-device-conf:source"></a>
`source`

Path on the host

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-unix-char-device-conf:source)

| **Key:**      | `source`                              |
|---------------|---------------------------------------|
| **Type:**     | string                                |
| **Required:** | either `source` or `path` must be set |

<a id="device-unix-char-device-conf:uid"></a>
`uid`

UID of the device owner in the container

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-unix-char-device-conf:uid)

| **Key:**     | `uid`   |
|--------------|---------|
| **Type:**    | integer |
| **Default:** | `0`     |

## Configuration examples

Add a `unix-char` device to a container by specifying its source and path:

```none
lxc config device add <instance_name> <device_name> unix-char source=<path_on_host> path=<path_on_instance>
```

If you want to use the same path on the container as on the host, you can omit the `source` option:

```none
lxc config device add <instance_name> <device_name> unix-char path=<path_to_the_device>
```

See [Configure devices](../howto/instances_configure.md#instances-configure-devices) for more information.

<a id="devices-unix-char-hotplugging"></a>

## Hotplugging

<!-- Include content from [devices_unix_block.md](device_unix_block.md) -->

Hotplugging is enabled if you set `required=false` and specify the `source` option for the device.

In this case, the device is automatically passed into the container when it appears on the host, even after the container starts.
If the device disappears from the host system, it is removed from the container as well.


# index.html.md

# UEFI variables for VMs

 variables store and represent configuration settings of the UEFI firmware.
See [UEFI](https://en.wikipedia.org/wiki/UEFI) for more information.

You can see a list of UEFI variables on your system by running `ls -l /sys/firmware/efi/efivars/`.
Usually, you don’t need to touch these variables, but in specific cases they can be useful to debug UEFI, SHIM, or boot loader issues in virtual machines.

To configure UEFI variables for a VM, use the [`lxc config uefi`](manpages/lxc/config/uefi.md#lxc-config-uefi-md) command or the `/1.0/instances/<instance_name>/uefi-vars` endpoint.

For example, to set a variable to a value (hexadecimal):

CLI

```none
lxc config uefi set <instance_name> <variable_name>-<GUID>=<value>
```

API

```none
lxc query --request PUT /1.0/instances/<instance_name>/uefi-vars --data '{
  "variables": {
    "<variable_name>-<GUID>": {
      "attr": 3,
      "data": "<value>"
    },
  }
}'
```

See [`PUT /1.0/instances/{name}/uefi-vars`](/api/#/instances/instance_uefi_vars_put) for more information.

To display the variables that are set for a specific VM:

CLI

```none
lxc config uefi show <instance_name>
```

API

```none
lxc query --request GET /1.0/instances/<instance_name>/uefi-vars
```

See [`GET /1.0/instances/{name}/uefi-vars`](/api/#/instances/instance_uefi_vars_get) for more information.

## Example

You can use UEFI variables to disable secure boot, for example.

#### IMPORTANT
Use this method only for debugging purposes.
LXD provides the [`boot.mode`](instance_options.md#instance-boot:boot.mode) option to control the secure boot behavior.

The following command checks the secure boot state:

```none
lxc config uefi get v1 SecureBootEnable-f0a30bc7-af08-4556-99c4-001009c93a44
```

A value of `01` indicates that secure boot is active.
You can then turn it off with the following command:

```none
lxc config uefi set v1 SecureBootEnable-f0a30bc7-af08-4556-99c4-001009c93a44=00
```


# index.html.md

<a id="ref-releases-snap"></a>

# Releases and snap

<a id="ref-releases"></a>

## Releases

The LXD team maintains both Long Term Support (LTS) and feature releases in parallel. Release notes are published on [Discourse](https://discourse.ubuntu.com/tags/c/lxd/news/143/release).

<a id="ref-releases-lts"></a>

### LTS releases

LTS releases are **intended for production use**.

LXD follows the [Ubuntu release cycle](https://ubuntu.com/about/release-cycle) cadence, meaning that an LTS release of LXD is created every two years. The release names follow the format *x.y.z*, always including the point number *z*. Updates are provided through point releases, incrementing *z*.

<a id="ref-releases-lts-support"></a>

#### Support

LTS releases receive standard support for five years, meaning that it receives continuous updates according to the support levels described below. An [Ubuntu Pro](https://ubuntu.com/pro) subscription can provide additional support and extends the support duration by an additional five years.

<a id="ref-releases-lts-support-levels"></a>

#### Support levels

Standard support for an LTS release starts at full support for its first two years, then moves to maintenance support for the remaining three years. Once an LTS reaches End of Life (EOL), it no longer receives any updates.

- **Full support**: Some new features, frequent bugfixes, and security updates are provided every six months. This schedule is an estimate that can change based on priorities and discovered bugs.
- **Maintenance support**: High impact bugfixes and critical security updates are provided as needed.

<a id="ref-releases-lts-support-current"></a>

#### Currently supported

The currently supported LTS releases are 5.21.*z* and 5.0.*z*.

- 5.21.*z* is supported until June 2029.
  - Currently in full support phase.
- 5.0.*z* is supported until June 2027.
  - Currently in maintenance support phase.

<a id="ref-releases-lts-kernel-support"></a>

#### Kernel support

LTS releases support the General Availability (GA) kernel of the Ubuntu release they were released with.
Support for the **final** Hardware Enablement (HWE) kernels of that Ubuntu release is provided on a best-effort basis.
Interim HWE kernels are only tentatively supported.

|   LXD version | Ubuntu release    |   GA Kernel (Supported) | HWE Kernel (Best effort)   |
|---------------|-------------------|-------------------------|----------------------------|
|          5.21 | 24.04 LTS (Noble) |                    6.8  | 7.0 (predicted)            |
|          5    | 22.04 LTS (Jammy) |                    5.15 | 6.8                        |
|          4    | 20.04 LTS (Focal) |                    5.4  | 5.15                       |

For more information on Ubuntu kernels support, please refer to the [Ubuntu kernels lifecycle](https://ubuntu.com/kernel/lifecycle).

<a id="ref-releases-feature"></a>

### Feature releases

Feature releases are pushed out more often and contain the newest features and bugfixes. Due to their frequent changes to the [API](../rest-api.md#rest-api) and [database](../database.md#database), they are **not recommended for production use**.

These releases follow the format *x.y*, and they never include a point number *z*. Currently, feature releases for LXD are numbered 6.*y*, with *y* incrementing for each new release. Every two years, the latest feature release becomes an LTS release.

#### Support

Feature releases receive continuous updates via each new release. The newest release at any given time is also eligible for additional support through an [Ubuntu Pro](https://ubuntu.com/pro) subscription.

<a id="ref-snap"></a>

## The LXD snap

The recommended way to [install LXD](../installing.md#installing) is [its snap package](https://snapcraft.io/lxd), if snaps are available for your system. A key benefit of snap packaging is that it includes all required dependencies. This allows LXD to run in a consistent environment on many different Linux distributions. Using the snap also streamlines updates through its channels.

<a id="ref-snap-channels"></a>

### Channels

Each installed LXD snap follows a channel. Channels are composed of a [track](#ref-snap-tracks) and a [risk level](#ref-snap-risk) (for example, the 6/stable channel). Each channel points to one release at a time, and when a new release is published to a channel, it replaces the previous one. [Updating the snap](#ref-snap-updates) then updates to that release.

To view all available channels, run:

```bash
snap info lxd
```

For more information about channels, see [Channels and tracks](https://snapcraft.io/docs/explanation/how-snaps-work/channels-and-tracks/#explanation-how-snaps-work-channels-and-tracks) in the Snap documentation.

<a id="ref-snap-tracks"></a>

### Tracks

LXD releases are grouped under snap tracks, such as 6 or 5.21.

<a id="ref-snap-tracks-lts"></a>

#### LTS tracks

LXD LTS tracks use the format *x[.y]*, corresponding to the major and minor numbers of [LTS releases](#ref-releases-lts).

Tracks up to `5.21` include both *x* and *y*, but future LTS tracks will use only *x*.

<a id="ref-snap-track-feature"></a>

#### Feature track

The LXD feature track uses the major number of the current [feature release](#ref-releases-feature). The current feature track is 6.

Feature releases within the same major version are published to the same track, replacing the previous release. For example, the `6.4` release replaced `6.3` in the `6` track. This simplifies updates, as you don’t need to switch channels to access new feature releases within the same major version.

Every two years, the current feature track becomes the next LTS, and a new feature track is then created by incrementing *x*. For example, after the `6` track becomes an LTS, the `7` track is created and becomes the next feature track.

<a id="ref-snap-tracks-default"></a>

#### The default track

If you [install the LXD snap](../installing.md#installing-snap-package) without specifying a track, the recommended default is used. The default track always points to the most recent LTS track, which is currently 5.21.

<a id="ref-snap-tracks-latest"></a>

#### The `latest` track

In the list of channels shown by `snap info lxd`, you might see channels with a track named `latest`. This track typically points to the latest feature release.

Since `latest` is a continuously rolling release track, it might become incompatible with your host OS version over time. Due to this, this track is *not recommended for general use* and might be removed in the future. Instead, use a feature or LTS track.

<a id="ref-snap-risk"></a>

### Risk levels

For each LXD track, there are three risk levels: `stable`, `candidate`, and `edge`.

We recommend that you use the `stable` risk level to install fully tested releases; this is the only risk level supported under [Ubuntu Pro](https://ubuntu.com/pro), as well as the default risk level if one is not specified at install. The `candidate` and `edge` levels offer newer but less-tested updates, posing higher risk.

For more information about risk levels, see [Channels and tracks](https://snapcraft.io/docs/explanation/how-snaps-work/channels-and-tracks/#explanation-how-snaps-work-channels-and-tracks) in the Snap documentation.

<a id="ref-snap-updates-upgrades"></a>

### Updates and upgrades

In this section, find information about updates and upgrades to the LXD snap, as well as about [Downgrades](#ref-snap-downgrades).

<a id="ref-snap-updates"></a>

#### Updates

To update the LXD snap means to refresh it to the release most recently published to its tracked channel. With the exception of updates published to [the latest track](#ref-snap-tracks-latest), these are always within the same major version. They can be automatically or manually performed.

By default, installed snaps update automatically when new releases are published to the channel they’re tracking. For control over LXD updates, we recommend that you modify this auto-update behavior by either [holding](../howto/snap.md#howto-snap-updates-hold) or [scheduling updates](../howto/snap.md#howto-snap-updates-schedule) as described in our [How to manage the LXD snap](../howto/snap.md#howto-snap) guide. You can then apply updates according to your schedule.

<a id="ref-snap-upgrades"></a>

#### Upgrades

To upgrade the LXD snap means to change its channel’s [track](#ref-snap-tracks) to a higher version, such as from 5.21 to 6. Such upgrades must be [manually performed](../howto/snap.md#howto-snap-change).

<a id="ref-snap-downgrades"></a>

#### Downgrades

We support the following changes *only* within the same LTS track:

- Reverting to an earlier snap revision
  - For details, see [Manage updates](https://snapcraft.io/docs/how-to-guides/manage-snaps/manage-updates/#how-to-guides-work-with-snaps-manage-updates) in the Snap documentation
- [Decreasing](../howto/snap.md#howto-snap-change) the [risk level](#ref-snap-risk) (such as from `edge` to `stable`)

Due to potential breaking changes, the following are *not* supported:

- All downgrades from a higher to a lower track
- For the [latest track](#ref-snap-tracks-latest) or the [current feature track](#ref-snap-track-feature):
  - Reverting to an earlier revision
  - Decreasing the risk level
  - Changing to an [LTS track](#ref-snap-tracks-lts)

<a id="ref-snap-cluster"></a>

#### Clusters

LXD cluster members must use the same version of the snap at all times. Thus, when updating or upgrading a cluster, the changes must be made to all cluster members. See: [Synchronize updates for a LXD cluster cohort](../howto/snap.md#howto-snap-updates-sync) and [Update or upgrade cluster members](../howto/cluster_manage.md#howto-cluster-manage-update-upgrade).

<a id="ref-snap-database"></a>

#### Database schema update and backup

When the daemon restarts after an LXD update or upgrade, if a new database schema is detected, the database is updated. A backup of the database before the update is created and stored in the same location as the active database. If LXD is installed through the snap, this location is `/var/snap/lxd/common/lxd/database`. If installed by other means, the location is typically `/var/lib/lxd/database/`.

## Related topics

How-to guides:

- [How to get support](../support.md#support)
- [Install the LXD snap package](../installing.md#installing-snap-package)
- [How to manage the LXD snap](../howto/snap.md#howto-snap)


# index.html.md

<a id="vm-live-migration-internals"></a>

# VM live migration implementation

[Live migration](../howto/instances_migrate.md#live-migration) in LXD is achieved by streaming instance state from a source  to a target QEMU. VM live migration is supported for all storage pool types.

API extension: `migration_vm_live`

## Conceptual process

The live migration workflow varies depending on the type of storage pool used. The two key scenarios are non-shared storage and shared storage within a cluster (e.g., Ceph). If live state transfer is not supported by a target, a stateful stop is performed prior to migration.

### Live migration for non-shared storage

This process leverages the QEMU built-in Network Block Device (NBD) client-server mechanism to transfer the virtual machine’s disk and memory state. Below is an overview of the steps:

1. Set up connection.
2. Determine migration type (shared or non-shared storage).
3. Set migration capabilities.
4. Non-shared storage preparation.
   1. Create and configure snapshot file for root disk writes during migration.
   2. Add the snapshot as a block device to the source VM.
   3. Redirect disk writes to the snapshot.
5. Storage transfer.
   1. For shared storage, we just perform checks at this point.
   2. For non-shared storage, set up an NBD listener and connect it to the target to transfer the disk.
6. Snapshot sync for non-shared storage to ensure consistency between source and target.
7. Transfer VM state to target.

![image](images/vm_live_migration_flowchart.svg)

The state transitions during the process are shown below:

![image](images/vm_live_migration_state_diagram.svg)

### Intra-cluster member live migration (Ceph shared storage pool)

For shared storage pools such as Ceph, disk data transfer is unnecessary. Instead, the process focuses on transferring the VM state through a dedicated migration socket:

1. Validate cluster state and storage pool readiness.
2. Notify the shared disks that they will be accessed from another system.
3. Pause the guest OS on the source VM and transfer the live state data over the migration socket.
4. Stop and delete source VM.
5. Start the target VM using the transferred state.

## Migration API

Sending a `POST` request to `/1.0/instances/{name}` renames, moves an instance between pools, or migrates an instance to another server. In the push case, the returned operation metadata for migration is a background operation with progress data. For the pull case, it is a WebSocket operation with a number of secrets to be passed to the target server.

## Live migration call stack

Below is a general overview of the key functions of the live migration call stack:

### [`lxd/lxd/instance_post.go`](https://github.com/canonical/lxd/blob/main/lxd/instance_post.go)

[`instancePost`](https://github.com/canonical/lxd/blob/main/lxd/instance_post.go#L74)

This function handles post requests to the `/1.0/instances` endpoint.

### [`lxd/lxd/migrate_instance.go`](https://github.com/canonical/lxd/blob/main/lxd/migrate_instance.go)

[`Do`](https://github.com/canonical/lxd/blob/main/lxd/migrate_instance.go#L87)

This function performs the migration operation on the source VM for the given state and operation. It sets up the necessary WebSocket connections for control, state, and filesystem, and then initiates the migration process.

### [`lxd/lxd/instance/drivers/driver_qemu.go`](https://github.com/canonical/lxd/blob/main/lxd/instance/drivers/driver_qemu.go)

[`MigrateSend`](https://github.com/canonical/lxd/blob/main/lxd/instance/drivers/driver_qemu.go#L6436)

This function controls the sending of a migration, checking for stateful support, waiting for connections, performing checks, and sending a migration offer. When performing an intra-cluster same-name migration, steps are taken to prevent corruption of volatile device configuration keys during the start and stop of the instance on both source and target.

[`migrateSendLive`](https://github.com/canonical/lxd/blob/main/lxd/instance/drivers/driver_qemu.go#L6666)

This function performs the live migration send process:

1. Connect to the QEMU monitor: The function begins by establishing a connection to the QEMU monitor using `qmp.Connect`.
2. Define disk names: The function defines names for the root disk (`lxd_root`), the NBD target disk (`lxd_root_nbd`), and the snapshot disk (`lxd_root_snapshot`). These will be used later to manage the root disk and its snapshot during migration.
3. Check for shared storage: If the migration involves shared storage, the migration process can bypass the need for synchronizing the root disk. The function checks for this condition by verifying if `clusterMoveSourceName` is non-empty and the pool is remote.
4. Non-shared storage snapshot setup: If shared storage is not used, the function proceeds to set up a temporary snapshot of the root disk.
   1. Migration capabilities such as `auto-converge`, `pause-before-switchover`, and `zero-blocks` are set to optimize the migration process.
   2. The function creates a QCOW2 snapshot file of the root disk, which will store changes to the disk during migration.
   3. The snapshot file is opened for reading and writing, and the file descriptor is passed to QEMU.
   4. The snapshot is added as a block device to QEMU, ensuring that it is not visible to the guest OS.
   5. A snapshot of the root disk is taken using `monitor.BlockDevSnapshot`. This ensures that changes to the root disk are isolated during migration.
   6. Revert function: The revert function is used to clean up in case of failure. It ensures that the guest is resumed, and any changes made during snapshot creation are merged back into the root disk if migration fails
5. Shared storage setup: If shared storage is used, only the `auto-converge` migration capability is set, and no snapshot creation is necessary.
6. Perform storage transfer: The storage pool is migrated while the VM is still running. The `volSourceArgs.AllowInconsistent` flag is set to true to allow migration while the disk is in use. The migration checks are done by calling `pool.MigrateInstance`.
7. Notify shared disk pools: For each disk in the VM, the migration process checks if the disk belongs to a shared pool. If so, the disk is prepared for migration by calling `MigrateVolume` on the source disk.
8. Set up NBD listener and connection: If shared storage is not used, the function sets up a Unix socket listener for NBD connections. This listener handles the actual data transfer of the root disk from the source VM to the migration target.
9. Begin block device mirroring: After setting up the NBD connection, the function starts transferring the migration snapshot to the target disk by using `monitor.BlockDevMirror`.
10. Send stateful migration checkpoint: The function creates a pipe to transfer the state of the VM during the migration process. It writes the VMs state to the `stateConn` via the pipe, using `d.saveStateHandle` to handle the state transfer. Note that the source VMs guest OS is paused while the state is transferred. This ensures that the VMs state is consistent when the migration completes.
11. Finalize snapshot transfer: If non-shared storage is used, the function waits for the state transfer to reach the `pre-switchover` stage, ensuring that the guest remains paused during this process. Next, the function cancels the block job associated with the root snapshot to finalize the transfer and ensure that no changes are lost.
12. Completion: Once all transfers are complete, the function proceeds to finalize the migration process by resuming the target VM and ensuring that source VM resources are cleaned up. The source VM is stopped, and its storage is discarded.


# index.html.md

<a id="ref-replicator-config"></a>

# Replicator configuration

Each replicator has its own key/value configuration with the following supported namespaces:

- [Replicator options](#ref-replicator-config-options)
- [Miscellaneous options](#ref-replicator-config-misc)

<a id="ref-replicator-config-options"></a>

## Replicator options

The following keys are currently supported:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="replicator-conf:cluster"></a>
`cluster`

Target cluster link name.

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#replicator-conf:cluster)

| **Key:**    | `cluster`   |
|-------------|-------------|
| **Type:**   | string      |
| **Scope:**  | global      |

Required when creating a replicator.

<a id="replicator-conf:schedule"></a>
`schedule`

Cron expression for the replication schedule.

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#replicator-conf:schedule)

| **Key:**    | `schedule`   |
|-------------|--------------|
| **Type:**   | string       |
| **Scope:**  | global       |

Specify a cron expression for the replication schedule. For example, `@daily` or `0 6 * * *`.

<a id="replicator-conf:snapshot"></a>
`snapshot`

Whether to snapshot instances before replication.

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#replicator-conf:snapshot)

| **Key:**    | `snapshot`   |
|-------------|--------------|
| **Type:**   | bool         |
| **Scope:**  | global       |

<a id="ref-replicator-config-misc"></a>

## Miscellaneous options

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="replicator-miscellaneous:user.*"></a>
`user.*`

Free form user key/value storage

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#replicator-miscellaneous:user.*)

| **Key:**    | `user.*`   |
|-------------|------------|
| **Type:**   | string     |

User keys can be used in search.


# index.html.md

<a id="devices-nic"></a>

# Type: `nic`


            <p class="youtube_link">
              <a href="https://www.youtube.com/watch?v=W62eno28KMY" target="_blank">
                <span title="LXD NIC devices" class="play_icon">▶</span>
                <span title="LXD NIC devices">Watch on YouTube</span>
              </a>
            </p>
        
#### NOTE
The `nic` device type is supported for both containers and VMs.

NICs support hotplugging for both containers and VMs (with the exception of the `ipvlan` NIC type).

Network devices, also referred to as *Network Interface Controllers* or *NICs*, supply a connection to a network.
LXD supports several different types of network devices (*NIC types*).

## `nictype` vs. `network`

When adding a network device to an instance, there are two methods to specify the type of device that you want to add: through the `nictype` device option or the `network` device option.

These two device options are mutually exclusive, and you can specify only one of them when you create a device.
However, note that when you specify the `network` option, the `nictype` option is derived automatically from the network type.

`nictype`
: When using the `nictype` device option, you can specify a network interface that is not controlled by LXD.
  Therefore, you must specify all information that LXD needs to use the network interface.
  <br/>
  When using this method, the `nictype` option must be specified when creating the device, and it cannot be changed later.

`network`
: When using the `network` device option, the NIC is linked to an existing [managed network](../explanation/networks.md#managed-networks).
  In this case, LXD has all required information about the network, and you need to specify only the network name when adding the device.
  <br/>
  When using this method, LXD derives the `nictype` option automatically.
  The value is read-only and cannot be changed.
  <br/>
  Other device options that are inherited from the network are marked with a “yes” in the “Managed” field of the NIC-specific device options.
  You cannot customize these options directly for the NIC if you’re using the `network` method.

See [Networking setups](../explanation/networks.md#networks) for more information.

## Available NIC types

The following NICs can be added using the `nictype` or `network` options:

- [`bridged`](#nic-bridged): Uses an existing bridge on the host and creates a virtual device pair to connect the host bridge to the instance.
- [`macvlan`](#nic-macvlan): Sets up a new network device based on an existing one, but using a different MAC address.
- [`sriov`](#nic-sriov): Passes a virtual function of an SR-IOV-enabled physical network device into the instance.
- [`physical`](#nic-physical): Passes a physical device from the host through to the instance.
  The targeted device will vanish from the host and appear in the instance.

The following NICs can be added using only the `network` option:

- [`ovn`](#nic-ovn): Uses an existing OVN network and creates a virtual device pair to connect the instance to it.

The following NICs can be added using only the `nictype` option:

- [`ipvlan`](#nic-ipvlan): Sets up a new network device based on an existing one, using the same MAC address but a different IP.
- [`p2p`](#nic-p2p): Creates a virtual device pair, putting one side in the instance and leaving the other side on the host.
- [`routed`](#nic-routed): Creates a virtual device pair to connect the host to the instance and sets up static routes and proxy ARP/NDP entries to allow the instance to join the network of a designated parent interface.

The available device options depend on the NIC type and are listed in the following sections.

<a id="nic-bridged"></a>

### `nictype`: `bridged`

#### NOTE
You can select this NIC type through the `nictype` option or the `network` option (see [Bridge network](network_bridge.md#network-bridge) for information about the managed `bridge` network).

A `bridged` NIC uses an existing bridge on the host and creates a virtual device pair to connect the host bridge to the instance.

#### Device options

NIC devices of type `bridged` have the following device options:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="device-nic-bridged-device-conf:boot.priority"></a>
`boot.priority`

Boot priority for VMs

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-bridged-device-conf:boot.priority)

| **Key:**     | `boot.priority`   |
|--------------|-------------------|
| **Type:**    | integer           |
| **Managed:** | no                |

A higher value for this option means that the VM boots first.

<a id="device-nic-bridged-device-conf:host_name"></a>
`host_name`

Name of the interface inside the host

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-bridged-device-conf:host_name)

| **Key:**     | `host_name`       |
|--------------|-------------------|
| **Type:**    | string            |
| **Default:** | randomly assigned |
| **Managed:** | no                |

<a id="device-nic-bridged-device-conf:hwaddr"></a>
`hwaddr`

MAC address of the new interface

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-bridged-device-conf:hwaddr)

| **Key:**     | `hwaddr`          |
|--------------|-------------------|
| **Type:**    | string            |
| **Default:** | randomly assigned |
| **Managed:** | no                |

<a id="device-nic-bridged-device-conf:ipv4.address"></a>
`ipv4.address`

IPv4 address to assign to the instance through DHCP

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-bridged-device-conf:ipv4.address)

| **Key:**     | `ipv4.address`   |
|--------------|------------------|
| **Type:**    | string           |
| **Managed:** | no               |

Set this option to `none` to restrict all IPv4 traffic when [`security.ipv4_filtering`](#device-nic-bridged-device-conf:security.ipv4_filtering) is set.

<a id="device-nic-bridged-device-conf:ipv4.routes"></a>
`ipv4.routes`

IPv4 static routes for the NIC to add on the host

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-bridged-device-conf:ipv4.routes)

| **Key:**     | `ipv4.routes`   |
|--------------|-----------------|
| **Type:**    | string          |
| **Managed:** | no              |

Specify a comma-delimited list of IPv4 static routes for this NIC to add on the host.

<a id="device-nic-bridged-device-conf:ipv4.routes.external"></a>
`ipv4.routes.external`

IPv4 static routes to route to NIC

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-bridged-device-conf:ipv4.routes.external)

| **Key:**     | `ipv4.routes.external`   |
|--------------|--------------------------|
| **Type:**    | string                   |
| **Managed:** | no                       |

Specify a comma-delimited list of IPv4 static routes to route to the NIC and publish on the uplink network (BGP).

<a id="device-nic-bridged-device-conf:ipv6.address"></a>
`ipv6.address`

IPv6 address to assign to the instance through DHCP

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-bridged-device-conf:ipv6.address)

| **Key:**     | `ipv6.address`   |
|--------------|------------------|
| **Type:**    | string           |
| **Managed:** | no               |

Set this option to `none` to restrict all IPv6 traffic when [`security.ipv6_filtering`](#device-nic-bridged-device-conf:security.ipv6_filtering) is set.

<a id="device-nic-bridged-device-conf:ipv6.routes"></a>
`ipv6.routes`

IPv6 static routes for the NIC to add on the host

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-bridged-device-conf:ipv6.routes)

| **Key:**     | `ipv6.routes`   |
|--------------|-----------------|
| **Type:**    | string          |
| **Managed:** | no              |

Specify a comma-delimited list of IPv6 static routes for this NIC to add on the host.

<a id="device-nic-bridged-device-conf:ipv6.routes.external"></a>
`ipv6.routes.external`

IPv6 static routes to route to NIC

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-bridged-device-conf:ipv6.routes.external)

| **Key:**     | `ipv6.routes.external`   |
|--------------|--------------------------|
| **Type:**    | string                   |
| **Managed:** | no                       |

Specify a comma-delimited list of IPv6 static routes to route to the NIC and publish on the uplink network (BGP).

<a id="device-nic-bridged-device-conf:limits.egress"></a>
`limits.egress`

I/O limit for outgoing traffic

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-bridged-device-conf:limits.egress)

| **Key:**     | `limits.egress`   |
|--------------|-------------------|
| **Type:**    | string            |
| **Managed:** | no                |

Specify the limit in bit/s. Various suffixes are supported (see [Units for storage and network limits](instance_units.md#instances-limit-units)).

<a id="device-nic-bridged-device-conf:limits.ingress"></a>
`limits.ingress`

I/O limit for incoming traffic

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-bridged-device-conf:limits.ingress)

| **Key:**     | `limits.ingress`   |
|--------------|--------------------|
| **Type:**    | string             |
| **Managed:** | no                 |

Specify the limit in bit/s. Various suffixes are supported (see [Units for storage and network limits](instance_units.md#instances-limit-units)).

<a id="device-nic-bridged-device-conf:limits.max"></a>
`limits.max`

I/O limit for both incoming and outgoing traffic

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-bridged-device-conf:limits.max)

| **Key:**     | `limits.max`   |
|--------------|----------------|
| **Type:**    | string         |
| **Managed:** | no             |

This option is the same as setting both [`limits.ingress`](#device-nic-bridged-device-conf:limits.ingress) and [`limits.egress`](#device-nic-bridged-device-conf:limits.egress).

Specify the limit in bit/s. Various suffixes are supported (see [Units for storage and network limits](instance_units.md#instances-limit-units)).

<a id="device-nic-bridged-device-conf:limits.priority"></a>
`limits.priority`

`skb->priority` value for outgoing traffic

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-bridged-device-conf:limits.priority)

| **Key:**     | `limits.priority`   |
|--------------|---------------------|
| **Type:**    | integer             |
| **Managed:** | no                  |

The `skb->priority` value for outgoing traffic is used by the kernel queuing discipline (qdisc) to prioritize network packets.
Specify the value as a 32-bit unsigned integer.

The effect of this value depends on the particular qdisc implementation, for example, `SKBPRIO` or `QFQ`.
Consult the kernel qdisc documentation before setting this value.

<a id="device-nic-bridged-device-conf:mtu"></a>
`mtu`

MTU of the new interface

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-bridged-device-conf:mtu)

| **Key:**     | `mtu`      |
|--------------|------------|
| **Type:**    | integer    |
| **Default:** | parent MTU |
| **Managed:** | yes        |

<a id="device-nic-bridged-device-conf:name"></a>
`name`

Name of the interface inside the instance

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-bridged-device-conf:name)

| **Key:**     | `name`          |
|--------------|-----------------|
| **Type:**    | string          |
| **Default:** | kernel assigned |
| **Managed:** | no              |

<a id="device-nic-bridged-device-conf:network"></a>
`network`

Managed network to link the device to

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-bridged-device-conf:network)

| **Key:**     | `network`   |
|--------------|-------------|
| **Type:**    | string      |
| **Managed:** | no          |

You can specify this option instead of specifying the `nictype` directly.

<a id="device-nic-bridged-device-conf:parent"></a>
`parent`

Name of the host device

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-bridged-device-conf:parent)

| **Key:**      | `parent`                             |
|---------------|--------------------------------------|
| **Type:**     | string                               |
| **Managed:**  | yes                                  |
| **Required:** | if specifying the `nictype` directly |

<a id="device-nic-bridged-device-conf:queue.tx.length"></a>
`queue.tx.length`

Transmit queue length for the NIC

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-bridged-device-conf:queue.tx.length)

| **Key:**     | `queue.tx.length`   |
|--------------|---------------------|
| **Type:**    | integer             |
| **Managed:** | no                  |

<a id="device-nic-bridged-device-conf:security.ipv4_filtering"></a>
`security.ipv4_filtering`

Whether to prevent the instance from spoofing an IPv4 address

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-bridged-device-conf:security.ipv4_filtering)

| **Key:**     | `security.ipv4_filtering`   |
|--------------|-----------------------------|
| **Type:**    | bool                        |
| **Default:** | `false`                     |
| **Managed:** | no                          |

Set this option to `true` to prevent the instance from spoofing another instance’s IPv4 address.
This option enables [`security.mac_filtering`](#device-nic-bridged-device-conf:security.mac_filtering).

<a id="device-nic-bridged-device-conf:security.ipv6_filtering"></a>
`security.ipv6_filtering`

Whether to prevent the instance from spoofing an IPv6 address

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-bridged-device-conf:security.ipv6_filtering)

| **Key:**     | `security.ipv6_filtering`   |
|--------------|-----------------------------|
| **Type:**    | bool                        |
| **Default:** | `false`                     |
| **Managed:** | no                          |

Set this option to `true` to prevent the instance from spoofing another instance’s IPv6 address.
This option enables [`security.mac_filtering`](#device-nic-bridged-device-conf:security.mac_filtering).

<a id="device-nic-bridged-device-conf:security.mac_filtering"></a>
`security.mac_filtering`

Whether to prevent the instance from spoofing a MAC address

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-bridged-device-conf:security.mac_filtering)

| **Key:**     | `security.mac_filtering`   |
|--------------|----------------------------|
| **Type:**    | bool                       |
| **Default:** | `false`                    |
| **Managed:** | no                         |

Set this option to `true` to prevent the instance from spoofing another instance’s MAC address.

<a id="device-nic-bridged-device-conf:security.port_isolation"></a>
`security.port_isolation`

Whether to respect port isolation

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-bridged-device-conf:security.port_isolation)

| **Key:**     | `security.port_isolation`   |
|--------------|-----------------------------|
| **Type:**    | bool                        |
| **Default:** | `false`                     |
| **Managed:** | no                          |

Set this option to `true` to prevent the NIC from communicating with other NICs in the network that have port isolation enabled.

<a id="device-nic-bridged-device-conf:vlan"></a>
`vlan`

VLAN ID to use for non-tagged traffic

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-bridged-device-conf:vlan)

| **Key:**     | `vlan`   |
|--------------|----------|
| **Type:**    | integer  |
| **Managed:** | no       |

Set this option to `none` to remove the port from the default VLAN.

<a id="device-nic-bridged-device-conf:vlan.tagged"></a>
`vlan.tagged`

VLAN IDs or VLAN ranges to join for tagged traffic

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-bridged-device-conf:vlan.tagged)

| **Key:**     | `vlan.tagged`   |
|--------------|-----------------|
| **Type:**    | integer         |
| **Managed:** | no              |

Specify the VLAN IDs or ranges as a comma-delimited list.

#### Configuration examples

Add a `bridged` network device to an instance, connecting to a LXD managed network:

```none
lxc network create <network_name> --type=bridge
lxc config device add <instance_name> <device_name> nic network=<network_name>
```

Note that `bridge` is the type when creating a managed bridge network, while the device `nictype` that is required when connecting to an unmanaged bridge is `bridged`.

Add a `bridged` network device to an instance, connecting to an existing bridge interface with `nictype`:

```none
lxc config device add <instance_name> <device_name> nic nictype=bridged parent=<existing_bridge>
```

See [How to create a network](../howto/network_create.md#network-create) and [Configure devices](../howto/instances_configure.md#instances-configure-devices) for more information.

<a id="nic-macvlan"></a>

### `nictype`: `macvlan`

#### NOTE
You can select this NIC type through the `nictype` option or the `network` option (see [Macvlan network](network_macvlan.md#network-macvlan) for information about the managed `macvlan` network).

A `macvlan` NIC sets up a new network device based on an existing one, but using a different MAC address.

If you are using a `macvlan` NIC, communication between the LXD host and the instances is not possible.
Both the host and the instances can talk to the gateway, but they cannot communicate directly.

#### Device options

NIC devices of type `macvlan` have the following device options:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="device-nic-macvlan-device-conf:boot.priority"></a>
`boot.priority`

Boot priority for VMs

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-macvlan-device-conf:boot.priority)

| **Key:**     | `boot.priority`   |
|--------------|-------------------|
| **Type:**    | integer           |
| **Managed:** | no                |

A higher value for this option means that the VM boots first.

<a id="device-nic-macvlan-device-conf:gvrp"></a>
`gvrp`

Whether to use GARP VLAN Registration Protocol

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-macvlan-device-conf:gvrp)

| **Key:**     | `gvrp`   |
|--------------|----------|
| **Type:**    | bool     |
| **Default:** | `false`  |
| **Managed:** | no       |

This option specifies whether to register the VLAN using the GARP VLAN Registration Protocol.

<a id="device-nic-macvlan-device-conf:hwaddr"></a>
`hwaddr`

MAC address of the new interface

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-macvlan-device-conf:hwaddr)

| **Key:**     | `hwaddr`          |
|--------------|-------------------|
| **Type:**    | string            |
| **Default:** | randomly assigned |
| **Managed:** | no                |

<a id="device-nic-macvlan-device-conf:mtu"></a>
`mtu`

MTU of the new interface

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-macvlan-device-conf:mtu)

| **Key:**     | `mtu`      |
|--------------|------------|
| **Type:**    | integer    |
| **Default:** | parent MTU |
| **Managed:** | yes        |

<a id="device-nic-macvlan-device-conf:name"></a>
`name`

Name of the interface inside the instance

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-macvlan-device-conf:name)

| **Key:**     | `name`          |
|--------------|-----------------|
| **Type:**    | string          |
| **Default:** | kernel assigned |
| **Managed:** | no              |

<a id="device-nic-macvlan-device-conf:network"></a>
`network`

Managed network to link the device to

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-macvlan-device-conf:network)

| **Key:**     | `network`   |
|--------------|-------------|
| **Type:**    | string      |
| **Managed:** | no          |

You can specify this option instead of specifying the `nictype` directly.

<a id="device-nic-macvlan-device-conf:parent"></a>
`parent`

Name of the host device

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-macvlan-device-conf:parent)

| **Key:**      | `parent`                             |
|---------------|--------------------------------------|
| **Type:**     | string                               |
| **Managed:**  | yes                                  |
| **Required:** | if specifying the `nictype` directly |

<a id="device-nic-macvlan-device-conf:vlan"></a>
`vlan`

VLAN ID to attach to

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-macvlan-device-conf:vlan)

| **Key:**     | `vlan`   |
|--------------|----------|
| **Type:**    | integer  |
| **Managed:** | no       |

#### Configuration examples

Add a `macvlan` network device to an instance, connecting to a LXD managed network:

```none
lxc network create <network_name> --type=macvlan parent=<existing_NIC>
lxc config device add <instance_name> <device_name> nic network=<network_name>
```

Add a `macvlan` network device to an instance, connecting to an existing network interface with `nictype`:

```none
lxc config device add <instance_name> <device_name> nic nictype=macvlan parent=<existing_NIC>
```

See [How to create a network](../howto/network_create.md#network-create) and [Configure devices](../howto/instances_configure.md#instances-configure-devices) for more information.

<a id="nic-sriov"></a>

### `nictype`: `sriov`

#### NOTE
You can select this NIC type through the `nictype` option or the `network` option (see [SR-IOV network](network_sriov.md#network-sriov) for information about the managed `sriov` network).

An `sriov` NIC passes a virtual function of an SR-IOV-enabled physical network device into the instance.

An SR-IOV-enabled network device associates a set of virtual functions (VFs) with the single physical function (PF) of the network device.
PFs are standard PCIe functions.
VFs, on the other hand, are very lightweight PCIe functions that are optimized for data movement.
They come with a limited set of configuration capabilities to prevent changing properties of the PF.

Given that VFs appear as regular PCIe devices to the system, they can be passed to instances just like a regular physical device.

VF allocation
: The `sriov` interface type expects to be passed the name of an SR-IOV enabled network device on the system via the `parent` property.
  LXD then checks for any available VFs on the system.
  <br/>
  By default, LXD allocates the first free VF it finds.
  If it detects that either none are enabled or all currently enabled VFs are in use, it bumps the number of supported VFs to the maximum value and uses the first free VF.
  If all possible VFs are in use or the kernel or card doesn’t support incrementing the number of VFs, LXD returns an error.
  <br/>
  #### NOTE
  If you need LXD to use a specific VF, use a `physical` NIC instead of a `sriov` NIC and set its `parent` option to the VF name.

#### Device options

NIC devices of type `sriov` have the following device options:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="device-nic-sriov-device-conf:boot.priority"></a>
`boot.priority`

Boot priority for VMs

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-sriov-device-conf:boot.priority)

| **Key:**     | `boot.priority`   |
|--------------|-------------------|
| **Type:**    | integer           |
| **Managed:** | no                |

A higher value for this option means that the VM boots first.

<a id="device-nic-sriov-device-conf:hwaddr"></a>
`hwaddr`

MAC address of the new interface

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-sriov-device-conf:hwaddr)

| **Key:**     | `hwaddr`          |
|--------------|-------------------|
| **Type:**    | string            |
| **Default:** | randomly assigned |
| **Managed:** | no                |

<a id="device-nic-sriov-device-conf:mtu"></a>
`mtu`

MTU of the new interface

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-sriov-device-conf:mtu)

| **Key:**     | `mtu`           |
|--------------|-----------------|
| **Type:**    | integer         |
| **Default:** | kernel assigned |
| **Managed:** | yes             |

<a id="device-nic-sriov-device-conf:name"></a>
`name`

Name of the interface inside the instance

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-sriov-device-conf:name)

| **Key:**     | `name`          |
|--------------|-----------------|
| **Type:**    | string          |
| **Default:** | kernel assigned |
| **Managed:** | no              |

<a id="device-nic-sriov-device-conf:network"></a>
`network`

Managed network to link the device to

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-sriov-device-conf:network)

| **Key:**     | `network`   |
|--------------|-------------|
| **Type:**    | string      |
| **Managed:** | no          |

You can specify this option instead of specifying the `nictype` directly.

<a id="device-nic-sriov-device-conf:parent"></a>
`parent`

Name of the host device

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-sriov-device-conf:parent)

| **Key:**      | `parent`                             |
|---------------|--------------------------------------|
| **Type:**     | string                               |
| **Managed:**  | yes                                  |
| **Required:** | if specifying the `nictype` directly |

<a id="device-nic-sriov-device-conf:security.mac_filtering"></a>
`security.mac_filtering`

Whether to prevent the instance from spoofing a MAC address

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-sriov-device-conf:security.mac_filtering)

| **Key:**     | `security.mac_filtering`   |
|--------------|----------------------------|
| **Type:**    | bool                       |
| **Default:** | `false`                    |
| **Managed:** | no                         |

Set this option to `true` to prevent the instance from spoofing another instance’s MAC address.

<a id="device-nic-sriov-device-conf:vlan"></a>
`vlan`

VLAN ID to attach to

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-sriov-device-conf:vlan)

| **Key:**     | `vlan`   |
|--------------|----------|
| **Type:**    | integer  |
| **Managed:** | no       |

#### Configuration examples

Add a `sriov` network device to an instance, connecting to a LXD managed network:

```none
lxc network create <network_name> --type=sriov parent=<sriov_enabled_NIC>
lxc config device add <instance_name> <device_name> nic network=<network_name>
```

Add a `sriov` network device to an instance, connecting to an existing SR-IOV-enabled interface with `nictype`:

```none
lxc config device add <instance_name> <device_name> nic nictype=sriov parent=<sriov_enabled_NIC>
```

See [How to create a network](../howto/network_create.md#network-create) and [Configure devices](../howto/instances_configure.md#instances-configure-devices) for more information.

<a id="nic-physical"></a>

### `nictype`: `physical`

#### NOTE
- You can select this NIC type through the `nictype` option or the `network` option (see [Physical network](network_physical.md#network-physical) for information about the managed `physical` network).
- You can have only one `physical` NIC for each parent device.

A `physical` NIC provides straight physical device pass-through from the host.
The targeted device will vanish from the host and appear in the instance (which means that you can have only one `physical` NIC for each targeted device).

#### Device options

NIC devices of type `physical` have the following device options:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="device-nic-physical-device-conf:boot.priority"></a>
`boot.priority`

Boot priority for VMs

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-physical-device-conf:boot.priority)

| **Key:**     | `boot.priority`   |
|--------------|-------------------|
| **Type:**    | integer           |
| **Managed:** | no                |

A higher value for this option means that the VM boots first.

<a id="device-nic-physical-device-conf:gvrp"></a>
`gvrp`

Whether to use GARP VLAN Registration Protocol

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-physical-device-conf:gvrp)

| **Key:**     | `gvrp`   |
|--------------|----------|
| **Type:**    | bool     |
| **Default:** | `false`  |
| **Managed:** | no       |

This option specifies whether to register the VLAN using the GARP VLAN Registration Protocol.

<a id="device-nic-physical-device-conf:hwaddr"></a>
`hwaddr`

MAC address of the new interface

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-physical-device-conf:hwaddr)

| **Key:**       | `hwaddr`           |
|----------------|--------------------|
| **Type:**      | string             |
| **Default:**   | parent MAC address |
| **Condition:** | container          |
| **Managed:**   | no                 |

<a id="device-nic-physical-device-conf:mtu"></a>
`mtu`

MTU of the new interface

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-physical-device-conf:mtu)

| **Key:**       | `mtu`      |
|----------------|------------|
| **Type:**      | integer    |
| **Default:**   | parent MTU |
| **Condition:** | container  |
| **Managed:**   | no         |

<a id="device-nic-physical-device-conf:name"></a>
`name`

Name of the interface inside the instance

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-physical-device-conf:name)

| **Key:**     | `name`          |
|--------------|-----------------|
| **Type:**    | string          |
| **Default:** | kernel assigned |
| **Managed:** | no              |

<a id="device-nic-physical-device-conf:network"></a>
`network`

Managed network to link the device to

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-physical-device-conf:network)

| **Key:**     | `network`   |
|--------------|-------------|
| **Type:**    | string      |
| **Managed:** | no          |

You can specify this option instead of specifying the `nictype` directly.

<a id="device-nic-physical-device-conf:parent"></a>
`parent`

Name of the host device

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-physical-device-conf:parent)

| **Key:**      | `parent`                             |
|---------------|--------------------------------------|
| **Type:**     | string                               |
| **Managed:**  | yes                                  |
| **Required:** | if specifying the `nictype` directly |

<a id="device-nic-physical-device-conf:vlan"></a>
`vlan`

VLAN ID to attach to

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-physical-device-conf:vlan)

| **Key:**       | `vlan`    |
|----------------|-----------|
| **Type:**      | integer   |
| **Condition:** | container |
| **Managed:**   | no        |

#### Configuration examples

Add a `physical` network device to an instance, connecting to an existing physical network interface with `nictype`:

```none
lxc config device add <instance_name> <device_name> nic nictype=physical parent=<physical_NIC>
```

Adding a `physical` network device to an instance using a managed network is not possible, because the `physical` managed network type is intended to be used only with OVN networks.

See [Configure devices](../howto/instances_configure.md#instances-configure-devices) for more information.

<a id="nic-ovn"></a>

### `nictype`: `ovn`

#### NOTE
You can select this NIC type only through the `network` option (see [OVN network](network_ovn.md#network-ovn) for information about the managed `ovn` network).

An `ovn` NIC uses an existing OVN network and creates a virtual device pair to connect the instance to it.

<a id="devices-nic-hw-acceleration"></a>

SR-IOV hardware acceleration
: To use `acceleration=sriov`, you must have a compatible SR-IOV physical NIC that supports the Ethernet switch device driver model (`switchdev`) in your LXD host.
  LXD assumes that the physical NIC (PF) is configured in `switchdev` mode and connected to the OVN integration OVS bridge, and that it has one or more virtual functions (VFs) active.
  <br/>
  To achieve this, follow these basic prerequisite setup steps:
  <br/>
  1. Set up PF and VF:
     1. Activate some VFs on PF (called `enp9s0f0np0` in the following example, with a PCI address of `0000:09:00.0`) and unbind them.
     2. Enable `switchdev` mode and `hw-tc-offload` on the PF.
     3. Rebind the VFs.
  <br/>
     ```default
     echo 4 > /sys/bus/pci/devices/0000:09:00.0/sriov_numvfs
     for i in $(lspci -nnn | grep "Virtual Function" | cut -d' ' -f1); do echo 0000:$i > /sys/bus/pci/drivers/mlx5_core/unbind; done
     devlink dev eswitch set pci/0000:09:00.0 mode switchdev
     ethtool -K enp9s0f0np0 hw-tc-offload on
     for i in $(lspci -nnn | grep "Virtual Function" | cut -d' ' -f1); do echo 0000:$i > /sys/bus/pci/drivers/mlx5_core/bind; done
     ```
  2. Set up OVS by enabling hardware offload and adding the PF NIC to the integration bridge (normally called `br-int`):
     ```default
     ovs-vsctl set open_vswitch . other_config:hw-offload=true
     systemctl restart openvswitch-switch
     ovs-vsctl add-port br-int enp9s0f0np0
     ip link set enp9s0f0np0 up
     ```

VDPA hardware acceleration
: To use `acceleration=vdpa`, you must have a compatible VDPA physical NIC.
  The setup is the same as for SR-IOV hardware acceleration, except that you must also enable the `vhost_vdpa` module and check that you have some available VDPA management devices :
  <br/>
  ```default
  modprobe vhost_vdpa && vdpa mgmtdev show
  ```

#### Device options

NIC devices of type `ovn` have the following device options:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="device-nic-ovn-device-conf:acceleration"></a>
`acceleration`

Enable hardware acceleration

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-ovn-device-conf:acceleration)

| **Key:**     | `acceleration`   |
|--------------|------------------|
| **Type:**    | string           |
| **Default:** | `none`           |
| **Managed:** | no               |

Possible values are `none`, `sriov`, or `vdpa`.
See [SR-IOV hardware acceleration](#devices-nic-hw-acceleration) for more information.

<a id="device-nic-ovn-device-conf:acceleration.parent"></a>
`acceleration.parent`

Physical function interfaces to allocate virtual functions from for hardware acceleration

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-ovn-device-conf:acceleration.parent)

| **Key:**     | `acceleration.parent`   |
|--------------|-------------------------|
| **Type:**    | string                  |
| **Managed:** | yes                     |

Comma separated list of physical function (PF) interfaces to allocate virtual functions (VFs) from for hardware acceleration when [`acceleration`](#device-nic-ovn-device-conf:acceleration) is enabled.
In [`restricted`](projects.md#project-restricted:restricted) projects, it can only be used when [`restricted.virtual-machines.lowlevel`](projects.md#project-restricted:restricted.virtual-machines.lowlevel) or [`restricted.containers.lowlevel`](projects.md#project-restricted:restricted.containers.lowlevel) is set to `allow`.
If this is not specified, and [`acceleration`](#device-nic-ovn-device-conf:acceleration) is enabled then all PFs connected to the OVS integration bridge are scanned for a free VF.
See [SR-IOV hardware acceleration](#devices-nic-hw-acceleration) for more information.

<a id="device-nic-ovn-device-conf:boot.priority"></a>
`boot.priority`

Boot priority for VMs

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-ovn-device-conf:boot.priority)

| **Key:**     | `boot.priority`   |
|--------------|-------------------|
| **Type:**    | integer           |
| **Managed:** | no                |

A higher value for this option means that the VM boots first.

<a id="device-nic-ovn-device-conf:host_name"></a>
`host_name`

Name of the interface inside the host

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-ovn-device-conf:host_name)

| **Key:**     | `host_name`       |
|--------------|-------------------|
| **Type:**    | string            |
| **Default:** | randomly assigned |
| **Managed:** | no                |

<a id="device-nic-ovn-device-conf:hwaddr"></a>
`hwaddr`

MAC address of the new interface

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-ovn-device-conf:hwaddr)

| **Key:**     | `hwaddr`          |
|--------------|-------------------|
| **Type:**    | string            |
| **Default:** | randomly assigned |
| **Managed:** | no                |

<a id="device-nic-ovn-device-conf:ipv4.address"></a>
`ipv4.address`

IPv4 address to assign to the instance through DHCP

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-ovn-device-conf:ipv4.address)

| **Key:**     | `ipv4.address`   |
|--------------|------------------|
| **Type:**    | string           |
| **Managed:** | no               |

<a id="device-nic-ovn-device-conf:ipv4.routes"></a>
`ipv4.routes`

IPv4 static routes to route for the NIC

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-ovn-device-conf:ipv4.routes)

| **Key:**     | `ipv4.routes`   |
|--------------|-----------------|
| **Type:**    | string          |
| **Managed:** | no              |

Specify a comma-delimited list of IPv4 static routes to route for this NIC.

<a id="device-nic-ovn-device-conf:ipv4.routes.external"></a>
`ipv4.routes.external`

IPv4 static routes to route to NIC

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-ovn-device-conf:ipv4.routes.external)

| **Key:**     | `ipv4.routes.external`   |
|--------------|--------------------------|
| **Type:**    | string                   |
| **Managed:** | no                       |

Specify a comma-delimited list of IPv4 static routes to route to the NIC and publish on the uplink network.

<a id="device-nic-ovn-device-conf:ipv6.address"></a>
`ipv6.address`

IPv6 address to assign to the instance through DHCP

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-ovn-device-conf:ipv6.address)

| **Key:**     | `ipv6.address`   |
|--------------|------------------|
| **Type:**    | string           |
| **Managed:** | no               |

<a id="device-nic-ovn-device-conf:ipv6.routes"></a>
`ipv6.routes`

IPv6 static routes to route to the NIC

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-ovn-device-conf:ipv6.routes)

| **Key:**     | `ipv6.routes`   |
|--------------|-----------------|
| **Type:**    | string          |
| **Managed:** | no              |

Specify a comma-delimited list of IPv6 static routes to route to the NIC.

<a id="device-nic-ovn-device-conf:ipv6.routes.external"></a>
`ipv6.routes.external`

IPv6 static routes to route to NIC

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-ovn-device-conf:ipv6.routes.external)

| **Key:**     | `ipv6.routes.external`   |
|--------------|--------------------------|
| **Type:**    | string                   |
| **Managed:** | no                       |

Specify a comma-delimited list of IPv6 static routes to route to the NIC and publish on the uplink network.

<a id="device-nic-ovn-device-conf:name"></a>
`name`

Name of the interface inside the instance

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-ovn-device-conf:name)

| **Key:**     | `name`          |
|--------------|-----------------|
| **Type:**    | string          |
| **Default:** | kernel assigned |
| **Managed:** | no              |

<a id="device-nic-ovn-device-conf:nested"></a>
`nested`

Parent NIC name to nest this NIC under

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-ovn-device-conf:nested)

| **Key:**     | `nested`   |
|--------------|------------|
| **Type:**    | string     |
| **Managed:** | no         |

See also [`vlan`](#device-nic-ovn-device-conf:vlan).

<a id="device-nic-ovn-device-conf:network"></a>
`network`

Managed network to link the device to

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-ovn-device-conf:network)

| **Key:**      | `network`   |
|---------------|-------------|
| **Type:**     | string      |
| **Managed:**  | yes         |
| **Required:** | yes         |

<a id="device-nic-ovn-device-conf:security.acls"></a>
`security.acls`

Network ACLs to apply

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-ovn-device-conf:security.acls)

| **Key:**     | `security.acls`   |
|--------------|-------------------|
| **Type:**    | string            |
| **Managed:** | no                |

Specify a comma-separated list

<a id="device-nic-ovn-device-conf:security.acls.default.egress.action"></a>
`security.acls.default.egress.action`

Default action to use for egress traffic

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-ovn-device-conf:security.acls.default.egress.action)

| **Key:**     | `security.acls.default.egress.action`   |
|--------------|-----------------------------------------|
| **Type:**    | string                                  |
| **Default:** | `reject`                                |
| **Managed:** | no                                      |

The specified action is used for all egress traffic that doesn’t match any ACL rule.

<a id="device-nic-ovn-device-conf:security.acls.default.egress.logged"></a>
`security.acls.default.egress.logged`

Whether to log egress traffic that doesn’t match any ACL rule

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-ovn-device-conf:security.acls.default.egress.logged)

| **Key:**     | `security.acls.default.egress.logged`   |
|--------------|-----------------------------------------|
| **Type:**    | bool                                    |
| **Default:** | `false`                                 |
| **Managed:** | no                                      |

<a id="device-nic-ovn-device-conf:security.acls.default.ingress.action"></a>
`security.acls.default.ingress.action`

Default action to use for ingress traffic

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-ovn-device-conf:security.acls.default.ingress.action)

| **Key:**     | `security.acls.default.ingress.action`   |
|--------------|------------------------------------------|
| **Type:**    | string                                   |
| **Default:** | `reject`                                 |
| **Managed:** | no                                       |

The specified action is used for all ingress traffic that doesn’t match any ACL rule.

<a id="device-nic-ovn-device-conf:security.acls.default.ingress.logged"></a>
`security.acls.default.ingress.logged`

Whether to log ingress traffic that doesn’t match any ACL rule

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-ovn-device-conf:security.acls.default.ingress.logged)

| **Key:**     | `security.acls.default.ingress.logged`   |
|--------------|------------------------------------------|
| **Type:**    | bool                                     |
| **Default:** | `false`                                  |
| **Managed:** | no                                       |

<a id="device-nic-ovn-device-conf:vlan"></a>
`vlan`

VLAN ID to use when nesting

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-ovn-device-conf:vlan)

| **Key:**     | `vlan`   |
|--------------|----------|
| **Type:**    | integer  |
| **Managed:** | no       |

See also [`nested`](#device-nic-ovn-device-conf:nested).

#### Configuration examples

An `ovn` network device must be added using a managed network.
To do so:

```none
lxc network create <network_name> --type=ovn network=<parent_network>
lxc config device add <instance_name> <device_name> nic network=<network_name>
```

See [How to set up OVN with LXD](../howto/network_ovn_setup.md#network-ovn-setup) for full instructions, and [How to create a network](../howto/network_create.md#network-create) and [Configure devices](../howto/instances_configure.md#instances-configure-devices) for more information.

<a id="nic-ipvlan"></a>

### `nictype`: `ipvlan`

#### NOTE
- This NIC type is available only for containers, not for virtual machines.
- You can select this NIC type only through the `nictype` option.
- This NIC type does not support hotplugging.

An `ipvlan` NIC sets up a new network device based on an existing one, using the same MAC address but a different IP.

If you are using an `ipvlan` NIC, communication between the LXD host and the instances is not possible.
Both the host and the instances can talk to the gateway, but they cannot communicate directly.

LXD currently supports IPVLAN in L2 and L3S mode.
In this mode, the gateway is automatically set by LXD, but the IP addresses must be manually specified using the `ipv4.address` and/or `ipv6.address` options before the container is started.

DNS
: The name servers must be configured inside the container, because they are not set automatically.
  To do this, set the following `sysctls`:
  <br/>
  - When using IPv4 addresses:
    ```default
    net.ipv4.conf.<parent>.forwarding=1
    ```
  - When using IPv6 addresses:
    ```default
    net.ipv6.conf.<parent>.forwarding=1
    net.ipv6.conf.<parent>.proxy_ndp=1
    ```

#### Device options

NIC devices of type `ipvlan` have the following device options:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="device-nic-ipvlan-device-conf:gvrp"></a>
`gvrp`

Whether to use GARP VLAN Registration Protocol

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-ipvlan-device-conf:gvrp)

| **Key:**     | `gvrp`   |
|--------------|----------|
| **Type:**    | bool     |
| **Default:** | `false`  |

This option specifies whether to register the VLAN using the GARP VLAN Registration Protocol.

<a id="device-nic-ipvlan-device-conf:hwaddr"></a>
`hwaddr`

MAC address of the new interface

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-ipvlan-device-conf:hwaddr)

| **Key:**     | `hwaddr`          |
|--------------|-------------------|
| **Type:**    | string            |
| **Default:** | randomly assigned |

<a id="device-nic-ipvlan-device-conf:ipv4.address"></a>
`ipv4.address`

IPv4 static addresses to add to the instance

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-ipvlan-device-conf:ipv4.address)

| **Key:**    | `ipv4.address`   |
|-------------|------------------|
| **Type:**   | string           |

Specify a comma-delimited list of IPv4 static addresses to add to the instance.
In `l2` mode, you can specify them as CIDR values or singular addresses using a subnet of `/24`.

<a id="device-nic-ipvlan-device-conf:ipv4.gateway"></a>
`ipv4.gateway`

IPv4 gateway

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-ipvlan-device-conf:ipv4.gateway)

| **Key:**     | `ipv4.gateway`             |
|--------------|----------------------------|
| **Type:**    | string                     |
| **Default:** | `auto` (`l3s`), `-` (`l2`) |

In `l3s` mode, the option specifies whether to add an automatic default IPv4 gateway.
Possible values are `auto` and `none`.

In `l2` mode, this option specifies the IPv4 address of the gateway.

<a id="device-nic-ipvlan-device-conf:ipv4.host_table"></a>
`ipv4.host_table`

Custom policy routing table ID to add IPv4 static routes to

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-ipvlan-device-conf:ipv4.host_table)

| **Key:**    | `ipv4.host_table`   |
|-------------|---------------------|
| **Type:**   | integer             |

The custom policy routing table is in addition to the main routing table.

<a id="device-nic-ipvlan-device-conf:ipv6.address"></a>
`ipv6.address`

IPv6 static addresses to add to the instance

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-ipvlan-device-conf:ipv6.address)

| **Key:**    | `ipv6.address`   |
|-------------|------------------|
| **Type:**   | string           |

Specify a comma-delimited list of IPv6 static addresses to add to the instance.
In `l2` mode, you can specify them as CIDR values or singular addresses using a subnet of `/64`.

<a id="device-nic-ipvlan-device-conf:ipv6.gateway"></a>
`ipv6.gateway`

IPv6 gateway

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-ipvlan-device-conf:ipv6.gateway)

| **Key:**     | `ipv6.gateway`             |
|--------------|----------------------------|
| **Type:**    | string                     |
| **Default:** | `auto` (`l3s`), `-` (`l2`) |

In `l3s` mode, the option specifies whether to add an automatic default IPv6 gateway.
Possible values are `auto` and `none`.

In `l2` mode, this option specifies the IPv6 address of the gateway.

<a id="device-nic-ipvlan-device-conf:ipv6.host_table"></a>
`ipv6.host_table`

Custom policy routing table ID to add IPv6 static routes to

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-ipvlan-device-conf:ipv6.host_table)

| **Key:**    | `ipv6.host_table`   |
|-------------|---------------------|
| **Type:**   | integer             |

The custom policy routing table is in addition to the main routing table.

<a id="device-nic-ipvlan-device-conf:mode"></a>
`mode`

IPVLAN mode

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-ipvlan-device-conf:mode)

| **Key:**     | `mode`   |
|--------------|----------|
| **Type:**    | string   |
| **Default:** | `l3s`    |

Possible values are `l2` and `l3s`.

<a id="device-nic-ipvlan-device-conf:mtu"></a>
`mtu`

The MTU of the new interface

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-ipvlan-device-conf:mtu)

| **Key:**     | `mtu`      |
|--------------|------------|
| **Type:**    | integer    |
| **Default:** | parent MTU |

<a id="device-nic-ipvlan-device-conf:name"></a>
`name`

Name of the interface inside the instance

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-ipvlan-device-conf:name)

| **Key:**     | `name`          |
|--------------|-----------------|
| **Type:**    | string          |
| **Default:** | kernel assigned |

<a id="device-nic-ipvlan-device-conf:parent"></a>
`parent`

Name of the host device

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-ipvlan-device-conf:parent)

| **Key:**      | `parent`   |
|---------------|------------|
| **Type:**     | string     |
| **Required:** | yes        |

<a id="device-nic-ipvlan-device-conf:vlan"></a>
`vlan`

VLAN ID to attach to

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-ipvlan-device-conf:vlan)

| **Key:**    | `vlan`   |
|-------------|----------|
| **Type:**   | integer  |

#### Configuration examples

Add an `ipvlan` network device to an instance, connecting to an existing network interface with `nictype`:

```none
lxc stop <instance_name>
lxc config device add <instance_name> <device_name> nic nictype=ipvlan parent=<existing_NIC>
```

Adding an `ipvlan` network device to an instance using a managed network is not possible.

See [Configure devices](../howto/instances_configure.md#instances-configure-devices) for more information.

<a id="nic-p2p"></a>

### `nictype`: `p2p`

#### NOTE
You can select this NIC type only through the `nictype` option.

A `p2p` NIC creates a virtual device pair, putting one side in the instance and leaving the other side on the host.

#### Device options

NIC devices of type `p2p` have the following device options:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="device-nic-p2p-device-conf:boot.priority"></a>
`boot.priority`

Boot priority for VMs

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-p2p-device-conf:boot.priority)

| **Key:**    | `boot.priority`   |
|-------------|-------------------|
| **Type:**   | integer           |

A higher value for this option means that the VM boots first.

<a id="device-nic-p2p-device-conf:host_name"></a>
`host_name`

Name of the interface inside the host

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-p2p-device-conf:host_name)

| **Key:**     | `host_name`       |
|--------------|-------------------|
| **Type:**    | string            |
| **Default:** | randomly assigned |

<a id="device-nic-p2p-device-conf:hwaddr"></a>
`hwaddr`

MAC address of the new interface

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-p2p-device-conf:hwaddr)

| **Key:**     | `hwaddr`          |
|--------------|-------------------|
| **Type:**    | string            |
| **Default:** | randomly assigned |

<a id="device-nic-p2p-device-conf:ipv4.routes"></a>
`ipv4.routes`

IPv4 static routes for the NIC to add on the host

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-p2p-device-conf:ipv4.routes)

| **Key:**    | `ipv4.routes`   |
|-------------|-----------------|
| **Type:**   | string          |

Specify a comma-delimited list of IPv4 static routes for this NIC to add on the host.

<a id="device-nic-p2p-device-conf:ipv6.routes"></a>
`ipv6.routes`

IPv6 static routes for the NIC to add on the host

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-p2p-device-conf:ipv6.routes)

| **Key:**    | `ipv6.routes`   |
|-------------|-----------------|
| **Type:**   | string          |

Specify a comma-delimited list of IPv6 static routes for this NIC to add on the host.

<a id="device-nic-p2p-device-conf:limits.egress"></a>
`limits.egress`

I/O limit for outgoing traffic

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-p2p-device-conf:limits.egress)

| **Key:**    | `limits.egress`   |
|-------------|-------------------|
| **Type:**   | string            |

Specify the limit in bit/s. Various suffixes are supported (see [Units for storage and network limits](instance_units.md#instances-limit-units)).

<a id="device-nic-p2p-device-conf:limits.ingress"></a>
`limits.ingress`

I/O limit for incoming traffic

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-p2p-device-conf:limits.ingress)

| **Key:**    | `limits.ingress`   |
|-------------|--------------------|
| **Type:**   | string             |

Specify the limit in bit/s. Various suffixes are supported (see [Units for storage and network limits](instance_units.md#instances-limit-units)).

<a id="device-nic-p2p-device-conf:limits.max"></a>
`limits.max`

I/O limit for both incoming and outgoing traffic

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-p2p-device-conf:limits.max)

| **Key:**    | `limits.max`   |
|-------------|----------------|
| **Type:**   | string         |

This option is the same as setting both [`limits.ingress`](#device-nic-bridged-device-conf:limits.ingress) and [`limits.egress`](#device-nic-bridged-device-conf:limits.egress).

Specify the limit in bit/s. Various suffixes are supported (see [Units for storage and network limits](instance_units.md#instances-limit-units)).

<a id="device-nic-p2p-device-conf:limits.priority"></a>
`limits.priority`

`skb->priority` value for outgoing traffic

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-p2p-device-conf:limits.priority)

| **Key:**    | `limits.priority`   |
|-------------|---------------------|
| **Type:**   | integer             |

The `skb->priority` value for outgoing traffic is used by the kernel queuing discipline (qdisc) to prioritize network packets.
Specify the value as a 32-bit unsigned integer.

The effect of this value depends on the particular qdisc implementation, for example, `SKBPRIO` or `QFQ`.
Consult the kernel qdisc documentation before setting this value.

<a id="device-nic-p2p-device-conf:mtu"></a>
`mtu`

MTU of the new interface

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-p2p-device-conf:mtu)

| **Key:**     | `mtu`           |
|--------------|-----------------|
| **Type:**    | integer         |
| **Default:** | kernel assigned |

<a id="device-nic-p2p-device-conf:name"></a>
`name`

Name of the interface inside the instance

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-p2p-device-conf:name)

| **Key:**     | `name`          |
|--------------|-----------------|
| **Type:**    | string          |
| **Default:** | kernel assigned |

<a id="device-nic-p2p-device-conf:queue.tx.length"></a>
`queue.tx.length`

Transmit queue length for the NIC

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-p2p-device-conf:queue.tx.length)

| **Key:**    | `queue.tx.length`   |
|-------------|---------------------|
| **Type:**   | integer             |

#### Configuration examples

Add a `p2p` network device to an instance using `nictype`:

```none
lxc config device add <instance_name> <device_name> nic nictype=p2p
```

Adding a `p2p` network device to an instance using a managed network is not possible.

See [Configure devices](../howto/instances_configure.md#instances-configure-devices) for more information.

<a id="nic-routed"></a>

### `nictype`: `routed`

#### NOTE
You can select this NIC type only through the `nictype` option.

A `routed` NIC creates a virtual device pair to connect the host to the instance and sets up static routes and proxy ARP/NDP entries to allow the instance to join the network of a designated parent interface.
For containers it uses a virtual Ethernet device pair, and for VMs it uses a TAP device.

This NIC type is similar in operation to `ipvlan`, in that it allows an instance to join an external network without needing to configure a bridge and shares the host’s MAC address.
However, it differs from `ipvlan` because it does not need IPVLAN support in the kernel, and the host and the instance can communicate with each other.

This NIC type respects `netfilter` rules on the host and uses the host’s routing table to route packets, which can be useful if the host is connected to multiple networks.

IP addresses, gateways and routes
: You must manually specify the IP addresses (using `ipv4.address` and/or `ipv6.address`) before the instance is started.
  <br/>
  For containers, the NIC configures the following link-local gateway IPs on the host end and sets them as the default gateways in the container’s NIC interface:
  <br/>
  ```none
  169.254.0.1
  fe80::1
  ```
  <br/>
  For VMs, the gateways must be configured manually or via a mechanism like `cloud-init` (see the [how to guide](../howto/instances_routed_nic_vm.md#instances-routed-nic-vm)).
  <br/>
  #### NOTE
  If your container image is configured to perform DHCP on the interface, it will likely remove the automatically added configuration.
  In this case, you must configure the IP addresses and gateways manually or via a mechanism like `cloud-init`.
  <br/>
  The NIC type configures static routes on the host pointing to the instance’s `veth` interface for all of the instance’s IPs.

Multiple IP addresses
: Each NIC device can have multiple IP addresses added to it.
  <br/>
  However, it might be preferable to use multiple `routed` NIC interfaces instead.
  In this case, set the `ipv4.gateway` and `ipv6.gateway` values to `none` on any subsequent interfaces to avoid default gateway conflicts.
  Also consider specifying a different host-side address for these subsequent interfaces using `ipv4.host_address` and/or `ipv6.host_address`.

<a id="nic-routed-parent"></a>

Parent interface
: This NIC can operate with and without a `parent` network interface set.

: With the `parent` network interface set, proxy ARP/NDP entries of the instance’s IPs are added to the parent interface, which allows the instance to join the parent interface’s network at layer 2.

: To enable this, the following network configuration must be applied on the host via `sysctl`:
  <br/>
  - When using IPv4 addresses:
    ```default
    net.ipv4.conf.<parent>.forwarding=1
    ```
  - When using IPv6 addresses:
    ```default
    net.ipv6.conf.all.forwarding=1
    net.ipv6.conf.<parent>.forwarding=1
    net.ipv6.conf.all.proxy_ndp=1
    net.ipv6.conf.<parent>.proxy_ndp=1
    ```

#### Device options

NIC devices of type `routed` have the following device options:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="device-nic-routed-device-conf:gvrp"></a>
`gvrp`

Whether to use GARP VLAN Registration Protocol

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-routed-device-conf:gvrp)

| **Key:**     | `gvrp`   |
|--------------|----------|
| **Type:**    | bool     |
| **Default:** | `false`  |

This option specifies whether to register the VLAN using the GARP VLAN Registration Protocol.

<a id="device-nic-routed-device-conf:host_name"></a>
`host_name`

Name of the interface inside the host

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-routed-device-conf:host_name)

| **Key:**     | `host_name`       |
|--------------|-------------------|
| **Type:**    | string            |
| **Default:** | randomly assigned |

<a id="device-nic-routed-device-conf:hwaddr"></a>
`hwaddr`

MAC address of the new interface

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-routed-device-conf:hwaddr)

| **Key:**     | `hwaddr`          |
|--------------|-------------------|
| **Type:**    | string            |
| **Default:** | randomly assigned |

<a id="device-nic-routed-device-conf:ipv4.address"></a>
`ipv4.address`

IPv4 static addresses to add to the instance

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-routed-device-conf:ipv4.address)

| **Key:**    | `ipv4.address`   |
|-------------|------------------|
| **Type:**   | string           |

Specify a comma-delimited list of IPv4 static addresses to add to the instance.

<a id="device-nic-routed-device-conf:ipv4.gateway"></a>
`ipv4.gateway`

Whether to add an automatic default IPv4 gateway

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-routed-device-conf:ipv4.gateway)

| **Key:**     | `ipv4.gateway`   |
|--------------|------------------|
| **Type:**    | string           |
| **Default:** | `auto`           |

Possible values are `auto` and `none`.

<a id="device-nic-routed-device-conf:ipv4.host_address"></a>
`ipv4.host_address`

IPv4 address to add to the host-side `veth` interface

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-routed-device-conf:ipv4.host_address)

| **Key:**     | `ipv4.host_address`   |
|--------------|-----------------------|
| **Type:**    | string                |
| **Default:** | `169.254.0.1`         |

<a id="device-nic-routed-device-conf:ipv4.host_table"></a>
`ipv4.host_table`

Custom policy routing table ID to add IPv4 static routes to

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-routed-device-conf:ipv4.host_table)

| **Key:**    | `ipv4.host_table`   |
|-------------|---------------------|
| **Type:**   | integer             |

The custom policy routing table is in addition to the main routing table.

<a id="device-nic-routed-device-conf:ipv4.neighbor_probe"></a>
`ipv4.neighbor_probe`

Whether to probe the parent network for IPv4 address availability

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-routed-device-conf:ipv4.neighbor_probe)

| **Key:**     | `ipv4.neighbor_probe`   |
|--------------|-------------------------|
| **Type:**    | bool                    |
| **Default:** | `true`                  |

<a id="device-nic-routed-device-conf:ipv4.routes"></a>
`ipv4.routes`

IPv4 static routes for the NIC to add on the host

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-routed-device-conf:ipv4.routes)

| **Key:**    | `ipv4.routes`   |
|-------------|-----------------|
| **Type:**   | string          |

Specify a comma-delimited list of IPv4 static routes for this NIC to add on the host (without L2 ARP/NDP proxy).

<a id="device-nic-routed-device-conf:ipv6.address"></a>
`ipv6.address`

IPv6 static addresses to add to the instance

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-routed-device-conf:ipv6.address)

| **Key:**    | `ipv6.address`   |
|-------------|------------------|
| **Type:**   | string           |

Specify a comma-delimited list of IPv6 static addresses to add to the instance.

<a id="device-nic-routed-device-conf:ipv6.gateway"></a>
`ipv6.gateway`

Whether to add an automatic default IPv6 gateway

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-routed-device-conf:ipv6.gateway)

| **Key:**     | `ipv6.gateway`   |
|--------------|------------------|
| **Type:**    | string           |
| **Default:** | `auto`           |

Possible values are `auto` and `none`.

<a id="device-nic-routed-device-conf:ipv6.host_address"></a>
`ipv6.host_address`

IPv6 address to add to the host-side `veth` interface

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-routed-device-conf:ipv6.host_address)

| **Key:**     | `ipv6.host_address`   |
|--------------|-----------------------|
| **Type:**    | string                |
| **Default:** | `fe80::1`             |

<a id="device-nic-routed-device-conf:ipv6.host_table"></a>
`ipv6.host_table`

Custom policy routing table ID to add IPv6 static routes to

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-routed-device-conf:ipv6.host_table)

| **Key:**    | `ipv6.host_table`   |
|-------------|---------------------|
| **Type:**   | integer             |

The custom policy routing table is in addition to the main routing table.

<a id="device-nic-routed-device-conf:ipv6.neighbor_probe"></a>
`ipv6.neighbor_probe`

Whether to probe the parent network for IPv6 address availability

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-routed-device-conf:ipv6.neighbor_probe)

| **Key:**     | `ipv6.neighbor_probe`   |
|--------------|-------------------------|
| **Type:**    | bool                    |
| **Default:** | `true`                  |

<a id="device-nic-routed-device-conf:ipv6.routes"></a>
`ipv6.routes`

IPv6 static routes for the NIC to add on the host

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-routed-device-conf:ipv6.routes)

| **Key:**    | `ipv6.routes`   |
|-------------|-----------------|
| **Type:**   | string          |

Specify a comma-delimited list of IPv6 static routes for this NIC to add on the host (without L2 ARP/NDP proxy).

<a id="device-nic-routed-device-conf:limits.egress"></a>
`limits.egress`

I/O limit for outgoing traffic

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-routed-device-conf:limits.egress)

| **Key:**    | `limits.egress`   |
|-------------|-------------------|
| **Type:**   | string            |

Specify the limit in bit/s. Various suffixes are supported (see [Units for storage and network limits](instance_units.md#instances-limit-units)).

<a id="device-nic-routed-device-conf:limits.ingress"></a>
`limits.ingress`

I/O limit for incoming traffic

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-routed-device-conf:limits.ingress)

| **Key:**    | `limits.ingress`   |
|-------------|--------------------|
| **Type:**   | string             |

Specify the limit in bit/s. Various suffixes are supported (see [Units for storage and network limits](instance_units.md#instances-limit-units)).

<a id="device-nic-routed-device-conf:limits.max"></a>
`limits.max`

I/O limit for both incoming and outgoing traffic

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-routed-device-conf:limits.max)

| **Key:**    | `limits.max`   |
|-------------|----------------|
| **Type:**   | string         |

This option is the same as setting both [`limits.ingress`](#device-nic-bridged-device-conf:limits.ingress) and [`limits.egress`](#device-nic-bridged-device-conf:limits.egress).

Specify the limit in bit/s. Various suffixes are supported (see [Units for storage and network limits](instance_units.md#instances-limit-units)).

<a id="device-nic-routed-device-conf:limits.priority"></a>
`limits.priority`

`skb->priority` value for outgoing traffic

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-routed-device-conf:limits.priority)

| **Key:**    | `limits.priority`   |
|-------------|---------------------|
| **Type:**   | integer             |

The `skb->priority` value for outgoing traffic is used by the kernel queuing discipline (qdisc) to prioritize network packets.
Specify the value as a 32-bit unsigned integer.

The effect of this value depends on the particular qdisc implementation, for example, `SKBPRIO` or `QFQ`.
Consult the kernel qdisc documentation before setting this value.

<a id="device-nic-routed-device-conf:mtu"></a>
`mtu`

The MTU of the new interface

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-routed-device-conf:mtu)

| **Key:**     | `mtu`      |
|--------------|------------|
| **Type:**    | integer    |
| **Default:** | parent MTU |

<a id="device-nic-routed-device-conf:name"></a>
`name`

Name of the interface inside the instance

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-routed-device-conf:name)

| **Key:**     | `name`          |
|--------------|-----------------|
| **Type:**    | string          |
| **Default:** | kernel assigned |

<a id="device-nic-routed-device-conf:parent"></a>
`parent`

Name of the host device to join the instance to

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-routed-device-conf:parent)

| **Key:**    | `parent`   |
|-------------|------------|
| **Type:**   | string     |

<a id="device-nic-routed-device-conf:queue.tx.length"></a>
`queue.tx.length`

Transmit queue length for the NIC

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-routed-device-conf:queue.tx.length)

| **Key:**    | `queue.tx.length`   |
|-------------|---------------------|
| **Type:**   | integer             |

<a id="device-nic-routed-device-conf:vlan"></a>
`vlan`

VLAN ID to attach to

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-nic-routed-device-conf:vlan)

| **Key:**    | `vlan`   |
|-------------|----------|
| **Type:**   | integer  |

#### Configuration examples

Add a `routed` network device to an instance using `nictype`:

```none
lxc config device add <instance_name> <device_name> nic nictype=routed ipv4.address=192.0.2.2 ipv6.address=2001:db8::2
```

Adding a `routed` network device to an instance using a managed network is not possible.

See [Configure devices](../howto/instances_configure.md#instances-configure-devices) for more information.

## `bridged`, `macvlan` or `ipvlan` for connection to physical network

The `bridged`, `macvlan` and `ipvlan` interface types can be used to connect to an existing physical network.

`macvlan` effectively lets you fork your physical NIC, getting a second interface that is then used by the instance.
This method saves you from creating a bridge device and virtual Ethernet device pairs and usually offers better performance than a bridge.

The downside to this method is that `macvlan` devices, while able to communicate between themselves and to the outside, cannot talk to their parent device.
This means that you can’t use `macvlan` if you ever need your instances to talk to the host itself.

In such case, a `bridge` device is preferable.
A bridge also lets you use MAC filtering and I/O limits, which cannot be applied to a `macvlan` device.

`ipvlan` is similar to `macvlan`, with the difference being that the forked device has IPs statically assigned to it and inherits the parent’s MAC address on the network.


# index.html.md

<a id="devices-none"></a>

# Type: `none`


            <p class="youtube_link">
              <a href="https://www.youtube.com/watch?v=6NCLnd5_guQ" target="_blank">
                <span title="LXD none devices" class="play_icon">▶</span>
                <span title="LXD none devices">Watch on YouTube</span>
              </a>
            </p>
        
#### NOTE
The `none` device type is supported for both containers and VMs.

A `none` device doesn’t have any properties and doesn’t create anything inside the instance.

Its only purpose is to stop inheriting devices that come from profiles.
To do so, add a device with the same name as the one that you do not want to inherit, but with the device type `none`.

You can add this device either in a profile that is applied after the profile that contains the original device, or directly on the instance.

## Configuration examples

Add a `none` device to an instance:

```none
lxc config device add <instance_name> <device_name> none
```

See [Configure devices](../howto/instances_configure.md#instances-configure-devices) for more information.


# index.html.md

<a id="devices-infiniband"></a>

# Type: `infiniband`


            <p class="youtube_link">
              <a href="https://www.youtube.com/watch?v=SDewhlRSOuM" target="_blank">
                <span title="LXD InfiniBand devices - YouTube" class="play_icon">▶</span>
                <span title="LXD InfiniBand devices - YouTube">Watch on YouTube</span>
              </a>
            </p>
        
#### NOTE
The `infiniband` device type is supported for both containers and VMs.
It supports hotplugging only for containers, not for VMs.

LXD supports two different kinds of network types for InfiniBand devices:

- `physical`: Passes a physical device from the host through to the instance.
  The targeted device will vanish from the host and appear in the instance.
- `sriov`: Passes a virtual function of an SR-IOV-enabled physical network device into the instance.

  #### NOTE
  InfiniBand devices support SR-IOV, but in contrast to other SR-IOV-enabled devices, InfiniBand does not support dynamic device creation in SR-IOV mode.
  Therefore, you must pre-configure the number of virtual functions by configuring the corresponding kernel module.

## Device options

`infiniband` devices have the following device options:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="device-infiniband-device-conf:hwaddr"></a>
`hwaddr`

MAC address of the new interface

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-infiniband-device-conf:hwaddr)

| **Key:**      | `hwaddr`          |
|---------------|-------------------|
| **Type:**     | string            |
| **Default:**  | randomly assigned |
| **Required:** | no                |

You can specify either the full 20-byte variant or the short 8-byte variant (which will modify only the last 8 bytes of the parent device).

<a id="device-infiniband-device-conf:mtu"></a>
`mtu`

MTU of the new interface

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-infiniband-device-conf:mtu)

| **Key:**      | `mtu`      |
|---------------|------------|
| **Type:**     | integer    |
| **Default:**  | parent MTU |
| **Required:** | no         |

<a id="device-infiniband-device-conf:name"></a>
`name`

Name of the interface inside the instance

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-infiniband-device-conf:name)

| **Key:**      | `name`          |
|---------------|-----------------|
| **Type:**     | string          |
| **Default:**  | kernel assigned |
| **Required:** | no              |

<a id="device-infiniband-device-conf:nictype"></a>
`nictype`

Device type

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-infiniband-device-conf:nictype)

| **Key:**      | `nictype`   |
|---------------|-------------|
| **Type:**     | string      |
| **Required:** | yes         |

Possible values are `physical` and `sriov`.

<a id="device-infiniband-device-conf:parent"></a>
`parent`

The name of the host device or bridge

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-infiniband-device-conf:parent)

| **Key:**      | `parent`   |
|---------------|------------|
| **Type:**     | string     |
| **Required:** | yes        |

## Configuration examples

Add a `physical` `infiniband` device to an instance:

```none
lxc config device add <instance_name> <device_name> infiniband nictype=physical parent=<device>
```

Add an `sriov` `infiniband` device to an instance:

```none
lxc config device add <instance_name> <device_name> infiniband nictype=sriov parent=<sriov_enabled_device>
```

See [Configure devices](../howto/instances_configure.md#instances-configure-devices) for more information.


# index.html.md

<a id="storage-cephobject"></a>

# Ceph Object - `cephobject`

<!-- Include content from [storage_ceph.md](storage_ceph.md) -->

[Ceph](https://ceph.io/en/) is an open-source storage platform that stores its data in a storage cluster based on .
It is highly scalable and, as a distributed system without a single point of failure, very reliable.

Ceph provides different components for block storage and for file systems.

[Ceph Object Gateway](https://docs.ceph.com/en/latest/radosgw/) is an object storage interface built on top of [`librados`](https://docs.ceph.com/en/latest/rados/api/librados-intro/) to provide applications with a RESTful gateway to [Ceph Storage Clusters](https://docs.ceph.com/en/latest/rados/).
It provides object storage functionality with an interface that is compatible with a large subset of the Amazon S3 RESTful API.

## Terminology

<!-- Include content from [storage_ceph.md](storage_ceph.md) -->

Ceph uses the term *object* for the data that it stores.
The daemon that is responsible for storing and managing data is the *Ceph* .
Ceph’s storage is divided into *pools*, which are logical partitions for storing objects.
They are also referred to as *data pools*, *storage pools* or *OSD pools*.

A *Ceph Object Gateway* consists of several OSD pools and one or more *Ceph Object Gateway daemon* (`radosgw`) processes that provide object gateway functionality.

## `cephobject` driver in LXD

#### NOTE
The `cephobject` driver can only be used for buckets.

For storage volumes, use the [Ceph](storage_ceph.md#storage-ceph) or [CephFS](storage_cephfs.md#storage-cephfs) drivers.

<!-- Include content from [storage_ceph.md](storage_ceph.md) -->

Unlike other storage drivers, this driver does not set up the storage system but assumes that you already have a Ceph cluster installed.

You must set up a `radosgw` environment beforehand and ensure that its HTTP/HTTPS endpoint URL is reachable from the LXD server or servers.
See [Manual Deployment](https://docs.ceph.com/en/latest/install/manual-deployment/) for information on how to set up a Ceph cluster and [Ceph Object Gateway](https://docs.ceph.com/en/latest/radosgw/) on how to set up a `radosgw` environment.

The `radosgw` URL can be specified at pool creation time using the [`cephobject.radosgw.endpoint`](#storage-cephobject-pool-conf:cephobject.radosgw.endpoint) option.

LXD uses the `radosgw-admin` command to manage buckets. So this command must be available and operational on the LXD servers.

<!-- Include content from [storage_ceph.md](storage_ceph.md) -->

This driver also behaves differently than other drivers in that it provides remote storage.
As a result and depending on the internal network, storage access might be a bit slower than for local storage.
On the other hand, using remote storage has big advantages in a cluster setup, because all cluster members have access to the same storage pools with the exact same contents, without the need to synchronize storage pools.

<!-- Include content from [storage_ceph.md](storage_ceph.md) -->

LXD assumes that it has full control over the OSD storage pool.
Therefore, you should never maintain any file system entities that are not owned by LXD in a LXD OSD storage pool, because LXD might delete them.

## Configuration options

The following configuration options are available for storage pools that use the `cephobject` driver and for storage buckets in these pools.

<a id="storage-cephobject-pool-config"></a>

### Storage pool configuration

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="storage-cephobject-pool-conf:cephobject.bucket.name_prefix"></a>
`cephobject.bucket.name_prefix`

Prefix to add to bucket names in Ceph

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-cephobject-pool-conf:cephobject.bucket.name_prefix)

| **Key:**    | `cephobject.bucket.name_prefix`   |
|-------------|-----------------------------------|
| **Type:**   | string                            |
| **Scope:**  | global                            |

<a id="storage-cephobject-pool-conf:cephobject.cluster_name"></a>
`cephobject.cluster_name`

The Ceph cluster to use

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-cephobject-pool-conf:cephobject.cluster_name)

| **Key:**    | `cephobject.cluster_name`   |
|-------------|-----------------------------|
| **Type:**   | string                      |
| **Scope:**  | global                      |

<a id="storage-cephobject-pool-conf:cephobject.radosgw.endpoint"></a>
`cephobject.radosgw.endpoint`

URL of the `radosgw` gateway process

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-cephobject-pool-conf:cephobject.radosgw.endpoint)

| **Key:**    | `cephobject.radosgw.endpoint`   |
|-------------|---------------------------------|
| **Type:**   | string                          |
| **Scope:**  | global                          |

<a id="storage-cephobject-pool-conf:cephobject.radosgw.endpoint_cert_file"></a>
`cephobject.radosgw.endpoint_cert_file`

TLS client certificate to use for endpoint communication

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-cephobject-pool-conf:cephobject.radosgw.endpoint_cert_file)

| **Key:**    | `cephobject.radosgw.endpoint_cert_file`   |
|-------------|-------------------------------------------|
| **Type:**   | string                                    |
| **Scope:**  | global                                    |

Specify the path to the file that contains the TLS client certificate.

<a id="storage-cephobject-pool-conf:cephobject.user.name"></a>
`cephobject.user.name`

The Ceph user to use

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-cephobject-pool-conf:cephobject.user.name)

| **Key:**     | `cephobject.user.name`   |
|--------------|--------------------------|
| **Type:**    | string                   |
| **Default:** | `admin`                  |
| **Scope:**   | global                   |

<a id="storage-cephobject-pool-conf:volatile.pool.pristine"></a>
`volatile.pool.pristine`

Whether the `radosgw` `lxd-admin` user existed at creation time

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-cephobject-pool-conf:volatile.pool.pristine)

| **Key:**     | `volatile.pool.pristine`   |
|--------------|----------------------------|
| **Type:**    | string                     |
| **Default:** | `true`                     |
| **Scope:**   | global                     |

### Storage bucket configuration

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="storage-cephobject-bucket-conf:size"></a>
`size`

Quota of the storage bucket

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-cephobject-bucket-conf:size)

| **Key:**    | `size`   |
|-------------|----------|
| **Type:**   | string   |
| **Scope:**  | local    |


# index.html.md

<a id="preseed-yaml-file-fields"></a>

# Preseed YAML file fields

You can configure a new LXD installation and reconfigure an existing installation with a preseed YAML file.

The preseed YAML file fields are as follows:

```yaml
config:
  core.https_address: ""
  images.auto_update_interval: 6

networks:
  - config:
      ipv4.address: auto
      ipv4.nat: "true"
      ipv6.address: auto
      ipv6.nat: "true"
    description: ""
    name: lxdbr0
    type: bridge
    project: default

storage_pools:
  - config: {}
    description: ""
    name: default
    driver: zfs

storage_volumes:
- name: my-vol
  pool: data

profiles:
  - config:
      limits.memory: 2GiB
    description: Default LXD profile
    devices:
      eth0:
        name: eth0
        network: lxdbr0
        type: nic
      root:
        path: /
        pool: default
        type: disk
    name: default

projects:
  - config:
      features.images: "true"
      features.networks: "true"
      features.networks.zones: "true"
      features.profiles: "true"
      features.storage.buckets: "true"
      features.storage.volumes: "true"
    description: Default LXD project
    name: default

cluster:
  enabled: true
  server_address: ""
  cluster_token: ""
  member_config:
  - entity: storage-pool
    name: default
    key: source
    value: ""
  - entity: storage-pool
    name: my-pool
    key: source
    value: ""
  - entity: storage-pool
    name: my-pool
    key: driver
    value: "zfs"
```

## Related topics

How-to guides:

- [How to initialize LXD](../howto/initialize.md#initialize)


# index.html.md

<a id="instance-properties"></a>

# Instance properties

Instance properties are set when the instance is created.
They cannot be part of a [profile](../profiles.md#profiles).

The following instance properties are available:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="instance-property-instance-conf:architecture"></a>
`architecture`

Instance architecture

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-property-instance-conf:architecture)

| **Key:**       | `architecture`   |
|----------------|------------------|
| **Type:**      | string           |
| **Read-only:** | no               |

<a id="instance-property-instance-conf:name"></a>
`name`

Instance name

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-property-instance-conf:name)

| **Key:**       | `name`   |
|----------------|----------|
| **Type:**      | string   |
| **Read-only:** | yes      |

See [Instance name requirements](#instance-name-requirements).

<a id="instance-name-requirements"></a>

## Instance name requirements

The instance name can be changed only by renaming the instance with the [`lxc rename`](manpages/lxc/rename.md#lxc-rename-md) command.

Valid instance names must fulfill the following requirements:

- The name must be between 1 and 63 characters long.
- The name must contain only letters, numbers and dashes from the ASCII table.
- The name must not start with a digit or a dash.
- The name must not end with a dash.

The purpose of these requirements is to ensure that the instance name can be used in DNS records, on the file system, in various security profiles and as the host name of the instance itself.


# index.html.md

<a id="storage-zfs"></a>

# ZFS - `zfs`


            <p class="youtube_link">
              <a href="https://www.youtube.com/watch?v=ysLi_LYAs_M" target="_blank">
                <span title="ZFS storage and LXD" class="play_icon">▶</span>
                <span title="ZFS storage and LXD">Watch on YouTube</span>
              </a>
            </p>
        
 combines both physical volume management and a file system.
A ZFS installation can span across a series of storage devices and is very scalable, allowing you to add disks to expand the available space in the storage pool immediately.

ZFS is a block-based file system that protects against data corruption by using checksums to verify, confirm and correct every operation.
To run at a sufficient speed, this mechanism requires a powerful environment with a lot of RAM.

In addition, ZFS offers snapshots and replication, RAID management, copy-on-write clones, compression and other features.

To use ZFS, make sure you have `zfsutils-linux` installed on your machine.

## Terminology

ZFS creates logical units based on physical storage devices.
These logical units are called *ZFS pools* or *zpools*.
Each zpool is then divided into a number of  *<spellexception>datasets</spellexception>*.
These <spellexception>datasets</spellexception> can be of different types:

- A  *<spellexception>ZFS filesystem</spellexception>* can be seen as a partition or a mounted file system.
- A *ZFS volume* represents a block device.
- A *ZFS snapshot* captures a specific state of either a <spellexception>ZFS filesystem</spellexception> or a ZFS volume.
  ZFS snapshots are read-only.
- A *ZFS clone* is a writable copy of a ZFS snapshot.

## `zfs` driver in LXD

The `zfs` driver in LXD uses <spellexception>ZFS filesystems</spellexception> and ZFS volumes for images and custom storage volumes, and ZFS snapshots and clones to create instances from images and for instance and custom volume snapshots.
By default, LXD enables compression when creating a ZFS pool.

LXD assumes that it has full control over the ZFS pool and <spellexception>dataset</spellexception>.
Therefore, you should never maintain any <spellexception>datasets</spellexception> or file system entities that are not owned by LXD in a ZFS pool or <spellexception>dataset</spellexception>, because LXD might delete them.

Due to the way copy-on-write works in ZFS, parent <spellexception>ZFS filesystems</spellexception> can’t be removed until all children are gone.
As a result, LXD automatically renames any objects that are removed but still referenced.
Such objects are kept at a random `deleted/` path until all references are gone and the object can safely be removed.
Note that this method might have ramifications for restoring snapshots.
See [Limitations](#storage-zfs-limitations) below.

LXD automatically enables trimming support on all newly created pools on ZFS 0.8 or later.
This increases the lifetime of SSDs by allowing better block re-use by the controller, and it also allows to free space on the root file system when using a loop-backed ZFS pool.
If you are running a ZFS version earlier than 0.8 and want to enable trimming, upgrade to at least version 0.8.
Then use the following commands to make sure that trimming is automatically enabled for the ZFS pool in the future and trim all currently unused space:

```none
zpool upgrade ZPOOL-NAME
zpool set autotrim=on ZPOOL-NAME
zpool trim ZPOOL-NAME
```

<a id="storage-zfs-image-variants"></a>

### Image variants and optimized instance creation

The ZFS driver supports optimized image volumes that significantly reduce instance creation time.

If an image is unpacked into an optimized image volume, when LXD creates an instance from that image, it can clone the instance from that volume rather than unpacking from scratch.
This speeds up instance creation.

The ZFS driver can maintain multiple variants of the same optimized image volume to support fast instance creation when using instance-specific initial root disk settings (see [Initial volume configuration for instance root disk devices](devices_disk.md#devices-disk-initial-config)).

#### Variant types

LXD can maintain multiple optimized image volumes for the same image, representing different volume configurations:

- **Dataset variant** (dataset mode): A `ZFS filesystem` dataset created when [`zfs.block_mode`](#storage-zfs-volume-conf:zfs.block_mode) is `false`.
- **Block-backed variants**: ZFS volumes with specific filesystems (ext4, btrfs, xfs) created when [`zfs.block_mode`](#storage-zfs-volume-conf:zfs.block_mode) is `true`.

#### Variant lifecycle

Variants are created lazily on demand when an instance requests a configuration that doesn’t match an existing variant.

A variant is deleted when one of the following events occurs:

- The last instance that uses the variant is removed.
- The variant is not used by any instance and the image is deleted.
- The variant is not used by any instance and the pool configuration is changed such that the variant no longer matches the new pool defaults (for example, a change from dataset mode to block mode).

Variants with active instances are always preserved regardless of image deletion or configuration changes.

#### Configuration

Changing pool configuration frequently can reduce optimization benefits, as variants may need to be recreated.
To optimize instance creation, set up default pool configurations and create instances that use those defaults (you can still override those settings for specific instances as needed):

- **Pool default**: Set [`zfs.block_mode`](#storage-zfs-volume-conf:zfs.block_mode) and [`block.filesystem`](#storage-zfs-volume-conf:block.filesystem) at the pool level during pool creation by using the `volume.` prefix.
- **Instance override**: Use `initial.zfs.block_mode` and `initial.block.filesystem` [device configuration](devices_disk.md#devices-disk-initial-config) for instances that require different settings.

#### Performance benefits

Using image variants provides:

- Faster instance creation (the time to clone a volume with ZFS is unrelated to the volume size).
- Minimal disk I/O during instance creation (metadata operations only).
- Copy-on-write space efficiency (instances initially share data with the image variant).

<a id="storage-zfs-limitations"></a>

### Limitations

The `zfs` driver has the following limitations:

Restoring from older snapshots
: ZFS doesn’t support restoring from snapshots other than the latest one.
  You can, however, create new instances from older snapshots.
  This method makes it possible to confirm whether a specific snapshot contains what you need.
  After determining the correct snapshot, you can [remove the newer snapshots](../howto/storage_backup_volume.md#storage-edit-snapshots) so that the snapshot you need is the latest one and you can restore it.
  <br/>
  Alternatively, you can configure LXD to automatically discard the newer snapshots during restore.
  To do so, set the [`zfs.remove_snapshots`](#storage-zfs-volume-conf:zfs.remove_snapshots) configuration for the volume (or the corresponding `volume.zfs.remove_snapshots` configuration on the storage pool for all volumes in the pool).
  <br/>
  Note, however, that if [`zfs.clone_copy`](#storage-zfs-pool-conf:zfs.clone_copy) is set to `true`, instance copies use ZFS snapshots too.
  In that case, you cannot restore an instance to a snapshot taken before the last copy without having to also delete all its descendants.
  If this is not an option, you can copy the wanted snapshot into a new instance and then delete the old instance.
  You will, however, lose any other snapshots the instance might have had.

Observing I/O quotas
: I/O quotas are unlikely to affect <spellexception>ZFS filesystems</spellexception> very much.
  That’s because ZFS is a port of a Solaris module (using SPL) and not a native Linux file system using the Linux VFS API, which is where I/O limits are applied.

Feature support in ZFS
: Some features, like the use of idmaps or delegation of a ZFS dataset, require ZFS 2.2 or higher and are therefore not widely available yet.

### Quotas

ZFS provides two different quota properties: `quota` and `refquota`.
`quota` restricts the total size of a <spellexception>dataset</spellexception>, including its snapshots and clones.
`refquota` restricts only the size of the data in the <spellexception>dataset</spellexception>, not its snapshots and clones.

By default, LXD uses the `quota` property when you set up a size/quota for your storage volume.
If you want to use the `refquota` property instead, set the [`zfs.use_refquota`](#storage-zfs-volume-conf:zfs.use_refquota) configuration for the volume (or the corresponding `volume.zfs.use_refquota` configuration on the storage pool for all volumes in the pool).

You can also set the [`zfs.reserve_space`](#storage-zfs-volume-conf:zfs.reserve_space) (or `volume.zfs.reserve_space`) configuration to use ZFS `reservation` or `refreservation` along with `quota` or `refquota`.

## Configuration options

The following configuration options are available for storage pools that use the `zfs` driver and for storage volumes in these pools.

<a id="storage-zfs-pool-config"></a>

### Storage pool configuration

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="storage-zfs-pool-conf:size"></a>
`size`

Size of the storage pool (for loop-based pools)

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-zfs-pool-conf:size)

| **Key:**     | `size`                                                |
|--------------|-------------------------------------------------------|
| **Type:**    | string                                                |
| **Default:** | auto (20% of free disk space, >= 5 GiB and <= 30 GiB) |
| **Scope:**   | local                                                 |

When creating loop-based pools, specify the size in bytes ([suffixes](instance_units.md#instances-limit-units) are supported).
You can increase the size to grow the storage pool.

The default (`auto`) creates a storage pool that uses 20% of the free disk space,
with a minimum of 5 GiB and a maximum of 30 GiB.

<a id="storage-zfs-pool-conf:source"></a>
`source`

Path to an existing block device, loop file, or ZFS dataset/pool

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-zfs-pool-conf:source)

| **Key:**    | `source`   |
|-------------|------------|
| **Type:**   | string     |
| **Scope:**  | local      |

<a id="storage-zfs-pool-conf:source.recover"></a>
`source.recover`

Whether to recover an existing `source`

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-zfs-pool-conf:source.recover)

| **Key:**     | `source.recover`   |
|--------------|--------------------|
| **Type:**    | bool               |
| **Default:** | `false`            |
| **Scope:**   | local              |

Set this option to true to recover an existing source which was previously created by LXD.

<a id="storage-zfs-pool-conf:source.wipe"></a>
`source.wipe`

Whether to wipe the block device before creating the pool

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-zfs-pool-conf:source.wipe)

| **Key:**     | `source.wipe`   |
|--------------|-----------------|
| **Type:**    | bool            |
| **Default:** | `false`         |
| **Scope:**   | local           |

Set this option to `true` to wipe the block device specified in `source`
prior to creating the storage pool.

<a id="storage-zfs-pool-conf:zfs.clone_copy"></a>
`zfs.clone_copy`

Whether to use ZFS lightweight clones

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-zfs-pool-conf:zfs.clone_copy)

| **Key:**     | `zfs.clone_copy`   |
|--------------|--------------------|
| **Type:**    | string             |
| **Default:** | `true`             |
| **Scope:**   | global             |

Set this option to `true` or `false` to enable or disable using ZFS lightweight clones rather
than full dataset copies.
Set the option to `rebase` to copy based on the initial image.

<a id="storage-zfs-pool-conf:zfs.export"></a>
`zfs.export`

Whether to export the zpool when an unmount is being performed

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-zfs-pool-conf:zfs.export)

| **Key:**     | `zfs.export`   |
|--------------|----------------|
| **Type:**    | bool           |
| **Default:** | `true`         |
| **Scope:**   | global         |

<a id="storage-zfs-pool-conf:zfs.pool_name"></a>
`zfs.pool_name`

Name of the zpool

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-zfs-pool-conf:zfs.pool_name)

| **Key:**     | `zfs.pool_name`   |
|--------------|-------------------|
| **Type:**    | string            |
| **Default:** | name of the pool  |
| **Scope:**   | local             |

<a id="storage-zfs-vol-config"></a>

### Storage volume configuration

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="storage-zfs-volume-conf:block.filesystem"></a>
`block.filesystem`

File system of the storage volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-zfs-volume-conf:block.filesystem)

| **Key:**       | `block.filesystem`                                                           |
|----------------|------------------------------------------------------------------------------|
| **Type:**      | string                                                                       |
| **Default:**   | same as `volume.block.filesystem`                                            |
| **Condition:** | block-based volume with content type `filesystem` (`zfs.block_mode` enabled) |
| **Scope:**     | global                                                                       |

Valid options: `btrfs`, `ext4`, `xfs`
If not set, `ext4` is assumed.

<a id="storage-zfs-volume-conf:block.mount_options"></a>
`block.mount_options`

Mount options for block-backed file system volumes

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-zfs-volume-conf:block.mount_options)

| **Key:**       | `block.mount_options`                                                        |
|----------------|------------------------------------------------------------------------------|
| **Type:**      | string                                                                       |
| **Default:**   | same as `volume.block.mount_options`                                         |
| **Condition:** | block-based volume with content type `filesystem` (`zfs.block_mode` enabled) |
| **Scope:**     | global                                                                       |

<a id="storage-zfs-volume-conf:security.shared"></a>
`security.shared`

Enable volume sharing

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-zfs-volume-conf:security.shared)

| **Key:**       | `security.shared`                           |
|----------------|---------------------------------------------|
| **Type:**      | bool                                        |
| **Default:**   | same as `volume.security.shared` or `false` |
| **Condition:** | virtual-machine or custom block volume      |
| **Scope:**     | global                                      |

Enable this option to allow the volume to be shared across multiple instances despite the possibility of data loss.

<a id="storage-zfs-volume-conf:security.shifted"></a>
`security.shifted`

Enable ID shifting overlay

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-zfs-volume-conf:security.shifted)

| **Key:**       | `security.shifted`                           |
|----------------|----------------------------------------------|
| **Type:**      | bool                                         |
| **Default:**   | same as `volume.security.shifted` or `false` |
| **Condition:** | custom volume                                |
| **Scope:**     | global                                       |

Enable this option to allow the volume to be attached to multiple isolated instances.

<a id="storage-zfs-volume-conf:security.unmapped"></a>
`security.unmapped`

Disable ID mapping for the volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-zfs-volume-conf:security.unmapped)

| **Key:**       | `security.unmapped`                           |
|----------------|-----------------------------------------------|
| **Type:**      | bool                                          |
| **Default:**   | same as `volume.security.unmapped` or `false` |
| **Condition:** | custom volume                                 |
| **Scope:**     | global                                        |

<a id="storage-zfs-volume-conf:size"></a>
`size`

Size/quota of the storage volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-zfs-volume-conf:size)

| **Key:**       | `size`                |
|----------------|-----------------------|
| **Type:**      | string                |
| **Default:**   | same as `volume.size` |
| **Condition:** | appropriate driver    |
| **Scope:**     | global                |

<a id="storage-zfs-volume-conf:snapshots.expiry"></a>
`snapshots.expiry`

Time until snapshots are deleted

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-zfs-volume-conf:snapshots.expiry)

| **Key:**       | `snapshots.expiry`                |
|----------------|-----------------------------------|
| **Type:**      | string                            |
| **Default:**   | same as `volume.snapshots.expiry` |
| **Condition:** | custom volume                     |
| **Scope:**     | global                            |

Specify an expression like `1M 2H 3d 4w 5m 6y`.

<a id="storage-zfs-volume-conf:snapshots.pattern"></a>
`snapshots.pattern`

Template for the snapshot name

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-zfs-volume-conf:snapshots.pattern)

| **Key:**       | `snapshots.pattern`                            |
|----------------|------------------------------------------------|
| **Type:**      | string                                         |
| **Default:**   | same as `volume.snapshots.pattern` or `snap%d` |
| **Condition:** | custom volume                                  |
| **Scope:**     | global                                         |

You can specify a naming template for scheduled snapshots and unnamed snapshots.

The `snapshots.pattern` option takes a Pongo2 template string to format the snapshot name.

To add a time stamp to the snapshot name, use the Pongo2 context variable `creation_date`.
Make sure to format the date in your template string to avoid forbidden characters in the snapshot name.
For example, set `snapshots.pattern` to `{{ creation_date|date:'2006-01-02_15-04-05' }}` to name the snapshots after their time of creation, down to the precision of a second.

Another way to avoid name collisions is to use the placeholder `%d` in the pattern.
If no matching snapshots exist, the placeholder is replaced with `0`.
Otherwise, it is replaced with the next snapshot index, which is one higher than the highest existing matching snapshot index.

<a id="storage-zfs-volume-conf:snapshots.schedule"></a>
`snapshots.schedule`

Schedule for automatic volume snapshots

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-zfs-volume-conf:snapshots.schedule)

| **Key:**       | `snapshots.schedule`         |
|----------------|------------------------------|
| **Type:**      | string                       |
| **Default:**   | same as `snapshots.schedule` |
| **Condition:** | custom volume                |
| **Scope:**     | global                       |

Specify either a cron expression (`<minute> <hour> <dom> <month> <dow>`), a comma-separated list of schedule aliases (`@hourly`, `@daily`, `@midnight`, `@weekly`, `@monthly`, `@annually`, `@yearly`), or leave empty to disable automatic snapshots (the default).

<a id="storage-zfs-volume-conf:volatile.devlxd.owner"></a>
`volatile.devlxd.owner`

ID of the DevLXD identity that owns the volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-zfs-volume-conf:volatile.devlxd.owner)

| **Key:**     | `volatile.devlxd.owner`   |
|--------------|---------------------------|
| **Type:**    | string                    |
| **Default:** | DevLXD owner identity ID  |
| **Scope:**   | global                    |

<a id="storage-zfs-volume-conf:volatile.idmap.last"></a>
`volatile.idmap.last`

JSON-serialized UID/GID map that has been applied to the volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-zfs-volume-conf:volatile.idmap.last)

| **Key:**       | `volatile.idmap.last`   |
|----------------|-------------------------|
| **Type:**      | string                  |
| **Condition:** | filesystem              |

<a id="storage-zfs-volume-conf:volatile.idmap.next"></a>
`volatile.idmap.next`

JSON-serialized UID/GID map that has been applied to the volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-zfs-volume-conf:volatile.idmap.next)

| **Key:**       | `volatile.idmap.next`   |
|----------------|-------------------------|
| **Type:**      | string                  |
| **Condition:** | filesystem              |

<a id="storage-zfs-volume-conf:volatile.uuid"></a>
`volatile.uuid`

Volume UUID

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-zfs-volume-conf:volatile.uuid)

| **Key:**     | `volatile.uuid`   |
|--------------|-------------------|
| **Type:**    | string            |
| **Default:** | random UUID       |
| **Scope:**   | global            |

<a id="storage-zfs-volume-conf:zfs.block_mode"></a>
`zfs.block_mode`

Whether to use a formatted `zvol` rather than a dataset

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-zfs-volume-conf:zfs.block_mode)

| **Key:**     | `zfs.block_mode`                |
|--------------|---------------------------------|
| **Type:**    | bool                            |
| **Default:** | same as `volume.zfs.block_mode` |
| **Scope:**   | global                          |

`zfs.block_mode` can be set only for custom storage volumes.
To enable ZFS block mode for all storage volumes in the pool, including instance volumes,
use `volume.zfs.block_mode`.

<a id="storage-zfs-volume-conf:zfs.blocksize"></a>
`zfs.blocksize`

Size of the ZFS block

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-zfs-volume-conf:zfs.blocksize)

| **Key:**     | `zfs.blocksize`                |
|--------------|--------------------------------|
| **Type:**    | string                         |
| **Default:** | same as `volume.zfs.blocksize` |
| **Scope:**   | global                         |

The size must be between 512 bytes and 16 MiB and must be a power of 2.
For a block volume, a maximum value of 128 KiB will be used even if a higher value is set.

Depending on the value of [`zfs.block_mode`](#storage-zfs-volume-conf:zfs.block_mode),
the specified size is used to set either `volblocksize` or `recordsize` in ZFS.

<a id="storage-zfs-volume-conf:zfs.delegate"></a>
`zfs.delegate`

Whether to delegate the ZFS dataset

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-zfs-volume-conf:zfs.delegate)

| **Key:**       | `zfs.delegate`                |
|----------------|-------------------------------|
| **Type:**      | bool                          |
| **Default:**   | same as `volume.zfs.delegate` |
| **Condition:** | ZFS 2.2 or higher             |
| **Scope:**     | global                        |

This option controls whether to delegate the ZFS dataset and anything underneath it to the
container or containers that use it. When used in conjunction with
[`security.nesting`](instance_options.md#instance-security:security.nesting), this allows
using the `zfs` command in the container.

<a id="storage-zfs-volume-conf:zfs.promote"></a>
`zfs.promote`

Whether to promote the ZFS dataset

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-zfs-volume-conf:zfs.promote)

| **Key:**     | `zfs.promote`   |
|--------------|-----------------|
| **Type:**    | bool            |
| **Default:** | false           |
| **Scope:**   | global          |

This option controls whether to promote the ZFS dataset at volume create/refresh time.
When enabled, if the source volume is a clone, the new volume will be promoted to be a parent.

<a id="storage-zfs-volume-conf:zfs.remove_snapshots"></a>
`zfs.remove_snapshots`

Remove snapshots as needed

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-zfs-volume-conf:zfs.remove_snapshots)

| **Key:**     | `zfs.remove_snapshots`                           |
|--------------|--------------------------------------------------|
| **Type:**    | bool                                             |
| **Default:** | same as `volume.zfs.remove_snapshots` or `false` |
| **Scope:**   | global                                           |

<a id="storage-zfs-volume-conf:zfs.reserve_space"></a>
`zfs.reserve_space`

Use `reservation`/`refreservation` along with `quota`/`refquota`

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-zfs-volume-conf:zfs.reserve_space)

| **Key:**     | `zfs.reserve_space`                           |
|--------------|-----------------------------------------------|
| **Type:**    | bool                                          |
| **Default:** | same as `volume.zfs.reserve_space` or `false` |
| **Scope:**   | global                                        |

<a id="storage-zfs-volume-conf:zfs.use_refquota"></a>
`zfs.use_refquota`

Use `refquota` instead of `quota` for space

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-zfs-volume-conf:zfs.use_refquota)

| **Key:**     | `zfs.use_refquota`                           |
|--------------|----------------------------------------------|
| **Type:**    | bool                                         |
| **Default:** | same as `volume.zfs.use_refquota` or `false` |
| **Scope:**   | global                                       |


# index.html.md

<a id="devices"></a>

# Devices

Devices are attached to an instance (see [Configure devices](../howto/instances_configure.md#instances-configure-devices)) or to a profile (see [Edit a profile](../profiles.md#profiles-edit)).

They include, for example, network interfaces, mount points, USB and GPU devices.
These devices can have instance device options, depending on the type of the instance device.

LXD supports the following device types:

|   ID (database) | Name                                                           | Condition   | Description                     |
|-----------------|----------------------------------------------------------------|-------------|---------------------------------|
|               0 | [`none`](devices_none.md#devices-none)                         | -           | Inheritance blocker             |
|               1 | [`nic`](devices_nic.md#devices-nic)                            | -           | Network interface               |
|               2 | [`disk`](devices_disk.md#devices-disk)                         | -           | Mount point inside the instance |
|               3 | [`unix-char`](devices_unix_char.md#devices-unix-char)          | container   | Unix character device           |
|               4 | [`unix-block`](devices_unix_block.md#devices-unix-block)       | container   | Unix block device               |
|               5 | [`usb`](devices_usb.md#devices-usb)                            | -           | USB device                      |
|               6 | [`gpu`](devices_gpu.md#devices-gpu)                            | -           | GPU device                      |
|               7 | [`infiniband`](devices_infiniband.md#devices-infiniband)       | container   | InfiniBand device               |
|               8 | [`proxy`](devices_proxy.md#devices-proxy)                      | container   | Proxy device                    |
|               9 | [`unix-hotplug`](devices_unix_hotplug.md#devices-unix-hotplug) | container   | Unix hotplug device             |
|              10 | [`tpm`](devices_tpm.md#devices-tpm)                            | -           | TPM device                      |
|              11 | [`pci`](devices_pci.md#devices-pci)                            | VM          | PCI device                      |

Each instance comes with a set of [Standard devices](standard_devices.md#standard-devices).


# index.html.md

<a id="storage-pure"></a>

# Pure Storage - `pure`

[Pure Storage](https://www.everpuredata.com/) is a software-defined storage solution. It offers the consumption of redundant block storage across the network.

LXD supports connecting to Pure Storage storage clusters through two protocols: either  or .
In addition, Pure Storage offers copy-on-write snapshots, thin provisioning, and other features.

To use Pure Storage with LXD requires a Pure Storage API version of at least `2.21`, corresponding to a minimum Purity//FA version of `6.4.2`.

Additionally, ensure that the required kernel modules for the selected protocol are installed on your host system.
For iSCSI, the iSCSI CLI named `iscsiadm` needs to be installed in addition to the required kernel modules.

## Terminology

Each storage pool created in LXD using a Pure Storage driver represents a Pure Storage *pod*, which is an abstraction that groups multiple volumes under a specific name.
One benefit of using Pure Storage pods is that they can be linked with multiple Pure Storage arrays to provide additional redundancy.

LXD creates volumes within a pod that is identified by the storage pool name.
When the first volume needs to be mapped to a specific LXD host, a corresponding Pure Storage host is created with the name of the LXD host and a suffix of the used protocol.
For example, if the LXD host is `host01` and the mode is `nvme/tcp`, the resulting Pure Storage host would be `host01-nvme-tcp`.

The Pure Storage host is then connected with the required volumes, to allow attaching and accessing volumes from the LXD host.
The created Pure Storage host is automatically removed once there are no volumes connected to it.

## The `pure` driver in LXD

The `pure` driver in LXD uses Pure Storage volumes for custom storage volumes, instances, and snapshots.
All created volumes are thin-provisioned block volumes. If required (for example, for containers and custom file system volumes), LXD formats the volume with a desired file system.

LXD expects Pure Storage to be pre-configured with a specific service (e.g. iSCSI) on network interfaces whose address is provided during storage pool configuration.
Furthermore, LXD assumes that it has full control over the Pure Storage pods it manages.
Therefore, you should never maintain any volumes in Pure Storage pods that are not owned by LXD because LXD might disconnect or even delete them.

This driver behaves differently than some of the other drivers in that it provides remote storage.
As a result, and depending on the internal network, storage access might be a bit slower compared to local storage.
On the other hand, using remote storage has significant advantages in a cluster setup: all cluster members have access to the same storage pools with the exact same contents, without the need to synchronize them.

When creating a new storage pool using the `pure` driver in either `iscsi` or `nvme/tcp` mode, LXD automatically discovers the array’s qualified name and target address (portal).
Upon successful discovery, LXD attaches all volumes that are connected to the Pure Storage host that is associated with a specific LXD server.
Pure Storage hosts and volume connections are fully managed by LXD.

Volume snapshots are also supported by Pure Storage.
When a volume with at least one snapshot is copied, LXD sequentially creates snapshots on the destination volume from snapshots on the source volume.
Each snapshot is associated with a parent volume and cannot be directly attached to the host; therefore, when a snapshot is exported, LXD creates a temporary volume behind the scenes.
This volume is attached to the LXD host and removed once the operation is complete.
Finally, once all snapshots are copied, the source volume is copied into the destination volume.

<a id="storage-pure-volume-names"></a>

### Volume names

Due to a [limitation](#storage-pure-limitations) in Pure Storage, volume names cannot exceed 63 characters.
Therefore, the driver uses the volume’s [`volatile.uuid`](#storage-pure-volume-conf:volatile.uuid) to generate a shorter volume name.

For example, a UUID `5a2504b0-6a6c-4849-8ee7-ddb0b674fd14` is first trimmed of any hyphens (`-`), resulting in the string `5a2504b06a6c48498ee7ddb0b674fd14`.
To distinguish volume types and snapshots, special identifiers are prepended and appended to the volume names, as depicted in the table below:

| Type            | Identifier   | Example                                                                                                                                                                              |
|-----------------|--------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Container       | `c-`         | `c-5a2504b06a6c48498ee7ddb0b674fd14`                                                                                                                                                 |
| Virtual machine | `v-`         | `v-5a2504b06a6c48498ee7ddb0b674fd14-b` (block volume) and `v-5a2504b06a6c48498ee7ddb0b674fd14` (file system volume)                                                                  |
| Image (ISO)     | `i-`         | `i-5a2504b06a6c48498ee7ddb0b674fd14-i`                                                                                                                                               |
| Custom volume   | `u-`         | `u-5a2504b06a6c48498ee7ddb0b674fd14` (file system volume) and `u-5a2504b06a6c48498ee7ddb0b674fd14-b` (block volume)                                                                  |
| Snapshot        | `s`          | `sc-5a2504b06a6c48498ee7ddb0b674fd14` (container snapshot), `sv-5a2504b06a6c48498ee7ddb0b674fd14-b` (VM snapshot) and `su-5a2504b06a6c48498ee7ddb0b674fd14` (custom volume snapshot) |

<a id="storage-pure-limitations"></a>

### Limitations

The `pure` driver has the following limitations:

Volume size constraints
: Minimum volume size (quota) is `1MiB` and must be a multiple of `512B`. If the requested size does not meet these conditions, LXD automatically rounds it up to the nearest valid value.

Snapshots cannot be mounted
: Snapshots cannot be mounted directly to the host. Instead, a temporary volume must be created to access the snapshot’s contents.
  For internal operations, such as copying instances or exporting snapshots, LXD handles this automatically.

Sharing the Pure Storage storage pool between multiple LXD installations
: Sharing a Pure Storage array between multiple LXD installations is possible provided that installations use distinct storage pool names. Storage pools are implemented as Pods on the array and pod names have to be unique.

Recovering Pure Storage storage pools
: Recovery of Pure Storage storage pools using `lxd recover` is currently not supported.

## Configuration options

The following configuration options are available for storage pools that use the `pure` driver, as well as storage volumes in these pools.

<a id="storage-pure-pool-config"></a>

### Storage pool configuration

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="storage-pure-pool-conf:pure.api.token"></a>
`pure.api.token`

API authorization token for Pure Storage gateway

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-pure-pool-conf:pure.api.token)

| **Key:**    | `pure.api.token`   |
|-------------|--------------------|
| **Type:**   | string             |

API authorization token for Pure Storage gateway. Must have array_admin role to give LXD full control over managed storage pools (Pure Storage pods).

<a id="storage-pure-pool-conf:pure.gateway"></a>
`pure.gateway`

Address of the Pure Storage gateway

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-pure-pool-conf:pure.gateway)

| **Key:**    | `pure.gateway`   |
|-------------|------------------|
| **Type:**   | string           |

<a id="storage-pure-pool-conf:pure.gateway.verify"></a>
`pure.gateway.verify`

Whether to verify the Pure Storage gateway’s certificate

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-pure-pool-conf:pure.gateway.verify)

| **Key:**     | `pure.gateway.verify`   |
|--------------|-------------------------|
| **Type:**    | bool                    |
| **Default:** | `true`                  |

<a id="storage-pure-pool-conf:pure.mode"></a>
`pure.mode`

How volumes are mapped to the local server

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-pure-pool-conf:pure.mode)

| **Key:**     | `pure.mode`         |
|--------------|---------------------|
| **Type:**    | string              |
| **Default:** | the discovered mode |

The mode to use to map Pure Storage volumes to the local server.
Supported values are `iscsi` and `nvme/tcp`.

<a id="storage-pure-pool-conf:pure.target"></a>
`pure.target`

List of target addresses.

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-pure-pool-conf:pure.target)

| **Key:**     | `pure.target`       |
|--------------|---------------------|
| **Type:**    | string              |
| **Default:** | the discovered mode |

A comma-separated list of target addresses. If empty, LXD discovers and connects to all available targets. Otherwise, it only connects to the specified addresses.

<a id="storage-pure-pool-conf:rsync.bwlimit"></a>
`rsync.bwlimit`

Upper limit on the socket I/O for `rsync`

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-pure-pool-conf:rsync.bwlimit)

| **Key:**     | `rsync.bwlimit`   |
|--------------|-------------------|
| **Type:**    | string            |
| **Default:** | `0` (no limit)    |
| **Scope:**   | global            |

When `rsync` must be used to transfer storage entities, this option specifies the upper limit
to be placed on the socket I/O.

<a id="storage-pure-pool-conf:rsync.compression"></a>
`rsync.compression`

Whether to use compression while migrating storage pools

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-pure-pool-conf:rsync.compression)

| **Key:**     | `rsync.compression`   |
|--------------|-----------------------|
| **Type:**    | bool                  |
| **Default:** | `true`                |
| **Scope:**   | global                |

<a id="storage-pure-pool-conf:volume.size"></a>
`volume.size`

Size/quota of the storage volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-pure-pool-conf:volume.size)

| **Key:**     | `volume.size`   |
|--------------|-----------------|
| **Type:**    | string          |
| **Default:** | `10GiB`         |

Default Pure Storage volume size rounded to 512B. The minimum size is 1MiB.

<a id="storage-pure-vol-config"></a>

### Storage volume configuration

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="storage-pure-volume-conf:block.filesystem"></a>
`block.filesystem`

File system of the storage volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-pure-volume-conf:block.filesystem)

| **Key:**       | `block.filesystem`                                |
|----------------|---------------------------------------------------|
| **Type:**      | string                                            |
| **Default:**   | same as `volume.block.filesystem`                 |
| **Condition:** | block-based volume with content type `filesystem` |

Valid options: `btrfs`, `ext4`, `xfs`
If not set, `ext4` is assumed.

<a id="storage-pure-volume-conf:block.mount_options"></a>
`block.mount_options`

Mount options for block-backed file system volumes

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-pure-volume-conf:block.mount_options)

| **Key:**       | `block.mount_options`                             |
|----------------|---------------------------------------------------|
| **Type:**      | string                                            |
| **Default:**   | same as `volume.block.mount_options`              |
| **Condition:** | block-based volume with content type `filesystem` |

<a id="storage-pure-volume-conf:security.shared"></a>
`security.shared`

Enable volume sharing

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-pure-volume-conf:security.shared)

| **Key:**       | `security.shared`                           |
|----------------|---------------------------------------------|
| **Type:**      | bool                                        |
| **Default:**   | same as `volume.security.shared` or `false` |
| **Condition:** | virtual-machine or custom block volume      |
| **Scope:**     | global                                      |

Enable this option to allow the volume to be shared across multiple instances despite the possibility of data loss.

<a id="storage-pure-volume-conf:security.shifted"></a>
`security.shifted`

Enable ID shifting overlay

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-pure-volume-conf:security.shifted)

| **Key:**       | `security.shifted`                           |
|----------------|----------------------------------------------|
| **Type:**      | bool                                         |
| **Default:**   | same as `volume.security.shifted` or `false` |
| **Condition:** | custom volume                                |
| **Scope:**     | global                                       |

Enable this option to allow the volume to be attached to multiple isolated instances.

<a id="storage-pure-volume-conf:security.unmapped"></a>
`security.unmapped`

Disable ID mapping for the volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-pure-volume-conf:security.unmapped)

| **Key:**       | `security.unmapped`                           |
|----------------|-----------------------------------------------|
| **Type:**      | bool                                          |
| **Default:**   | same as `volume.security.unmapped` or `false` |
| **Condition:** | custom volume                                 |
| **Scope:**     | global                                        |

<a id="storage-pure-volume-conf:size"></a>
`size`

Size/quota of the storage volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-pure-volume-conf:size)

| **Key:**     | `size`                |
|--------------|-----------------------|
| **Type:**    | string                |
| **Default:** | same as `volume.size` |

Default Pure Storage volume size rounded to 512B. The minimum size is 1MiB.

<a id="storage-pure-volume-conf:snapshots.expiry"></a>
`snapshots.expiry`

Time until snapshots are deleted

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-pure-volume-conf:snapshots.expiry)

| **Key:**       | `snapshots.expiry`                |
|----------------|-----------------------------------|
| **Type:**      | string                            |
| **Default:**   | same as `volume.snapshots.expiry` |
| **Condition:** | custom volume                     |
| **Scope:**     | global                            |

Specify an expression like `1M 2H 3d 4w 5m 6y`.

<a id="storage-pure-volume-conf:snapshots.pattern"></a>
`snapshots.pattern`

Template for the snapshot name

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-pure-volume-conf:snapshots.pattern)

| **Key:**       | `snapshots.pattern`                            |
|----------------|------------------------------------------------|
| **Type:**      | string                                         |
| **Default:**   | same as `volume.snapshots.pattern` or `snap%d` |
| **Condition:** | custom volume                                  |
| **Scope:**     | global                                         |

You can specify a naming template for scheduled snapshots and unnamed snapshots.

The `snapshots.pattern` option takes a Pongo2 template string to format the snapshot name.

To add a time stamp to the snapshot name, use the Pongo2 context variable `creation_date`.
Make sure to format the date in your template string to avoid forbidden characters in the snapshot name.
For example, set `snapshots.pattern` to `{{ creation_date|date:'2006-01-02_15-04-05' }}` to name the snapshots after their time of creation, down to the precision of a second.

Another way to avoid name collisions is to use the placeholder `%d` in the pattern.
If no matching snapshots exist, the placeholder is replaced with `0`.
Otherwise, it is replaced with the next snapshot index, which is one higher than the highest existing matching snapshot index.

<a id="storage-pure-volume-conf:snapshots.schedule"></a>
`snapshots.schedule`

Schedule for automatic volume snapshots

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-pure-volume-conf:snapshots.schedule)

| **Key:**       | `snapshots.schedule`         |
|----------------|------------------------------|
| **Type:**      | string                       |
| **Default:**   | same as `snapshots.schedule` |
| **Condition:** | custom volume                |
| **Scope:**     | global                       |

Specify either a cron expression (`<minute> <hour> <dom> <month> <dow>`), a comma-separated list of schedule aliases (`@hourly`, `@daily`, `@midnight`, `@weekly`, `@monthly`, `@annually`, `@yearly`), or leave empty to disable automatic snapshots (the default).

<a id="storage-pure-volume-conf:volatile.devlxd.owner"></a>
`volatile.devlxd.owner`

ID of the DevLXD identity that owns the volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-pure-volume-conf:volatile.devlxd.owner)

| **Key:**     | `volatile.devlxd.owner`   |
|--------------|---------------------------|
| **Type:**    | string                    |
| **Default:** | DevLXD owner identity ID  |
| **Scope:**   | global                    |

<a id="storage-pure-volume-conf:volatile.idmap.last"></a>
`volatile.idmap.last`

JSON-serialized UID/GID map that has been applied to the volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-pure-volume-conf:volatile.idmap.last)

| **Key:**       | `volatile.idmap.last`   |
|----------------|-------------------------|
| **Type:**      | string                  |
| **Condition:** | filesystem              |

<a id="storage-pure-volume-conf:volatile.idmap.next"></a>
`volatile.idmap.next`

JSON-serialized UID/GID map that has been applied to the volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-pure-volume-conf:volatile.idmap.next)

| **Key:**       | `volatile.idmap.next`   |
|----------------|-------------------------|
| **Type:**      | string                  |
| **Condition:** | filesystem              |

<a id="storage-pure-volume-conf:volatile.uuid"></a>
`volatile.uuid`

Volume UUID

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-pure-volume-conf:volatile.uuid)

| **Key:**     | `volatile.uuid`   |
|--------------|-------------------|
| **Type:**    | string            |
| **Default:** | random UUID       |
| **Scope:**   | global            |


# index.html.md

<a id="instance-options"></a>

# Instance options

Instance options are configuration options that are directly related to the instance.

See [Configure instance options](../howto/instances_configure.md#instances-configure-options) for instructions on how to set the instance options.

The key/value configuration is namespaced.
The following options are available:

- [Miscellaneous options](#instance-options-misc)
- [Boot-related options](#instance-options-boot)
- [`cloud-init` configuration](#instance-options-cloud-init)
- [Resource limits](#instance-options-limits)
- [Migration options](#instance-options-migration)
- [Placement options](#instance-options-placement)
- [NVIDIA and CUDA configuration](#instance-options-nvidia)
- [Raw instance configuration overrides](#instance-options-raw)
- [Security policies](#instance-options-security)
- [Snapshot scheduling and configuration](#instance-options-snapshots)
- [Volatile internal data](#instance-options-volatile)

Note that while a type is defined for each option, all values are stored as strings and should be exported over the REST API as strings (which makes it possible to support any extra values without breaking backward compatibility).

<a id="instance-options-misc"></a>

## Miscellaneous options

In addition to the configuration options listed in the following sections, these instance options are supported:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="instance-miscellaneous:agent.nic_config"></a>
`agent.nic_config`

Whether to use the name and MTU of the default network interfaces

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-miscellaneous:agent.nic_config)

| **Key:**         | `agent.nic_config`   |
|------------------|----------------------|
| **Type:**        | bool                 |
| **Default:**     | `false`              |
| **Live update:** | no                   |
| **Condition:**   | virtual machine      |

When set to true, the name and MTU of the default network interfaces inside the virtual machine will match those of the instance devices.

<a id="instance-miscellaneous:cluster.evacuate"></a>
`cluster.evacuate`

What to do when evacuating the instance

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-miscellaneous:cluster.evacuate)

| **Key:**         | `cluster.evacuate`   |
|------------------|----------------------|
| **Type:**        | string               |
| **Default:**     | `auto`               |
| **Live update:** | no                   |

The `cluster.evacuate` provides control over how instances are handled when a cluster member is being evacuated.

Available Modes:

- `auto`  *(default)*: The system will automatically decide the best evacuation method based on the instance’s type and configured devices:
  + If any device is not suitable for migration, the instance will not be migrated (only stopped).
  + Live migration will be used only for virtual machines with the `migration.stateful` setting enabled and for which all its devices can be migrated as well.
- `live-migrate`: Eligible instances are live-migrated to another node. This means the instance remains running and operational during the migration process, ensuring minimal disruption.
  Note: Live migration is supported for virtual machines only.
  If no target member is available, an instance is skipped.
  If a live migration attempt fails, the evacuation operation fails.
- `migrate`: In this mode, instances are migrated to another node in the cluster. The migration process will not be live, meaning there will be a brief downtime for the instance during the migration.
- `stop`: Instances are not migrated. Instead, they are stopped on the current node.

See [Evacuate a cluster member](../howto/cluster_manage.md#cluster-evacuate) for more information.

<a id="instance-miscellaneous:environment.*"></a>
`environment.*`

Free-form environment key/value

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-miscellaneous:environment.*)

| **Key:**         | `environment.*`   |
|------------------|-------------------|
| **Type:**        | string            |
| **Live update:** | yes               |

Extra environment variables to set on boot (for containers) and during exec.

<a id="instance-miscellaneous:linux.kernel_modules"></a>
`linux.kernel_modules`

Kernel modules to load or allow loading

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-miscellaneous:linux.kernel_modules)

| **Key:**         | `linux.kernel_modules`   |
|------------------|--------------------------|
| **Type:**        | string                   |
| **Live update:** | yes                      |
| **Condition:**   | container                |

Specify the kernel modules as a comma-separated list.

The modules are loaded before the instance starts, or they can be loaded by a privileged user if [`linux.kernel_modules.load`](#instance-miscellaneous:linux.kernel_modules.load) is set to `ondemand`.

<a id="instance-miscellaneous:linux.kernel_modules.load"></a>
`linux.kernel_modules.load`

How to load kernel modules

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-miscellaneous:linux.kernel_modules.load)

| **Key:**         | `linux.kernel_modules.load`   |
|------------------|-------------------------------|
| **Type:**        | string                        |
| **Default:**     | `boot`                        |
| **Live update:** | no                            |
| **Condition:**   | container                     |

This option specifies how to load the kernel modules that are specified in [`linux.kernel_modules`](#instance-miscellaneous:linux.kernel_modules).
Possible values are `boot` (load the modules when booting the container) and `ondemand` (intercept the `finit_modules()` syscall and allow a privileged user in the container’s user namespace to load the modules).

<a id="instance-miscellaneous:linux.sysctl.*"></a>
`linux.sysctl.*`

Override for the corresponding `sysctl` setting in the container

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-miscellaneous:linux.sysctl.*)

| **Key:**         | `linux.sysctl.*`   |
|------------------|--------------------|
| **Type:**        | string             |
| **Live update:** | no                 |
| **Condition:**   | container          |

<a id="instance-miscellaneous:ubuntu_pro.guest_attach"></a>
`ubuntu_pro.guest_attach`

Whether to auto-attach Ubuntu Pro.

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-miscellaneous:ubuntu_pro.guest_attach)

| **Key:**         | `ubuntu_pro.guest_attach`   |
|------------------|-----------------------------|
| **Type:**        | string                      |
| **Live update:** | no                          |

Indicate whether the guest should auto-attach Ubuntu Pro at start up.

See [How to configure Ubuntu Pro guest attachment](../howto/instances_ubuntu_pro_attach.md#instances-ubuntu-pro-attach) for more information.

<a id="instance-miscellaneous:user.*"></a>
`user.*`

Free-form user key/value storage

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-miscellaneous:user.*)

| **Key:**         | `user.*`   |
|------------------|------------|
| **Type:**        | string     |
| **Live update:** | no         |

User keys can be used in search.

`environment.*`

Environment variables for the instance

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-miscellaneous:environment.*)

| **Key:**         | `environment.*`   |
|------------------|-------------------|
| **Type:**        | string            |
| **Live update:** | yes (exec)        |

You can export key/value environment variables to the instance.
These are then set for [`lxc exec`](manpages/lxc/exec.md#lxc-exec-md).

<a id="instance-options-boot"></a>

## Boot-related options

The following instance options control the boot-related behavior of the instance:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="instance-boot:boot.autostart"></a>
`boot.autostart`

Whether to always start the instance when LXD starts

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-boot:boot.autostart)

| **Key:**         | `boot.autostart`   |
|------------------|--------------------|
| **Type:**        | bool               |
| **Live update:** | no                 |

If set to `true`, the instance will always be auto-started, unless `security.protection.start` is also enabled.
If set to `false`, the instance will not be started on LXD start up.
If this option is not set, the instance will be restored to its last known state.

<a id="instance-boot:boot.autostart.delay"></a>
`boot.autostart.delay`

Delay after starting the instance

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-boot:boot.autostart.delay)

| **Key:**         | `boot.autostart.delay`   |
|------------------|--------------------------|
| **Type:**        | integer                  |
| **Default:**     | `0`                      |
| **Live update:** | no                       |

The number of seconds to wait after the instance started before starting the next one.

<a id="instance-boot:boot.autostart.priority"></a>
`boot.autostart.priority`

What order to start the instances in

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-boot:boot.autostart.priority)

| **Key:**         | `boot.autostart.priority`   |
|------------------|-----------------------------|
| **Type:**        | integer                     |
| **Default:**     | `0`                         |
| **Live update:** | no                          |

The instance with the highest value is started first.

<a id="instance-boot:boot.debug_edk2"></a>
`boot.debug_edk2`

Enable debug version of the `edk2`

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-boot:boot.debug_edk2)

| **Key:**    | `boot.debug_edk2`   |
|-------------|---------------------|
| **Type:**   | bool                |

The instance should use a debug version of the `edk2`.
A log file can be found in `$LXD_DIR/logs/<instance_name>/edk2.log`.

<a id="instance-boot:boot.host_shutdown_timeout"></a>
`boot.host_shutdown_timeout`

How long to wait for the instance to shut down

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-boot:boot.host_shutdown_timeout)

| **Key:**         | `boot.host_shutdown_timeout`   |
|------------------|--------------------------------|
| **Type:**        | integer                        |
| **Default:**     | `30`                           |
| **Live update:** | yes                            |

Number of seconds to wait for the instance to shut down before it is force-stopped.

<a id="instance-boot:boot.mode"></a>
`boot.mode`

Boot firmware mode for the VM (uefi-secureboot, uefi-nosecureboot or bios)

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-boot:boot.mode)

| **Key:**         | `boot.mode`       |
|------------------|-------------------|
| **Type:**        | string            |
| **Default:**     | `uefi-secureboot` |
| **Live update:** | no                |
| **Condition:**   | virtual machine   |

The `uefi-secureboot` mode uses UEFI firmware with secure boot enabled.
The `uefi-nosecureboot` mode uses UEFI firmware with secure boot disabled.
The `bios` mode is supported only on `x86_64` (`amd64`).

<a id="instance-boot:boot.stop.priority"></a>
`boot.stop.priority`

What order to shut down the instances in

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-boot:boot.stop.priority)

| **Key:**         | `boot.stop.priority`   |
|------------------|------------------------|
| **Type:**        | integer                |
| **Default:**     | `0`                    |
| **Live update:** | no                     |

The instance with the highest value is shut down first.

<a id="instance-options-cloud-init"></a>

## `cloud-init` configuration

The following instance options control the [`cloud-init`](../cloud-init.md#cloud-init) configuration of the instance:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="instance-cloud-init:cloud-init.network-config"></a>
`cloud-init.network-config`

Network configuration for `cloud-init`

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-cloud-init:cloud-init.network-config)

| **Key:**         | `cloud-init.network-config`   |
|------------------|-------------------------------|
| **Type:**        | string                        |
| **Default:**     | `DHCP on eth0`                |
| **Live update:** | no                            |
| **Condition:**   | If supported by image         |

The content is used as seed value for `cloud-init`.

<a id="instance-cloud-init:cloud-init.ssh-keys.KEYNAME"></a>
`cloud-init.ssh-keys.KEYNAME`

Additional SSH key to be injected on the instance by `cloud-init`

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-cloud-init:cloud-init.ssh-keys.KEYNAME)

| **Key:**         | `cloud-init.ssh-keys.KEYNAME`   |
|------------------|---------------------------------|
| **Type:**        | string                          |
| **Live update:** | no                              |
| **Condition:**   | If supported by image           |

Represents an additional SSH public key to be merged into existing `cloud-init` seed data
and injected into an instance. Has the format `{user}:{key}`, where {user} is a Linux username and
{key} can be either a pure SSH public key or an import ID for a key hosted elsewhere.
// For example: `root:gh:githubUser`, `myUser:ssh-keyAlg publicKeyHash`

<a id="instance-cloud-init:cloud-init.user-data"></a>
`cloud-init.user-data`

User data for `cloud-init`

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-cloud-init:cloud-init.user-data)

| **Key:**         | `cloud-init.user-data`   |
|------------------|--------------------------|
| **Type:**        | string                   |
| **Default:**     | `#cloud-config`          |
| **Live update:** | no                       |
| **Condition:**   | If supported by image    |

The content is used as seed value for `cloud-init`.

<a id="instance-cloud-init:cloud-init.vendor-data"></a>
`cloud-init.vendor-data`

Vendor data for `cloud-init`

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-cloud-init:cloud-init.vendor-data)

| **Key:**         | `cloud-init.vendor-data`   |
|------------------|----------------------------|
| **Type:**        | string                     |
| **Default:**     | `#cloud-config`            |
| **Live update:** | no                         |
| **Condition:**   | If supported by image      |

The content is used as seed value for `cloud-init`.

<a id="instance-cloud-init:user.network-config"></a>
`user.network-config`

Legacy version of `cloud-init.network-config`

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-cloud-init:user.network-config)

| **Key:**         | `user.network-config`   |
|------------------|-------------------------|
| **Type:**        | string                  |
| **Default:**     | `DHCP on eth0`          |
| **Live update:** | no                      |
| **Condition:**   | If supported by image   |

<a id="instance-cloud-init:user.user-data"></a>
`user.user-data`

Legacy version of `cloud-init.user-data`

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-cloud-init:user.user-data)

| **Key:**         | `user.user-data`      |
|------------------|-----------------------|
| **Type:**        | string                |
| **Default:**     | `#cloud-config`       |
| **Live update:** | no                    |
| **Condition:**   | If supported by image |

<a id="instance-cloud-init:user.vendor-data"></a>
`user.vendor-data`

Legacy version of `cloud-init.vendor-data`

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-cloud-init:user.vendor-data)

| **Key:**         | `user.vendor-data`    |
|------------------|-----------------------|
| **Type:**        | string                |
| **Default:**     | `#cloud-config`       |
| **Live update:** | no                    |
| **Condition:**   | If supported by image |

Support for these options depends on the image that is used and is not guaranteed.

If you specify both `cloud-init.user-data` and `cloud-init.vendor-data`, the content of both options is merged.
Therefore, make sure that the `cloud-init` configuration you specify in those options does not contain the same keys.

<a id="instance-options-limits"></a>

## Resource limits

The following instance options specify resource limits for the instance:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="instance-resource-limits:limits.cpu"></a>
`limits.cpu`

Which CPUs to expose to the instance

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-resource-limits:limits.cpu)

| **Key:**         | `limits.cpu`   |
|------------------|----------------|
| **Type:**        | string         |
| **Default:**     | 1 (VMs)        |
| **Live update:** | yes            |

A number or a specific range of CPUs to expose to the instance.

See [CPU pinning](#instance-options-limits-cpu) for more information.

<a id="instance-resource-limits:limits.cpu.allowance"></a>
`limits.cpu.allowance`

How much of the CPU can be used

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-resource-limits:limits.cpu.allowance)

| **Key:**         | `limits.cpu.allowance`   |
|------------------|--------------------------|
| **Type:**        | string                   |
| **Default:**     | 100%                     |
| **Live update:** | yes                      |
| **Condition:**   | container                |

To control how much of the CPU can be used, specify either a percentage (`50%`) for a soft limit
or a chunk of time (`25ms/100ms`) for a hard limit.

See [Allowance and priority (container only)](#instance-options-limits-cpu-container) for more information.

<a id="instance-resource-limits:limits.cpu.nodes"></a>
`limits.cpu.nodes`

Which NUMA nodes to place the instance CPUs on

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-resource-limits:limits.cpu.nodes)

| **Key:**         | `limits.cpu.nodes`   |
|------------------|----------------------|
| **Type:**        | string               |
| **Live update:** | yes                  |

A comma-separated list of NUMA node IDs or ranges to place the instance CPUs on.

See [Allowance and priority (container only)](#instance-options-limits-cpu-container) for more information.

<a id="instance-resource-limits:limits.cpu.pin_strategy"></a>
`limits.cpu.pin_strategy`

VM CPU auto pinning strategy

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-resource-limits:limits.cpu.pin_strategy)

| **Key:**         | `limits.cpu.pin_strategy`   |
|------------------|-----------------------------|
| **Type:**        | string                      |
| **Default:**     | `none`                      |
| **Live update:** | no                          |
| **Condition:**   | virtual machine             |

Specify the strategy for VM CPU auto pinning.
Possible values: `none` (disables CPU auto pinning) and `auto` (enables CPU auto pinning).

See [CPU limits for virtual machines](#instance-options-limits-cpu-vm) for more information.

<a id="instance-resource-limits:limits.cpu.priority"></a>
`limits.cpu.priority`

CPU scheduling priority compared to other instances

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-resource-limits:limits.cpu.priority)

| **Key:**         | `limits.cpu.priority`   |
|------------------|-------------------------|
| **Type:**        | integer                 |
| **Default:**     | `10` (maximum)          |
| **Live update:** | yes                     |
| **Condition:**   | container               |

When overcommitting resources, specify the CPU scheduling priority compared to other instances that share the same CPUs.
Specify an integer between 0 and 10.

See [Allowance and priority (container only)](#instance-options-limits-cpu-container) for more information.

<a id="instance-resource-limits:limits.disk.priority"></a>
`limits.disk.priority`

Priority of the instance’s I/O requests

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-resource-limits:limits.disk.priority)

| **Key:**         | `limits.disk.priority`   |
|------------------|--------------------------|
| **Type:**        | integer                  |
| **Default:**     | `5` (medium)             |
| **Live update:** | yes                      |

Controls how much priority to give to the instance’s I/O requests when under load.

Specify an integer between 0 and 10.

<a id="instance-resource-limits:limits.hugepages.1GB"></a>
`limits.hugepages.1GB`

Limit for the number of 1 GB huge pages

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-resource-limits:limits.hugepages.1GB)

| **Key:**         | `limits.hugepages.1GB`   |
|------------------|--------------------------|
| **Type:**        | string                   |
| **Live update:** | yes                      |
| **Condition:**   | container                |

Fixed value (in bytes) to limit the number of 1 GB huge pages.
Various suffixes are supported (see [Units for storage and network limits](instance_units.md#instances-limit-units)).

See [Huge page limits](#instance-options-limits-hugepages) for more information.

<a id="instance-resource-limits:limits.hugepages.1MB"></a>
`limits.hugepages.1MB`

Limit for the number of 1 MB huge pages

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-resource-limits:limits.hugepages.1MB)

| **Key:**         | `limits.hugepages.1MB`   |
|------------------|--------------------------|
| **Type:**        | string                   |
| **Live update:** | yes                      |
| **Condition:**   | container                |

Fixed value (in bytes) to limit the number of 1 MB huge pages.
Various suffixes are supported (see [Units for storage and network limits](instance_units.md#instances-limit-units)).

See [Huge page limits](#instance-options-limits-hugepages) for more information.

<a id="instance-resource-limits:limits.hugepages.2MB"></a>
`limits.hugepages.2MB`

Limit for the number of 2 MB huge pages

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-resource-limits:limits.hugepages.2MB)

| **Key:**         | `limits.hugepages.2MB`   |
|------------------|--------------------------|
| **Type:**        | string                   |
| **Live update:** | yes                      |
| **Condition:**   | container                |

Fixed value (in bytes) to limit the number of 2 MB huge pages.
Various suffixes are supported (see [Units for storage and network limits](instance_units.md#instances-limit-units)).

See [Huge page limits](#instance-options-limits-hugepages) for more information.

<a id="instance-resource-limits:limits.hugepages.64KB"></a>
`limits.hugepages.64KB`

Limit for the number of 64 KB huge pages

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-resource-limits:limits.hugepages.64KB)

| **Key:**         | `limits.hugepages.64KB`   |
|------------------|---------------------------|
| **Type:**        | string                    |
| **Live update:** | yes                       |
| **Condition:**   | container                 |

Fixed value (in bytes) to limit the number of 64 KB huge pages.
Various suffixes are supported (see [Units for storage and network limits](instance_units.md#instances-limit-units)).

See [Huge page limits](#instance-options-limits-hugepages) for more information.

<a id="instance-resource-limits:limits.max_bus_ports"></a>
`limits.max_bus_ports`

Limit of allowed PCI/PCIe devices

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-resource-limits:limits.max_bus_ports)

| **Key:**         | `limits.max_bus_ports`   |
|------------------|--------------------------|
| **Type:**        | integer                  |
| **Default:**     | `8`                      |
| **Live update:** | no                       |
| **Condition:**   | virtual machine          |

Total number of user configurable PCI/PCIe devices that can be attached to the VM.

<a id="instance-resource-limits:limits.memory"></a>
`limits.memory`

Usage limit for the host’s memory

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-resource-limits:limits.memory)

| **Key:**         | `limits.memory`   |
|------------------|-------------------|
| **Type:**        | string            |
| **Default:**     | `1GiB` (VMs)      |
| **Live update:** | yes               |

Percentage of the host’s memory or a fixed value in bytes.
Various suffixes are supported.

See [Units for storage and network limits](instance_units.md#instances-limit-units) for details.

<a id="instance-resource-limits:limits.memory.enforce"></a>
`limits.memory.enforce`

Whether the memory limit is `hard` or `soft`

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-resource-limits:limits.memory.enforce)

| **Key:**         | `limits.memory.enforce`   |
|------------------|---------------------------|
| **Type:**        | string                    |
| **Default:**     | `hard`                    |
| **Live update:** | yes                       |
| **Condition:**   | container                 |

If the instance’s memory limit is `hard`, the instance cannot exceed its limit.
If it is `soft`, the instance can exceed its memory limit when extra host memory is available.

<a id="instance-resource-limits:limits.memory.hugepages"></a>
`limits.memory.hugepages`

Whether to back the instance using huge pages

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-resource-limits:limits.memory.hugepages)

| **Key:**         | `limits.memory.hugepages`   |
|------------------|-----------------------------|
| **Type:**        | bool                        |
| **Default:**     | `false`                     |
| **Live update:** | no                          |
| **Condition:**   | virtual machine             |

If this option is set to `false`, regular system memory is used.

<a id="instance-resource-limits:limits.memory.swap"></a>
`limits.memory.swap`

Whether to encourage/discourage swapping less used pages for this instance

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-resource-limits:limits.memory.swap)

| **Key:**         | `limits.memory.swap`   |
|------------------|------------------------|
| **Type:**        | bool                   |
| **Default:**     | `true`                 |
| **Live update:** | yes                    |
| **Condition:**   | container              |

<a id="instance-resource-limits:limits.memory.swap.priority"></a>
`limits.memory.swap.priority`

Prevents the instance from being swapped to disk

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-resource-limits:limits.memory.swap.priority)

| **Key:**         | `limits.memory.swap.priority`   |
|------------------|---------------------------------|
| **Type:**        | integer                         |
| **Default:**     | `10` (maximum)                  |
| **Live update:** | yes                             |
| **Condition:**   | container                       |

Specify an integer between 0 and 10.
The higher the value, the less likely the instance is to be swapped to disk.

<a id="instance-resource-limits:limits.processes"></a>
`limits.processes`

Maximum number of processes that can run in the instance

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-resource-limits:limits.processes)

| **Key:**         | `limits.processes`   |
|------------------|----------------------|
| **Type:**        | integer              |
| **Default:**     | empty                |
| **Live update:** | yes                  |
| **Condition:**   | container            |

If left empty, no limit is set.

<a id="instance-resource-limits:limits.kernel.*"></a>
`limits.kernel.*`

Kernel resources per instance

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-resource-limits:limits.kernel.*)

| **Key:**         | `limits.kernel.*`   |
|------------------|---------------------|
| **Type:**        | string              |
| **Live update:** | no                  |
| **Condition:**   | container           |

You can set kernel limits on an instance, for example, you can limit the number of open files.
See [Kernel resource limits](#instance-options-limits-kernel) for more information.

### CPU limits

You have different options to limit CPU usage:

- Set [`limits.cpu`](#instance-resource-limits:limits.cpu) to restrict which CPUs the instance can see and use.
  See [CPU pinning](#instance-options-limits-cpu) for how to set this option.
- Set [`limits.cpu.allowance`](#instance-resource-limits:limits.cpu.allowance) to restrict the load an instance can put on the available CPUs.
  This option is available only for containers.
  See [Allowance and priority (container only)](#instance-options-limits-cpu-container) for how to set this option.
- Set [`limits.cpu.pin_strategy`](#instance-resource-limits:limits.cpu.pin_strategy) to specify the strategy for virtual-machine CPU auto pinning.
  This option is available only for virtual machines.
  See [CPU limits for virtual machines](#instance-options-limits-cpu-vm) for how to set this option.

It is possible to set both options at the same time to restrict both which CPUs are visible to the instance and the allowed usage of those instances.
However, if you use [`limits.cpu.allowance`](#instance-resource-limits:limits.cpu.allowance) with a time limit, you should avoid using [`limits.cpu`](#instance-resource-limits:limits.cpu) in addition, because that puts a lot of constraints on the scheduler and might lead to less efficient allocations.

The CPU limits are implemented through a mix of the `cpuset` and `cpu` cgroup controllers.

<a id="instance-options-limits-cpu"></a>

#### CPU pinning

[`limits.cpu`](#instance-resource-limits:limits.cpu) results in CPU pinning through the `cpuset` controller.
You can specify either which CPUs or how many CPUs are visible and available to the instance:

- To specify which CPUs to use, set `limits.cpu` to either a set of CPUs (for example, `1,2,3`) or a CPU range (for example, `0-3`).

  To pin to a single CPU, use the range syntax (for example, `1-1`) to differentiate it from a number of CPUs.
- If you specify a number (for example, `4`) of CPUs, LXD will do dynamic load-balancing of all instances that aren’t pinned to specific CPUs, trying to spread the load on the machine.
  Instances are re-balanced every time an instance starts or stops, as well as whenever a CPU is added to the system.

<a id="instance-options-limits-cpu-vm"></a>

##### CPU limits for virtual machines

#### NOTE
LXD supports live-updating the [`limits.cpu`](#instance-resource-limits:limits.cpu) option.
However, for virtual machines, this only means that the respective CPUs are hotplugged.
Depending on the guest operating system, you might need to either restart the instance or complete some manual actions to bring the new CPUs online.

LXD virtual machines default to having just one vCPU allocated, which shows up as matching the host CPU vendor and type, but has a single core and no threads.

When [`limits.cpu`](#instance-resource-limits:limits.cpu) is set to a single integer, LXD allocates multiple vCPUs and exposes them to the guest as full cores.
Unless [`limits.cpu.pin_strategy`](#instance-resource-limits:limits.cpu.pin_strategy) is set to `auto`, those vCPUs are not pinned to specific cores on the host.
The number of vCPUs can be updated while the VM is running.

When [`limits.cpu`](#instance-resource-limits:limits.cpu) is set to a range or comma-separated list of CPU IDs (as provided by [`lxc info --resources`](manpages/lxc/info.md#lxc-info-md)), the vCPUs are pinned to those cores.
In this scenario, LXD checks whether the CPU configuration lines up with a realistic hardware topology and if it does, it replicates that topology in the guest.
When doing CPU pinning, it is not possible to change the configuration while the VM is running.

For example, if the pinning configuration includes eight threads, with each pair of thread coming from the same core and an even number of cores spread across two CPUs, the guest will show two CPUs, each with two cores and each core with two threads.
The NUMA layout is similarly replicated and in this scenario, the guest would most likely end up with two NUMA nodes, one for each CPU socket.

In such an environment with multiple NUMA nodes, the memory is similarly divided across NUMA nodes and be pinned accordingly on the host and then exposed to the guest.

All this allows for very high performance operations in the guest as the guest scheduler can properly reason about sockets, cores and threads as well as consider NUMA topology when sharing memory or moving processes across NUMA nodes.

<a id="instance-options-limits-cpu-container"></a>

#### Allowance and priority (container only)

[`limits.cpu.allowance`](#instance-resource-limits:limits.cpu.allowance) drives either the CFS scheduler quotas when passed a time constraint, or the generic CPU shares mechanism when passed a percentage value:

- The time constraint (for example, `20ms/50ms`) is a hard limit.
  For example, if you want to allow the container to use a maximum of one CPU, set [`limits.cpu.allowance`](#instance-resource-limits:limits.cpu.allowance) to a value like `100ms/100ms`.
  The value is relative to one CPU worth of time, so to restrict to two CPUs worth of time, use something like `100ms/50ms` or `200ms/100ms`.
- When using a percentage value, the limit is a soft limit that is applied only when under load.
  It is used to calculate the scheduler priority for the instance, relative to any other instance that is using the same CPU or CPUs.
  For example, to limit the CPU usage of the container to one CPU when under load, set [`limits.cpu.allowance`](#instance-resource-limits:limits.cpu.allowance) to `100%`.

[`limits.cpu.nodes`](#instance-resource-limits:limits.cpu.nodes) can be used to restrict the CPUs that the instance can use to a specific set of NUMA nodes.
To specify which NUMA nodes to use, set [`limits.cpu.nodes`](#instance-resource-limits:limits.cpu.nodes) to either a set of NUMA node IDs (for example, `0,1`) or a set of NUMA node ranges (for example, `0-1,2-4`).

[`limits.cpu.priority`](#instance-resource-limits:limits.cpu.priority) is another factor that is used to compute the scheduler priority score when a number of instances sharing a set of CPUs have the same percentage of CPU assigned to them.

<a id="instance-options-limits-hugepages"></a>

### Huge page limits

LXD allows to limit the number of huge pages available to a container through the `limits.hugepage.[size]` key (for example, [`limits.hugepages.1MB`](#instance-resource-limits:limits.hugepages.1MB)).

Architectures often expose multiple huge-page sizes.
The available huge-page sizes depend on the architecture.

Setting limits for huge pages is especially useful when LXD is configured to intercept the `mount` syscall for the `hugetlbfs` file system in unprivileged containers.
When LXD intercepts a `hugetlbfs` `mount` syscall, it mounts the `hugetlbfs` file system for a container with correct `uid` and `gid` values as mount options.
This makes it possible to use huge pages from unprivileged containers.
However, it is recommended to limit the number of huge pages available to the container through `limits.hugepages.[size]` to stop the container from being able to exhaust the huge pages available to the host.

Limiting huge pages is done through the `hugetlb` cgroup controller, which means that the host system must expose the `hugetlb` controller in the legacy or unified cgroup hierarchy for these limits to apply.

<a id="instance-options-limits-kernel"></a>

### Kernel resource limits

For container instances, LXD exposes a generic namespaced key [`limits.kernel.*`](#instance-resource-limits:limits.kernel.*) that can be used to set resource limits.

It is generic in the sense that LXD does not perform any validation on the resource that is specified following the `limits.kernel.*` prefix.
LXD cannot know about all the possible resources that a given kernel supports.
Instead, LXD simply passes down the corresponding resource key after the `limits.kernel.*` prefix and its value to the kernel.
The kernel does the appropriate validation.
This allows users to specify any supported limit on their system.

Some common limits are:

| Key                        | Resource            | Description                                                                         |
|----------------------------|---------------------|-------------------------------------------------------------------------------------|
| `limits.kernel.as`         | `RLIMIT_AS`         | Maximum size of the process’s virtual memory                                        |
| `limits.kernel.core`       | `RLIMIT_CORE`       | Maximum size of the process’s core dump file                                        |
| `limits.kernel.cpu`        | `RLIMIT_CPU`        | Limit in seconds on the amount of CPU time the process can consume                  |
| `limits.kernel.data`       | `RLIMIT_DATA`       | Maximum size of the process’s data segment                                          |
| `limits.kernel.fsize`      | `RLIMIT_FSIZE`      | Maximum size of files the process may create                                        |
| `limits.kernel.locks`      | `RLIMIT_LOCKS`      | Limit on the number of file locks that this process may establish                   |
| `limits.kernel.memlock`    | `RLIMIT_MEMLOCK`    | Limit on the number of bytes of memory that the process may lock in RAM             |
| `limits.kernel.nice`       | `RLIMIT_NICE`       | Maximum value to which the process’s nice value can be raised                       |
| `limits.kernel.nofile`     | `RLIMIT_NOFILE`     | Maximum number of open files for the process                                        |
| `limits.kernel.nproc`      | `RLIMIT_NPROC`      | Maximum number of processes that can be created for the user of the calling process |
| `limits.kernel.rtprio`     | `RLIMIT_RTPRIO`     | Maximum value on the real-time-priority that may be set for this process            |
| `limits.kernel.sigpending` | `RLIMIT_SIGPENDING` | Maximum number of signals that may be queued for the user of the calling process    |

A full list of all available limits can be found in the manpages for the `getrlimit(2)`/`setrlimit(2)` system calls.

To specify a limit within the `limits.kernel.*` namespace, use the resource name in lowercase without the `RLIMIT_` prefix.
For example, `RLIMIT_NOFILE` should be specified as `nofile`.

A limit is specified as two colon-separated values that are either numeric or the word `unlimited` (for example, `limits.kernel.nofile=1000:2000`).
A single value can be used as a shortcut to set both soft and hard limit to the same value (for example, `limits.kernel.nofile=3000`).

A resource with no explicitly configured limit will inherit its limit from the process that starts up the container.
Note that this inheritance is not enforced by LXD but by the kernel.

<a id="instance-options-migration"></a>

## Migration options

The following instance options control the behavior if the instance is [moved from one LXD server to another](../howto/instances_migrate.md#howto-instances-migrate):

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="instance-migration:migration.incremental.memory"></a>
`migration.incremental.memory`

Whether to use incremental memory transfer

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-migration:migration.incremental.memory)

| **Key:**         | `migration.incremental.memory`   |
|------------------|----------------------------------|
| **Type:**        | bool                             |
| **Default:**     | `false`                          |
| **Live update:** | yes                              |
| **Condition:**   | container                        |

Using incremental memory transfer of the instance’s memory can reduce downtime.

<a id="instance-migration:migration.incremental.memory.goal"></a>
`migration.incremental.memory.goal`

Percentage of memory to have in sync before stopping the instance

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-migration:migration.incremental.memory.goal)

| **Key:**         | `migration.incremental.memory.goal`   |
|------------------|---------------------------------------|
| **Type:**        | integer                               |
| **Default:**     | `70`                                  |
| **Live update:** | yes                                   |
| **Condition:**   | container                             |

<a id="instance-migration:migration.incremental.memory.iterations"></a>
`migration.incremental.memory.iterations`

Maximum number of transfer operations to go through before stopping the instance

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-migration:migration.incremental.memory.iterations)

| **Key:**         | `migration.incremental.memory.iterations`   |
|------------------|---------------------------------------------|
| **Type:**        | integer                                     |
| **Default:**     | `10`                                        |
| **Live update:** | yes                                         |
| **Condition:**   | container                                   |

<a id="instance-migration:migration.stateful"></a>
`migration.stateful`

Whether to allow for stateful stop/start and snapshots

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-migration:migration.stateful)

| **Key:**         | `migration.stateful`                                                      |
|------------------|---------------------------------------------------------------------------|
| **Type:**        | bool                                                                      |
| **Default:**     | `false` or value from profiles or `instances.migration.stateful` (if set) |
| **Live update:** | no                                                                        |
| **Condition:**   | virtual machine                                                           |

Enabling this option prevents the use of some features that are incompatible with it.

<a id="instance-options-placement"></a>

## Placement options

The following instance option controls the placement of instances in a cluster:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="instance-placement:placement.group"></a>
`placement.group`

Placement group controlling instance scheduling

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-placement:placement.group)

| **Key:**         | `placement.group`   |
|------------------|---------------------|
| **Type:**        | string              |
| **Live update:** | yes                 |

Specifies the placement group that determines where this instance is scheduled within the cluster.
The placement group defines the placement policy (e.g. spread or compact) and rigor (e.g. strict or permissive)
used to determine eligible cluster members during LXD scheduling events.

See [How to use placement groups](../howto/cluster_placement_groups.md#cluster-placement-groups) for more information about placement groups.

<a id="instance-options-nvidia"></a>

## NVIDIA and CUDA configuration

The following instance options specify the NVIDIA and CUDA configuration of the instance:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="instance-nvidia:nvidia.driver.capabilities"></a>
`nvidia.driver.capabilities`

What driver capabilities the instance needs

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-nvidia:nvidia.driver.capabilities)

| **Key:**         | `nvidia.driver.capabilities`   |
|------------------|--------------------------------|
| **Type:**        | string                         |
| **Default:**     | `compute,utility`              |
| **Live update:** | no                             |
| **Condition:**   | container                      |

The specified driver capabilities are used to set `libnvidia-container NVIDIA_DRIVER_CAPABILITIES`.

<a id="instance-nvidia:nvidia.require.cuda"></a>
`nvidia.require.cuda`

Required CUDA version

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-nvidia:nvidia.require.cuda)

| **Key:**         | `nvidia.require.cuda`   |
|------------------|-------------------------|
| **Type:**        | string                  |
| **Live update:** | no                      |
| **Condition:**   | container               |

The specified version expression is used to set `libnvidia-container NVIDIA_REQUIRE_CUDA`.

<a id="instance-nvidia:nvidia.require.driver"></a>
`nvidia.require.driver`

Required driver version

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-nvidia:nvidia.require.driver)

| **Key:**         | `nvidia.require.driver`   |
|------------------|---------------------------|
| **Type:**        | string                    |
| **Live update:** | no                        |
| **Condition:**   | container                 |

The specified version expression is used to set `libnvidia-container NVIDIA_REQUIRE_DRIVER`.

<a id="instance-nvidia:nvidia.runtime"></a>
`nvidia.runtime`

Whether to pass the host NVIDIA and CUDA runtime libraries into the instance

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-nvidia:nvidia.runtime)

| **Key:**         | `nvidia.runtime`   |
|------------------|--------------------|
| **Type:**        | bool               |
| **Default:**     | `false`            |
| **Live update:** | no                 |
| **Condition:**   | container          |

<a id="instance-options-raw"></a>

## Raw instance configuration overrides

The following instance options allow direct interaction with the backend features that LXD itself uses:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="instance-raw:raw.apparmor"></a>
`raw.apparmor`

AppArmor profile entries

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-raw:raw.apparmor)

| **Key:**         | `raw.apparmor`   |
|------------------|------------------|
| **Type:**        | blob             |
| **Live update:** | yes              |

The specified entries are appended to the generated profile.

<a id="instance-raw:raw.idmap"></a>
`raw.idmap`

Raw idmap configuration

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-raw:raw.idmap)

| **Key:**         | `raw.idmap`   |
|------------------|---------------|
| **Type:**        | blob          |
| **Live update:** | no            |

For example: `both 1000 1000`

<a id="instance-raw:raw.lxc"></a>
`raw.lxc`

Raw LXC configuration to be appended to the generated one

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-raw:raw.lxc)

| **Key:**         | `raw.lxc`   |
|------------------|-------------|
| **Type:**        | blob        |
| **Live update:** | no          |
| **Condition:**   | container   |

<a id="instance-raw:raw.qemu"></a>
`raw.qemu`

Raw QEMU configuration to be appended to the generated command line

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-raw:raw.qemu)

| **Key:**         | `raw.qemu`      |
|------------------|-----------------|
| **Type:**        | blob            |
| **Live update:** | no              |
| **Condition:**   | virtual machine |

<a id="instance-raw:raw.qemu.conf"></a>
`raw.qemu.conf`

Addition/override to the generated `qemu.conf` file

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-raw:raw.qemu.conf)

| **Key:**         | `raw.qemu.conf`   |
|------------------|-------------------|
| **Type:**        | blob              |
| **Live update:** | no                |
| **Condition:**   | virtual machine   |

See [Override QEMU configuration](#instance-options-qemu) for more information.

<a id="instance-raw:raw.seccomp"></a>
`raw.seccomp`

Raw Seccomp configuration

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-raw:raw.seccomp)

| **Key:**         | `raw.seccomp`   |
|------------------|-----------------|
| **Type:**        | blob            |
| **Live update:** | no              |
| **Condition:**   | container       |

#### IMPORTANT
Setting these `raw.*` keys might break LXD in non-obvious ways.
Therefore, you should avoid setting any of these keys.

<a id="instance-options-qemu"></a>

### Override QEMU configuration

For VM instances, LXD configures QEMU through a configuration file that is passed to QEMU with the `-readconfig` command-line option.
This configuration file is generated for each instance before boot.
It can be found at `/var/log/lxd/<instance_name>/qemu.conf`.

The default configuration works fine for LXD’s most common use case: modern UEFI guests with VirtIO devices.
In some situations, however, you might need to override the generated configuration.
For example:

- To run an old guest OS that doesn’t support UEFI.
- To specify custom virtual devices when VirtIO is not supported by the guest OS.
- To add devices that are not supported by LXD before the machines boots.
- To remove devices that conflict with the guest OS.

To override the configuration, set the [`raw.qemu.conf`](#instance-raw:raw.qemu.conf) option.
It supports a format similar to `qemu.conf`, with some additions.
Since it is a multi-line configuration option, you can use it to modify multiple sections or keys.

- To replace a section or key in the generated configuration file, add a section with a different value.

  For example, use the following section to override the default `virtio-gpu-pci` GPU driver:
  ```default
  raw.qemu.conf: |-
      [device "qemu_gpu"]
      driver = "qxl-vga"
  ```
- To remove a section, specify a section without any keys.
  For example:
  ```default
  raw.qemu.conf: |-
      [device "qemu_gpu"]
  ```
- To remove a key, specify an empty string as the value.
  For example:
  ```default
  raw.qemu.conf: |-
      [device "qemu_gpu"]
      driver = ""
  ```
- To add a new section, specify a section name that is not present in the configuration file.

The configuration file format used by QEMU allows multiple sections with the same name.
Here’s a piece of the configuration generated by LXD:

```default
[global]
driver = "ICH9-LPC"
property = "disable_s3"
value = "1"

[global]
driver = "ICH9-LPC"
property = "disable_s4"
value = "1"
```

To specify which section to override, specify an index.
For example:

```default
raw.qemu.conf: |-
    [global][1]
    value = "0"
```

Section indexes start at 0 (which is the default value when not specified), so the above example would generate the following configuration:

```default
[global]
driver = "ICH9-LPC"
property = "disable_s3"
value = "1"

[global]
driver = "ICH9-LPC"
property = "disable_s4"
value = "0"
```

<a id="instance-options-security"></a>

## Security policies

The following instance options control the [Security](../explanation/security.md#security) policies of the instance:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="instance-security:security.agent.metrics"></a>
`security.agent.metrics`

Whether the `lxd-agent` is queried for state information and metrics

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-security:security.agent.metrics)

| **Key:**         | `security.agent.metrics`   |
|------------------|----------------------------|
| **Type:**        | bool                       |
| **Default:**     | `true`                     |
| **Live update:** | no                         |
| **Condition:**   | virtual machine            |

<a id="instance-security:security.delegate_bpf"></a>
`security.delegate_bpf`

Whether to enable eBPF delegation using BPF Token mechanism

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-security:security.delegate_bpf)

| **Key:**         | `security.delegate_bpf`   |
|------------------|---------------------------|
| **Type:**        | bool                      |
| **Default:**     | `false`                   |
| **Live update:** | no                        |
| **Condition:**   | unprivileged container    |

This option enables BPF functionality delegation mechanism (using BPF Token).

Note: `security.delegate_bpf.cmd_types`, `security.delegate_bpf.map_types`,
`security.delegate_bpf.prog_types`, `security.delegate_bpf.attach_types`
need to be configured depending on BPF workload in the container.

See [Privilege delegation using BPF Token](../explanation/bpf.md#bpf-delegation-token) for more information.

<a id="instance-security:security.delegate_bpf.attach_types"></a>
`security.delegate_bpf.attach_types`

Which eBPF attach types to allow with delegation mechanism

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-security:security.delegate_bpf.attach_types)

| **Key:**         | `security.delegate_bpf.attach_types`   |
|------------------|----------------------------------------|
| **Type:**        | bool                                   |
| **Default:**     | `false`                                |
| **Live update:** | no                                     |
| **Condition:**   | unprivileged container                 |

Which eBPF program attachment types to allow with delegation mechanism. Syntax follows
a kernel one for `delegate_attachs` bpffs mount option.
A number (bitmask) or `:`-separated list of attachment types to allow can be specified.
For example, `cgroup_inet_ingress` allows `BPF_CGROUP_INET_INGRESS` attachment type.

<a id="instance-security:security.delegate_bpf.cmd_types"></a>
`security.delegate_bpf.cmd_types`

Which eBPF commands to allow with delegation mechanism

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-security:security.delegate_bpf.cmd_types)

| **Key:**         | `security.delegate_bpf.cmd_types`   |
|------------------|-------------------------------------|
| **Type:**        | bool                                |
| **Default:**     | `false`                             |
| **Live update:** | no                                  |
| **Condition:**   | unprivileged container              |

Which eBPF commands to allow with delegation mechanism. Syntax follows a kernel one for `delegate_cmds`
bpffs mount option. A number (bitmask) or `:`-separated list of commands to allow can be specified.
For example, `prog_load:map_create` allows eBPF programs loading and eBPF maps creation.
Notice: `security.delegate_bpf.prog_types` and `security.delegate_bpf.map_types` still need to
be configured accordingly.

<a id="instance-security:security.delegate_bpf.map_types"></a>
`security.delegate_bpf.map_types`

Which eBPF maps to allow with delegation mechanism

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-security:security.delegate_bpf.map_types)

| **Key:**         | `security.delegate_bpf.map_types`   |
|------------------|-------------------------------------|
| **Type:**        | bool                                |
| **Default:**     | `false`                             |
| **Live update:** | no                                  |
| **Condition:**   | unprivileged container              |

Which eBPF maps to allow with delegation mechanism. Syntax follows a kernel one for `delegate_maps`
bpffs mount option. A number (bitmask) or `:`-separated list of map types to allow can be specified.
For example, `ringbuf` allows `BPF_MAP_TYPE_RINGBUF` map.

<a id="instance-security:security.delegate_bpf.prog_types"></a>
`security.delegate_bpf.prog_types`

Which eBPF program types to allow with delegation mechanism

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-security:security.delegate_bpf.prog_types)

| **Key:**         | `security.delegate_bpf.prog_types`   |
|------------------|--------------------------------------|
| **Type:**        | bool                                 |
| **Default:**     | `false`                              |
| **Live update:** | no                                   |
| **Condition:**   | unprivileged container               |

Which eBPF program types to allow with delegation mechanism. Syntax follows a kernel one for `delegate_progs`
bpffs mount option. A number (bitmask) or `:`-separated list of program types to allow can be specified.
For example, `socket_filter` allows `BPF_PROG_TYPE_SOCKET_FILTER` program type.

<a id="instance-security:security.devlxd"></a>
`security.devlxd`

Whether `/dev/lxd` is present in the instance

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-security:security.devlxd)

| **Key:**         | `security.devlxd`   |
|------------------|---------------------|
| **Type:**        | bool                |
| **Default:**     | `true`              |
| **Live update:** | no                  |

See [Communication between instance and host](../dev-lxd.md#dev-lxd) for more information.

<a id="instance-security:security.devlxd.images"></a>
`security.devlxd.images`

Controls the availability of the `/1.0/images` API over `devlxd`

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-security:security.devlxd.images)

| **Key:**         | `security.devlxd.images`   |
|------------------|----------------------------|
| **Type:**        | bool                       |
| **Default:**     | `false`                    |
| **Live update:** | yes                        |

<a id="instance-security:security.devlxd.management.volumes"></a>
`security.devlxd.management.volumes`

Controls the availability of the volume management API over `devlxd`

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-security:security.devlxd.management.volumes)

| **Key:**         | `security.devlxd.management.volumes`   |
|------------------|----------------------------------------|
| **Type:**        | bool                                   |
| **Default:**     | `false`                                |
| **Live update:** | yes                                    |

<a id="instance-security:security.idmap.base"></a>
`security.idmap.base`

The base host ID to use for the allocation

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-security:security.idmap.base)

| **Key:**         | `security.idmap.base`   |
|------------------|-------------------------|
| **Type:**        | integer                 |
| **Live update:** | no                      |
| **Condition:**   | unprivileged container  |

Setting this option overrides auto-detection.

<a id="instance-security:security.idmap.isolated"></a>
`security.idmap.isolated`

Whether to use a unique idmap for this instance

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-security:security.idmap.isolated)

| **Key:**         | `security.idmap.isolated`   |
|------------------|-----------------------------|
| **Type:**        | bool                        |
| **Default:**     | `false`                     |
| **Live update:** | no                          |
| **Condition:**   | unprivileged container      |

If specified, the idmap used for this instance is unique among instances that have this option set.

<a id="instance-security:security.idmap.size"></a>
`security.idmap.size`

The size of the idmap to use

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-security:security.idmap.size)

| **Key:**         | `security.idmap.size`   |
|------------------|-------------------------|
| **Type:**        | integer                 |
| **Live update:** | no                      |
| **Condition:**   | unprivileged container  |

<a id="instance-security:security.nesting"></a>
`security.nesting`

Whether to support running LXD (nested) inside the instance

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-security:security.nesting)

| **Key:**         | `security.nesting`   |
|------------------|----------------------|
| **Type:**        | bool                 |
| **Default:**     | `false`              |
| **Live update:** | yes                  |
| **Condition:**   | container            |

<a id="instance-security:security.privileged"></a>
`security.privileged`

Whether to run the instance in privileged mode

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-security:security.privileged)

| **Key:**         | `security.privileged`   |
|------------------|-------------------------|
| **Type:**        | bool                    |
| **Default:**     | `false`                 |
| **Live update:** | no                      |
| **Condition:**   | container               |

See [Container security](../explanation/security.md#container-security) for more information.

<a id="instance-security:security.protection.delete"></a>
`security.protection.delete`

Whether to prevent the instance from being deleted

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-security:security.protection.delete)

| **Key:**         | `security.protection.delete`   |
|------------------|--------------------------------|
| **Type:**        | bool                           |
| **Default:**     | `false`                        |
| **Live update:** | container                      |

<a id="instance-security:security.protection.shift"></a>
`security.protection.shift`

Whether to protect the file system from being UID/GID shifted

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-security:security.protection.shift)

| **Key:**         | `security.protection.shift`   |
|------------------|-------------------------------|
| **Type:**        | bool                          |
| **Default:**     | `false`                       |
| **Live update:** | yes                           |
| **Condition:**   | container                     |

Set this option to `true` to prevent the instance’s file system from being UID/GID shifted on startup.

<a id="instance-security:security.protection.start"></a>
`security.protection.start`

Whether to prevent the instance from being started

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-security:security.protection.start)

| **Key:**         | `security.protection.start`   |
|------------------|-------------------------------|
| **Type:**        | bool                          |
| **Default:**     | `false`                       |
| **Live update:** | container                     |

<a id="instance-security:security.sev"></a>
`security.sev`

Whether AMD SEV (Secure Encrypted Virtualization) is enabled for this VM

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-security:security.sev)

| **Key:**         | `security.sev`   |
|------------------|------------------|
| **Type:**        | bool             |
| **Default:**     | `false`          |
| **Live update:** | no               |
| **Condition:**   | virtual machine  |

<a id="instance-security:security.sev.policy.es"></a>
`security.sev.policy.es`

Whether AMD SEV-ES (SEV Encrypted State) is enabled for this VM

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-security:security.sev.policy.es)

| **Key:**         | `security.sev.policy.es`   |
|------------------|----------------------------|
| **Type:**        | bool                       |
| **Default:**     | `false`                    |
| **Live update:** | no                         |
| **Condition:**   | virtual machine            |

<a id="instance-security:security.sev.session.data"></a>
`security.sev.session.data`

The guest owner’s `base64`-encoded session blob

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-security:security.sev.session.data)

| **Key:**         | `security.sev.session.data`   |
|------------------|-------------------------------|
| **Type:**        | string                        |
| **Default:**     | `true`                        |
| **Live update:** | no                            |
| **Condition:**   | virtual machine               |

<a id="instance-security:security.sev.session.dh"></a>
`security.sev.session.dh`

The guest owner’s `base64`-encoded Diffie-Hellman key

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-security:security.sev.session.dh)

| **Key:**         | `security.sev.session.dh`   |
|------------------|-----------------------------|
| **Type:**        | string                      |
| **Default:**     | `true`                      |
| **Live update:** | no                          |
| **Condition:**   | virtual machine             |

<a id="instance-security:security.syscalls.allow"></a>
`security.syscalls.allow`

List of syscalls to allow

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-security:security.syscalls.allow)

| **Key:**         | `security.syscalls.allow`   |
|------------------|-----------------------------|
| **Type:**        | string                      |
| **Live update:** | no                          |
| **Condition:**   | container                   |

A `\n`-separated list of syscalls to allow.
This list must be mutually exclusive with `security.syscalls.deny*`.

<a id="instance-security:security.syscalls.deny"></a>
`security.syscalls.deny`

List of syscalls to deny

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-security:security.syscalls.deny)

| **Key:**         | `security.syscalls.deny`   |
|------------------|----------------------------|
| **Type:**        | string                     |
| **Live update:** | no                         |
| **Condition:**   | container                  |

A `\n`-separated list of syscalls to deny.
This list must be mutually exclusive with `security.syscalls.allow`.

<a id="instance-security:security.syscalls.deny_compat"></a>
`security.syscalls.deny_compat`

Whether to block `compat_*` syscalls (`x86_64` only)

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-security:security.syscalls.deny_compat)

| **Key:**         | `security.syscalls.deny_compat`   |
|------------------|-----------------------------------|
| **Type:**        | bool                              |
| **Default:**     | `false`                           |
| **Live update:** | no                                |
| **Condition:**   | container                         |

On `x86_64`, this option controls whether to block `compat_*` syscalls.
On other architectures, the option is ignored.

<a id="instance-security:security.syscalls.deny_default"></a>
`security.syscalls.deny_default`

Whether to enable the default syscall deny

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-security:security.syscalls.deny_default)

| **Key:**         | `security.syscalls.deny_default`   |
|------------------|------------------------------------|
| **Type:**        | bool                               |
| **Default:**     | `true`                             |
| **Live update:** | no                                 |
| **Condition:**   | container                          |

<a id="instance-security:security.syscalls.intercept.bpf"></a>
`security.syscalls.intercept.bpf`

Whether to handle the `bpf()` system call

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-security:security.syscalls.intercept.bpf)

| **Key:**         | `security.syscalls.intercept.bpf`   |
|------------------|-------------------------------------|
| **Type:**        | bool                                |
| **Default:**     | `false`                             |
| **Live update:** | no                                  |
| **Condition:**   | container                           |

<a id="instance-security:security.syscalls.intercept.bpf.devices"></a>
`security.syscalls.intercept.bpf.devices`

Whether to allow BPF programs

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-security:security.syscalls.intercept.bpf.devices)

| **Key:**         | `security.syscalls.intercept.bpf.devices`   |
|------------------|---------------------------------------------|
| **Type:**        | bool                                        |
| **Default:**     | `false`                                     |
| **Live update:** | no                                          |
| **Condition:**   | container                                   |

This option controls whether to allow BPF programs for the devices cgroup in the unified hierarchy to be loaded.

<a id="instance-security:security.syscalls.intercept.mknod"></a>
`security.syscalls.intercept.mknod`

Whether to handle the `mknod` and `mknodat` system calls

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-security:security.syscalls.intercept.mknod)

| **Key:**         | `security.syscalls.intercept.mknod`   |
|------------------|---------------------------------------|
| **Type:**        | bool                                  |
| **Default:**     | `false`                               |
| **Live update:** | no                                    |
| **Condition:**   | container                             |

These system calls allow creation of a limited subset of char/block devices.

<a id="instance-security:security.syscalls.intercept.mount"></a>
`security.syscalls.intercept.mount`

Whether to handle the `mount` system call

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-security:security.syscalls.intercept.mount)

| **Key:**         | `security.syscalls.intercept.mount`   |
|------------------|---------------------------------------|
| **Type:**        | bool                                  |
| **Default:**     | `false`                               |
| **Live update:** | no                                    |
| **Condition:**   | container                             |

<a id="instance-security:security.syscalls.intercept.mount.allowed"></a>
`security.syscalls.intercept.mount.allowed`

File systems that can be mounted

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-security:security.syscalls.intercept.mount.allowed)

| **Key:**         | `security.syscalls.intercept.mount.allowed`   |
|------------------|-----------------------------------------------|
| **Type:**        | string                                        |
| **Live update:** | yes                                           |
| **Condition:**   | container                                     |

Specify a comma-separated list of file systems that are safe to mount for processes inside the instance.

<a id="instance-security:security.syscalls.intercept.mount.fuse"></a>
`security.syscalls.intercept.mount.fuse`

File system that should be redirected to FUSE implementation

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-security:security.syscalls.intercept.mount.fuse)

| **Key:**         | `security.syscalls.intercept.mount.fuse`   |
|------------------|--------------------------------------------|
| **Type:**        | string                                     |
| **Live update:** | yes                                        |
| **Condition:**   | container                                  |

Specify the mounts of a given file system that should be redirected to their FUSE implementation (for example, `ext4=fuse2fs`).

<a id="instance-security:security.syscalls.intercept.mount.shift"></a>
`security.syscalls.intercept.mount.shift`

Whether to use idmapped mounts for syscall interception

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-security:security.syscalls.intercept.mount.shift)

| **Key:**         | `security.syscalls.intercept.mount.shift`   |
|------------------|---------------------------------------------|
| **Type:**        | bool                                        |
| **Default:**     | `false`                                     |
| **Live update:** | yes                                         |
| **Condition:**   | container                                   |

<a id="instance-security:security.syscalls.intercept.sched_setscheduler"></a>
`security.syscalls.intercept.sched_setscheduler`

Whether to handle the `sched_setscheduler` system call

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-security:security.syscalls.intercept.sched_setscheduler)

| **Key:**         | `security.syscalls.intercept.sched_setscheduler`   |
|------------------|----------------------------------------------------|
| **Type:**        | bool                                               |
| **Default:**     | `false`                                            |
| **Live update:** | no                                                 |
| **Condition:**   | container                                          |

This system call allows increasing process priority.

<a id="instance-security:security.syscalls.intercept.setxattr"></a>
`security.syscalls.intercept.setxattr`

Whether to handle the `setxattr` system call

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-security:security.syscalls.intercept.setxattr)

| **Key:**         | `security.syscalls.intercept.setxattr`   |
|------------------|------------------------------------------|
| **Type:**        | bool                                     |
| **Default:**     | `false`                                  |
| **Live update:** | no                                       |
| **Condition:**   | container                                |

This system call allows setting a limited subset of restricted extended attributes.

<a id="instance-security:security.syscalls.intercept.sysinfo"></a>
`security.syscalls.intercept.sysinfo`

Whether to handle the `sysinfo` system call

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-security:security.syscalls.intercept.sysinfo)

| **Key:**         | `security.syscalls.intercept.sysinfo`   |
|------------------|-----------------------------------------|
| **Type:**        | bool                                    |
| **Default:**     | `false`                                 |
| **Live update:** | no                                      |
| **Condition:**   | container                               |

This system call can be used to get cgroup-based resource usage information.

<a id="instance-options-snapshots"></a>

## Snapshot scheduling and configuration

The following instance options control the creation and expiry of [instance snapshots](../howto/instances_backup.md#instances-snapshots):

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="instance-snapshots:snapshots.expiry"></a>
`snapshots.expiry`

Time until snapshots are deleted

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-snapshots:snapshots.expiry)

| **Key:**         | `snapshots.expiry`   |
|------------------|----------------------|
| **Type:**        | string               |
| **Live update:** | no                   |

Specify an expression like `1M 2H 3d 4w 5m 6y`.

<a id="instance-snapshots:snapshots.pattern"></a>
`snapshots.pattern`

Template for the snapshot name

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-snapshots:snapshots.pattern)

| **Key:**         | `snapshots.pattern`   |
|------------------|-----------------------|
| **Type:**        | string                |
| **Default:**     | `snap%d`              |
| **Live update:** | no                    |

Specify a Pongo2 template string that represents the snapshot name.
This template is used for scheduled snapshots and for unnamed snapshots.

See [Automatic snapshot names](#instance-options-snapshots-names) for more information.

<a id="instance-snapshots:snapshots.schedule"></a>
`snapshots.schedule`

Schedule for automatic instance snapshots

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-snapshots:snapshots.schedule)

| **Key:**         | `snapshots.schedule`   |
|------------------|------------------------|
| **Type:**        | string                 |
| **Default:**     | empty                  |
| **Live update:** | no                     |

Specify either a cron expression (`<minute> <hour> <dom> <month> <dow>`), a comma-separated list of schedule aliases (`@hourly`, `@daily`, `@midnight`, `@weekly`, `@monthly`, `@annually`, `@yearly`), or leave empty to disable automatic snapshots.

<a id="instance-snapshots:snapshots.schedule.stopped"></a>
`snapshots.schedule.stopped`

Whether to automatically snapshot stopped instances

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-snapshots:snapshots.schedule.stopped)

| **Key:**         | `snapshots.schedule.stopped`   |
|------------------|--------------------------------|
| **Type:**        | bool                           |
| **Default:**     | `false`                        |
| **Live update:** | no                             |

<a id="instance-options-snapshots-names"></a>

### Automatic snapshot names

The `snapshots.pattern` option takes a Pongo2 template string to format the snapshot name.

To add a time stamp to the snapshot name, use the Pongo2 context variable `creation_date`.
Make sure to format the date in your template string to avoid forbidden characters in the snapshot name.
For example, set `snapshots.pattern` to `{{ creation_date|date:'2006-01-02_15-04-05' }}` to name the snapshots after their time of creation, down to the precision of a second.

Another way to avoid name collisions is to use the placeholder `%d` in the pattern.
If no matching snapshots exist, the placeholder is replaced with `0`.
Otherwise, it is replaced with the next snapshot index, which is one higher than the highest existing matching snapshot index.

<a id="instance-options-volatile"></a>

## Volatile internal data

#### WARNING
The `volatile.*` keys cannot be manipulated by the user. Do not attempt to modify these keys in any way. LXD modifies these keys, and attempting to manipulate them yourself might break LXD in non-obvious ways.

The following volatile keys are currently used internally by LXD to store internal data specific to an instance:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="instance-volatile:volatile.<name>.apply_quota"></a>
`volatile.<name>.apply_quota`

Disk quota

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-volatile:volatile.<name>.apply_quota)

| **Key:**    | `volatile.<name>.apply_quota`   |
|-------------|---------------------------------|
| **Type:**   | string                          |

The disk quota is applied the next time the instance starts.

<a id="instance-volatile:volatile.<name>.bus"></a>
`volatile.<name>.bus`

Persistent VM bus number

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-volatile:volatile.<name>.bus)

| **Key:**    | `volatile.<name>.bus`   |
|-------------|-------------------------|
| **Type:**   | integer                 |

Persistent VM bus number.

<a id="instance-volatile:volatile.<name>.ceph_rbd"></a>
`volatile.<name>.ceph_rbd`

RBD device path for Ceph disk devices

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-volatile:volatile.<name>.ceph_rbd)

| **Key:**    | `volatile.<name>.ceph_rbd`   |
|-------------|------------------------------|
| **Type:**   | string                       |

RBD device path for Ceph disk devices.

<a id="instance-volatile:volatile.<name>.devlxd.owner"></a>
`volatile.<name>.devlxd.owner`

DevLXD identity ID that owns the device.

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-volatile:volatile.<name>.devlxd.owner)

| **Key:**    | `volatile.<name>.devlxd.owner`   |
|-------------|----------------------------------|
| **Type:**   | string                           |

ID of the DevLXD identity that owns the device. It is used by DevLXD to restrict
access of an identity to devices that were created by that identity.

<a id="instance-volatile:volatile.<name>.host_name"></a>
`volatile.<name>.host_name`

Network device name on the host

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-volatile:volatile.<name>.host_name)

| **Key:**    | `volatile.<name>.host_name`   |
|-------------|-------------------------------|
| **Type:**   | string                        |

Network device name on the host.

<a id="instance-volatile:volatile.<name>.hwaddr"></a>
`volatile.<name>.hwaddr`

Network device MAC address

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-volatile:volatile.<name>.hwaddr)

| **Key:**    | `volatile.<name>.hwaddr`   |
|-------------|----------------------------|
| **Type:**   | string                     |

The network device MAC address is used when no `hwaddr` property is set on the device itself.

<a id="instance-volatile:volatile.<name>.last_state.created"></a>
`volatile.<name>.last_state.created`

Whether the network device physical device was created

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-volatile:volatile.<name>.last_state.created)

| **Key:**    | `volatile.<name>.last_state.created`   |
|-------------|----------------------------------------|
| **Type:**   | bool                                   |

Possible values are `true` or `false`.

<a id="instance-volatile:volatile.<name>.last_state.hwaddr"></a>
`volatile.<name>.last_state.hwaddr`

Network device original MAC

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-volatile:volatile.<name>.last_state.hwaddr)

| **Key:**    | `volatile.<name>.last_state.hwaddr`   |
|-------------|---------------------------------------|
| **Type:**   | string                                |

The original MAC that was used when moving a physical device into an instance.

<a id="instance-volatile:volatile.<name>.last_state.mtu"></a>
`volatile.<name>.last_state.mtu`

Network device original MTU

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-volatile:volatile.<name>.last_state.mtu)

| **Key:**    | `volatile.<name>.last_state.mtu`   |
|-------------|------------------------------------|
| **Type:**   | string                             |

The original MTU that was used when moving a physical device into an instance.

<a id="instance-volatile:volatile.<name>.last_state.vdpa.name"></a>
`volatile.<name>.last_state.vdpa.name`

VDPA device name

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-volatile:volatile.<name>.last_state.vdpa.name)

| **Key:**    | `volatile.<name>.last_state.vdpa.name`   |
|-------------|------------------------------------------|
| **Type:**   | string                                   |

The VDPA device name used when moving a VDPA device file descriptor into an instance.

<a id="instance-volatile:volatile.<name>.last_state.vf.hwaddr"></a>
`volatile.<name>.last_state.vf.hwaddr`

SR-IOV virtual function original MAC

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-volatile:volatile.<name>.last_state.vf.hwaddr)

| **Key:**    | `volatile.<name>.last_state.vf.hwaddr`   |
|-------------|------------------------------------------|
| **Type:**   | string                                   |

The original MAC used when moving a VF into an instance.

<a id="instance-volatile:volatile.<name>.last_state.vf.id"></a>
`volatile.<name>.last_state.vf.id`

SR-IOV virtual function ID

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-volatile:volatile.<name>.last_state.vf.id)

| **Key:**    | `volatile.<name>.last_state.vf.id`   |
|-------------|--------------------------------------|
| **Type:**   | string                               |

The ID used when moving a VF into an instance.

<a id="instance-volatile:volatile.<name>.last_state.vf.spoofcheck"></a>
`volatile.<name>.last_state.vf.spoofcheck`

SR-IOV virtual function original spoof check setting

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-volatile:volatile.<name>.last_state.vf.spoofcheck)

| **Key:**    | `volatile.<name>.last_state.vf.spoofcheck`   |
|-------------|----------------------------------------------|
| **Type:**   | string                                       |

The original spoof check setting used when moving a VF into an instance.

<a id="instance-volatile:volatile.<name>.last_state.vf.vlan"></a>
`volatile.<name>.last_state.vf.vlan`

SR-IOV virtual function original VLAN

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-volatile:volatile.<name>.last_state.vf.vlan)

| **Key:**    | `volatile.<name>.last_state.vf.vlan`   |
|-------------|----------------------------------------|
| **Type:**   | string                                 |

The original VLAN used when moving a VF into an instance.

<a id="instance-volatile:volatile.apply_nvram"></a>
`volatile.apply_nvram`

Whether to regenerate VM NVRAM the next time the instance starts

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-volatile:volatile.apply_nvram)

| **Key:**    | `volatile.apply_nvram`   |
|-------------|--------------------------|
| **Type:**   | bool                     |

<a id="instance-volatile:volatile.apply_template"></a>
`volatile.apply_template`

Template hook

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-volatile:volatile.apply_template)

| **Key:**    | `volatile.apply_template`   |
|-------------|-----------------------------|
| **Type:**   | string                      |

The template with the given name is triggered upon next startup.

<a id="instance-volatile:volatile.attached_volumes"></a>
`volatile.attached_volumes`

JSON-serialized map of attached volume device names to the UUIDs of their corresponding snapshots.

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-volatile:volatile.attached_volumes)

| **Key:**       | `volatile.attached_volumes`   |
|----------------|-------------------------------|
| **Type:**      | string                        |
| **Condition:** | snapshot                      |

JSON-serialized map of attached volume device names to the UUIDs of their corresponding
snapshots, created as part of a multi-volume snapshot.

<a id="instance-volatile:volatile.base_image"></a>
`volatile.base_image`

Hash of the base image

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-volatile:volatile.base_image)

| **Key:**    | `volatile.base_image`   |
|-------------|-------------------------|
| **Type:**   | string                  |

The hash of the image that the instance was created from (empty if the instance was not created from an image).

<a id="instance-volatile:volatile.bus.mode"></a>
`volatile.bus.mode`

Device bus allocation mode

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-volatile:volatile.bus.mode)

| **Key:**    | `volatile.bus.mode`   |
|-------------|-----------------------|
| **Type:**   | string                |

Set to `persistent` when persistent bus allocation mode is enabled.

<a id="instance-volatile:volatile.cloud-init.instance-id"></a>
`volatile.cloud-init.instance-id`

`instance-id` (UUID) exposed to `cloud-init`

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-volatile:volatile.cloud-init.instance-id)

| **Key:**    | `volatile.cloud-init.instance-id`   |
|-------------|-------------------------------------|
| **Type:**   | string                              |

<a id="instance-volatile:volatile.cluster.group"></a>
`volatile.cluster.group`

The target cluster group

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-volatile:volatile.cluster.group)

| **Key:**    | `volatile.cluster.group`   |
|-------------|----------------------------|
| **Type:**   | string                     |

The target cluster group at instance creation or migration time. This is used during scheduling events such as evacuation to ensure the instance is placed correctly.

<a id="instance-volatile:volatile.evacuate.origin"></a>
`volatile.evacuate.origin`

The origin of the evacuated instance

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-volatile:volatile.evacuate.origin)

| **Key:**    | `volatile.evacuate.origin`   |
|-------------|------------------------------|
| **Type:**   | string                       |

The cluster member that the instance lived on before evacuation.

<a id="instance-volatile:volatile.idmap.base"></a>
`volatile.idmap.base`

The first ID in the container’s primary idmap range

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-volatile:volatile.idmap.base)

| **Key:**       | `volatile.idmap.base`   |
|----------------|-------------------------|
| **Type:**      | integer                 |
| **Condition:** | container               |

<a id="instance-volatile:volatile.idmap.current"></a>
`volatile.idmap.current`

The idmap currently in use by the container

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-volatile:volatile.idmap.current)

| **Key:**       | `volatile.idmap.current`   |
|----------------|----------------------------|
| **Type:**      | string                     |
| **Condition:** | container                  |

<a id="instance-volatile:volatile.idmap.next"></a>
`volatile.idmap.next`

The idmap to use the next time the container starts

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-volatile:volatile.idmap.next)

| **Key:**       | `volatile.idmap.next`   |
|----------------|-------------------------|
| **Type:**      | string                  |
| **Condition:** | container               |

<a id="instance-volatile:volatile.last_state.idmap"></a>
`volatile.last_state.idmap`

On-disk UID/GID map for the container’s rootfs

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-volatile:volatile.last_state.idmap)

| **Key:**       | `volatile.last_state.idmap`   |
|----------------|-------------------------------|
| **Type:**      | string                        |
| **Condition:** | container                     |

The UID/GID map that has been applied to the container’s underlying storage.
This is usually set for containers created on older kernels that don’t
support idmapped mounts.

<a id="instance-volatile:volatile.last_state.power"></a>
`volatile.last_state.power`

Instance state as of last host shutdown

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-volatile:volatile.last_state.power)

| **Key:**    | `volatile.last_state.power`   |
|-------------|-------------------------------|
| **Type:**   | string                        |

<a id="instance-volatile:volatile.uuid"></a>
`volatile.uuid`

Instance UUID

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-volatile:volatile.uuid)

| **Key:**    | `volatile.uuid`   |
|-------------|-------------------|
| **Type:**   | string            |

The instance UUID is globally unique across all servers and projects.

<a id="instance-volatile:volatile.uuid.generation"></a>
`volatile.uuid.generation`

Instance generation UUID

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-volatile:volatile.uuid.generation)

| **Key:**    | `volatile.uuid.generation`   |
|-------------|------------------------------|
| **Type:**   | string                       |

The instance generation UUID changes whenever the instance’s place in time moves backwards.
It is globally unique across all servers and projects.

<a id="instance-volatile:volatile.vsock_id"></a>
`volatile.vsock_id`

Instance `vsock ID` used as of last start

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#instance-volatile:volatile.vsock_id)

| **Key:**    | `volatile.vsock_id`   |
|-------------|-----------------------|
| **Type:**   | string                |


# index.html.md

<a id="storage-alletra"></a>

# HPE Alletra - `alletra`

[HPE Alletra](https://www.hpe.com/emea_europe/en/hpe-alletra.html) is a storage solution. It offers the consumption of redundant block storage across the network.

LXD supports connecting to HPE Alletra storage through .
In addition, HPE Alletra offers copy-on-write snapshots, thin provisioning, and other features.

Using HPE Alletra with LXD requires a HPE Alletra WSAPI version `1`. Additionally, ensure that the required kernel modules for the selected protocol are installed on your host system.

<a id="storage-alletra-terminology"></a>

## Terminology

Each storage pool created in LXD using an HPE Alletra driver represents an HPE Alletra *volume set*, which is an abstraction that groups multiple volumes under a specific name.

LXD creates volumes within a volume set that is identified by the storage pool name.
When the first volume needs to be mapped to a specific LXD host, a corresponding HPE Alletra host entity is created with the name of the LXD host and a suffix of the used protocol.
For example, if the LXD host is `host01` and the mode is `nvme/tcp`, the resulting HPE Alletra host entity would be `host01-nvme-tcp`.

The HPE Alletra host is then connected with the required volumes to allow attaching and accessing volumes from the LXD host.
The HPE Alletra host is automatically removed once there are no volumes connected to it.

<a id="storage-alletra-driver"></a>

## The `alletra` driver in LXD

The `alletra` driver in LXD uses HPE Alletra volumes for custom storage volumes, instances, and snapshots.
All created volumes are thin-provisioned block volumes. If required (for example, for containers and custom file system volumes), LXD formats the volume with a desired file system.

LXD expects HPE Alletra to be pre-configured with a specific service (such as iSCSI) on the network interfaces whose addresses you provide during storage pool configuration.
Furthermore, LXD assumes that it has full control over the HPE Alletra volume sets it manages.
Therefore, do not keep any volumes in HPE Alletra volume sets unless they are owned by LXD, because LXD might disconnect or even delete them.

This driver provides remote storage.
As a result, and depending on the internal network, storage access might be a bit slower compared to local storage.
On the other hand, using remote storage has significant advantages in a cluster setup: all cluster members have access to the same storage pools with the exact same contents, without the need to synchronize them.

When creating a new storage pool using the `alletra` driver, LXD automatically discovers the array’s qualified name and target address.
Upon successful discovery, LXD attaches all volumes that are connected to the HPE Alletra host that is associated with a specific LXD server.
HPE Alletra hosts and volume connections () are fully managed by LXD.

Volume snapshots are also supported by HPE Alletra.
When a volume with at least one snapshot is copied, LXD sequentially creates snapshots on the destination volume from snapshots on the source volume.
Finally, once all snapshots are copied, the source volume is copied into the destination volume.

<a id="storage-alletra-volume-names"></a>

### Volume names

As a Pure storage driver, the `alletra` driver uses the volume’s [`volatile.uuid`](#storage-alletra-volume-conf:volatile.uuid) to generate a volume name.

For example, a UUID `5a2504b0-6a6c-4849-8ee7-ddb0b674fd14` is first trimmed of any hyphens (`-`), resulting in the string `5a2504b06a6c48498ee7ddb0b674fd14`.
To distinguish volume types and snapshots, special identifiers are prepended and appended to the volume names, as depicted in the table below:

| Type            | Identifier   | Example                                                                                                                                                                              |
|-----------------|--------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Container       | `c-`         | `c-5a2504b06a6c48498ee7ddb0b674fd14`                                                                                                                                                 |
| Virtual machine | `v-`         | `v-5a2504b06a6c48498ee7ddb0b674fd14-b` (block volume) and `v-5a2504b06a6c48498ee7ddb0b674fd14` (file system volume)                                                                  |
| Image (ISO)     | `i-`         | `i-5a2504b06a6c48498ee7ddb0b674fd14-i`                                                                                                                                               |
| Custom volume   | `u-`         | `u-5a2504b06a6c48498ee7ddb0b674fd14` (file system volume) and `u-5a2504b06a6c48498ee7ddb0b674fd14-b` (block volume)                                                                  |
| Snapshot        | `s`          | `sc-5a2504b06a6c48498ee7ddb0b674fd14` (container snapshot), `sv-5a2504b06a6c48498ee7ddb0b674fd14-b` (VM snapshot) and `su-5a2504b06a6c48498ee7ddb0b674fd14` (custom volume snapshot) |

<a id="storage-alletra-limitations"></a>

### Limitations

The `alletra` driver has the following limitations:

Volume size constraints
: The minimum volume size (quota) is `256MiB` and must be a multiple of `256MiB`. If the requested size does not meet these conditions, LXD automatically rounds it up to the nearest valid value.

Sharing an HPE Alletra storage pool between multiple LXD installations
: Sharing an HPE Alletra array among multiple LXD installations is possible, provided that the installations use distinct storage pool names. Storage pools are implemented as volume sets on the array, and volume set names must be unique.

Recovering HPE Alletra storage pools
: Recovery of HPE Alletra storage pools using `lxd recover` is currently not supported.

<a id="storage-alletra-options"></a>

## Configuration options

The following configuration options are available for storage pools that use the `alletra` driver, as well as storage volumes in these pools.

<a id="storage-alletra-pool-config"></a>

### Storage pool configuration

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="storage-alletra-pool-conf:alletra.cpg"></a>
`alletra.cpg`

HPE Alletra Common Provisioning Group (CPG) name

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-alletra-pool-conf:alletra.cpg)

| **Key:**    | `alletra.cpg`   |
|-------------|-----------------|
| **Type:**   | string          |

<a id="storage-alletra-pool-conf:alletra.mode"></a>
`alletra.mode`

How volumes are mapped to the local server

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-alletra-pool-conf:alletra.mode)

| **Key:**     | `alletra.mode`      |
|--------------|---------------------|
| **Type:**    | string              |
| **Default:** | the discovered mode |

The mode to use to map storage volumes to the local server.
Supported values are `iscsi` and `nvme/tcp`.

<a id="storage-alletra-pool-conf:alletra.target"></a>
`alletra.target`

List of target addresses.

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-alletra-pool-conf:alletra.target)

| **Key:**     | `alletra.target`    |
|--------------|---------------------|
| **Type:**    | string              |
| **Default:** | the discovered mode |

A comma-separated list of target addresses. If empty, LXD discovers and connects to all available targets. Otherwise, it only connects to the specified addresses.

<a id="storage-alletra-pool-conf:alletra.user.name"></a>
`alletra.user.name`

HPE Alletra storage admin username

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-alletra-pool-conf:alletra.user.name)

| **Key:**    | `alletra.user.name`   |
|-------------|-----------------------|
| **Type:**   | string                |

<a id="storage-alletra-pool-conf:alletra.user.password"></a>
`alletra.user.password`

HPE Alletra storage admin password

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-alletra-pool-conf:alletra.user.password)

| **Key:**    | `alletra.user.password`   |
|-------------|---------------------------|
| **Type:**   | string                    |

<a id="storage-alletra-pool-conf:alletra.wsapi"></a>
`alletra.wsapi`

Address of the HPE Alletra Storage UI/WSAPI

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-alletra-pool-conf:alletra.wsapi)

| **Key:**    | `alletra.wsapi`   |
|-------------|-------------------|
| **Type:**   | string            |

<a id="storage-alletra-pool-conf:alletra.wsapi.verify"></a>
`alletra.wsapi.verify`

Whether to verify the HPE Alletra Storage UI/WSAPI certificate

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-alletra-pool-conf:alletra.wsapi.verify)

| **Key:**     | `alletra.wsapi.verify`   |
|--------------|--------------------------|
| **Type:**    | bool                     |
| **Default:** | `true`                   |

<a id="storage-alletra-pool-conf:rsync.bwlimit"></a>
`rsync.bwlimit`

Upper limit on the socket I/O for `rsync`

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-alletra-pool-conf:rsync.bwlimit)

| **Key:**     | `rsync.bwlimit`   |
|--------------|-------------------|
| **Type:**    | string            |
| **Default:** | `0` (no limit)    |
| **Scope:**   | global            |

When `rsync` must be used to transfer storage entities, this option specifies the upper limit
to be placed on the socket I/O.

<a id="storage-alletra-pool-conf:rsync.compression"></a>
`rsync.compression`

Whether to use compression while migrating storage pools

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-alletra-pool-conf:rsync.compression)

| **Key:**     | `rsync.compression`   |
|--------------|-----------------------|
| **Type:**    | bool                  |
| **Default:** | `true`                |
| **Scope:**   | global                |

<a id="storage-alletra-pool-conf:volume.size"></a>
`volume.size`

Size/quota of the storage volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-alletra-pool-conf:volume.size)

| **Key:**     | `volume.size`   |
|--------------|-----------------|
| **Type:**    | string          |
| **Default:** | `10GiB`         |

Default storage volume size rounded to 256MiB. The minimum size is 256MiB.

<a id="storage-alletra-vol-config"></a>

### Storage volume configuration

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="storage-alletra-volume-conf:block.filesystem"></a>
`block.filesystem`

File system of the storage volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-alletra-volume-conf:block.filesystem)

| **Key:**       | `block.filesystem`                                |
|----------------|---------------------------------------------------|
| **Type:**      | string                                            |
| **Default:**   | same as `volume.block.filesystem`                 |
| **Condition:** | block-based volume with content type `filesystem` |

Valid options: `btrfs`, `ext4`, `xfs`
If not set, `ext4` is assumed.

<a id="storage-alletra-volume-conf:block.mount_options"></a>
`block.mount_options`

Mount options for block-backed file system volumes

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-alletra-volume-conf:block.mount_options)

| **Key:**       | `block.mount_options`                             |
|----------------|---------------------------------------------------|
| **Type:**      | string                                            |
| **Default:**   | same as `volume.block.mount_options`              |
| **Condition:** | block-based volume with content type `filesystem` |

<a id="storage-alletra-volume-conf:security.shared"></a>
`security.shared`

Enable volume sharing

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-alletra-volume-conf:security.shared)

| **Key:**       | `security.shared`                           |
|----------------|---------------------------------------------|
| **Type:**      | bool                                        |
| **Default:**   | same as `volume.security.shared` or `false` |
| **Condition:** | virtual-machine or custom block volume      |
| **Scope:**     | global                                      |

Enable this option to allow the volume to be shared across multiple instances despite the possibility of data loss.

<a id="storage-alletra-volume-conf:security.shifted"></a>
`security.shifted`

Enable ID shifting overlay

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-alletra-volume-conf:security.shifted)

| **Key:**       | `security.shifted`                           |
|----------------|----------------------------------------------|
| **Type:**      | bool                                         |
| **Default:**   | same as `volume.security.shifted` or `false` |
| **Condition:** | custom volume                                |
| **Scope:**     | global                                       |

Enable this option to allow the volume to be attached to multiple isolated instances.

<a id="storage-alletra-volume-conf:security.unmapped"></a>
`security.unmapped`

Disable ID mapping for the volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-alletra-volume-conf:security.unmapped)

| **Key:**       | `security.unmapped`                           |
|----------------|-----------------------------------------------|
| **Type:**      | bool                                          |
| **Default:**   | same as `volume.security.unmapped` or `false` |
| **Condition:** | custom volume                                 |
| **Scope:**     | global                                        |

<a id="storage-alletra-volume-conf:size"></a>
`size`

Size/quota of the storage volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-alletra-volume-conf:size)

| **Key:**     | `size`   |
|--------------|----------|
| **Type:**    | string   |
| **Default:** | `10GiB`  |

Default storage volume size rounded to 256MiB. The minimum size is 256MiB.

<a id="storage-alletra-volume-conf:snapshots.expiry"></a>
`snapshots.expiry`

Time until snapshots are deleted

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-alletra-volume-conf:snapshots.expiry)

| **Key:**       | `snapshots.expiry`                |
|----------------|-----------------------------------|
| **Type:**      | string                            |
| **Default:**   | same as `volume.snapshots.expiry` |
| **Condition:** | custom volume                     |
| **Scope:**     | global                            |

Specify an expression like `1M 2H 3d 4w 5m 6y`.

<a id="storage-alletra-volume-conf:snapshots.pattern"></a>
`snapshots.pattern`

Template for the snapshot name

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-alletra-volume-conf:snapshots.pattern)

| **Key:**       | `snapshots.pattern`                            |
|----------------|------------------------------------------------|
| **Type:**      | string                                         |
| **Default:**   | same as `volume.snapshots.pattern` or `snap%d` |
| **Condition:** | custom volume                                  |
| **Scope:**     | global                                         |

You can specify a naming template for scheduled snapshots and unnamed snapshots.

The `snapshots.pattern` option takes a Pongo2 template string to format the snapshot name.

To add a time stamp to the snapshot name, use the Pongo2 context variable `creation_date`.
Make sure to format the date in your template string to avoid forbidden characters in the snapshot name.
For example, set `snapshots.pattern` to `{{ creation_date|date:'2006-01-02_15-04-05' }}` to name the snapshots after their time of creation, down to the precision of a second.

Another way to avoid name collisions is to use the placeholder `%d` in the pattern.
If no matching snapshots exist, the placeholder is replaced with `0`.
Otherwise, it is replaced with the next snapshot index, which is one higher than the highest existing matching snapshot index.

<a id="storage-alletra-volume-conf:snapshots.schedule"></a>
`snapshots.schedule`

Schedule for automatic volume snapshots

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-alletra-volume-conf:snapshots.schedule)

| **Key:**       | `snapshots.schedule`         |
|----------------|------------------------------|
| **Type:**      | string                       |
| **Default:**   | same as `snapshots.schedule` |
| **Condition:** | custom volume                |
| **Scope:**     | global                       |

Specify either a cron expression (`<minute> <hour> <dom> <month> <dow>`), a comma-separated list of schedule aliases (`@hourly`, `@daily`, `@midnight`, `@weekly`, `@monthly`, `@annually`, `@yearly`), or leave empty to disable automatic snapshots (the default).

<a id="storage-alletra-volume-conf:volatile.devlxd.owner"></a>
`volatile.devlxd.owner`

ID of the DevLXD identity that owns the volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-alletra-volume-conf:volatile.devlxd.owner)

| **Key:**     | `volatile.devlxd.owner`   |
|--------------|---------------------------|
| **Type:**    | string                    |
| **Default:** | DevLXD owner identity ID  |
| **Scope:**   | global                    |

<a id="storage-alletra-volume-conf:volatile.idmap.last"></a>
`volatile.idmap.last`

JSON-serialized UID/GID map that has been applied to the volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-alletra-volume-conf:volatile.idmap.last)

| **Key:**       | `volatile.idmap.last`   |
|----------------|-------------------------|
| **Type:**      | string                  |
| **Condition:** | filesystem              |

<a id="storage-alletra-volume-conf:volatile.idmap.next"></a>
`volatile.idmap.next`

JSON-serialized UID/GID map that has been applied to the volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-alletra-volume-conf:volatile.idmap.next)

| **Key:**       | `volatile.idmap.next`   |
|----------------|-------------------------|
| **Type:**      | string                  |
| **Condition:** | filesystem              |

<a id="storage-alletra-volume-conf:volatile.uuid"></a>
`volatile.uuid`

Volume UUID

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-alletra-volume-conf:volatile.uuid)

| **Key:**     | `volatile.uuid`   |
|--------------|-------------------|
| **Type:**    | string            |
| **Default:** | random UUID       |
| **Scope:**   | global            |


# index.html.md

<a id="storage-zfs-internals"></a>

# ZFS storage driver internals

This page describes implementation details of the ZFS storage driver that are not required for day-to-day use but are useful for understanding its behavior or for debugging.

## Image variant datasets

When LXD unpacks an image on a ZFS pool, it stores the result as an *image variant* dataset.
The dataset naming convention is:

- `<pool>/images/<fingerprint>` : dataset variant (when [`zfs.block_mode`](storage_zfs.md#storage-zfs-volume-conf:zfs.block_mode) is `false`)
- `<pool>/images/<fingerprint>_<filesystem>` : block-backed variant, where `<filesystem>` is `ext4`, `btrfs`, or `xfs` (when [`zfs.block_mode`](storage_zfs.md#storage-zfs-volume-conf:zfs.block_mode) is `true`)

Each variant dataset has a `@readonly` ZFS snapshot.
When a new instance is created from the image, LXD clones this `@readonly` snapshot rather than unpacking the image again, which speeds up instance creation.

## Soft deletion

When an image is deleted but one or more instances are still cloned from a variant dataset, LXD cannot immediately destroy the dataset because ZFS does not allow a dataset with dependent clones to be destroyed.
Instead, the variant is renamed to `<pool>/deleted/images/<fingerprint>` (or `<pool>/deleted/images/<fingerprint>_<filesystem>` for block-backed variants). This is referred to as *soft deletion*.

The soft-deleted dataset persists until the last instance that depends on it is removed.
At that point LXD destroys the dataset permanently.


# index.html.md

<a id="ref-placement-groups"></a>

# Placement group configuration

Placement groups can be configured through a set of key/value configuration options.
See [How to use placement groups](../howto/cluster_placement_groups.md#cluster-placement-groups) for instructions on how to create and manage placement groups.

The key/value configuration is namespaced.
The following options are available:

- [Placement group options](#placement-group-config)

<a id="placement-group-config"></a>

## Placement group options

Placement groups require two configuration keys to control instance placement behavior across cluster members.

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="placement-group-placement-group:policy"></a>
`policy`

Instance placement policy

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#placement-group-placement-group:policy)

| **Key:**      | `policy`   |
|---------------|------------|
| **Type:**     | string     |
| **Required:** | yes        |

Determines whether instances are spread across cluster members or
compacted onto the same cluster member(s).

Possible values are `spread` and `compact`.
See [Automatic placement of instances](../explanation/clusters.md#clustering-instance-placement) for more information.

<a id="placement-group-placement-group:rigor"></a>
`rigor`

Enforcement level of the placement policy

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#placement-group-placement-group:rigor)

| **Key:**      | `rigor`   |
|---------------|-----------|
| **Type:**     | string    |
| **Required:** | yes       |

Determines whether the policy is strictly enforced or allows fallback.

Possible values are `strict` and `permissive`.
See [Automatic placement of instances](../explanation/clusters.md#clustering-instance-placement) for more information.

<a id="placement-group-placement-group:user.*"></a>
`user.*`

Free form user key/value storage

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#placement-group-placement-group:user.*)

| **Key:**    | `user.*`   |
|-------------|------------|
| **Type:**   | string     |

User keys can be used in search.

## Related topics

How-to guides:

- [Clustering](../clustering.md#clustering)

Explanation:

- [Clusters](../explanation/clusters.md#exp-clusters)


# index.html.md

<a id="ref-networks"></a>

# Networks

LXD supports different network types for [Managed networks](../explanation/networks.md#managed-networks).

## Fully controlled networks

<!-- Include start controlled intro -->

Fully controlled networks create and manage their own network interfaces, supporting features like IP management and network ACLs, forwards, and zones.

LXD supports the following network types:

<!-- Include end controlled intro -->

* [Bridge network](network_bridge.md)
* [OVN network](network_ovn.md)

## External networks

<!-- Include start external intro -->

External networks use interfaces that already exist. As a result, LXD has limited control over them, and LXD networking features like ACLs, forwards, and zones are not supported.

External networks mainly serve as uplink networks, providing a parent interface for connecting instances or other networks. They also specify the configuration presets applied when making those connections.

LXD supports the following external network types:

<!-- Include end external intro -->

* [Macvlan network](network_macvlan.md)
* [Physical network](network_physical.md)
* [SR-IOV network](network_sriov.md)

## Related topics

How-to guides:

- [Networking](../networks.md#networking)

Explanation:

- [Networking setups](../explanation/networks.md#networks)


# index.html.md

<a id="ref-clusters"></a>

# Clusters

These reference guides cover LXD configuration settings for cluster members and cluster links. For server-level cluster configuration options, refer to [Server configuration](../server.md#server).

## Cluster member configuration

Member configuration includes custom user keys and instance scheduler information.

* [Cluster member configuration](cluster_member_config.md)

## Cluster link configuration

Link configuration includes custom user keys and cluster link member addresses.

* [Cluster link configuration](cluster_link_config.md)

## Related topics

How-to guides:

- [Clustering](../clustering.md#clustering)

Explanation:

- [Clusters](../explanation/clusters.md#exp-clusters)


# index.html.md

<a id="standard-devices"></a>

# Standard devices

LXD provides each instance with the basic devices that are required for a standard POSIX system to work.
These devices aren’t visible in the instance or profile configuration, and they may not be overridden.

The standard devices are:

| Device         | Type of device    |
|----------------|-------------------|
| `/dev/null`    | Character device  |
| `/dev/zero`    | Character device  |
| `/dev/full`    | Character device  |
| `/dev/console` | Character device  |
| `/dev/tty`     | Character device  |
| `/dev/random`  | Character device  |
| `/dev/urandom` | Character device  |
| `/dev/net/tun` | Character device  |
| `/dev/fuse`    | Character device  |
| `lo`           | Network interface |

Any other devices must be defined in the instance configuration or in one of the profiles used by the instance.
The default profile typically contains a network interface that becomes `eth0` in the instance.


# index.html.md

<a id="devices-tpm"></a>

# Type: `tpm`


            <p class="youtube_link">
              <a href="https://www.youtube.com/watch?v=iE1TN7YIqP0" target="_blank">
                <span title="LXD TPM devices" class="play_icon">▶</span>
                <span title="LXD TPM devices">Watch on YouTube</span>
              </a>
            </p>
        
#### NOTE
The `tpm` device type is supported for both containers and VMs.
It supports hotplugging only for containers, not for VMs.

TPM devices enable access to a  emulator.

TPM devices can be used to validate the boot process and ensure that no steps in the boot chain have been tampered with, and they can securely generate and store encryption keys.

LXD uses a software TPM that supports TPM 2.0.
For containers, the main use case is sealing certificates, which means that the keys are stored outside of the container, making it virtually impossible for attackers to retrieve them.
For virtual machines, TPM can be used both for sealing certificates and for validating the boot process, which allows using full disk encryption compatible with, for example, Windows BitLocker.

## Device options

`tpm` devices have the following device options:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="device-tpm-device-conf:path"></a>
`path`

Path inside the container

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-tpm-device-conf:path)

| **Key:**      | `path`         |
|---------------|----------------|
| **Type:**     | string         |
| **Required:** | for containers |

For example: `/dev/tpm0`

<a id="device-tpm-device-conf:pathrm"></a>
`pathrm`

Resource manager path inside the container

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-tpm-device-conf:pathrm)

| **Key:**      | `pathrm`       |
|---------------|----------------|
| **Type:**     | string         |
| **Required:** | for containers |

For example: `/dev/tpmrm0`

## Configuration examples

Add a `tpm` device to a container by specifying its path and the resource manager path:

```none
lxc config device add <instance_name> <device_name> tpm path=<path_on_instance> pathrm=<resource_manager_path>
```

Add a `tpm` device to a virtual machine:

```none
lxc config device add <instance_name> <device_name> tpm
```

See [Configure devices](../howto/instances_configure.md#instances-configure-devices) for more information.


# index.html.md

<a id="ref-csi"></a>

# LXD CSI driver reference

This document contains reference information for the LXD CSI driver CLI, including available Helm chart values and its versioning information.

<a id="ref-csi-cli"></a>

## CLI

The `lxd-csi-driver` provides CSI controller and node server functionality.
You can configure runtime options using these flags:

| Flag               | Default                 | Description                   |
|--------------------|-------------------------|-------------------------------|
| `--driver-name`    | `lxd.csi.canonical.com` | CSI driver name               |
| `--endpoint`       | `unix:///tmp/csi.sock`  | Internal CSI Unix socket path |
| `--devLXDEndpoint` | `unix:///dev/lxd/sock`  | DevLXD Unix socket path       |
| `--nodeID`         | `""`                    | Kubernetes node ID            |
| `--controller`     | `false`                 | Run as controller server      |
| `--version`        |                         | Print version and exit        |

<a id="ref-csi-helm"></a>

## Helm chart

The LXD CSI driver Helm chart is available as an [OCI image](https://ghcr.io/canonical/charts/lxd-csi-driver).
The source of the Helm chart can be found in the [LXD CSI driver repository](https://github.com/canonical/lxd-csi-driver/tree/main/charts).

The table below contains configurable Helm chart values with their default values and descriptions.

| Key                                                | Type   | Default                                                 | Description                                                                                                                                                                                                                  |
|----------------------------------------------------|--------|---------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `driver.image.repository`                          | string | `ghcr.io/canonical/lxd-csi-driver`                      | LXD CSI image                                                                                                                                                                                                                |
| `driver.image.tag`                                 | string | Chart version                                           | LXD CSI image tag                                                                                                                                                                                                            |
| `driver.image.pullPolicy`                          | string | `IfNotPresent`                                          | LXD CSI image pull policy                                                                                                                                                                                                    |
| `driver.imagePullSecrets`                          | list   | `[]`                                                    | LXD CSI image pull secrets                                                                                                                                                                                                   |
| `driver.tokenSecretName`                           | string | `lxd-csi-secret`                                        | Name of the secret containing DevLXD bearer token in `token` field                                                                                                                                                           |
| `driver.fsGroupPolicy`                             | string | `File`                                                  | Controls Kubernetes `fsGroup` behavior for the driver (`None`, `ReadWriteOnceWithFSType`, `File`)                                                                                                                            |
| `driver.volumeNamePrefix`                          | string | `csi`                                                   | Prefix used for LXD volume names. Resulting volume name is in format `<prefix>-<uuid>`.                                                                                                                                      |
| `rbac.create`                                      | bool   | `true`                                                  | Create RBAC resources allowing LXD CSI access to relevant Kubernetes objects                                                                                                                                                 |
| `controller.name`                                  | string | `lxd-csi-controller`                                    | Controller Deployment name                                                                                                                                                                                                   |
| `controller.replicas`                              | int    | `1`                                                     | Controller Deployment replicas. When deployed in multiple replicas, the preferred affinity is configured in an attempt to distribute Pods across multiple nodes.                                                             |
| `controller.strategy.type`                         | string | `RollingUpdate`                                         | Controller Deployment update strategy (`RollingUpdate`, `Recreate`)                                                                                                                                                          |
| `controller.strategy.rollingUpdate.maxUnavailable` | string | `50%`                                                   | Max unavailable Pods during update                                                                                                                                                                                           |
| `controller.priorityClassName`                     | string | `system-cluster-critical`                               | Controller Pod scheduling priority                                                                                                                                                                                           |
| `controller.serviceAccount.create`                 | bool   | `true`                                                  | Whether to create required service account for controller server                                                                                                                                                             |
| `controller.serviceAccount.name`                   | string | `""` (Equal to Controller server name if empty)         | Custom service account name                                                                                                                                                                                                  |
| `controller.runOnControlPlaneOnly`                 | bool   | `true`                                                  | Whether to run controller only on control plane nodes. This ensures appropriate node affinity and tolerations are configured. If node affinity is manually set, this option is disabled.                                     |
| `controller.nodeSelector`                          | object | `{}`                                                    | Node selector for controller Pods                                                                                                                                                                                            |
| `controller.tolerations`                           | list   | `[]`                                                    | Controller Pod tolerations                                                                                                                                                                                                   |
| `controller.affinity`                              | object | `{}`                                                    | Controller Pod affinity                                                                                                                                                                                                      |
| `controller.annotations`                           | object | `{}`                                                    | Controller Deployment annotations                                                                                                                                                                                            |
| `controller.podAnnotations`                        | object | `{}`                                                    | Controller Pod annotations                                                                                                                                                                                                   |
| `controller.resources`                             | object | `{}`                                                    | Controller resource limits and requests                                                                                                                                                                                      |
| `controller.csiProvisioner.image.repository`       | string | `registry.k8s.io/sig-storage/csi-provisioner`           | CSI provisioner image                                                                                                                                                                                                        |
| `controller.csiProvisioner.image.tag`              | string | Chart release dependent                                 | CSI provisioner image tag                                                                                                                                                                                                    |
| `controller.csiProvisioner.image.pullPolicy`       | string | `IfNotPresent`                                          | CSI provisioner pull policy                                                                                                                                                                                                  |
| `controller.csiProvisioner.resources`              | object | `{}`                                                    | CSI provisioner resource limits and requests                                                                                                                                                                                 |
| `controller.csiAttacher.image.repository`          | string | `registry.k8s.io/sig-storage/csi-attacher`              | CSI attacher image                                                                                                                                                                                                           |
| `controller.csiAttacher.image.tag`                 | string | Chart release dependent                                 | CSI attacher image tag                                                                                                                                                                                                       |
| `controller.csiAttacher.image.pullPolicy`          | string | `IfNotPresent`                                          | CSI attacher image pull policy                                                                                                                                                                                               |
| `controller.csiAttacher.resources`                 | object | `{}`                                                    | CSI attacher resource limits and requests                                                                                                                                                                                    |
| `controller.csiResizer.image.repository`           | string | `registry.k8s.io/sig-storage/csi-resizer`               | CSI resizer image                                                                                                                                                                                                            |
| `controller.csiResizer.image.tag`                  | string | Chart release dependent                                 | CSI resizer image tag                                                                                                                                                                                                        |
| `controller.csiResizer.image.pullPolicy`           | string | `IfNotPresent`                                          | CSI resizer image pull policy                                                                                                                                                                                                |
| `controller.csiResizer.resources`                  | object | `{}`                                                    | CSI resizer resource limits and requests                                                                                                                                                                                     |
| `controller.csiSnapshotter.image.repository`       | string | `registry.k8s.io/sig-storage/csi-snapshotter`           | CSI snapshotter image                                                                                                                                                                                                        |
| `controller.csiSnapshotter.image.tag`              | string | Chart release dependent                                 | CSI snapshotter image tag                                                                                                                                                                                                    |
| `controller.csiSnapshotter.image.pullPolicy`       | string | `IfNotPresent`                                          | CSI snapshotter image pull policy                                                                                                                                                                                            |
| `controller.csiSnapshotter.resources`              | object | `{}`                                                    | CSI snapshotter resource limits and requests                                                                                                                                                                                 |
| `controller.csiLivenessProbe.image.repository`     | string | `registry.k8s.io/sig-storage/livenessprobe`             | CSI liveness probe image                                                                                                                                                                                                     |
| `controller.csiLivenessProbe.image.tag`            | string | Chart release dependent                                 | CSI liveness probe image tag                                                                                                                                                                                                 |
| `controller.csiLivenessProbe.image.pullPolicy`     | string | `IfNotPresent`                                          | CSI liveness probe image pull policy                                                                                                                                                                                         |
| `controller.csiLivenessProbe.resources`            | object | `{}`                                                    | CSI liveness probe resource limits and requests                                                                                                                                                                              |
| `node.name`                                        | string | `lxd-csi-node`                                          | Node DaemonSet name                                                                                                                                                                                                          |
| `node.strategy.type`                               | string | `RollingUpdate`                                         | Node DaemonSet update strategy (`RollingUpdate`, `OnDelete`)                                                                                                                                                                 |
| `node.strategy.rollingUpdate.maxUnavailable`       | string | `1`                                                     | Max unavailable Pods during update                                                                                                                                                                                           |
| `node.priorityClassName`                           | string | `system-node-critical`                                  | Node Pod scheduling priority                                                                                                                                                                                                 |
| `node.serviceAccount.create`                       | bool   | `true`                                                  | Whether to create required service account for node server                                                                                                                                                                   |
| `node.serviceAccount.name`                         | string | `""` (Equal to Node server name if empty)               | Custom service account name                                                                                                                                                                                                  |
| `node.nodeSelector`                                | object | `{}`                                                    | Node selector for node server Pods                                                                                                                                                                                           |
| `node.tolerations`                                 | list   | `[]`                                                    | Node Pod tolerations                                                                                                                                                                                                         |
| `node.affinity`                                    | object | `{}`                                                    | Node Pod affinity                                                                                                                                                                                                            |
| `node.annotations`                                 | object | `{}`                                                    | Node DaemonSet annotations                                                                                                                                                                                                   |
| `node.podAnnotations`                              | object | `{}`                                                    | Node Pod annotations                                                                                                                                                                                                         |
| `node.resources`                                   | object | `{}`                                                    | Node server resource limits and requests                                                                                                                                                                                     |
| `node.nodeDriverRegistrar.image.repository`        | string | `registry.k8s.io/sig-storage/csi-node-driver-registrar` | Node driver registrar image                                                                                                                                                                                                  |
| `node.nodeDriverRegistrar.image.tag`               | string | Chart release dependent                                 | Node driver registrar image tag                                                                                                                                                                                              |
| `node.nodeDriverRegistrar.image.pullPolicy`        | string | `IfNotPresent`                                          | Node driver registrar image pull policy                                                                                                                                                                                      |
| `node.nodeDriverRegistrar.resources`               | object | `{}`                                                    | Node driver registrar resource limits and requests                                                                                                                                                                           |
| `node.csiLivenessProbe.image.repository`           | string | `registry.k8s.io/sig-storage/livenessprobe`             | CSI liveness probe image                                                                                                                                                                                                     |
| `node.csiLivenessProbe.image.tag`                  | string | Chart release dependent                                 | CSI liveness probe image tag                                                                                                                                                                                                 |
| `node.csiLivenessProbe.image.pullPolicy`           | string | `IfNotPresent`                                          | CSI liveness probe image pull policy                                                                                                                                                                                         |
| `node.csiLivenessProbe.resources`                  | object | `{}`                                                    | CSI liveness probe resource limits and requests                                                                                                                                                                              |
| `snapshotter.enabled`                              | bool   | `false`                                                 | Whether to enable support for volume snapshots. If enabled, CSI snapshot controller is deployed along with the CSI driver.                                                                                                   |
| `snapshotter.installCRDs`                          | bool   | `true`                                                  | Whether to install required volume snapshot CRDs. If CRDs are installed manually or by other CSI drivers, set this to `false` to avoid conflicts with other drivers. The value is ignored if `snapshotter.enabled` is false. |
| `snapshotter.controller.name`                      | string | `snapshot-controller`                                   | CSI snapshot controller Deployment name                                                                                                                                                                                      |
| `snapshotter.controller.replicas`                  | int    | `1`                                                     | CSI snapshot controller Deployment replicas                                                                                                                                                                                  |
| `snapshotter.controller.priorityClassName`         | string | `system-cluster-critical`                               | CSI snapshot controller Pod scheduling priority                                                                                                                                                                              |
| `snapshotter.controller.image.repository`          | string | `registry.k8s.io/sig-storage/snapshot-controller`       | CSI snapshot controller image                                                                                                                                                                                                |
| `snapshotter.controller.image.tag`                 | string | Chart release dependent                                 | CSI snapshot controller image tag                                                                                                                                                                                            |
| `snapshotter.controller.image.pullPolicy`          | string | `IfNotPresent`                                          | CSI snapshot controller image pull policy                                                                                                                                                                                    |
| `snapshotter.controller.resources`                 | object | `{}`                                                    | CSI snapshot controller resource limits and requests                                                                                                                                                                         |
| `storageClasses[].create`                          | bool   | `true`                                                  | Create the specified storage class                                                                                                                                                                                           |
| `storageClasses[].name`                            | string | `""`                                                    | Storage class name                                                                                                                                                                                                           |
| `storageClasses[].storagePool`                     | string | `""`                                                    | Name of the target LXD storage pool                                                                                                                                                                                          |
| `storageClasses[].volumeBindingMode`               | string | `WaitForFirstConsumer`                                  | Volume binding mode (`Immediate`, `WaitForFirstConsumer`)                                                                                                                                                                    |
| `storageClasses[].reclaimPolicy`                   | string | `Delete`                                                | Volume reclaim policy (`Delete`, `Retain`)                                                                                                                                                                                   |
| `storageClasses[].annotations`                     | object | `{}`                                                    | Additional storage class annotations                                                                                                                                                                                         |
| `storageClasses[].allowVolumeExpansion`            | bool   | `true`                                                  | Whether to allow volume expansion once the volume is created.                                                                                                                                                                |

<a id="ref-csi-versioning"></a>

## Versioning

The LXD CSI driver follows Semantic Versioning independently of LXD releases, starting at `v0.0.1`.

| Tag type   | Format                     | Example   | Description                                                                                                                              |
|------------|----------------------------|-----------|------------------------------------------------------------------------------------------------------------------------------------------|
| Patch      | `v<major>.<minor>.<patch>` | `v1.2.3`  | Bugfix release. Each patch within the same minor version provides the same set of features.                                              |
| Minor      | `v<major>.<minor>`         | `v4.5`    | Feature release. Adds new features in a backward-compatible way within the major version. Features may be deprecated, but remain usable. |
| Major      | `v<major>`                 | `v6`      | Breaking release. May include breaking changes and may raise minimum LXD version.                                                        |

Whenever a new stable LXD CSI version is released, it includes three tags.
For example, version `v1.2.3` is tagged with its fixed tag `v1.2.3`, as well as floating tags `v1` and `v1.2` until the next release.
This allows users to either pin to a specific version or track the latest stable version for a given major or minor release.

<a id="ref-csi-versioning-compatibility"></a>

### Compatibility

For any major driver version `≥1`, the minimum supported LXD version is fixed.
Updates within that major version remain compatible with that LXD version (or newer) until the driver version reaches end-of-life (EOL).

On the other hand, Kubernetes versions receive roughly one year of patch support.
The LXD CSI driver only supports Kubernetes versions that are themselves supported upstream.
When a Kubernetes version reaches end of life, it is no longer supported by the driver.

| CSI Version   | Min. LXD Version   | Min. Kubernetes Version   | EOL   |
|---------------|--------------------|---------------------------|-------|
| `v1`          | `6.6`              | `v1.31`                   | N/A   |

<a id="ref-csi-versioning-exceptions"></a>

### Special versions

- All versions before the first major release (`< v1.0.0`) make no guarantees. Behavior may change even in patch releases.
- Versions with non-semantic tags (e.g. `latest-edge`) or with pre-release identifiers (e.g. `v1.2.3-edge`) are considered unstable and should be used only for testing.
- Certain non-semantic tags are prefixed with `v0` to satisfy versioning requirements. For example, the Helm chart `v0-latest-edge` represents the latest Helm chart release.

## Related topics

Explanation:

- [The LXD CSI driver](../explanation/csi.md#exp-csi)

How-to guides:

- [How to use the LXD CSI driver with Kubernetes](../howto/storage_csi.md#howto-storage-csi)


# index.html.md

<a id="storage-lvm"></a>

# LVM - `lvm`


            <p class="youtube_link">
              <a href="https://www.youtube.com/watch?v=AqLl2eMZE6U" target="_blank">
                <span title="LVM storage and LXD" class="play_icon">▶</span>
                <span title="LVM storage and LXD">Watch on YouTube</span>
              </a>
            </p>
        
 is a storage management framework rather than a file system.
It is used to manage physical storage devices, allowing you to create a number of logical storage volumes that use and virtualize the underlying physical storage devices.

Note that it is possible to over-commit the physical storage in the process, to allow flexibility for scenarios where not all available storage is in use at the same time.

To use LVM, make sure you have `lvm2` installed on your machine.

## Terminology

LVM can combine several physical storage devices into a *volume group*.
You can then allocate *logical volumes* of different types from this volume group.

One supported volume type is a *thin pool*, which allows over-committing the resources by creating thinly provisioned volumes whose total allowed maximum size (quota) is larger than the available physical storage.
Another type is a *volume snapshot*, which captures a specific state of a logical volume.

## `lvm` driver in LXD

The `lvm` driver in LXD uses logical volumes for images, and volume snapshots for instances and snapshots.

LXD assumes that it has full control over the volume group.
Therefore, you should not maintain any file system entities that are not owned by LXD in an LVM volume group, because LXD might delete them.
However, if you need to reuse an existing volume group (for example, because your setup has only one volume group), you can do so by setting the [`lvm.vg.force_reuse`](#storage-lvm-pool-conf:lvm.vg.force_reuse) configuration.

By default, LVM storage pools use an LVM thin pool and create logical volumes for all LXD storage entities (images, instances and custom volumes) in there.
This behavior can be changed by setting [`lvm.use_thinpool`](#storage-lvm-pool-conf:lvm.use_thinpool) to `false` when you create the pool.
In this case, LXD uses “normal” logical volumes for all storage entities that are not snapshots.
Note that this entails serious performance and space reductions for the `lvm` driver (close to the `dir` driver both in speed and storage usage).
The reason for this is that most storage operations must fall back to using `rsync`, because logical volumes that are not thin pools do not support snapshots of snapshots.
In addition, non-thin snapshots take up much more storage space than thin snapshots, because they must reserve space for their maximum size (quota) at creation time.
Therefore, this option should only be chosen if the use case requires it.

For environments with a high instance turnover (for example, continuous integration) you should tweak the backup `retain_min` and `retain_days` settings in `/etc/lvm/lvm.conf` to avoid slowdowns when interacting with LXD.

## Configuration options

The following configuration options are available for storage pools that use the `lvm` driver and for storage volumes in these pools.

<a id="storage-lvm-pool-config"></a>

### Storage pool configuration

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="storage-lvm-pool-conf:lvm.thinpool_metadata_size"></a>
`lvm.thinpool_metadata_size`

The size of the thin pool metadata volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-lvm-pool-conf:lvm.thinpool_metadata_size)

| **Key:**     | `lvm.thinpool_metadata_size`   |
|--------------|--------------------------------|
| **Type:**    | string                         |
| **Default:** | `0` (auto)                     |
| **Scope:**   | global                         |

By default, LVM calculates an appropriate size.

<a id="storage-lvm-pool-conf:lvm.thinpool_name"></a>
`lvm.thinpool_name`

Thin pool where volumes are created

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-lvm-pool-conf:lvm.thinpool_name)

| **Key:**     | `lvm.thinpool_name`   |
|--------------|-----------------------|
| **Type:**    | string                |
| **Default:** | `LXDThinPool`         |
| **Scope:**   | local                 |

<a id="storage-lvm-pool-conf:lvm.use_thinpool"></a>
`lvm.use_thinpool`

Whether the storage pool uses a thin pool for logical volumes

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-lvm-pool-conf:lvm.use_thinpool)

| **Key:**     | `lvm.use_thinpool`   |
|--------------|----------------------|
| **Type:**    | bool                 |
| **Default:** | `true`               |
| **Scope:**   | global               |

<a id="storage-lvm-pool-conf:lvm.vg.force_reuse"></a>
`lvm.vg.force_reuse`

Force using an existing non-empty volume group

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-lvm-pool-conf:lvm.vg.force_reuse)

| **Key:**     | `lvm.vg.force_reuse`   |
|--------------|------------------------|
| **Type:**    | bool                   |
| **Default:** | `false`                |
| **Scope:**   | global                 |

<a id="storage-lvm-pool-conf:lvm.vg_name"></a>
`lvm.vg_name`

Name of the volume group to create

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-lvm-pool-conf:lvm.vg_name)

| **Key:**     | `lvm.vg_name`    |
|--------------|------------------|
| **Type:**    | string           |
| **Default:** | name of the pool |
| **Scope:**   | local            |

<a id="storage-lvm-pool-conf:rsync.bwlimit"></a>
`rsync.bwlimit`

Upper limit on the socket I/O for `rsync`

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-lvm-pool-conf:rsync.bwlimit)

| **Key:**     | `rsync.bwlimit`   |
|--------------|-------------------|
| **Type:**    | string            |
| **Default:** | `0` (no limit)    |
| **Scope:**   | global            |

When `rsync` must be used to transfer storage entities, this option specifies the upper limit
to be placed on the socket I/O.

<a id="storage-lvm-pool-conf:rsync.compression"></a>
`rsync.compression`

Whether to use compression while migrating storage pools

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-lvm-pool-conf:rsync.compression)

| **Key:**     | `rsync.compression`   |
|--------------|-----------------------|
| **Type:**    | bool                  |
| **Default:** | `true`                |
| **Scope:**   | global                |

<a id="storage-lvm-pool-conf:size"></a>
`size`

Size of the storage pool (for loop-based pools)

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-lvm-pool-conf:size)

| **Key:**     | `size`                                                |
|--------------|-------------------------------------------------------|
| **Type:**    | string                                                |
| **Default:** | auto (20% of free disk space, >= 5 GiB and <= 30 GiB) |
| **Scope:**   | local                                                 |

When creating loop-based pools, specify the size in bytes ([suffixes](instance_units.md#instances-limit-units) are supported).
You can increase the size to grow the storage pool.

The default (`auto`) creates a storage pool that uses 20% of the free disk space,
with a minimum of 5 GiB and a maximum of 30 GiB.

<a id="storage-lvm-pool-conf:source"></a>
`source`

Path to an existing block device, loop file, or LVM volume group

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-lvm-pool-conf:source)

| **Key:**    | `source`   |
|-------------|------------|
| **Type:**   | string     |
| **Scope:**  | local      |

<a id="storage-lvm-pool-conf:source.recover"></a>
`source.recover`

Whether to recover an existing `source`

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-lvm-pool-conf:source.recover)

| **Key:**     | `source.recover`   |
|--------------|--------------------|
| **Type:**    | bool               |
| **Default:** | `false`            |
| **Scope:**   | local              |

Set this option to true to recover an existing source which was previously created by LXD.

<a id="storage-lvm-pool-conf:source.wipe"></a>
`source.wipe`

Whether to wipe the block device before creating the pool

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-lvm-pool-conf:source.wipe)

| **Key:**     | `source.wipe`   |
|--------------|-----------------|
| **Type:**    | bool            |
| **Default:** | `false`         |
| **Scope:**   | local           |

Set this option to `true` to wipe the block device specified in `source`
prior to creating the storage pool.

<a id="storage-lvm-vol-config"></a>

### Storage volume configuration

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="storage-lvm-volume-conf:block.filesystem"></a>
`block.filesystem`

File system of the storage volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-lvm-volume-conf:block.filesystem)

| **Key:**       | `block.filesystem`                                |
|----------------|---------------------------------------------------|
| **Type:**      | string                                            |
| **Default:**   | same as `volume.block.filesystem`                 |
| **Condition:** | block-based volume with content type `filesystem` |
| **Scope:**     | global                                            |

Valid options: `btrfs`, `ext4`, `xfs`
If not set, `ext4` is assumed.

<a id="storage-lvm-volume-conf:block.mount_options"></a>
`block.mount_options`

Mount options for block-backed file system volumes

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-lvm-volume-conf:block.mount_options)

| **Key:**       | `block.mount_options`                             |
|----------------|---------------------------------------------------|
| **Type:**      | string                                            |
| **Default:**   | same as `volume.block.mount_options`              |
| **Condition:** | block-based volume with content type `filesystem` |
| **Scope:**     | global                                            |

<a id="storage-lvm-volume-conf:lvm.stripes"></a>
`lvm.stripes`

Number of stripes to use for new volumes (or thin pool volume)

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-lvm-volume-conf:lvm.stripes)

| **Key:**     | `lvm.stripes`                |
|--------------|------------------------------|
| **Type:**    | string                       |
| **Default:** | same as `volume.lvm.stripes` |
| **Scope:**   | global                       |

<a id="storage-lvm-volume-conf:lvm.stripes.size"></a>
`lvm.stripes.size`

Size of stripes to use

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-lvm-volume-conf:lvm.stripes.size)

| **Key:**     | `lvm.stripes.size`                |
|--------------|-----------------------------------|
| **Type:**    | string                            |
| **Default:** | same as `volume.lvm.stripes.size` |
| **Scope:**   | global                            |

The size must be at least 4096 bytes, and a multiple of 512 bytes.

<a id="storage-lvm-volume-conf:security.shared"></a>
`security.shared`

Enable volume sharing

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-lvm-volume-conf:security.shared)

| **Key:**       | `security.shared`                           |
|----------------|---------------------------------------------|
| **Type:**      | bool                                        |
| **Default:**   | same as `volume.security.shared` or `false` |
| **Condition:** | virtual-machine or custom block volume      |
| **Scope:**     | global                                      |

Enable this option to allow the volume to be shared across multiple instances despite the possibility of data loss.

<a id="storage-lvm-volume-conf:security.shifted"></a>
`security.shifted`

Enable ID shifting overlay

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-lvm-volume-conf:security.shifted)

| **Key:**       | `security.shifted`                           |
|----------------|----------------------------------------------|
| **Type:**      | bool                                         |
| **Default:**   | same as `volume.security.shifted` or `false` |
| **Condition:** | custom volume                                |
| **Scope:**     | global                                       |

Enable this option to allow the volume to be attached to multiple isolated instances.

<a id="storage-lvm-volume-conf:security.unmapped"></a>
`security.unmapped`

Disable ID mapping for the volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-lvm-volume-conf:security.unmapped)

| **Key:**       | `security.unmapped`                           |
|----------------|-----------------------------------------------|
| **Type:**      | bool                                          |
| **Default:**   | same as `volume.security.unmapped` or `false` |
| **Condition:** | custom volume                                 |
| **Scope:**     | global                                        |

<a id="storage-lvm-volume-conf:size"></a>
`size`

Size/quota of the storage volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-lvm-volume-conf:size)

| **Key:**       | `size`                |
|----------------|-----------------------|
| **Type:**      | string                |
| **Default:**   | same as `volume.size` |
| **Condition:** | appropriate driver    |
| **Scope:**     | global                |

<a id="storage-lvm-volume-conf:snapshots.expiry"></a>
`snapshots.expiry`

Time until snapshots are deleted

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-lvm-volume-conf:snapshots.expiry)

| **Key:**       | `snapshots.expiry`                |
|----------------|-----------------------------------|
| **Type:**      | string                            |
| **Default:**   | same as `volume.snapshots.expiry` |
| **Condition:** | custom volume                     |
| **Scope:**     | global                            |

Specify an expression like `1M 2H 3d 4w 5m 6y`.

<a id="storage-lvm-volume-conf:snapshots.pattern"></a>
`snapshots.pattern`

Template for the snapshot name

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-lvm-volume-conf:snapshots.pattern)

| **Key:**       | `snapshots.pattern`                            |
|----------------|------------------------------------------------|
| **Type:**      | string                                         |
| **Default:**   | same as `volume.snapshots.pattern` or `snap%d` |
| **Condition:** | custom volume                                  |
| **Scope:**     | global                                         |

You can specify a naming template for scheduled snapshots and unnamed snapshots.

The `snapshots.pattern` option takes a Pongo2 template string to format the snapshot name.

To add a time stamp to the snapshot name, use the Pongo2 context variable `creation_date`.
Make sure to format the date in your template string to avoid forbidden characters in the snapshot name.
For example, set `snapshots.pattern` to `{{ creation_date|date:'2006-01-02_15-04-05' }}` to name the snapshots after their time of creation, down to the precision of a second.

Another way to avoid name collisions is to use the placeholder `%d` in the pattern.
If no matching snapshots exist, the placeholder is replaced with `0`.
Otherwise, it is replaced with the next snapshot index, which is one higher than the highest existing matching snapshot index.

<a id="storage-lvm-volume-conf:snapshots.schedule"></a>
`snapshots.schedule`

Schedule for automatic volume snapshots

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-lvm-volume-conf:snapshots.schedule)

| **Key:**       | `snapshots.schedule`         |
|----------------|------------------------------|
| **Type:**      | string                       |
| **Default:**   | same as `snapshots.schedule` |
| **Condition:** | custom volume                |
| **Scope:**     | global                       |

Specify either a cron expression (`<minute> <hour> <dom> <month> <dow>`), a comma-separated list of schedule aliases (`@hourly`, `@daily`, `@midnight`, `@weekly`, `@monthly`, `@annually`, `@yearly`), or leave empty to disable automatic snapshots (the default).

<a id="storage-lvm-volume-conf:volatile.devlxd.owner"></a>
`volatile.devlxd.owner`

ID of the DevLXD identity that owns the volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-lvm-volume-conf:volatile.devlxd.owner)

| **Key:**     | `volatile.devlxd.owner`   |
|--------------|---------------------------|
| **Type:**    | string                    |
| **Default:** | DevLXD owner identity ID  |
| **Scope:**   | global                    |

<a id="storage-lvm-volume-conf:volatile.idmap.last"></a>
`volatile.idmap.last`

JSON-serialized UID/GID map that has been applied to the volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-lvm-volume-conf:volatile.idmap.last)

| **Key:**       | `volatile.idmap.last`   |
|----------------|-------------------------|
| **Type:**      | string                  |
| **Condition:** | filesystem              |

<a id="storage-lvm-volume-conf:volatile.idmap.next"></a>
`volatile.idmap.next`

JSON-serialized UID/GID map that has been applied to the volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-lvm-volume-conf:volatile.idmap.next)

| **Key:**       | `volatile.idmap.next`   |
|----------------|-------------------------|
| **Type:**      | string                  |
| **Condition:** | filesystem              |

<a id="storage-lvm-volume-conf:volatile.uuid"></a>
`volatile.uuid`

Volume UUID

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-lvm-volume-conf:volatile.uuid)

| **Key:**     | `volatile.uuid`   |
|--------------|-------------------|
| **Type:**    | string            |
| **Default:** | random UUID       |
| **Scope:**   | global            |


# index.html.md

<a id="storage-cephfs"></a>

# CephFS - `cephfs`


            <p class="youtube_link">
              <a href="https://youtube.com/watch?v=kVLGbvRU98A" target="_blank">
                <span title="Ceph and a LXD cluster" class="play_icon">▶</span>
                <span title="Ceph and a LXD cluster">Watch on YouTube</span>
              </a>
            </p>
        <!-- Include content from [storage_ceph.md](storage_ceph.md) -->

[Ceph](https://ceph.io/en/) is an open-source storage platform that stores its data in a storage cluster based on .
It is highly scalable and, as a distributed system without a single point of failure, very reliable.

Ceph provides different components for block storage and for file systems.

 is Ceph’s file system component that provides a robust, fully-featured POSIX-compliant distributed file system.
Internally, it maps files to Ceph objects and stores file metadata (for example, file ownership, directory paths, access permissions) in a separate data pool.

## Terminology

<!-- Include content from [storage_ceph.md](storage_ceph.md) -->

Ceph uses the term *object* for the data that it stores.
The daemon that is responsible for storing and managing data is the *Ceph* .
Ceph’s storage is divided into *pools*, which are logical partitions for storing objects.
They are also referred to as *data pools*, *storage pools* or *OSD pools*.

A *CephFS file system* consists of two OSD storage pools, one for the actual data and one for the file metadata.

## `cephfs` driver in LXD

#### NOTE
The `cephfs` driver can only be used for custom storage volumes with content type `filesystem`.

For other storage volumes, use the [Ceph](storage_ceph.md#storage-ceph) driver.
That driver can also be used for custom storage volumes with content type `filesystem`, but it implements them through Ceph RBD images.

<!-- Include content from [storage_ceph.md](storage_ceph.md) -->

Unlike other storage drivers, this driver does not set up the storage system but assumes that you already have a Ceph cluster installed.

You can either create the CephFS file system that you want to use beforehand and specify it through the [`cephfs.path`](#storage-cephfs-pool-conf:cephfs.path) option, or specify the [`cephfs.create_missing`](#storage-cephfs-pool-conf:cephfs.create_missing) option to automatically create the file system and the data and metadata OSD pools (with the names given in [`cephfs.data_pool`](#storage-cephfs-pool-conf:cephfs.data_pool) and [`cephfs.meta_pool`](#storage-cephfs-pool-conf:cephfs.meta_pool)).

<!-- Include content from [storage_ceph.md](storage_ceph.md) -->

This driver also behaves differently than other drivers in that it provides remote storage.
As a result and depending on the internal network, storage access might be a bit slower than for local storage.
On the other hand, using remote storage has big advantages in a cluster setup, because all cluster members have access to the same storage pools with the exact same contents, without the need to synchronize storage pools.

<!-- Include content from [storage_ceph.md](storage_ceph.md) -->

LXD assumes that it has full control over the OSD storage pool.
Therefore, you should never maintain any file system entities that are not owned by LXD in a LXD OSD storage pool, because LXD might delete them.

The `cephfs` driver in LXD supports snapshots if snapshots are enabled on the server side.

## Configuration options

The following configuration options are available for storage pools that use the `cephfs` driver and for storage volumes in these pools.

<a id="storage-cephfs-pool-config"></a>

### Storage pool configuration

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="storage-cephfs-pool-conf:cephfs.cluster_name"></a>
`cephfs.cluster_name`

Name of the Ceph cluster that contains the CephFS file system

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-cephfs-pool-conf:cephfs.cluster_name)

| **Key:**     | `cephfs.cluster_name`   |
|--------------|-------------------------|
| **Type:**    | string                  |
| **Default:** | `ceph`                  |
| **Scope:**   | global                  |

<a id="storage-cephfs-pool-conf:cephfs.create_missing"></a>
`cephfs.create_missing`

Automatically create the CephFS file system

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-cephfs-pool-conf:cephfs.create_missing)

| **Key:**     | `cephfs.create_missing`   |
|--------------|---------------------------|
| **Type:**    | bool                      |
| **Default:** | `false`                   |
| **Scope:**   | global                    |

Use this option if the CephFS file system does not exist yet.
LXD will then automatically create the file system and the missing data and metadata OSD pools.

<a id="storage-cephfs-pool-conf:cephfs.data_pool"></a>
`cephfs.data_pool`

Data OSD pool name

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-cephfs-pool-conf:cephfs.data_pool)

| **Key:**    | `cephfs.data_pool`   |
|-------------|----------------------|
| **Type:**   | string               |
| **Scope:**  | global               |

This option specifies the name for the data OSD pool that should be used when creating
a file system automatically.

<a id="storage-cephfs-pool-conf:cephfs.fscache"></a>
`cephfs.fscache`

Enable use of kernel `fscache` and `cachefilesd`

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-cephfs-pool-conf:cephfs.fscache)

| **Key:**     | `cephfs.fscache`   |
|--------------|--------------------|
| **Type:**    | bool               |
| **Default:** | `false`            |
| **Scope:**   | global             |

<a id="storage-cephfs-pool-conf:cephfs.meta_pool"></a>
`cephfs.meta_pool`

Metadata OSD pool name

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-cephfs-pool-conf:cephfs.meta_pool)

| **Key:**    | `cephfs.meta_pool`   |
|-------------|----------------------|
| **Type:**   | string               |
| **Scope:**  | global               |

This option specifies the name for the file metadata OSD pool that should be used when
creating a file system automatically.

<a id="storage-cephfs-pool-conf:cephfs.osd_pg_num"></a>
`cephfs.osd_pg_num`

Number of placement groups when creating missing OSD pools

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-cephfs-pool-conf:cephfs.osd_pg_num)

| **Key:**    | `cephfs.osd_pg_num`   |
|-------------|-----------------------|
| **Type:**   | string                |
| **Scope:**  | global                |

This option specifies the number of OSD pool placement groups (`pg_num`) to use
when creating a missing OSD pool.

<a id="storage-cephfs-pool-conf:cephfs.osd_pool_size"></a>
`cephfs.osd_pool_size`

Number of RADOS object replicas. Set to 1 for no replication.

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-cephfs-pool-conf:cephfs.osd_pool_size)

| **Key:**     | `cephfs.osd_pool_size`   |
|--------------|--------------------------|
| **Type:**    | string                   |
| **Default:** | `3`                      |

This option specifies the number of OSD pool replicas to use
when creating an OSD pool.

<a id="storage-cephfs-pool-conf:cephfs.path"></a>
`cephfs.path`

The base path for the CephFS mount

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-cephfs-pool-conf:cephfs.path)

| **Key:**     | `cephfs.path`   |
|--------------|-----------------|
| **Type:**    | string          |
| **Default:** | `/`             |
| **Scope:**   | global          |

This option specifies the base path for the CephFS mount.
The path gets created if missing.

<a id="storage-cephfs-pool-conf:cephfs.user.name"></a>
`cephfs.user.name`

The Ceph user to use

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-cephfs-pool-conf:cephfs.user.name)

| **Key:**     | `cephfs.user.name`   |
|--------------|----------------------|
| **Type:**    | string               |
| **Default:** | `admin`              |
| **Scope:**   | global               |

<a id="storage-cephfs-pool-conf:source.recover"></a>
`source.recover`

Whether to recover an existing `source`

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-cephfs-pool-conf:source.recover)

| **Key:**     | `source.recover`   |
|--------------|--------------------|
| **Type:**    | bool               |
| **Default:** | `false`            |
| **Scope:**   | local              |

Set this option to true to recover an existing source which was previously created by LXD.

### Storage volume configuration

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="storage-cephfs-volume-conf:security.shifted"></a>
`security.shifted`

Enable ID shifting overlay

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-cephfs-volume-conf:security.shifted)

| **Key:**       | `security.shifted`                           |
|----------------|----------------------------------------------|
| **Type:**      | bool                                         |
| **Default:**   | same as `volume.security.shifted` or `false` |
| **Condition:** | custom volume                                |
| **Scope:**     | global                                       |

Enable this option to allow the volume to be attached to multiple isolated instances.

<a id="storage-cephfs-volume-conf:security.unmapped"></a>
`security.unmapped`

Disable ID mapping for the volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-cephfs-volume-conf:security.unmapped)

| **Key:**       | `security.unmapped`                           |
|----------------|-----------------------------------------------|
| **Type:**      | bool                                          |
| **Default:**   | same as `volume.security.unmapped` or `false` |
| **Condition:** | custom volume                                 |
| **Scope:**     | global                                        |

<a id="storage-cephfs-volume-conf:size"></a>
`size`

Size/quota of the storage volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-cephfs-volume-conf:size)

| **Key:**       | `size`                |
|----------------|-----------------------|
| **Type:**      | string                |
| **Default:**   | same as `volume.size` |
| **Condition:** | appropriate driver    |
| **Scope:**     | global                |

<a id="storage-cephfs-volume-conf:snapshots.expiry"></a>
`snapshots.expiry`

Time until snapshots are deleted

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-cephfs-volume-conf:snapshots.expiry)

| **Key:**       | `snapshots.expiry`                |
|----------------|-----------------------------------|
| **Type:**      | string                            |
| **Default:**   | same as `volume.snapshots.expiry` |
| **Condition:** | custom volume                     |
| **Scope:**     | global                            |

Specify an expression like `1M 2H 3d 4w 5m 6y`.

<a id="storage-cephfs-volume-conf:snapshots.pattern"></a>
`snapshots.pattern`

Template for the snapshot name

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-cephfs-volume-conf:snapshots.pattern)

| **Key:**       | `snapshots.pattern`                            |
|----------------|------------------------------------------------|
| **Type:**      | string                                         |
| **Default:**   | same as `volume.snapshots.pattern` or `snap%d` |
| **Condition:** | custom volume                                  |
| **Scope:**     | global                                         |

You can specify a naming template for scheduled snapshots and unnamed snapshots.

The `snapshots.pattern` option takes a Pongo2 template string to format the snapshot name.

To add a time stamp to the snapshot name, use the Pongo2 context variable `creation_date`.
Make sure to format the date in your template string to avoid forbidden characters in the snapshot name.
For example, set `snapshots.pattern` to `{{ creation_date|date:'2006-01-02_15-04-05' }}` to name the snapshots after their time of creation, down to the precision of a second.

Another way to avoid name collisions is to use the placeholder `%d` in the pattern.
If no matching snapshots exist, the placeholder is replaced with `0`.
Otherwise, it is replaced with the next snapshot index, which is one higher than the highest existing matching snapshot index.

<a id="storage-cephfs-volume-conf:snapshots.schedule"></a>
`snapshots.schedule`

Schedule for automatic volume snapshots

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-cephfs-volume-conf:snapshots.schedule)

| **Key:**       | `snapshots.schedule`         |
|----------------|------------------------------|
| **Type:**      | string                       |
| **Default:**   | same as `snapshots.schedule` |
| **Condition:** | custom volume                |
| **Scope:**     | global                       |

Specify either a cron expression (`<minute> <hour> <dom> <month> <dow>`), a comma-separated list of schedule aliases (`@hourly`, `@daily`, `@midnight`, `@weekly`, `@monthly`, `@annually`, `@yearly`), or leave empty to disable automatic snapshots (the default).

<a id="storage-cephfs-volume-conf:volatile.devlxd.owner"></a>
`volatile.devlxd.owner`

ID of the DevLXD identity that owns the volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-cephfs-volume-conf:volatile.devlxd.owner)

| **Key:**     | `volatile.devlxd.owner`   |
|--------------|---------------------------|
| **Type:**    | string                    |
| **Default:** | DevLXD owner identity ID  |
| **Scope:**   | global                    |

<a id="storage-cephfs-volume-conf:volatile.idmap.last"></a>
`volatile.idmap.last`

JSON-serialized UID/GID map that has been applied to the volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-cephfs-volume-conf:volatile.idmap.last)

| **Key:**       | `volatile.idmap.last`   |
|----------------|-------------------------|
| **Type:**      | string                  |
| **Condition:** | filesystem              |

<a id="storage-cephfs-volume-conf:volatile.idmap.next"></a>
`volatile.idmap.next`

JSON-serialized UID/GID map that has been applied to the volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-cephfs-volume-conf:volatile.idmap.next)

| **Key:**       | `volatile.idmap.next`   |
|----------------|-------------------------|
| **Type:**      | string                  |
| **Condition:** | filesystem              |

<a id="storage-cephfs-volume-conf:volatile.uuid"></a>
`volatile.uuid`

Volume UUID

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-cephfs-volume-conf:volatile.uuid)

| **Key:**     | `volatile.uuid`   |
|--------------|-------------------|
| **Type:**    | string            |
| **Default:** | random UUID       |
| **Scope:**   | global            |


# index.html.md

<a id="devices-unix-block"></a>

# Type: `unix-block`


            <p class="youtube_link">
              <a href="https://www.youtube.com/watch?v=C2e3LD5wLI8" target="_blank">
                <span title="LXD Unix devices - YouTube" class="play_icon">▶</span>
                <span title="LXD Unix devices - YouTube">Watch on YouTube</span>
              </a>
            </p>
        
#### NOTE
The `unix-block` device type is supported for containers.
It supports hotplugging.

Unix block devices make the specified block device appear as a device in the container (under `/dev`).
You can read from the device and write to it.

## Device options

`unix-block` devices have the following device options:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="device-unix-block-device-conf:gid"></a>
`gid`

GID of the device owner in the container

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-unix-block-device-conf:gid)

| **Key:**     | `gid`   |
|--------------|---------|
| **Type:**    | integer |
| **Default:** | `0`     |

<a id="device-unix-block-device-conf:major"></a>
`major`

Device major number

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-unix-block-device-conf:major)

| **Key:**     | `major`        |
|--------------|----------------|
| **Type:**    | integer        |
| **Default:** | device on host |

<a id="device-unix-block-device-conf:minor"></a>
`minor`

Device minor number

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-unix-block-device-conf:minor)

| **Key:**     | `minor`        |
|--------------|----------------|
| **Type:**    | integer        |
| **Default:** | device on host |

<a id="device-unix-block-device-conf:mode"></a>
`mode`

Mode of the device in the container

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-unix-block-device-conf:mode)

| **Key:**     | `mode`   |
|--------------|----------|
| **Type:**    | integer  |
| **Default:** | `0660`   |

<a id="device-unix-block-device-conf:path"></a>
`path`

Path inside the container

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-unix-block-device-conf:path)

| **Key:**      | `path`                                |
|---------------|---------------------------------------|
| **Type:**     | string                                |
| **Required:** | either `source` or `path` must be set |

<a id="device-unix-block-device-conf:required"></a>
`required`

Whether this device is required to start the container

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-unix-block-device-conf:required)

| **Key:**     | `required`   |
|--------------|--------------|
| **Type:**    | bool         |
| **Default:** | `true`       |

See [Hotplugging](#devices-unix-block-hotplugging) for more information.

<a id="device-unix-block-device-conf:source"></a>
`source`

Path on the host

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-unix-block-device-conf:source)

| **Key:**      | `source`                              |
|---------------|---------------------------------------|
| **Type:**     | string                                |
| **Required:** | either `source` or `path` must be set |

<a id="device-unix-block-device-conf:uid"></a>
`uid`

UID of the device owner in the container

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-unix-block-device-conf:uid)

| **Key:**     | `uid`   |
|--------------|---------|
| **Type:**    | integer |
| **Default:** | `0`     |

## Configuration examples

Add a `unix-block` device to a container by specifying its source and path:

```none
lxc config device add <instance_name> <device_name> unix-block source=<path_on_host> path=<path_on_instance>
```

If you want to use the same path on the container as on the host, you can omit the `source` option:

```none
lxc config device add <instance_name> <device_name> unix-block path=<path_to_the_device>
```

See [Configure devices](../howto/instances_configure.md#instances-configure-devices) for more information.

<a id="devices-unix-block-hotplugging"></a>

## Hotplugging

Hotplugging is enabled if you set `required=false` and specify the `source` option for the device.

In this case, the device is automatically passed into the container when it appears on the host, even after the container starts.
If the device disappears from the host system, it is removed from the container as well.


# index.html.md

<a id="ref-ovn-internals"></a>

# OVN implementation

Open Virtual Networks (OVN) is an open source Software Defined Network (SDN) solution.
OVN is designed to be incredibly flexible.
This flexibility comes at the cost of complexity.
OVN is not prescriptive about how it should be used.

For LXD, the best way to think of OVN is as a toolkit.
We need to translate networking concepts in LXD to their OVN analogue and instruct OVN directly, at a low level, what to do.

This document outlines LXD’s approach to OVN in a basic setup.
It does not yet cover load-balancers, peering, forwards, zones, or ACLs.

For more detailed documentation on OVN itself, please see:

- [Overview of OVN and SDNs](https://ubuntu.com/blog/data-centre-networking-what-is-ovn).
- [OVN architectural overview](https://manpages.ubuntu.com/manpages/noble/man7/ovn-architecture.7.html).
- [OVN northbound database schema documentation](https://manpages.ubuntu.com/manpages/noble/man5/ovn-nb.5.html).
- [OVN southbound database schema documentation](https://manpages.ubuntu.com/manpages/noble/man5/ovn-sb.5.html).

## OVN concepts

This section outlines the OVN concepts that we use in LXD.
These are usually represented in tables in the OVN northbound database.

<a id="ref-ovn-internals-chassis"></a>

### Chassis

A chassis is where traffic physically ingresses into or egresses out of the virtual network. In LXD, there will usually be one chassis per cluster member. If LXD is configured to use OVN networking, then all members *can* be used as OVN chassis.

<a id="ref-ovn-internals-chassis-group"></a>

### Chassis group

A chassis group is an indirection between physical chassis and the virtual networks that use them. Each LXD OVN network has one chassis group. This allows us to, for example, set chassis priority on a per-network basis so that not all ingress/egress occurs on a single cluster member.

If any cluster members are assigned the [member role](../explanation/clusters.md#clustering-member-roles) of `ovn-chassis`, only those members are added to the chassis group. If none are assigned the `ovn-chassis` role, all members are added to the chassis group.

### Open vSwitch (OVS) Bridge

OVS bridges are used to connect virtual networks to physical ones and vice-versa.
If the LXD daemon invokes OVS APIs, that means changes are being applied on the same host machine.

For each LXD cluster member there are two OVS bridges:

- The provider bridge. This is used when connecting the uplink network on the host to the external switch inside each OVN network.
- The integration bridge. This is used when connecting instances to the internal switch inside each OVN network.

### OVN underlay

The OVN underlay is the means by which networks are virtualized across cluster members.
It is a Geneve tunnel which creates a layer 2 overlay network across layer 3 infrastructure.
The OVN underlay is configured and managed by OVN.

### Logical router

A logical router is a virtualized router.
There is one per LXD OVN network.
This handles layer 3 networking and additionally has associated NAT rules and security policies.

### Logical switch

Logical routers cannot be directly connected to OVS bridges; for this, we use a logical switch.
There are two logical switches per LXD OVN network:

- The external switch, which connects via logical switch port to a port on the logical router and to the provider OVS switch.
- The internal switch, which connects via logical switch port to a port on the logical router and to the integration bridge.
  This switch contains DHCP and IP allocation configuration.

### Logical switch/router ports

When you create a logical router or switch in OVN, it doesn’t initially have any ports.
You need to create ports and then link them.
For example, the internal logical switch and the logical router for a LXD OVN network are connected by:

1. Adding a logical router port to the logical router.
2. Adding a logical switch port to the internal logical switch.
3. Configuring the internal logical switch port as a router port and setting the logical router name.

Some configuration is applied directly at port level.
For example, in a LXD OVN network, IPv6 router advertisement settings are applied on the logical router port for the internal switch.
This is by design. It allows OVN to push configuration down to the port level so that packets are handled as quickly as possible.

### Port groups

When a LXD OVN network is created, a port group will be created that is specific to that network.
When instances are connected to the network, logical switch ports are created for them on the internal switch.
These logical switch ports are added to the port group for the network.
When a port group is created or updated in the OVN northbound database, the address set table is automatically populated.
Address sets are used for managing access control lists (ACLs).
By creating and maintaining the port group, we can easily select the whole network when managing ACLs.

## OVN Uplink

An OVN network can specify an uplink network.
That uplink network must be a managed network and be of type `physical` or `bridge`.
From these managed network definitions LXD ascertains a `parent` interface to use for the uplink connectivity.

For managed `bridge` networks the interface is the name of the network itself.

For managed `physical` networks it is the per-cluster member value of the `parent` setting.
The `parent` interface itself can have one of three types:

- Linux native bridge.
- OVS Bridge.
- Physical interface (or `bond` or `vlan`).

It is important to note that a `physical` managed network’s `parent` interface can be any of these types, and that for a managed `bridge` network the parent interface can be either types of bridges.

### Bridge (OVS)

A user can separately configure a managed bridge network with the `openvswitch` `bridge.driver`.
An OVN network can be created with `network` set to the name of the managed bridge network.
In this case LXD configures a bridge mapping on the OVS bridge to connect the OVN network:

![image](images/ovn/ovn-uplink-bridge-ovs.svg)

### Physical

An OVN network can be created with `network` set to a physical network, where the physical network is essentially a database entry in LXD that tells it how to interact with an actual `parent` network device.
In this case, an OVS bridge is created automatically.
A bridge port connects the OVS bridge to the parent.
A bridge mapping is used (as above) to connect the OVS bridge to the OVN network.

![image](images/ovn/ovn-uplink-physical.svg)

#### NOTE
When using a physical network as an uplink for OVN, any IP addresses on the parent interface will become defunct.
The parent network must not have any assigned IP addresses.

### Bridge (native)

A native Linux bridge can be used.
In this case, we perform the same steps as in the physical network and additionally configure a `veth` pair.
The `veth` pair is used so that the bridge can still be used for other purposes (since the bridge maintains its configuration).
This is handy for development and testing but is not performant and should not be used in production.

![image](images/ovn/ovn-uplink-bridge-native.svg)

## OVN Network

In the simplest case, a LXD OVN network has the below configuration:

![image](images/ovn/ovn-network.svg)

#### NOTE
This diagram does not show cross-cluster networks.
This conceptual diagram should look the same on all cluster members.
If the chassis group prioritizes another chassis for the uplink, the traffic is routed through that chassis.

## Integration bridge

The cluster setting `network.ovn.integration_bridge` must contain the name of an OVS bridge that is used to connect instances to an OVN network via a NIC device.
This OVS bridge must be pre-configured on all cluster members with the same name.
Connectivity to the integration bridge differs between containers and virtual machines:

- Containers use a `veth` pair (similar to connecting to a native bridge uplink network).
  ![image](images/ovn/ovn-integration-bridge-container.svg)
- Virtual machines use a TAP device (this can be presented to QEMU as a device whereas a `veth` pair cannot).
  ![image](images/ovn/ovn-integration-bridge-vm.svg)


# index.html.md

<a id="network-ovn"></a>

# OVN network

<!-- Include start OVN intro -->

 is a software-defined networking system that supports virtual network abstraction.
You can use it to build your own private cloud.
See [`www.ovn.org`](https://www.ovn.org/) for more information.

<!-- Include end OVN intro -->

The `ovn` network type allows to create logical networks using the OVN .
This kind of network can be useful for labs and multi-tenant environments where the same logical subnets are used in multiple discrete networks.

A LXD OVN network can be connected to an existing managed [Bridge network](network_bridge.md#network-bridge) or [Physical network](network_physical.md#network-physical) to gain access to the wider network.
By default, all connections from the OVN logical networks are NATed to an IP allocated from the uplink network.

See [How to set up OVN with LXD](../howto/network_ovn_setup.md#network-ovn-setup) for basic instructions for setting up an OVN network.

<!-- Include content from [network_bridge.md](network_bridge.md) -->

#### NOTE
Static DHCP assignments depend on the client using its MAC address as the DHCP identifier.
This method prevents conflicting leases when copying an instance, and thus makes statically assigned leases work properly.

<a id="network-ovn-architecture"></a>

## OVN networking architecture

The following figure shows the OVN network traffic flow in a LXD cluster:

![image](images/ovn_networking_1.svg)

The OVN network connects the different cluster members.
Network traffic between the cluster members passes through the NIC for inter-cluster traffic (`eth1` in the figure) and is transmitted through an OVN tunnel.
This traffic between cluster members is referred to as *OVN east/west traffic*.

For outside connectivity, the OVN network requires an uplink network (a [Bridge network](network_bridge.md#network-bridge) or a [Physical network](network_physical.md#network-physical)).
The OVN network uses a virtual router to connect to the uplink network through the NIC for uplink traffic (`eth0` in the figure).
The virtual router is active on only one of the cluster members, and can move to a different member at any time.
Independent of where the router resides, the OVN network is available on all cluster members.

Every instance on any cluster member can connect to the OVN network through its virtual NIC (usually `eth0` for containers and `enp5s0` for virtual machines).
The traffic between the instances and the uplink network is referred to as *OVN north/south traffic*.

The strengths of using OVN become apparent when looking at a networking architecture with more than one OVN network:

![image](images/ovn_networking_2.svg)

In this case, both depicted OVN networks are completely independent.
Both networks are available on all cluster members (with each virtual router being active on one random cluster member).
Each instance can use either of the networks, and the traffic on either network is completely isolated from the other network.

<a id="network-ovn-options"></a>

## Configuration options

The following configuration key namespaces are currently supported for the `ovn` network type:

- `bridge` (L2 interface configuration)
- `dns` (DNS server and resolution configuration)
- `ipv4` (L3 IPv4 configuration)
- `ipv6` (L3 IPv6 configuration)
- `security` (network ACL configuration)
- `user` (free-form key/value for user metadata)

#### NOTE
LXD uses the [CIDR notation](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing) where network subnet information is required, for example, `192.0.2.0/24` or `2001:db8::/32`. This does not apply to cases where a single address is required, for example, local/remote addresses of tunnels, NAT addresses or specific addresses to apply to an instance.

The following configuration options are available for the `ovn` network type:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="network-ovn-network-conf:acceleration.parent"></a>
`acceleration.parent`

Physical function interfaces to allocate virtual functions from for hardware acceleration

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-ovn-network-conf:acceleration.parent)

| **Key:**    | `acceleration.parent`   |
|-------------|-------------------------|
| **Type:**   | string                  |

Comma separated list of physical function (PF) interfaces to allocate virtual functions (VFs) from for hardware acceleration when [`acceleration`](devices_nic.md#device-nic-ovn-device-conf:acceleration) is enabled.
See [SR-IOV hardware acceleration](devices_nic.md#devices-nic-hw-acceleration) for more information.

<a id="network-ovn-network-conf:bridge.hwaddr"></a>
`bridge.hwaddr`

MAC address for the bridge

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-ovn-network-conf:bridge.hwaddr)

| **Key:**    | `bridge.hwaddr`   |
|-------------|-------------------|
| **Type:**   | string            |

<a id="network-ovn-network-conf:bridge.mtu"></a>
`bridge.mtu`

Bridge MTU

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-ovn-network-conf:bridge.mtu)

| **Key:**     | `bridge.mtu`   |
|--------------|----------------|
| **Type:**    | integer        |
| **Default:** | `1442`         |

The default value allows the host to host Geneve tunnels.

<a id="network-ovn-network-conf:dns.domain"></a>
`dns.domain`

Domain to advertise to DHCP clients and use for DNS resolution

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-ovn-network-conf:dns.domain)

| **Key:**     | `dns.domain`   |
|--------------|----------------|
| **Type:**    | string         |
| **Default:** | `lxd`          |

<a id="network-ovn-network-conf:dns.search"></a>
`dns.search`

Full domain search list

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-ovn-network-conf:dns.search)

| **Key:**     | `dns.search`       |
|--------------|--------------------|
| **Type:**    | string             |
| **Default:** | `dns.domain` value |

Specify a comma-separated list of domains.

<a id="network-ovn-network-conf:dns.zone.forward"></a>
`dns.zone.forward`

DNS zone names for forward DNS records

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-ovn-network-conf:dns.zone.forward)

| **Key:**    | `dns.zone.forward`   |
|-------------|----------------------|
| **Type:**   | string               |

Specify a comma-separated list of DNS zone names.

<a id="network-ovn-network-conf:dns.zone.reverse.ipv4"></a>
`dns.zone.reverse.ipv4`

DNS zone name for IPv4 reverse DNS records

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-ovn-network-conf:dns.zone.reverse.ipv4)

| **Key:**    | `dns.zone.reverse.ipv4`   |
|-------------|---------------------------|
| **Type:**   | string                    |

<a id="network-ovn-network-conf:dns.zone.reverse.ipv6"></a>
`dns.zone.reverse.ipv6`

DNS zone name for IPv6 reverse DNS records

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-ovn-network-conf:dns.zone.reverse.ipv6)

| **Key:**    | `dns.zone.reverse.ipv6`   |
|-------------|---------------------------|
| **Type:**   | string                    |

<a id="network-ovn-network-conf:ipv4.address"></a>
`ipv4.address`

IPv4 address for the OVN network

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-ovn-network-conf:ipv4.address)

| **Key:**       | `ipv4.address`                    |
|----------------|-----------------------------------|
| **Type:**      | string                            |
| **Default:**   | initial value on creation: `auto` |
| **Condition:** | standard mode                     |

Use CIDR notation.

You can set the option to `none` to turn off IPv4, or to `auto` to generate a new random unused subnet.

<a id="network-ovn-network-conf:ipv4.dhcp"></a>
`ipv4.dhcp`

Whether to allocate IPv4 addresses using DHCP

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-ovn-network-conf:ipv4.dhcp)

| **Key:**       | `ipv4.dhcp`   |
|----------------|---------------|
| **Type:**      | bool          |
| **Default:**   | `true`        |
| **Condition:** | IPv4 address  |

<a id="network-ovn-network-conf:ipv4.dhcp.ranges"></a>
`ipv4.dhcp.ranges`

IPv4 ranges to use for DHCP

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-ovn-network-conf:ipv4.dhcp.ranges)

| **Key:**       | `ipv4.dhcp.ranges`   |
|----------------|----------------------|
| **Type:**      | string               |
| **Default:**   | all addresses        |
| **Condition:** | IPv4 DHCP            |
| **Scope:**     | global               |

Specify a comma-separated list of IPv4 ranges in FIRST-LAST format.

<a id="network-ovn-network-conf:ipv4.l3only"></a>
`ipv4.l3only`

Whether to enable layer 3 only mode for IPv4

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-ovn-network-conf:ipv4.l3only)

| **Key:**       | `ipv4.l3only`   |
|----------------|-----------------|
| **Type:**      | bool            |
| **Default:**   | `false`         |
| **Condition:** | IPv4 address    |

<a id="network-ovn-network-conf:ipv4.nat"></a>
`ipv4.nat`

Whether to use NAT for IPv4

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-ovn-network-conf:ipv4.nat)

| **Key:**       | `ipv4.nat`                                                                     |
|----------------|--------------------------------------------------------------------------------|
| **Type:**      | bool                                                                           |
| **Default:**   | `false` (initial value on creation if `ipv4.address` is set to `auto`: `true`) |
| **Condition:** | IPv4 address                                                                   |

<a id="network-ovn-network-conf:ipv4.nat.address"></a>
`ipv4.nat.address`

Source address used for outbound traffic from the network

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-ovn-network-conf:ipv4.nat.address)

| **Key:**       | `ipv4.nat.address`                                      |
|----------------|---------------------------------------------------------|
| **Type:**      | string                                                  |
| **Condition:** | IPv4 address; requires uplink `ovn.ingress_mode=routed` |

<a id="network-ovn-network-conf:ipv6.address"></a>
`ipv6.address`

IPv6 address for the OVN network

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-ovn-network-conf:ipv6.address)

| **Key:**       | `ipv6.address`                    |
|----------------|-----------------------------------|
| **Type:**      | string                            |
| **Default:**   | initial value on creation: `auto` |
| **Condition:** | standard mode                     |

Use CIDR notation.

You can set the option to `none` to turn off IPv6, or to `auto` to generate a new random unused subnet.

<a id="network-ovn-network-conf:ipv6.dhcp"></a>
`ipv6.dhcp`

Whether to provide additional network configuration over DHCP

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-ovn-network-conf:ipv6.dhcp)

| **Key:**       | `ipv6.dhcp`   |
|----------------|---------------|
| **Type:**      | bool          |
| **Default:**   | `true`        |
| **Condition:** | IPv6 address  |

<a id="network-ovn-network-conf:ipv6.dhcp.stateful"></a>
`ipv6.dhcp.stateful`

Whether to allocate IPv6 addresses using DHCP

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-ovn-network-conf:ipv6.dhcp.stateful)

| **Key:**       | `ipv6.dhcp.stateful`   |
|----------------|------------------------|
| **Type:**      | bool                   |
| **Default:**   | `false`                |
| **Condition:** | IPv6 DHCP              |

<a id="network-ovn-network-conf:ipv6.l3only"></a>
`ipv6.l3only`

Whether to enable layer 3 only mode for IPv6

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-ovn-network-conf:ipv6.l3only)

| **Key:**       | `ipv6.l3only`      |
|----------------|--------------------|
| **Type:**      | bool               |
| **Default:**   | `false`            |
| **Condition:** | IPv6 DHCP stateful |

<a id="network-ovn-network-conf:ipv6.nat"></a>
`ipv6.nat`

Whether to use NAT for IPv6

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-ovn-network-conf:ipv6.nat)

| **Key:**       | `ipv6.nat`                                                                     |
|----------------|--------------------------------------------------------------------------------|
| **Type:**      | bool                                                                           |
| **Default:**   | `false` (initial value on creation if `ipv6.address` is set to `auto`: `true`) |
| **Condition:** | IPv6 address                                                                   |

<a id="network-ovn-network-conf:ipv6.nat.address"></a>
`ipv6.nat.address`

Source address used for outbound traffic from the network

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-ovn-network-conf:ipv6.nat.address)

| **Key:**       | `ipv6.nat.address`                                      |
|----------------|---------------------------------------------------------|
| **Type:**      | string                                                  |
| **Condition:** | IPv6 address; requires uplink `ovn.ingress_mode=routed` |

<a id="network-ovn-network-conf:network"></a>
`network`

Uplink network to use for external network access

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-ovn-network-conf:network)

| **Key:**    | `network`   |
|-------------|-------------|
| **Type:**   | string      |

<a id="network-ovn-network-conf:security.acls"></a>
`security.acls`

Network ACLs to apply to NICs connected to this network

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-ovn-network-conf:security.acls)

| **Key:**    | `security.acls`   |
|-------------|-------------------|
| **Type:**   | string            |

Specify a comma-separated list of network ACLs.

<a id="network-ovn-network-conf:security.acls.default.egress.action"></a>
`security.acls.default.egress.action`

Default action to use for egress traffic

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-ovn-network-conf:security.acls.default.egress.action)

| **Key:**       | `security.acls.default.egress.action`   |
|----------------|-----------------------------------------|
| **Type:**      | string                                  |
| **Default:**   | `reject`                                |
| **Condition:** | `security.acls`                         |

The specified action is used for all egress traffic that doesn’t match any ACL rule.

<a id="network-ovn-network-conf:security.acls.default.egress.logged"></a>
`security.acls.default.egress.logged`

Whether to log egress traffic that doesn’t match any ACL rule

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-ovn-network-conf:security.acls.default.egress.logged)

| **Key:**       | `security.acls.default.egress.logged`   |
|----------------|-----------------------------------------|
| **Type:**      | bool                                    |
| **Default:**   | `false`                                 |
| **Condition:** | `security.acls`                         |

<a id="network-ovn-network-conf:security.acls.default.ingress.action"></a>
`security.acls.default.ingress.action`

Default action to use for ingress traffic

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-ovn-network-conf:security.acls.default.ingress.action)

| **Key:**       | `security.acls.default.ingress.action`   |
|----------------|------------------------------------------|
| **Type:**      | string                                   |
| **Default:**   | `reject`                                 |
| **Condition:** | `security.acls`                          |

The specified action is used for all ingress traffic that doesn’t match any ACL rule.

<a id="network-ovn-network-conf:security.acls.default.ingress.logged"></a>
`security.acls.default.ingress.logged`

Whether to log ingress traffic that doesn’t match any ACL rule

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-ovn-network-conf:security.acls.default.ingress.logged)

| **Key:**       | `security.acls.default.ingress.logged`   |
|----------------|------------------------------------------|
| **Type:**      | bool                                     |
| **Default:**   | `false`                                  |
| **Condition:** | `security.acls`                          |

<a id="network-ovn-network-conf:user.*"></a>
`user.*`

User-provided free-form key/value pairs

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-ovn-network-conf:user.*)

| **Key:**    | `user.*`   |
|-------------|------------|
| **Type:**   | string     |

<a id="network-ovn-features"></a>

## Supported features

The following features are supported for the `ovn` network type:

- [How to configure network ACLs](../howto/network_acls.md#network-acls)
- [How to configure network forwards](../howto/network_forwards.md#network-forwards)
- [How to configure network zones](../howto/network_zones.md#network-zones)
- [How to create OVN peer routing relationships](../howto/network_ovn_peers.md#network-ovn-peers)
- [How to configure network load balancers](../howto/network_load_balancers.md#network-load-balancers)


# index.html.md

<a id="provided-metrics"></a>

# Provided metrics

LXD provides a number of instance metrics and internal metrics.
See [How to monitor metrics](../metrics.md#metrics) for instructions on how to work with these metrics.

## Instance metrics

The following instance metrics are provided:

| Metric                                                       | Description                                              |
|--------------------------------------------------------------|----------------------------------------------------------|
| `lxd_cpu_effective_total`                                    | Total number of effective CPUs                           |
| `lxd_cpu_seconds_total{cpu="<cpu>", mode="<mode>"}`          | Total number of CPU time used (in seconds)               |
| `lxd_disk_read_bytes_total{device="<dev>"}`                  | Total number of bytes read                               |
| `lxd_disk_reads_completed_total{device="<dev>"}`             | Total number of completed reads                          |
| `lxd_disk_written_bytes_total{device="<dev>"}`               | Total number of bytes written                            |
| `lxd_disk_writes_completed_total{device="<dev>"}`            | Total number of completed writes                         |
| `lxd_filesystem_avail_bytes{device="<dev>",fstype="<type>"}` | Available space (in bytes)                               |
| `lxd_filesystem_free_bytes{device="<dev>",fstype="<type>"}`  | Free space (in bytes)                                    |
| `lxd_filesystem_size_bytes{device="<dev>",fstype="<type>"}`  | Size of the file system (in bytes)                       |
| `lxd_memory_Active_anon_bytes`                               | Amount of anonymous memory on active LRU list            |
| `lxd_memory_Active_bytes`                                    | Amount of memory on active LRU list                      |
| `lxd_memory_Active_file_bytes`                               | Amount of file-backed memory on active LRU list          |
| `lxd_memory_Cached_bytes`                                    | Amount of cached memory                                  |
| `lxd_memory_Dirty_bytes`                                     | Amount of memory waiting to be written back to the disk  |
| `lxd_memory_HugepagesFree_bytes`                             | Amount of free memory for `hugetlb`                      |
| `lxd_memory_HugepagesTotal_bytes`                            | Amount of used memory for `hugetlb`                      |
| `lxd_memory_Inactive_anon_bytes`                             | Amount of anonymous memory on inactive LRU list          |
| `lxd_memory_Inactive_bytes`                                  | Amount of memory on inactive LRU list                    |
| `lxd_memory_Inactive_file_bytes`                             | Amount of file-backed memory on inactive LRU list        |
| `lxd_memory_Mapped_bytes`                                    | Amount of mapped memory                                  |
| `lxd_memory_MemAvailable_bytes`                              | Amount of available memory                               |
| `lxd_memory_MemFree_bytes`                                   | Amount of free memory                                    |
| `lxd_memory_MemTotal_bytes`                                  | Amount of used memory                                    |
| `lxd_memory_OOM_kills_total`                                 | The number of out-of-memory kills                        |
| `lxd_memory_RSS_bytes`                                       | Amount of anonymous and swap cache memory                |
| `lxd_memory_Shmem_bytes`                                     | Amount of cached file system data that is swap-backed    |
| `lxd_memory_SReclaimable_bytes`                              | Amount of reclaimable slab memory                        |
| `lxd_memory_Swap_bytes`                                      | Amount of used swap memory                               |
| `lxd_memory_Unevictable_bytes`                               | Amount of unevictable memory                             |
| `lxd_memory_Writeback_bytes`                                 | Amount of memory queued for syncing to disk              |
| `lxd_network_receive_bytes_total{device="<dev>"}`            | Amount of received bytes on a given interface            |
| `lxd_network_receive_drop_total{device="<dev>"}`             | Amount of received dropped bytes on a given interface    |
| `lxd_network_receive_errs_total{device="<dev>"}`             | Amount of received errors on a given interface           |
| `lxd_network_receive_packets_total{device="<dev>"}`          | Amount of received packets on a given interface          |
| `lxd_network_transmit_bytes_total{device="<dev>"}`           | Amount of transmitted bytes on a given interface         |
| `lxd_network_transmit_drop_total{device="<dev>"}`            | Amount of transmitted dropped bytes on a given interface |
| `lxd_network_transmit_errs_total{device="<dev>"}`            | Amount of transmitted errors on a given interface        |
| `lxd_network_transmit_packets_total{device="<dev>"}`         | Amount of transmitted packets on a given interface       |
| `lxd_procs_total`                                            | Number of running processes                              |

## Internal metrics

The following internal metrics are provided:

| Metric                             | Description                                                                              |
|------------------------------------|------------------------------------------------------------------------------------------|
| `lxd_api_requests_completed_total` | Total number of completed requests. See [API rates metrics](#api-rates-metrics).         |
| `lxd_api_requests_ongoing`         | Number of requests currently being handled. See [API rates metrics](#api-rates-metrics). |
| `lxd_go_alloc_bytes_total`         | Total number of bytes allocated (even if freed)                                          |
| `lxd_go_alloc_bytes`               | Number of bytes allocated and still in use                                               |
| `lxd_go_buck_hash_sys_bytes`       | Number of bytes used by the profiling bucket hash table                                  |
| `lxd_go_frees_total`               | Total number of frees                                                                    |
| `lxd_go_gc_sys_bytes`              | Number of bytes used for garbage collection system metadata                              |
| `lxd_go_goroutines`                | Number of goroutines that currently exist                                                |
| `lxd_go_heap_alloc_bytes`          | Number of heap bytes allocated and still in use                                          |
| `lxd_go_heap_idle_bytes`           | Number of heap bytes waiting to be used                                                  |
| `lxd_go_heap_inuse_bytes`          | Number of heap bytes that are in use                                                     |
| `lxd_go_heap_objects`              | Number of allocated objects                                                              |
| `lxd_go_heap_released_bytes`       | Number of heap bytes released to OS                                                      |
| `lxd_go_heap_sys_bytes`            | Number of heap bytes obtained from system                                                |
| `lxd_go_lookups_total`             | Total number of pointer lookups                                                          |
| `lxd_go_mallocs_total`             | Total number of `mallocs`                                                                |
| `lxd_go_mcache_inuse_bytes`        | Number of bytes in use by `mcache` structures                                            |
| `lxd_go_mcache_sys_bytes`          | Number of bytes used for `mcache` structures obtained from system                        |
| `lxd_go_mspan_inuse_bytes`         | Number of bytes in use by `mspan` structures                                             |
| `lxd_go_mspan_sys_bytes`           | Number of bytes used for `mspan` structures obtained from system                         |
| `lxd_go_next_gc_bytes`             | Number of heap bytes when next garbage collection will take place                        |
| `lxd_go_other_sys_bytes`           | Number of bytes used for other system allocations                                        |
| `lxd_go_stack_inuse_bytes`         | Number of bytes in use by the stack allocator                                            |
| `lxd_go_stack_sys_bytes`           | Number of bytes obtained from system for stack allocator                                 |
| `lxd_go_sys_bytes`                 | Number of bytes obtained from system                                                     |
| `lxd_operations_total`             | Number of running operations                                                             |
| `lxd_uptime_seconds`               | Daemon uptime (in seconds)                                                               |
| `lxd_warnings_total`               | Number of active warnings                                                                |

<a id="api-rates-metrics"></a>

## API rates metrics

The API rates metrics include `lxd_api_requests_completed_total` and `lxd_api_requests_ongoing`. These metrics can be consumed by an observability tool deployed externally (for example, the [Canonical Observability Stack](https://charmhub.io/topics/canonical-observability-stack) or another third-party tool) to help identify failures or overload on a LXD server. You can set thresholds on the observability tools for these metrics’ values to trigger alarms and take programmatic actions.

These metrics consider all endpoints in the [LXD REST API](../api.md), with the exception of the `/` endpoint. Requests using an invalid URL are also counted. Requests against the metrics server are also counted. Both introduced metrics include a label `entity_type` based on the main entity type that the endpoint is operating on.

`lxd_api_requests_ongoing` contains the number of requests that are not yet completed by the time the metrics are queried. A request is considered completed when the response is returned to the client and any asynchronous operations spawned by that request are done. `lxd_api_requests_completed_total` contains the number of completed requests. This metric includes an additional label named `result` based on the outcome of the request. The label can have one of the following values:

- `error_server`, for errors on the server side, this includes responses with HTTP status codes from 500 to 599. Any failed asynchronous operations also fall into this category.
- `error_client`, for responses with HTTP status codes from 400 to 499, indicating an error on the client side.
- `succeeded`, for endpoints that executed successfully.

## Related topics

How-to guides:

- [How to monitor metrics](../metrics.md#metrics)

Explanation:

- [Performance tuning](../explanation/performance_tuning.md#performance-tuning)


# index.html.md

<a id="reference-manpages"></a>

<a id="manpages"></a>

# Man pages

These man pages document all commands and subcommands of the `lxc` CLI client for LXD.

* [`lxc`](manpages/lxc.md)


# index.html.md

<a id="network-sriov"></a>

# SR-IOV network

<!-- Include start SR-IOV intro -->

 is a hardware standard that allows a single network card port to appear as several virtual network interfaces in a virtualized environment.

<!-- Include end SR-IOV intro -->

The `sriov` network type allows to specify presets to use when connecting instances to a parent interface.
In this case, the instance NICs can simply set the `network` option to the network they connect to without knowing any of the underlying configuration details.

<a id="network-sriov-options"></a>

## Configuration options

The following configuration key namespaces are currently supported for the `sriov` network type:

- `user` (free-form key/value for user metadata)

#### NOTE
LXD uses the [CIDR notation](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing) where network subnet information is required, for example, `192.0.2.0/24` or `2001:db8::/32`. This does not apply to cases where a single address is required, for example, local/remote addresses of tunnels, NAT addresses or specific addresses to apply to an instance.

The following configuration options are available for the `sriov` network type:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="network-sriov-network-conf:mtu"></a>
`mtu`

MTU of the new interface

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-sriov-network-conf:mtu)

| **Key:**    | `mtu`   |
|-------------|---------|
| **Type:**   | integer |
| **Scope:**  | global  |

<a id="network-sriov-network-conf:parent"></a>
`parent`

Parent interface to create `sriov` NICs on

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-sriov-network-conf:parent)

| **Key:**    | `parent`   |
|-------------|------------|
| **Type:**   | string     |
| **Scope:**  | local      |

<a id="network-sriov-network-conf:user.*"></a>
`user.*`

User-provided free-form key/value pairs

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-sriov-network-conf:user.*)

| **Key:**    | `user.*`   |
|-------------|------------|
| **Type:**   | string     |
| **Scope:**  | global     |

<a id="network-sriov-network-conf:vlan"></a>
`vlan`

VLAN ID to attach to

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-sriov-network-conf:vlan)

| **Key:**    | `vlan`   |
|-------------|----------|
| **Type:**   | integer  |
| **Scope:**  | global   |


# index.html.md

<a id="server-settings"></a>

# Server settings for a LXD production setup

To allow your LXD server to run a large number of instances, configure the following settings to avoid hitting server limits.

The `Value` column contains the suggested value for each parameter.

## `/etc/security/limits.conf`

#### NOTE
For users of the snap, those limits are automatically raised.

| Domain   | Type   | Item      | Value       | Default   | Description                                                                           |
|----------|--------|-----------|-------------|-----------|---------------------------------------------------------------------------------------|
| `*`      | soft   | `nofile`  | `1048576`   | unset     | Maximum number of open files                                                          |
| `*`      | hard   | `nofile`  | `1048576`   | unset     | Maximum number of open files                                                          |
| `root`   | soft   | `nofile`  | `1048576`   | unset     | Maximum number of open files                                                          |
| `root`   | hard   | `nofile`  | `1048576`   | unset     | Maximum number of open files                                                          |
| `*`      | soft   | `memlock` | `unlimited` | unset     | Maximum locked-in-memory address space (KB)                                           |
| `*`      | hard   | `memlock` | `unlimited` | unset     | Maximum locked-in-memory address space (KB)                                           |
| `root`   | soft   | `memlock` | `unlimited` | unset     | Maximum locked-in-memory address space (KB), only need with `bpf` syscall supervision |
| `root`   | hard   | `memlock` | `unlimited` | unset     | Maximum locked-in-memory address space (KB), only need with `bpf` syscall supervision |

## `/etc/sysctl.conf`

#### NOTE
Reboot the server after changing any of these parameters.

<a id="sysctl:fs.aio-max-nr"></a>
`fs.aio-max-nr`

Maximum number of concurrent asynchronous I/O operations

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#sysctl:fs.aio-max-nr)

| **Key:**     | `fs.aio-max-nr`   |
|--------------|-------------------|
| **Type:**    | integer           |
| **Default:** | `65536`           |

Suggested value: `524288`

You might need to increase this limit further if you have a lot of workloads that use the AIO subsystem (for example, MySQL).

<a id="sysctl:fs.inotify.max_queued_events"></a>
`fs.inotify.max_queued_events`

Upper limit on the number of events that can be queued

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#sysctl:fs.inotify.max_queued_events)

| **Key:**     | `fs.inotify.max_queued_events`   |
|--------------|----------------------------------|
| **Type:**    | integer                          |
| **Default:** | `16384`                          |

Suggested value: `1048576`

This option specifies the maximum number of events that can be queued to the corresponding `inotify` instance (see [`inotify`](https://man7.org/linux/man-pages/man7/inotify.7.html) for more information).

<a id="sysctl:fs.inotify.max_user_instances"></a>
`fs.inotify.max_user_instances`

Upper limit on the number of `inotify` instances

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#sysctl:fs.inotify.max_user_instances)

| **Key:**     | `fs.inotify.max_user_instances`   |
|--------------|-----------------------------------|
| **Type:**    | integer                           |
| **Default:** | `128`                             |

Suggested value: `1048576`

This option specifies the maximum number of `inotify` instances that can be created per real user ID (see [`inotify`](https://man7.org/linux/man-pages/man7/inotify.7.html) for more information).

<a id="sysctl:fs.inotify.max_user_watches"></a>
`fs.inotify.max_user_watches`

Upper limit on the number of watches

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#sysctl:fs.inotify.max_user_watches)

| **Key:**     | `fs.inotify.max_user_watches`   |
|--------------|---------------------------------|
| **Type:**    | integer                         |
| **Default:** | `8192`                          |

Suggested value: `1048576`

This option specifies the maximum number of watches that can be created per real user ID (see [`inotify`](https://man7.org/linux/man-pages/man7/inotify.7.html) for more information).

<a id="sysctl:kernel.dmesg_restrict"></a>
`kernel.dmesg_restrict`

Whether to deny access to the messages in the kernel ring buffer

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#sysctl:kernel.dmesg_restrict)

| **Key:**     | `kernel.dmesg_restrict`   |
|--------------|---------------------------|
| **Type:**    | integer                   |
| **Default:** | `0`                       |

Suggested value: `1`

Set this option to `1` to deny container access to the messages in the kernel ring buffer.
Note that setting this value to `1` will also deny access to non-root users on the host system.

<a id="sysctl:kernel.keys.maxbytes"></a>
`kernel.keys.maxbytes`

Maximum size of the key ring that non-root users can use

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#sysctl:kernel.keys.maxbytes)

| **Key:**     | `kernel.keys.maxbytes`   |
|--------------|--------------------------|
| **Type:**    | integer                  |
| **Default:** | `20000`                  |

Suggested value: `2000000`

<a id="sysctl:kernel.keys.maxkeys"></a>
`kernel.keys.maxkeys`

Maximum number of keys that a non-root user can use

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#sysctl:kernel.keys.maxkeys)

| **Key:**     | `kernel.keys.maxkeys`   |
|--------------|-------------------------|
| **Type:**    | integer                 |
| **Default:** | `200`                   |

Suggested value: `2000`

Set this option to a value that is higher than the number of instances.

<a id="sysctl:net.core.bpf_jit_limit"></a>
`net.core.bpf_jit_limit`

Limit on the size of eBPF JIT allocations

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#sysctl:net.core.bpf_jit_limit)

| **Key:**     | `net.core.bpf_jit_limit`   |
|--------------|----------------------------|
| **Type:**    | integer                    |
| **Default:** | varies                     |

Suggested value: `1000000000`

On kernels < 5.15 that are compiled with `CONFIG_BPF_JIT_ALWAYS_ON=y`, this value might limit the amount of instances that can be created.

<a id="sysctl:net.ipv4.neigh.default.gc_thresh3"></a>
`net.ipv4.neigh.default.gc_thresh3`

Maximum number of entries in the IPv4 ARP table

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#sysctl:net.ipv4.neigh.default.gc_thresh3)

| **Key:**     | `net.ipv4.neigh.default.gc_thresh3`   |
|--------------|---------------------------------------|
| **Type:**    | integer                               |
| **Default:** | `1024`                                |

Suggested value: `8192`

Increase this value if you plan to create over 1024 instances.
Otherwise, you will get the error `neighbour: ndisc_cache: neighbor table overflow!` when the ARP table gets full and the instances cannot get a network configuration.
See [`ip-sysctl`](https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt) for more information.

<a id="sysctl:net.ipv6.neigh.default.gc_thresh3"></a>
`net.ipv6.neigh.default.gc_thresh3`

Maximum number of entries in IPv6 ARP table

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#sysctl:net.ipv6.neigh.default.gc_thresh3)

| **Key:**     | `net.ipv6.neigh.default.gc_thresh3`   |
|--------------|---------------------------------------|
| **Type:**    | integer                               |
| **Default:** | `1024`                                |

Suggested value: `8192`

Increase this value if you plan to create over 1024 instances.
Otherwise, you will get the error `neighbour: ndisc_cache: neighbor table overflow!` when the ARP table gets full and the instances cannot get a network configuration.
See [`ip-sysctl`](https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt) for more information.

<a id="sysctl:vm.max_map_count"></a>
`vm.max_map_count`

Maximum number of memory map areas a process may have

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#sysctl:vm.max_map_count)

| **Key:**     | `vm.max_map_count`   |
|--------------|----------------------|
| **Type:**    | integer              |
| **Default:** | `65530`              |

Suggested value: `262144`

Memory map areas are used as a side-effect of calling `malloc`, directly by `mmap` and `mprotect`, and also when loading shared libraries.

## Related topics

How-to guides:

- [How to benchmark performance](../howto/benchmark_performance.md#benchmark-performance)
- [How to increase the network bandwidth](../howto/network_increase_bandwidth.md#network-increase-bandwidth)
- [How to monitor metrics](../metrics.md#metrics)

Explanation:

- [Performance tuning](../explanation/performance_tuning.md#performance-tuning)


# index.html.md

<a id="devices-pci"></a>

# Type: `pci`


            <p class="youtube_link">
              <a href="https://www.youtube.com/watch?v=h3DZXbmsZHg" target="_blank">
                <span title="LXD PCI devices" class="play_icon">▶</span>
                <span title="LXD PCI devices">Watch on YouTube</span>
              </a>
            </p>
        
#### NOTE
The `pci` device type is supported for VMs.

PCI devices are used to pass raw PCI devices from the host into a virtual machine.

They are mainly intended to be used for specialized single-function PCI cards like sound cards or video capture cards.
In theory, you can also use them for more advanced PCI devices like GPUs or network cards, but it’s usually more convenient to use the specific device types that LXD provides for these devices ([`gpu` device](devices_gpu.md#devices-gpu) or [`nic` device](devices_nic.md#devices-nic)).

## Device options

`pci` devices have the following device options:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="device-pci-device-conf:address"></a>
`address`

PCI address of the device

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-pci-device-conf:address)

| **Key:**      | `address`   |
|---------------|-------------|
| **Type:**     | string      |
| **Required:** | yes         |

## Configuration examples

Add a `pci` device to a virtual machine by specifying its PCI address:

```none
lxc config device add <instance_name> <device_name> pci address=<pci_address>
```

To determine the PCI address, you can use **lspci**, for example.

See [Configure devices](../howto/instances_configure.md#instances-configure-devices) for more information.


# index.html.md

<a id="storage-dir"></a>

# Directory - `dir`


            <p class="youtube_link">
              <a href="https://www.youtube.com/watch?v=imWkPM9GjCY" target="_blank">
                <span title="Directory storage and LXD" class="play_icon">▶</span>
                <span title="Directory storage and LXD">Watch on YouTube</span>
              </a>
            </p>
        
The directory storage driver is a basic backend that stores its data in a standard file and directory structure.
This driver is quick to set up and allows inspecting the files directly on the disk, which can be convenient for testing.
However, LXD operations are [not optimized](storage_drivers.md#storage-drivers-features) for this driver.

## `dir` driver in LXD

The `dir` driver in LXD is fully functional and provides the same set of features as other drivers.
However, it is much slower than all the other drivers because it must unpack images and do instant copies of instances, snapshots and images.

Unless specified differently during creation (with the `source` configuration option), the data is stored in the `/var/snap/lxd/common/lxd/storage-pools/` (for snap installations) or `/var/lib/lxd/storage-pools/` directory.

<a id="storage-dir-quotas"></a>

### Quotas

<!-- Include start dir quotas -->

The `dir` driver supports storage quotas when running on either ext4 or XFS with project quotas enabled at the file system level.

<!-- Include end dir quotas -->

## Configuration options

The following configuration options are available for storage pools that use the `dir` driver and for storage volumes in these pools.

### Storage pool configuration

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="storage-dir-pool-conf:rsync.bwlimit"></a>
`rsync.bwlimit`

Upper limit on the socket I/O for `rsync`

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-dir-pool-conf:rsync.bwlimit)

| **Key:**     | `rsync.bwlimit`   |
|--------------|-------------------|
| **Type:**    | string            |
| **Default:** | `0` (no limit)    |
| **Scope:**   | global            |

When `rsync` must be used to transfer storage entities, this option specifies the upper limit
to be placed on the socket I/O.

<a id="storage-dir-pool-conf:rsync.compression"></a>
`rsync.compression`

Whether to use compression while migrating storage pools

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-dir-pool-conf:rsync.compression)

| **Key:**     | `rsync.compression`   |
|--------------|-----------------------|
| **Type:**    | bool                  |
| **Default:** | `true`                |
| **Scope:**   | global                |

<a id="storage-dir-pool-conf:source"></a>
`source`

Path to an existing directory

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-dir-pool-conf:source)

| **Key:**    | `source`   |
|-------------|------------|
| **Type:**   | string     |
| **Scope:**  | local      |

<a id="storage-dir-pool-conf:source.recover"></a>
`source.recover`

Whether to recover an existing `source`

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-dir-pool-conf:source.recover)

| **Key:**     | `source.recover`   |
|--------------|--------------------|
| **Type:**    | bool               |
| **Default:** | `false`            |
| **Scope:**   | local              |

Set this option to true to recover an existing source which was previously created by LXD.

### Storage volume configuration

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="storage-dir-volume-conf:security.shared"></a>
`security.shared`

Enable volume sharing

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-dir-volume-conf:security.shared)

| **Key:**       | `security.shared`                           |
|----------------|---------------------------------------------|
| **Type:**      | bool                                        |
| **Default:**   | same as `volume.security.shared` or `false` |
| **Condition:** | virtual-machine or custom block volume      |
| **Scope:**     | global                                      |

Enable this option to allow the volume to be shared across multiple instances despite the possibility of data loss.

<a id="storage-dir-volume-conf:security.shifted"></a>
`security.shifted`

Enable ID shifting overlay

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-dir-volume-conf:security.shifted)

| **Key:**       | `security.shifted`                           |
|----------------|----------------------------------------------|
| **Type:**      | bool                                         |
| **Default:**   | same as `volume.security.shifted` or `false` |
| **Condition:** | custom volume                                |
| **Scope:**     | global                                       |

Enable this option to allow the volume to be attached to multiple isolated instances.

<a id="storage-dir-volume-conf:security.unmapped"></a>
`security.unmapped`

Disable ID mapping for the volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-dir-volume-conf:security.unmapped)

| **Key:**       | `security.unmapped`                           |
|----------------|-----------------------------------------------|
| **Type:**      | bool                                          |
| **Default:**   | same as `volume.security.unmapped` or `false` |
| **Condition:** | custom volume                                 |
| **Scope:**     | global                                        |

<a id="storage-dir-volume-conf:size"></a>
`size`

Size/quota of the storage volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-dir-volume-conf:size)

| **Key:**       | `size`                |
|----------------|-----------------------|
| **Type:**      | string                |
| **Default:**   | same as `volume.size` |
| **Condition:** | appropriate driver    |
| **Scope:**     | global                |

<a id="storage-dir-volume-conf:snapshots.expiry"></a>
`snapshots.expiry`

Time until snapshots are deleted

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-dir-volume-conf:snapshots.expiry)

| **Key:**       | `snapshots.expiry`                |
|----------------|-----------------------------------|
| **Type:**      | string                            |
| **Default:**   | same as `volume.snapshots.expiry` |
| **Condition:** | custom volume                     |
| **Scope:**     | global                            |

Specify an expression like `1M 2H 3d 4w 5m 6y`.

<a id="storage-dir-volume-conf:snapshots.pattern"></a>
`snapshots.pattern`

Template for the snapshot name

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-dir-volume-conf:snapshots.pattern)

| **Key:**       | `snapshots.pattern`                            |
|----------------|------------------------------------------------|
| **Type:**      | string                                         |
| **Default:**   | same as `volume.snapshots.pattern` or `snap%d` |
| **Condition:** | custom volume                                  |
| **Scope:**     | global                                         |

You can specify a naming template for scheduled snapshots and unnamed snapshots.

The `snapshots.pattern` option takes a Pongo2 template string to format the snapshot name.

To add a time stamp to the snapshot name, use the Pongo2 context variable `creation_date`.
Make sure to format the date in your template string to avoid forbidden characters in the snapshot name.
For example, set `snapshots.pattern` to `{{ creation_date|date:'2006-01-02_15-04-05' }}` to name the snapshots after their time of creation, down to the precision of a second.

Another way to avoid name collisions is to use the placeholder `%d` in the pattern.
If no matching snapshots exist, the placeholder is replaced with `0`.
Otherwise, it is replaced with the next snapshot index, which is one higher than the highest existing matching snapshot index.

<a id="storage-dir-volume-conf:snapshots.schedule"></a>
`snapshots.schedule`

Schedule for automatic volume snapshots

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-dir-volume-conf:snapshots.schedule)

| **Key:**       | `snapshots.schedule`         |
|----------------|------------------------------|
| **Type:**      | string                       |
| **Default:**   | same as `snapshots.schedule` |
| **Condition:** | custom volume                |
| **Scope:**     | global                       |

Specify either a cron expression (`<minute> <hour> <dom> <month> <dow>`), a comma-separated list of schedule aliases (`@hourly`, `@daily`, `@midnight`, `@weekly`, `@monthly`, `@annually`, `@yearly`), or leave empty to disable automatic snapshots (the default).

<a id="storage-dir-volume-conf:volatile.devlxd.owner"></a>
`volatile.devlxd.owner`

ID of the DevLXD identity that owns the volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-dir-volume-conf:volatile.devlxd.owner)

| **Key:**     | `volatile.devlxd.owner`   |
|--------------|---------------------------|
| **Type:**    | string                    |
| **Default:** | DevLXD owner identity ID  |
| **Scope:**   | global                    |

<a id="storage-dir-volume-conf:volatile.idmap.last"></a>
`volatile.idmap.last`

JSON-serialized UID/GID map that has been applied to the volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-dir-volume-conf:volatile.idmap.last)

| **Key:**       | `volatile.idmap.last`   |
|----------------|-------------------------|
| **Type:**      | string                  |
| **Condition:** | filesystem              |

<a id="storage-dir-volume-conf:volatile.idmap.next"></a>
`volatile.idmap.next`

JSON-serialized UID/GID map that has been applied to the volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-dir-volume-conf:volatile.idmap.next)

| **Key:**       | `volatile.idmap.next`   |
|----------------|-------------------------|
| **Type:**      | string                  |
| **Condition:** | filesystem              |

<a id="storage-dir-volume-conf:volatile.uuid"></a>
`volatile.uuid`

Volume UUID

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-dir-volume-conf:volatile.uuid)

| **Key:**     | `volatile.uuid`   |
|--------------|-------------------|
| **Type:**    | string            |
| **Default:** | random UUID       |
| **Scope:**   | global            |


# index.html.md

<a id="devices-usb"></a>

# Type: `usb`


            <p class="youtube_link">
              <a href="https://www.youtube.com/watch?v=SAord28VS4g" target="_blank">
                <span title="LXD USB devices" class="play_icon">▶</span>
                <span title="LXD USB devices">Watch on YouTube</span>
              </a>
            </p>
        
#### NOTE
The `usb` device type is supported for both containers and VMs.
It supports hotplugging for both containers and VMs.

USB devices make the specified USB device appear in the instance.
For performance issues, avoid using devices that require high throughput or low latency.

For containers, only `libusb` devices (at `/dev/bus/usb`) are passed to the instance.
This method works for devices that have user-space drivers.
For devices that require dedicated kernel drivers, use a [`unix-char` device](devices_unix_char.md#devices-unix-char) or a [`unix-hotplug` device](devices_unix_hotplug.md#devices-unix-hotplug) instead.

For virtual machines, the entire USB device is passed through, so any USB device is supported.
When a device is passed to the instance, it vanishes from the host.

## Device options

`usb` devices have the following device options:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="device-unix-usb-device-conf:busnum"></a>
`busnum`

The bus number of which the USB device is attached

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-unix-usb-device-conf:busnum)

| **Key:**    | `busnum`   |
|-------------|------------|
| **Type:**   | int        |

<a id="device-unix-usb-device-conf:devnum"></a>
`devnum`

The device number of the USB device

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-unix-usb-device-conf:devnum)

| **Key:**    | `devnum`   |
|-------------|------------|
| **Type:**   | int        |

<a id="device-unix-usb-device-conf:gid"></a>
`gid`

GID of the device owner in the instance

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-unix-usb-device-conf:gid)

| **Key:**       | `gid`     |
|----------------|-----------|
| **Type:**      | integer   |
| **Default:**   | `0`       |
| **Condition:** | container |

<a id="device-unix-usb-device-conf:mode"></a>
`mode`

Mode of the device in the instance

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-unix-usb-device-conf:mode)

| **Key:**       | `mode`    |
|----------------|-----------|
| **Type:**      | integer   |
| **Default:**   | `0660`    |
| **Condition:** | container |

<a id="device-unix-usb-device-conf:productid"></a>
`productid`

Product ID of the USB device

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-unix-usb-device-conf:productid)

| **Key:**    | `productid`   |
|-------------|---------------|
| **Type:**   | string        |

<a id="device-unix-usb-device-conf:required"></a>
`required`

Whether this device is required to start the instance

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-unix-usb-device-conf:required)

| **Key:**     | `required`   |
|--------------|--------------|
| **Type:**    | bool         |
| **Default:** | `false`      |

The default is `false`, which means that all devices can be hotplugged.

<a id="device-unix-usb-device-conf:serial"></a>
`serial`

The serial number of the USB device

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-unix-usb-device-conf:serial)

| **Key:**    | `serial`   |
|-------------|------------|
| **Type:**   | string     |

<a id="device-unix-usb-device-conf:uid"></a>
`uid`

UID of the device owner in the instance

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-unix-usb-device-conf:uid)

| **Key:**       | `uid`     |
|----------------|-----------|
| **Type:**      | integer   |
| **Default:**   | `0`       |
| **Condition:** | container |

<a id="device-unix-usb-device-conf:vendorid"></a>
`vendorid`

Vendor ID of the USB device

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-unix-usb-device-conf:vendorid)

| **Key:**    | `vendorid`   |
|-------------|--------------|
| **Type:**   | string       |

## Configuration examples

Add a `usb` device to an instance by specifying its vendor ID and product ID:

```none
lxc config device add <instance_name> <device_name> usb vendorid=<vendor_ID> productid=<product_ID>
```

To determine the vendor ID and product ID, you can use **lsusb**, for example.

See [Configure devices](../howto/instances_configure.md#instances-configure-devices) for more information.


# index.html.md

<a id="devices-disk"></a>

# Type: `disk`


            <p class="youtube_link">
              <a href="https://www.youtube.com/watch?v=JhRw2OYTgtg" target="_blank">
                <span title="LXD disk devices" class="play_icon">▶</span>
                <span title="LXD disk devices">Watch on YouTube</span>
              </a>
            </p>
        
#### NOTE
The `disk` device type is supported for both containers and VMs.
It supports hotplugging for both containers and VMs.

Disk devices supply additional storage to instances.

For containers, they are essentially mount points inside the instance (either as a bind-mount of an existing file or directory on the host, or, if the source is a block device, a regular mount).
Virtual machines share host-side mounts or directories through `9p` or `virtiofs` (if available), or as VirtIO disks for block-based disks.

<a id="devices-disk-types"></a>

## Types of disk devices

You can create disk devices from different sources.
The value that you specify for the `source` option specifies the type of disk device that is added.
See [Configuration examples](#devices-disk-examples) for more detailed information on how to add each type of disk device.

Storage volume
: The most common type of disk device is a storage volume.
  Specify the storage volume name as the [`source`](#device-disk-device-conf:source) to add a storage volume as a disk device. \`virtual-machine’ storage volumes (and their snapshots) can also be attached as disk devices.

Path on the host
: You can share a path on your host (either a file system or a block device) to your instance.
  Specify the host path as the source to add it as a disk device.

Ceph RBD
: LXD can use Ceph to manage an internal file system for the instance, but if you have an existing, externally managed Ceph RBD that you would like to use for an instance, you can add it by specifying `ceph:<pool_name>/<volume_name>` as the source.

CephFS
: LXD can use Ceph to manage an internal file system for the instance, but if you have an existing, externally managed Ceph file system that you would like to use for an instance, you can add it by specifying `cephfs:<fs_name>/<path>` as the source.

ISO file
: You can add an ISO file as a disk device for a virtual machine by specifying its file path as the source.
  It is added as a ROM device inside the VM.
  <br/>
  This source type is applicable only to VMs.

<a id="vm-cloud-init-config"></a>

VM `cloud-init`
: You can generate a `cloud-init` configuration ISO from the [`cloud-init.vendor-data`](instance_options.md#instance-cloud-init:cloud-init.vendor-data) and [`cloud-init.user-data`](instance_options.md#instance-cloud-init:cloud-init.user-data) configuration keys and attach it to a virtual machine by specifying `cloud-init:config` as the source.
  The `cloud-init` that is running inside the VM then detects the drive on boot and applies the configuration.
  <br/>
  This source type is applicable only to VMs.
  <br/>
  Adding such a configuration disk might be needed if the VM image that is used includes `cloud-init` but not the `lxd-agent`. This is the case for official Ubuntu images prior to `20.04`. On such images, the following steps enable the LXD agent and thus provide the ability to use `lxc exec` to access the VM:
  <br/>
  ```none
  lxc init ubuntu-daily:18.04 --vm u1
  lxc config device add u1 config disk source=cloud-init:config
  lxc config set u1 cloud-init.user-data - << EOF
  #cloud-config
  #packages:
  #  - linux-image-virtual-hwe-16.04  # 16.04 GA kernel as a problem with vsock
  runcmd:
    - mount -t 9p config /mnt
    - cd /mnt
    - ./install.sh
    - cd /
    - umount /mnt
    - systemctl start lxd-agent  # XXX: causes a reboot
  EOF
  lxc start --console u1
  ```
  <br/>
  Note that for `16.04`, the HWE kernel is required to work around a problem with `vsock` (see the commented out section in the above `cloud-config`).

<a id="devices-disk-initial-config"></a>

## Initial volume configuration for instance root disk devices

Initial volume configuration allows setting specific configurations for the root disk devices of new instances.
These settings are prefixed with `initial.` and are only applied when the instance is created.
This method allows creating instances that have unique configurations, independent of the default storage pool settings.

For example, you can add an initial volume configuration for [`zfs.block_mode`](storage_zfs.md#storage-zfs-volume-conf:zfs.block_mode) to an existing profile, and this
will then take effect for each new instance you create using this profile:

```none
lxc profile device set <profile_name> <device_name> initial.zfs.block_mode=true
```

You can also set an initial configuration directly when creating an instance. For example:

```none
lxc init <image> <instance_name> --device <device_name>,initial.zfs.block_mode=true
```

Note that you cannot use initial volume configurations with custom volume options or to set the volume’s size (quota).

<a id="devices-disk-options"></a>

## Device options

`disk` devices have the following device options:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="device-disk-device-conf:boot.priority"></a>
`boot.priority`

Boot priority for VMs

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-disk-device-conf:boot.priority)

| **Key:**       | `boot.priority`   |
|----------------|-------------------|
| **Type:**      | integer           |
| **Condition:** | virtual machine   |
| **Required:**  | no                |

A higher value indicates a higher boot precedence for the disk device.
This is useful for prioritizing boot sources like ISO-backed disks.

<a id="device-disk-device-conf:ceph.cluster_name"></a>
`ceph.cluster_name`

Cluster name of the Ceph cluster

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-disk-device-conf:ceph.cluster_name)

| **Key:**      | `ceph.cluster_name`        |
|---------------|----------------------------|
| **Type:**     | string                     |
| **Default:**  | `ceph`                     |
| **Required:** | for Ceph or CephFS sources |

<a id="device-disk-device-conf:ceph.user_name"></a>
`ceph.user_name`

User name of the Ceph cluster

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-disk-device-conf:ceph.user_name)

| **Key:**      | `ceph.user_name`           |
|---------------|----------------------------|
| **Type:**     | string                     |
| **Default:**  | `admin`                    |
| **Required:** | for Ceph or CephFS sources |

<a id="device-disk-device-conf:initial.*"></a>
`initial.*`

Initial volume configuration

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-disk-device-conf:initial.*)

| **Key:**      | `initial.*`   |
|---------------|---------------|
| **Type:**     | n/a           |
| **Required:** | no            |

Initial volume configuration allows setting unique configurations independent of the default storage pool settings.
See [Initial volume configuration for instance root disk devices](#devices-disk-initial-config) for more information.

<a id="device-disk-device-conf:io.bus"></a>
`io.bus`

Bus for the device

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-disk-device-conf:io.bus)

| **Key:**       | `io.bus`        |
|----------------|-----------------|
| **Type:**      | string          |
| **Default:**   | `virtio-scsi`   |
| **Condition:** | virtual machine |
| **Required:**  | no              |

Possible values are `virtio-scsi`, `virtio-blk` or `nvme`.

<a id="device-disk-device-conf:io.cache"></a>
`io.cache`

Caching mode for the device

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-disk-device-conf:io.cache)

| **Key:**       | `io.cache`      |
|----------------|-----------------|
| **Type:**      | string          |
| **Default:**   | `none`          |
| **Condition:** | virtual machine |
| **Required:**  | no              |

Possible values are `none`, `writeback`, or `unsafe`.

<a id="device-disk-device-conf:io.threads"></a>
`io.threads`

Thread pool for virtiofs file system shares

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-disk-device-conf:io.threads)

| **Key:**       | `io.threads`    |
|----------------|-----------------|
| **Type:**      | integer         |
| **Default:**   | `0`             |
| **Condition:** | virtual machine |
| **Required:**  | no              |

This option controls the `virtiofsd` thread pool size, which can help improve I/O performance. Only applies to virtiofs file system shares.
In [`restricted`](projects.md#project-restricted:restricted) projects, it can only be used when [`restricted.virtual-machines.lowlevel`](projects.md#project-restricted:restricted.virtual-machines.lowlevel) is set to `allow`.

<a id="device-disk-device-conf:limits.max"></a>
`limits.max`

I/O limit in byte/s or IOPS for both read and write

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-disk-device-conf:limits.max)

| **Key:**      | `limits.max`   |
|---------------|----------------|
| **Type:**     | string         |
| **Required:** | no             |

This option is the same as setting both [`limits.read`](#device-disk-device-conf:limits.read) and [`limits.write`](#device-disk-device-conf:limits.write).

You can specify a value in byte/s (various suffixes supported, see [Units for storage and network limits](instance_units.md#instances-limit-units)) or in IOPS (must be suffixed with `iops`).
See also storage-configure-io.

<a id="device-disk-device-conf:limits.read"></a>
`limits.read`

Read I/O limit in byte/s or IOPS

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-disk-device-conf:limits.read)

| **Key:**      | `limits.read`   |
|---------------|-----------------|
| **Type:**     | string          |
| **Required:** | no              |

You can specify a value in byte/s (various suffixes supported, see [Units for storage and network limits](instance_units.md#instances-limit-units)) or in IOPS (must be suffixed with `iops`).
See also storage-configure-io.

<a id="device-disk-device-conf:limits.write"></a>
`limits.write`

Write I/O limit in byte/s or IOPS

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-disk-device-conf:limits.write)

| **Key:**      | `limits.write`   |
|---------------|------------------|
| **Type:**     | string           |
| **Required:** | no               |

You can specify a value in byte/s (various suffixes supported, see [Units for storage and network limits](instance_units.md#instances-limit-units)) or in IOPS (must be suffixed with `iops`).
See also storage-configure-io.

<a id="device-disk-device-conf:path"></a>
`path`

Mount path

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-disk-device-conf:path)

| **Key:**       | `path`    |
|----------------|-----------|
| **Type:**      | string    |
| **Condition:** | container |
| **Required:**  | yes       |

This option specifies the path inside the container where the disk will be mounted.
For containers, this option allows mounting filesystem disk devices, as well as specific paths and individual files within those devices.
For VMs, this option allows mounting filesystem disk devices and paths within them. Mounting individual files is not supported.

<a id="device-disk-device-conf:pool"></a>
`pool`

Storage pool to which the disk device belongs

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-disk-device-conf:pool)

| **Key:**       | `pool`                         |
|----------------|--------------------------------|
| **Type:**      | string                         |
| **Condition:** | storage volumes managed by LXD |
| **Required:**  | no                             |

<a id="device-disk-device-conf:propagation"></a>
`propagation`

How a bind-mount is shared between the instance and the host

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-disk-device-conf:propagation)

| **Key:**      | `propagation`   |
|---------------|-----------------|
| **Type:**     | string          |
| **Default:**  | `private`       |
| **Required:** | no              |

Possible values are `private` (the default), `shared`, `slave`, `unbindable`, `rshared`, `rslave`, `runbindable`, `rprivate`.
See the Linux Kernel [shared subtree](https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt) documentation for a full explanation.

<a id="device-disk-device-conf:raw.mount.options"></a>
`raw.mount.options`

File system specific mount options

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-disk-device-conf:raw.mount.options)

| **Key:**      | `raw.mount.options`   |
|---------------|-----------------------|
| **Type:**     | string                |
| **Required:** | no                    |

<a id="device-disk-device-conf:readonly"></a>
`readonly`

Whether to make the mount read-only

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-disk-device-conf:readonly)

| **Key:**      | `readonly`   |
|---------------|--------------|
| **Type:**     | bool         |
| **Default:**  | `false`      |
| **Required:** | no           |

<a id="device-disk-device-conf:recursive"></a>
`recursive`

Whether to recursively mount the source path

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-disk-device-conf:recursive)

| **Key:**      | `recursive`   |
|---------------|---------------|
| **Type:**     | bool          |
| **Default:**  | `false`       |
| **Required:** | no            |

<a id="device-disk-device-conf:required"></a>
`required`

Whether to fail if the source doesn’t exist

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-disk-device-conf:required)

| **Key:**      | `required`   |
|---------------|--------------|
| **Type:**     | bool         |
| **Default:**  | `true`       |
| **Required:** | no           |

<a id="device-disk-device-conf:shift"></a>
`shift`

Whether to set up a UID/GID shifting overlay

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-disk-device-conf:shift)

| **Key:**       | `shift`   |
|----------------|-----------|
| **Type:**      | bool      |
| **Default:**   | `false`   |
| **Condition:** | container |
| **Required:**  | no        |

If enabled, this option sets up a shifting overlay to translate the source UID/GID to match the container instance.

<a id="device-disk-device-conf:size"></a>
`size`

Disk size

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-disk-device-conf:size)

| **Key:**      | `size`   |
|---------------|----------|
| **Type:**     | string   |
| **Required:** | no       |

This option is supported only for the rootfs (`/`).

Specify a value in bytes (various suffixes supported, see [Units for storage and network limits](instance_units.md#instances-limit-units)).

<a id="device-disk-device-conf:size.state"></a>
`size.state`

Size of the file-system volume used for saving runtime state

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-disk-device-conf:size.state)

| **Key:**       | `size.state`    |
|----------------|-----------------|
| **Type:**      | string          |
| **Condition:** | virtual machine |
| **Required:**  | no              |

This option is similar to [`size`](#device-disk-device-conf:size), but applies to the file-system volume used for saving the runtime state in VMs.

<a id="device-disk-device-conf:source"></a>
`source`

Source of a file system or block device

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-disk-device-conf:source)

| **Key:**      | `source`   |
|---------------|------------|
| **Type:**     | string     |
| **Required:** | yes        |

See [Types of disk devices](#devices-disk-types) for details.

<a id="device-disk-device-conf:source.snapshot"></a>
`source.snapshot`

`source` snapshot name

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-disk-device-conf:source.snapshot)

| **Key:**      | `source.snapshot`   |
|---------------|---------------------|
| **Type:**     | string              |
| **Required:** | no                  |

Snapshot of the volume given by `source`.

<a id="device-disk-device-conf:source.type"></a>
`source.type`

Type of the backing storage volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-disk-device-conf:source.type)

| **Key:**      | `source.type`   |
|---------------|-----------------|
| **Type:**     | string          |
| **Default:**  | `custom`        |
| **Required:** | no              |

Possible values are `custom` (the default) or `virtual-machine`. This
key is only valid when `source` is the name of a storage volume.

<a id="devices-disk-examples"></a>

## Configuration examples

How to add a disk device depends on its [type](#devices-disk-types).

Storage volume
: To add a storage volume, specify its name as the `source` of the device:
  <br/>
  ```none
  lxc config device add <instance_name> <device_name> disk pool=<pool_name> source=<volume_name> [path=<path_in_instance>]
  ```
  <br/>
  The path is required for file system volumes, but not for block volumes.
  <br/>
  Alternatively, you can use the [`lxc storage volume attach`](manpages/lxc/storage/volume/attach.md#lxc-storage-volume-attach-md) command to [Attach the volume to an instance](../howto/storage_volumes.md#storage-attach-volume).
  Both commands use the same mechanism to add a storage volume as a disk device.

Path on the host
: To add a host device, specify the host path as the `source`:
  <br/>
  ```none
  lxc config device add <instance_name> <device_name> disk source=<path_on_host> [path=<path_in_instance>]
  ```
  <br/>
  The path is required for file systems, but not for block devices.

Ceph RBD
: To add an existing Ceph RBD volume, specify its pool and volume name:
  <br/>
  ```none
  lxc config device add <instance_name> <device_name> disk source=ceph:<pool_name>/<volume_name> ceph.user_name=<user_name> ceph.cluster_name=<cluster_name> [path=<path_in_instance>]
  ```
  <br/>
  The path is required for file systems, but not for block devices.

CephFS
: To add an existing CephFS file system, specify its name and path:
  <br/>
  ```none
  lxc config device add <instance_name> <device_name> disk source=cephfs:<fs_name>/<path> ceph.user_name=<user_name> ceph.cluster_name=<cluster_name> path=<path_in_instance>
  ```

ISO file
: To add an ISO file, specify its file path as the `source`:
  <br/>
  ```none
  lxc config device add <instance_name> <device_name> disk source=<file_path_on_host>
  ```

VM `cloud-init`
: To add `cloud-init` configuration, specify `cloud-init:config` as the source:
  <br/>
  ```none
  lxc config device add <instance_name> <device_name> disk source=cloud-init:config
  ```

See [Configure devices](../howto/instances_configure.md#instances-configure-devices) for more information.


# index.html.md

<a id="instances-limit-units"></a>

# Units for storage and network limits

Any value that represents bytes or bits can make use of a number of suffixes to make it easier to understand what a particular limit is.

Both decimal and binary (kibi) units are supported, with the latter mostly making sense for storage limits.

The full list of bit suffixes currently supported is:

- bit (1)
- kbit (1000)
- Mbit (1000^2)
- Gbit (1000^3)
- Tbit (1000^4)
- Pbit (1000^5)
- Ebit (1000^6)
- Kibit (1024)
- Mibit (1024^2)
- Gibit (1024^3)
- Tibit (1024^4)
- Pibit (1024^5)
- Eibit (1024^6)

The full list of byte suffixes currently supported is:

- B or bytes (1)
- kB (1000)
- MB (1000^2)
- GB (1000^3)
- TB (1000^4)
- PB (1000^5)
- EB (1000^6)
- KiB (1024)
- MiB (1024^2)
- GiB (1024^3)
- TiB (1024^4)
- PiB (1024^5)
- EiB (1024^6)


# index.html.md

<a id="remote-image-servers"></a>

# Remote image servers

The [`lxc`](manpages/lxc.md#lxc-md) CLI command comes pre-configured with the following default remote image servers:

`images:`
: This server provides unofficial images for a variety of Linux distributions.
  The images are built to be compact and minimal, and therefore the default image variants do not include `cloud-init`.
  Where possible, `/cloud` variants that include `cloud-init` are provided.
  See [`cloud-init` support in images](../cloud-init.md#cloud-init-support).
  <br/>
  This server does not provide official Ubuntu images (for those, use the `ubuntu:` server).
  It does, however, provide desktop variants of current Ubuntu releases.
  <br/>
  See [`images.lxd.canonical.com`](https://images.lxd.canonical.com) for an overview of available images.

`ubuntu:`
: This server provides official stable Ubuntu images.
  All images are cloud images, which means that they include both `cloud-init` and the `lxd-agent`.
  <br/>
  See [`cloud-images.ubuntu.com/releases`](https://cloud-images.ubuntu.com/releases/) for an overview of available images.

`ubuntu-daily:`
: This server provides official daily Ubuntu images.
  All images are cloud images, which means that they include both `cloud-init` and the `lxd-agent`.
  <br/>
  See [`cloud-images.ubuntu.com/daily`](https://cloud-images.ubuntu.com/daily/) for an overview of available images.

`ubuntu-minimal:`
: This server provides official Ubuntu Minimal images.
  All images are cloud images, which means that they include both `cloud-init` and the `lxd-agent`.
  <br/>
  See [`cloud-images.ubuntu.com/minimal/releases`](https://cloud-images.ubuntu.com/minimal/releases/) for an overview of available images.

`ubuntu-minimal-daily:`
: This server provides official daily Ubuntu Minimal images.
  All images are cloud images, which means that they include both `cloud-init` and the `lxd-agent`.
  <br/>
  See [`cloud-images.ubuntu.com/minimal/daily`](https://cloud-images.ubuntu.com/minimal/daily/) for an overview of available images.

<a id="remote-image-server-types"></a>

## Remote server types

LXD supports the following types of remote image servers:

Simple streams servers
: Pure image servers that use the [simple streams format](https://git.launchpad.net/simplestreams/tree/).
  The default image servers are simple streams servers.

Public LXD servers
: LXD servers that are used solely to serve images and do not run instances themselves.
  <br/>
  To make a LXD server publicly available over the network on port 8443, set the [`core.https_address`](../server.md#server-core:core.https_address) configuration option to `:8443` and do not configure any authentication methods (see [How to expose LXD to the network](../howto/server_expose.md#server-expose) for more information).
  Then set the images that you want to share to `public`.

LXD servers
: Regular LXD servers that you can manage over a network, and that can also be used as image servers.
  <br/>
  For security reasons, you should restrict the access to the remote API and configure an authentication method to control access.
  See [How to expose LXD to the network](../howto/server_expose.md#server-expose) and [Remote API authentication](../authentication.md#authentication) for more information.

## Related topics

How-to guides:

- [Images](../images.md#images)

Explanation:

- [Local and remote images](../image-handling.md#about-images)


# index.html.md

<a id="ref-cluster-link-config"></a>

# Cluster link configuration

Each cluster link has its own key/value configuration with the following supported namespaces:

- [Miscellaneous options](#ref-cluster-link-config-misc)
- [Volatile internal data](#ref-cluster-link-config-volatile)

<a id="ref-cluster-link-config-misc"></a>

## Miscellaneous options

The following keys are currently supported:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="cluster-link-conf:user.*"></a>
`user.*`

Free form user key/value storage

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#cluster-link-conf:user.*)

| **Key:**    | `user.*`   |
|-------------|------------|
| **Type:**   | string     |

User keys can be used in search.

<a id="ref-cluster-link-config-volatile"></a>

## Volatile internal data

#### WARNING
The `volatile.*` keys cannot be manipulated by the user. Do not attempt to modify these keys in any way. LXD modifies these keys, and attempting to manipulate them yourself might break LXD in non-obvious ways.

The following volatile keys are currently used internally by LXD to store internal data specific to a cluster link:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="cluster-link-volatile-conf:volatile.addresses"></a>
`volatile.addresses`

Cluster link member addresses.

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#cluster-link-volatile-conf:volatile.addresses)

| **Key:**    | `volatile.addresses`   |
|-------------|------------------------|
| **Type:**   | string                 |
| **Scope:**  | global                 |

A comma-separated list of cluster link member addresses.

## Related topics

How-to guides:

- [Clustering](../clustering.md#clustering)

Explanation:

- [Clusters](../explanation/clusters.md#exp-clusters)


# index.html.md

<a id="devices-gpu"></a>

# Type: `gpu`


            <p class="youtube_link">
              <a href="https://www.youtube.com/watch?v=T0aV2LsMpoA" target="_blank">
                <span title="LXD and the NVIDIA A100" class="play_icon">▶</span>
                <span title="LXD and the NVIDIA A100">Watch on YouTube</span>
              </a>
            </p>
        
GPU devices make the specified GPU device or devices appear in the instance.

#### NOTE
For containers, a `gpu` device may match multiple GPUs at once.
For VMs, each device can match only a single GPU.

The following types of GPUs can be added using the `gputype` device option:

- [`physical`](#gpu-physical) (container and VM): Passes an entire GPU through into the instance.
  This value is the default if `gputype` is unspecified.
- [`mdev`](#gpu-mdev) (VM only): Creates and passes a virtual GPU (vGPU) through into the instance.
- [`mig`](#gpu-mig) (container only): Creates and passes a MIG (Multi-Instance GPU) through into the instance.
- [`sriov`](#gpu-sriov) (VM only): Passes a virtual function of an SR-IOV-enabled GPU into the instance.

The available device options depend on the GPU type and are listed in the tables in the following sections.

<a id="gpu-physical"></a>

## `gputype`: `physical`

#### NOTE
The `physical` GPU type is supported for both containers and VMs.
It supports hotplugging only for containers, not for VMs.

A `physical` GPU device passes an entire GPU through into the instance.

### Device options

GPU devices of type `physical` have the following device options:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="device-gpu-physical-device-conf:gid"></a>
`gid`

GID of the device owner in the container

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-gpu-physical-device-conf:gid)

| **Key:**       | `gid`     |
|----------------|-----------|
| **Type:**      | integer   |
| **Default:**   | `0`       |
| **Condition:** | container |

<a id="device-gpu-physical-device-conf:id"></a>
`id`

ID of the GPU device

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-gpu-physical-device-conf:id)

| **Key:**    | `id`   |
|-------------|--------|
| **Type:**   | string |

The ID can either be the DRM card ID of the GPU device (container or VM) or a fully-qualified Container Device Interface (CDI) name (container only).
Here are some examples of fully-qualified CDI names:

- `nvidia.com/gpu=0`: Instructs LXD to operate a discrete GPU (dGPU) pass-through of brand NVIDIA with the first discovered GPU on your system. You can use the `nvidia-smi` tool on your host to find out which identifier to use.
- `nvidia.com/gpu=1833c8b5-9aa0-5382-b784-68b7e77eb185`: Instructs LXD to operate a discrete GPU (dGPU) pass-through of brand NVIDIA with a given GPU unique identifier. This identifier should also appear with `nvidia-smi -L`.
- `nvidia.com/igpu=all`: Instructs LXD to pass all the host integrated GPUs (iGPU) of brand NVIDIA. The concept of an index does not currently map to iGPUs. It is possible to list them with the `nvidia-smi -L` command. A special `nvgpu` mention should appear in the generated list to indicate a device to be an iGPU.
- `nvidia.com/gpu=all`: Instructs LXD to pass all the host GPUs of brand NVIDIA through to the container.

<a id="device-gpu-physical-device-conf:mode"></a>
`mode`

Mode of the device in the container

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-gpu-physical-device-conf:mode)

| **Key:**       | `mode`    |
|----------------|-----------|
| **Type:**      | integer   |
| **Default:**   | `0660`    |
| **Condition:** | container |

<a id="device-gpu-physical-device-conf:pci"></a>
`pci`

PCI address of the GPU device

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-gpu-physical-device-conf:pci)

| **Key:**    | `pci`   |
|-------------|---------|
| **Type:**   | string  |

<a id="device-gpu-physical-device-conf:productid"></a>
`productid`

Product ID of the GPU device

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-gpu-physical-device-conf:productid)

| **Key:**    | `productid`   |
|-------------|---------------|
| **Type:**   | string        |

<a id="device-gpu-physical-device-conf:uid"></a>
`uid`

UID of the device owner in the container

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-gpu-physical-device-conf:uid)

| **Key:**       | `uid`     |
|----------------|-----------|
| **Type:**      | integer   |
| **Default:**   | `0`       |
| **Condition:** | container |

<a id="device-gpu-physical-device-conf:vendorid"></a>
`vendorid`

Vendor ID of the GPU device

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-gpu-physical-device-conf:vendorid)

| **Key:**    | `vendorid`   |
|-------------|--------------|
| **Type:**   | string       |

### Configuration examples

Add all GPUs from the host system as a `physical` GPU device to an instance:

```none
lxc config device add <instance_name> <device_name> gpu gputype=physical
```

Add a specific GPU from the host system as a `physical` GPU device to an instance by specifying its PCI address:

```none
lxc config device add <instance_name> <device_name> gpu gputype=physical pci=<pci_address>
```

See [Configure devices](../howto/instances_configure.md#instances-configure-devices) for more information.

<a id="gpu-physical-cdi"></a>

#### CDI mode

#### NOTE
The CDI mode is currently not supported on `armhf` architectures.

Add a specific GPU from the host system as a `physical` GPU device to an instance using the [Container Device Interface](https://github.com/cncf-tags/container-device-interface) (CDI) notation through a fully-qualified CDI name:

```none
lxc config device add <instance_name> <device_name> gpu gputype=physical id=<fully_qualified_CDI_name>
```

For example, add the first available NVIDIA discrete GPU on your system:

```none
lxc config device add <instance_name> <device_name> gpu gputype=physical id=nvidia.com/gpu=0
```

If your machine has an NVIDIA iGPU (integrated GPU) located at index 0, you can add it like this:

```none
lxc config device add <instance_name> <device_name> gpu gputype=physical id=nvidia.com/igpu=0
```

Similarly, for AMD GPUs using CDI, you can add the first available discrete GPU or all GPUs:

```none
lxc config device add <instance_name> <device_name> gpu gputype=physical id=amd.com/gpu=0
```

Or pass all AMD GPUs from the host:

```none
lxc config device add <instance_name> <device_name> gpu gputype=physical id=amd.com/gpu=all
```

For a complete example on how to use a GPU CDI pass-through, see [How to pass an NVIDIA GPU to a container](../howto/container_gpu_passthrough_with_docker.md#container-gpu-passthrough-with-docker).

<a id="gpu-mdev"></a>

## `gputype`: `mdev`

#### NOTE
The `mdev` GPU type is supported only for VMs.
It does not support hotplugging.

An `mdev` GPU device creates and passes a virtual GPU (vGPU) through into the instance.
You can check the list of available `mdev` profiles by running [`lxc info --resources`](manpages/lxc/info.md#lxc-info-md).

### Device options

GPU devices of type `mdev` have the following device options:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="device-gpu-mdev-device-conf:id"></a>
`id`

DRM card ID of the GPU device

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-gpu-mdev-device-conf:id)

| **Key:**    | `id`   |
|-------------|--------|
| **Type:**   | string |

<a id="device-gpu-mdev-device-conf:mdev"></a>
`mdev`

The `mdev` profile to use

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-gpu-mdev-device-conf:mdev)

| **Key:**      | `mdev`   |
|---------------|----------|
| **Type:**     | string   |
| **Default:**  | `0`      |
| **Required:** | yes      |

For example: `i915-GVTg_V5_4`

<a id="device-gpu-mdev-device-conf:pci"></a>
`pci`

PCI address of the GPU device

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-gpu-mdev-device-conf:pci)

| **Key:**    | `pci`   |
|-------------|---------|
| **Type:**   | string  |

<a id="device-gpu-mdev-device-conf:productid"></a>
`productid`

Product ID of the GPU device

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-gpu-mdev-device-conf:productid)

| **Key:**    | `productid`   |
|-------------|---------------|
| **Type:**   | string        |

<a id="device-gpu-mdev-device-conf:vendorid"></a>
`vendorid`

Vendor ID of the GPU device

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-gpu-mdev-device-conf:vendorid)

| **Key:**    | `vendorid`   |
|-------------|--------------|
| **Type:**   | string       |

### Configuration examples

Add an `mdev` GPU device to an instance by specifying its `mdev` profile and the PCI address of the GPU:

```none
lxc config device add <instance_name> <device_name> gpu gputype=mdev mdev=<mdev_profile> pci=<pci_address>
```

See [Configure devices](../howto/instances_configure.md#instances-configure-devices) for more information.

<a id="gpu-mig"></a>

## `gputype`: `mig`

#### NOTE
The `mig` GPU type is supported only for containers.
It does not support hotplugging.

A `mig` GPU device creates and passes a MIG compute instance through into the instance.
Currently, this requires NVIDIA MIG instances to be pre-created.

### Device options

GPU devices of type `mig` have the following device options:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="device-gpu-mig-device-conf:id"></a>
`id`

DRM card ID of the GPU device

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-gpu-mig-device-conf:id)

| **Key:**    | `id`   |
|-------------|--------|
| **Type:**   | string |

<a id="device-gpu-mig-device-conf:mig.ci"></a>
`mig.ci`

Existing MIG compute instance ID

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-gpu-mig-device-conf:mig.ci)

| **Key:**    | `mig.ci`   |
|-------------|------------|
| **Type:**   | integer    |

<a id="device-gpu-mig-device-conf:mig.gi"></a>
`mig.gi`

Existing MIG GPU instance ID

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-gpu-mig-device-conf:mig.gi)

| **Key:**    | `mig.gi`   |
|-------------|------------|
| **Type:**   | integer    |

<a id="device-gpu-mig-device-conf:mig.uuid"></a>
`mig.uuid`

Existing MIG device UUID

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-gpu-mig-device-conf:mig.uuid)

| **Key:**    | `mig.uuid`   |
|-------------|--------------|
| **Type:**   | string       |

You can omit the `MIG-` prefix when specifying this option.

<a id="device-gpu-mig-device-conf:pci"></a>
`pci`

PCI address of the GPU device

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-gpu-mig-device-conf:pci)

| **Key:**    | `pci`   |
|-------------|---------|
| **Type:**   | string  |

<a id="device-gpu-mig-device-conf:productid"></a>
`productid`

Product ID of the GPU device

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-gpu-mig-device-conf:productid)

| **Key:**    | `productid`   |
|-------------|---------------|
| **Type:**   | string        |

<a id="device-gpu-mig-device-conf:vendorid"></a>
`vendorid`

Vendor ID of the GPU device

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-gpu-mig-device-conf:vendorid)

| **Key:**    | `vendorid`   |
|-------------|--------------|
| **Type:**   | string       |

You must set either [`mig.uuid`](#device-gpu-mig-device-conf:mig.uuid) (NVIDIA drivers 470+) or both [`mig.ci`](#device-gpu-mig-device-conf:mig.ci) and [`mig.gi`](#device-gpu-mig-device-conf:mig.gi) (old NVIDIA drivers).

### Configuration examples

Add a `mig` GPU device to an instance by specifying its UUID and the PCI address of the GPU:

```none
lxc config device add <instance_name> <device_name> gpu gputype=mig mig.uuid=<mig_uuid> pci=<pci_address>
```

See [Configure devices](../howto/instances_configure.md#instances-configure-devices) for more information.

<a id="gpu-sriov"></a>

## `gputype`: `sriov`

#### NOTE
The `sriov` GPU type is supported only for VMs.
It does not support hotplugging.

An `sriov` GPU device passes a virtual function of an SR-IOV-enabled GPU into the instance.

### Device options

GPU devices of type `sriov` have the following device options:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="device-gpu-sriov-device-conf:id"></a>
`id`

DRM card ID of the parent GPU device

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-gpu-sriov-device-conf:id)

| **Key:**    | `id`   |
|-------------|--------|
| **Type:**   | string |

<a id="device-gpu-sriov-device-conf:pci"></a>
`pci`

PCI address of the parent GPU device

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-gpu-sriov-device-conf:pci)

| **Key:**    | `pci`   |
|-------------|---------|
| **Type:**   | string  |

<a id="device-gpu-sriov-device-conf:productid"></a>
`productid`

Product ID of the parent GPU device

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-gpu-sriov-device-conf:productid)

| **Key:**    | `productid`   |
|-------------|---------------|
| **Type:**   | string        |

<a id="device-gpu-sriov-device-conf:vendorid"></a>
`vendorid`

Vendor ID of the parent GPU device

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-gpu-sriov-device-conf:vendorid)

| **Key:**    | `vendorid`   |
|-------------|--------------|
| **Type:**   | string       |

### Configuration examples

Add a `sriov` GPU device to an instance by specifying the PCI address of the parent GPU:

```none
lxc config device add <instance_name> <device_name> gpu gputype=sriov pci=<pci_address>
```

See [Configure devices](../howto/instances_configure.md#instances-configure-devices) for more information.

## Related topics

- [How to pass an NVIDIA GPU to a container](../howto/container_gpu_passthrough_with_docker.md#container-gpu-passthrough-with-docker)
- [Why does my VM stop responding when I try to pass through a GPU?](../faq.md#faq-gpu-passthrough-stop)


# index.html.md

<a id="dqlite-internals"></a>

# Dqlite internals

Dqlite (distributed SQLite) implements a replicated SQLite database by combining the SQLite engine with a Raft-based consensus layer. Each LXD daemon (cluster member) runs a Dqlite node which exposes a SQLite-like API backed by a Raft replicated state machine. A single leader handles writes; followers apply replicated log entries and serve reads depending on configuration.

## Raft

[Raft](https://raft.github.io/) is a consensus algorithm that ensures a cluster of nodes can agree on a sequence of state machine commands even in the presence of failures. Raft handles leader election, log replication, safety, and membership changes.

## Dqlite Raft implementation

Raft nodes in Dqlite move between four runtime states: `RAFT_UNAVAILABLE`, `RAFT_FOLLOWER`, `RAFT_CANDIDATE` and `RAFT_LEADER`. Followers are passive: they accept `AppendEntries` RPCs (remote procedure calls) from an active leader and reset an election timer; when a follower’s randomized election timeout elapses without leader contact it becomes a candidate, increments its term and sends `RequestVote` RPCs to gather votes. A candidate becomes leader after receiving votes from a majority of voting servers and then starts replicating log entries to followers using `AppendEntries` (heartbeats are empty `AppendEntries` used to maintain authority).

The election timeout is randomized, but always shorter than the heartbeat interval. Features such as pre-vote and explicit leadership transfer ensure reliable handover even if all servers cannot vote. Leaders also step down if they lose contact with a majority of voters. The [Dqlite raft roles](#dqlite-internals-raft-roles) control whether a server participates in quorum and elections.

For more information on the Canonical Dqlite Raft implementation, see [`dqlite/src/raft.h`](https://github.com/canonical/dqlite/blob/main/src/raft.h) and [Dqlite replication](https://canonical.com/dqlite/docs/explanation/replication).

<a id="dqlite-internals-raft-roles"></a>

### Dqlite raft roles

1. `RAFT_VOTER`: Replicates the log and participates in quorum/elections.
2. `RAFT_STANDBY`: Replicates the log but does not participate in quorum/elections.
3. `RAFT_SPARE`: Does not replicate the log and does not participate in quorum/elections.

<a id="dqlite-internals-lxd-cluster-roles"></a>

### LXD cluster roles

LXD assigns database roles to cluster members based on their Dqlite Raft role:

1. `database-voter`: Assigned to cluster members with the `RAFT_VOTER` role (excluding the leader).
2. `database-standby`: Assigned to cluster members with the `RAFT_STANDBY` role.
3. `database-leader`: Assigned to the current Raft leader.

LXD also provides a `control-plane` role that restricts which members can be assigned Raft roles. When 3 or more members have the `control-plane` role assigned, members without it are assigned the `RAFT_SPARE` role and excluded from automatic promotion. The [`cluster.max_voters`](../server.md#server-cluster:cluster.max_voters) and [`cluster.max_standby`](../server.md#server-cluster:cluster.max_standby) settings determine how many control-plane members are promoted to `RAFT_VOTER` and `RAFT_STANDBY` roles. If control plane members exceed these limits, the extras remain as promotion candidates.


# index.html.md

<a id="network-physical"></a>

# Physical network

<!-- Include start physical intro -->

The `physical` network type connects to an existing physical network, which can be a network interface or a bridge, and serves as an uplink network for OVN.

<!-- Include end physical intro -->

This network type allows to specify presets to use when connecting OVN networks to a parent interface or to allow an instance to use a physical interface as a NIC.
In this case, the instance NICs can simply set the `network`option to the network they connect to without knowing any of the underlying configuration details.

<a id="network-physical-options"></a>

## Configuration options

The following configuration key namespaces are currently supported for the `physical` network type:

- `bgp` (BGP peer configuration)
- `dns` (DNS server and resolution configuration)
- `ipv4` (L3 IPv4 configuration)
- `ipv6` (L3 IPv6 configuration)
- `ovn` (OVN configuration)
- `user` (free-form key/value for user metadata)

#### NOTE
LXD uses the [CIDR notation](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing) where network subnet information is required, for example, `192.0.2.0/24` or `2001:db8::/32`. This does not apply to cases where a single address is required, for example, local/remote addresses of tunnels, NAT addresses or specific addresses to apply to an instance.

The following configuration options are available for the `physical` network type:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="network-physical-network-conf:bgp.peers.NAME.address"></a>
`bgp.peers.NAME.address`

Peer address for use by `ovn` downstream networks

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-physical-network-conf:bgp.peers.NAME.address)

| **Key:**       | `bgp.peers.NAME.address`   |
|----------------|----------------------------|
| **Type:**      | string                     |
| **Condition:** | BGP server                 |
| **Scope:**     | global                     |

The address can be IPv4 or IPv6.

<a id="network-physical-network-conf:bgp.peers.NAME.asn"></a>
`bgp.peers.NAME.asn`

Peer AS number for use by `ovn` downstream networks

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-physical-network-conf:bgp.peers.NAME.asn)

| **Key:**       | `bgp.peers.NAME.asn`   |
|----------------|------------------------|
| **Type:**      | integer                |
| **Condition:** | BGP server             |
| **Scope:**     | global                 |

<a id="network-physical-network-conf:bgp.peers.NAME.holdtime"></a>
`bgp.peers.NAME.holdtime`

Peer session hold time

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-physical-network-conf:bgp.peers.NAME.holdtime)

| **Key:**       | `bgp.peers.NAME.holdtime`   |
|----------------|-----------------------------|
| **Type:**      | integer                     |
| **Default:**   | `180`                       |
| **Condition:** | BGP server                  |
| **Required:**  | no                          |
| **Scope:**     | global                      |

Specify the peer session hold time in seconds.

<a id="network-physical-network-conf:bgp.peers.NAME.password"></a>
`bgp.peers.NAME.password`

Peer session password for use by `ovn` downstream networks

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-physical-network-conf:bgp.peers.NAME.password)

| **Key:**       | `bgp.peers.NAME.password`   |
|----------------|-----------------------------|
| **Type:**      | string                      |
| **Default:**   | (no password)               |
| **Condition:** | BGP server                  |
| **Required:**  | no                          |
| **Scope:**     | global                      |

<a id="network-physical-network-conf:dns.nameservers"></a>
`dns.nameservers`

DNS server IPs on physical network

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-physical-network-conf:dns.nameservers)

| **Key:**       | `dns.nameservers`   |
|----------------|---------------------|
| **Type:**      | string              |
| **Condition:** | standard mode       |
| **Scope:**     | global              |

Specify a list of DNS server IPs.

<a id="network-physical-network-conf:gvrp"></a>
`gvrp`

Whether to use GARP VLAN Registration Protocol

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-physical-network-conf:gvrp)

| **Key:**     | `gvrp`   |
|--------------|----------|
| **Type:**    | bool     |
| **Default:** | `false`  |
| **Scope:**   | global   |

This option specifies whether to register the VLAN using the GARP VLAN Registration Protocol.

<a id="network-physical-network-conf:ipv4.gateway"></a>
`ipv4.gateway`

IPv4 address for the gateway and network

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-physical-network-conf:ipv4.gateway)

| **Key:**       | `ipv4.gateway`   |
|----------------|------------------|
| **Type:**      | string           |
| **Condition:** | standard mode    |
| **Scope:**     | global           |

Use CIDR notation.

<a id="network-physical-network-conf:ipv4.ovn.ranges"></a>
`ipv4.ovn.ranges`

IPv4 ranges to use for child OVN network routers

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-physical-network-conf:ipv4.ovn.ranges)

| **Key:**    | `ipv4.ovn.ranges`   |
|-------------|---------------------|
| **Type:**   | string              |
| **Scope:**  | global              |

Specify a comma-separated list of IPv4 ranges in FIRST-LAST format.

<a id="network-physical-network-conf:ipv4.routes"></a>
`ipv4.routes`

Additional IPv4 CIDR subnets

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-physical-network-conf:ipv4.routes)

| **Key:**       | `ipv4.routes`   |
|----------------|-----------------|
| **Type:**      | string          |
| **Condition:** | IPv4 address    |
| **Scope:**     | global          |

Specify a comma-separated list of IPv4 CIDR subnets that can be used with child OVN network forwarders, load-balancers and [`ipv4.routes.external`](devices_nic.md#device-nic-ovn-device-conf:ipv4.routes.external) setting.

<a id="network-physical-network-conf:ipv4.routes.anycast"></a>
`ipv4.routes.anycast`

Whether to allow IPv4 routes on multiple networks/NICs

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-physical-network-conf:ipv4.routes.anycast)

| **Key:**       | `ipv4.routes.anycast`   |
|----------------|-------------------------|
| **Type:**      | bool                    |
| **Default:**   | `false`                 |
| **Condition:** | IPv4 address            |
| **Scope:**     | global                  |

If set to `true`, this option allows the overlapping routes to be used on multiple networks/NICs at the same time.

<a id="network-physical-network-conf:ipv6.gateway"></a>
`ipv6.gateway`

IPv6 address for the gateway and network

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-physical-network-conf:ipv6.gateway)

| **Key:**       | `ipv6.gateway`   |
|----------------|------------------|
| **Type:**      | string           |
| **Condition:** | standard mode    |
| **Scope:**     | global           |

Use CIDR notation.

<a id="network-physical-network-conf:ipv6.ovn.ranges"></a>
`ipv6.ovn.ranges`

IPv6 ranges to use for child OVN network routers

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-physical-network-conf:ipv6.ovn.ranges)

| **Key:**    | `ipv6.ovn.ranges`   |
|-------------|---------------------|
| **Type:**   | string              |
| **Scope:**  | global              |

Specify a comma-separated list of IPv6 ranges in FIRST-LAST format.

<a id="network-physical-network-conf:ipv6.routes"></a>
`ipv6.routes`

Additional IPv6 CIDR subnets

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-physical-network-conf:ipv6.routes)

| **Key:**       | `ipv6.routes`   |
|----------------|-----------------|
| **Type:**      | string          |
| **Condition:** | IPv6 address    |
| **Scope:**     | global          |

Specify a comma-separated list of IPv6 CIDR subnets that can be used with child OVN network forwarders, load-balancers and [`ipv6.routes.external`](devices_nic.md#device-nic-ovn-device-conf:ipv6.routes.external) setting.

<a id="network-physical-network-conf:ipv6.routes.anycast"></a>
`ipv6.routes.anycast`

Whether to allow IPv6 routes on multiple networks/NICs

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-physical-network-conf:ipv6.routes.anycast)

| **Key:**       | `ipv6.routes.anycast`   |
|----------------|-------------------------|
| **Type:**      | bool                    |
| **Default:**   | `false`                 |
| **Condition:** | IPv6 address            |
| **Scope:**     | global                  |

If set to `true`, this option allows the overlapping routes to be used on multiple networks/NICs at the same time.

<a id="network-physical-network-conf:mtu"></a>
`mtu`

MTU of the new interface

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-physical-network-conf:mtu)

| **Key:**    | `mtu`   |
|-------------|---------|
| **Type:**   | integer |
| **Scope:**  | global  |

<a id="network-physical-network-conf:ovn.ingress_mode"></a>
`ovn.ingress_mode`

How OVN NIC external IPs are advertised on uplink network

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-physical-network-conf:ovn.ingress_mode)

| **Key:**       | `ovn.ingress_mode`   |
|----------------|----------------------|
| **Type:**      | string               |
| **Default:**   | `l2proxy`            |
| **Condition:** | standard mode        |
| **Scope:**     | global               |

Possible values are `l2proxy` (proxy ARP/NDP) and `routed`.

<a id="network-physical-network-conf:parent"></a>
`parent`

Existing interface to use for network

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-physical-network-conf:parent)

| **Key:**    | `parent`   |
|-------------|------------|
| **Type:**   | string     |
| **Scope:**  | local      |

<a id="network-physical-network-conf:user.*"></a>
`user.*`

User-provided free-form key/value pairs

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-physical-network-conf:user.*)

| **Key:**    | `user.*`   |
|-------------|------------|
| **Type:**   | string     |
| **Scope:**  | global     |

<a id="network-physical-network-conf:vlan"></a>
`vlan`

VLAN ID to attach to

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-physical-network-conf:vlan)

| **Key:**    | `vlan`   |
|-------------|----------|
| **Type:**   | integer  |
| **Scope:**  | global   |

<a id="network-physical-features"></a>

## Supported features

The following features are supported for the `physical` network type:

- [How to configure LXD as a BGP server](../howto/network_bgp.md#network-bgp)


# index.html.md

<a id="ref-projects"></a>

# Project configuration

Projects can be configured through a set of key/value configuration options.
See [Configure a project](../howto/projects_create.md#projects-configure) for instructions on how to set these options.

The key/value configuration is namespaced.
The following options are available:

- [Project features](#project-features)
- [Project limits](#project-limits)
- [Project restrictions](#project-restrictions)
- [Project-specific configuration](#project-specific-config)
- [Replica configuration](#project-replica-config)

<a id="project-features"></a>

## Project features

The project features define which entities are isolated in the project and which are inherited from the `default` project.

If a `feature.*` option is set to `true`, the corresponding entity is isolated in the project.

#### NOTE
When you create a project without explicitly configuring a specific option, this option is set to the initial value given in the following table.

However, if you unset one of the `feature.*` options, it does not go back to the initial value, but to the default value.
The default value for all `feature.*` options is `false`.

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="project-features:features.images"></a>
`features.images`

Whether to use a separate set of images for the project

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-features:features.images)

| **Key:**           | `features.images`   |
|--------------------|---------------------|
| **Type:**          | bool                |
| **Default:**       | `false`             |
| **Initial value:** | `true`              |

This setting applies to both images and image aliases.

<a id="project-features:features.networks"></a>
`features.networks`

Whether to use a separate set of networks for the project

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-features:features.networks)

| **Key:**           | `features.networks`   |
|--------------------|-----------------------|
| **Type:**          | bool                  |
| **Default:**       | `false`               |
| **Initial value:** | `false`               |

<a id="project-features:features.networks.zones"></a>
`features.networks.zones`

Whether to use a separate set of network zones for the project

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-features:features.networks.zones)

| **Key:**           | `features.networks.zones`   |
|--------------------|-----------------------------|
| **Type:**          | bool                        |
| **Default:**       | `false`                     |
| **Initial value:** | `false`                     |

<a id="project-features:features.profiles"></a>
`features.profiles`

Whether to use a separate set of profiles for the project

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-features:features.profiles)

| **Key:**           | `features.profiles`   |
|--------------------|-----------------------|
| **Type:**          | bool                  |
| **Default:**       | `false`               |
| **Initial value:** | `true`                |

<a id="project-features:features.storage.buckets"></a>
`features.storage.buckets`

Whether to use a separate set of storage buckets for the project

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-features:features.storage.buckets)

| **Key:**           | `features.storage.buckets`   |
|--------------------|------------------------------|
| **Type:**          | bool                         |
| **Default:**       | `false`                      |
| **Initial value:** | `true`                       |

<a id="project-features:features.storage.volumes"></a>
`features.storage.volumes`

Whether to use a separate set of storage volumes for the project

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-features:features.storage.volumes)

| **Key:**           | `features.storage.volumes`   |
|--------------------|------------------------------|
| **Type:**          | bool                         |
| **Default:**       | `false`                      |
| **Initial value:** | `true`                       |

<a id="project-limits"></a>

## Project limits

Project limits define a hard upper bound for the resources that can be used by the containers and VMs that belong to a project.

Depending on the `limits.*` option, the limit applies to the number of entities that are allowed in the project (for example, [`limits.containers`](#project-limits:limits.containers) or [`limits.networks`](#project-limits:limits.networks)) or to the aggregate value of resource usage for all instances in the project (for example, [`limits.cpu`](#project-limits:limits.cpu) or [`limits.processes`](#project-limits:limits.processes)).
In the latter case, the limit usually applies to the [Resource limits](instance_options.md#instance-options-limits) that are configured for each instance (either directly or via a profile), and not to the resources that are actually in use.

For example, if you set the project’s [`limits.memory`](#project-limits:limits.memory) configuration to `50GiB`, the sum of the individual values of all [`limits.memory`](instance_options.md#instance-resource-limits:limits.memory) configuration keys defined on the project’s instances will be kept under 50 GiB.

Similarly, setting the project’s [`limits.cpu`](#project-limits:limits.cpu) configuration key to `100` means that the sum of individual [`limits.cpu`](instance_options.md#instance-resource-limits:limits.cpu) values will be kept below 100.

When using project limits, the following conditions must be fulfilled:

- When you set one of the `limits.*` configurations and there is a corresponding configuration for the instance, all instances in the project must have the corresponding configuration defined (either directly or via a profile).
  See [Resource limits](instance_options.md#instance-options-limits) for the instance configuration options.
- The [`limits.cpu`](#project-limits:limits.cpu) configuration cannot be used if [CPU pinning](instance_options.md#instance-options-limits-cpu) is enabled.
  This means that to use [`limits.cpu`](#project-limits:limits.cpu) on a project, the [`limits.cpu`](instance_options.md#instance-resource-limits:limits.cpu) configuration of each instance in the project must be set to a number of CPUs, not a set or a range of CPUs.
- The [`limits.memory`](#project-limits:limits.memory) configuration must be set to an absolute value, not a percentage.

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="project-limits:limits.containers"></a>
`limits.containers`

Maximum number of containers that can be created in the project

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-limits:limits.containers)

| **Key:**    | `limits.containers`   |
|-------------|-----------------------|
| **Type:**   | integer               |

<a id="project-limits:limits.cpu"></a>
`limits.cpu`

Maximum number of CPUs to use in the project

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-limits:limits.cpu)

| **Key:**    | `limits.cpu`   |
|-------------|----------------|
| **Type:**   | integer        |

This value is the maximum value for the sum of the individual [`limits.cpu`](instance_options.md#instance-resource-limits:limits.cpu) configurations set on the instances of the project.

<a id="project-limits:limits.disk"></a>
`limits.disk`

Maximum disk space used by the project

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-limits:limits.disk)

| **Key:**    | `limits.disk`   |
|-------------|-----------------|
| **Type:**   | string          |

This value is the maximum value of the aggregate disk space used by all instance volumes, custom volumes, and images of the project.

<a id="project-limits:limits.disk.pool.POOL_NAME"></a>
`limits.disk.pool.POOL_NAME`

Maximum disk space used by the project on this pool

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-limits:limits.disk.pool.POOL_NAME)

| **Key:**    | `limits.disk.pool.POOL_NAME`   |
|-------------|--------------------------------|
| **Type:**   | string                         |

This value is the maximum value of the aggregate disk
space used by all instance volumes, custom volumes, and images of the
project on this specific storage pool.

When set to 0, the pool is excluded from storage pool list for
the project.

<a id="project-limits:limits.instances"></a>
`limits.instances`

Maximum number of instances that can be created in the project

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-limits:limits.instances)

| **Key:**    | `limits.instances`   |
|-------------|----------------------|
| **Type:**   | integer              |

<a id="project-limits:limits.memory"></a>
`limits.memory`

Usage limit for the host’s memory for the project

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-limits:limits.memory)

| **Key:**    | `limits.memory`   |
|-------------|-------------------|
| **Type:**   | string            |

The value is the maximum value for the sum of the individual [`limits.memory`](instance_options.md#instance-resource-limits:limits.memory) configurations set on the instances of the project.

<a id="project-limits:limits.networks"></a>
`limits.networks`

Maximum number of networks that the project can have

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-limits:limits.networks)

| **Key:**    | `limits.networks`   |
|-------------|---------------------|
| **Type:**   | integer             |

<a id="project-limits:limits.networks.uplink_ips.ipv4.NETWORK_NAME"></a>
`limits.networks.uplink_ips.ipv4.NETWORK_NAME`

Quota of IPv4 addresses from a specified uplink network that can be used by entities in this project

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-limits:limits.networks.uplink_ips.ipv4.NETWORK_NAME)

| **Key:**    | `limits.networks.uplink_ips.ipv4.NETWORK_NAME`   |
|-------------|--------------------------------------------------|
| **Type:**   | string                                           |

Maximum number of IPv4 addresses that this project can consume from the specified uplink network.
This number of IPs can be consumed by networks, forwards and load balancers in this project.

<a id="project-limits:limits.networks.uplink_ips.ipv6.NETWORK_NAME"></a>
`limits.networks.uplink_ips.ipv6.NETWORK_NAME`

Quota of IPv6 addresses from a specified uplink network that can be used by entities in this project

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-limits:limits.networks.uplink_ips.ipv6.NETWORK_NAME)

| **Key:**    | `limits.networks.uplink_ips.ipv6.NETWORK_NAME`   |
|-------------|--------------------------------------------------|
| **Type:**   | string                                           |

Maximum number of IPv6 addresses that this project can consume from the specified uplink network.
This number of IPs can be consumed by networks, forwards and load balancers in this project.

<a id="project-limits:limits.processes"></a>
`limits.processes`

Maximum number of processes within the project

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-limits:limits.processes)

| **Key:**    | `limits.processes`   |
|-------------|----------------------|
| **Type:**   | integer              |

This value is the maximum value for the sum of the individual [`limits.processes`](instance_options.md#instance-resource-limits:limits.processes) configurations set on the instances of the project.

<a id="project-limits:limits.virtual-machines"></a>
`limits.virtual-machines`

Maximum number of VMs that can be created in the project

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-limits:limits.virtual-machines)

| **Key:**    | `limits.virtual-machines`   |
|-------------|-----------------------------|
| **Type:**   | integer                     |

<a id="project-restrictions"></a>

## Project restrictions

To prevent the instances of a project from accessing security-sensitive features (such as container nesting or raw LXC configuration), set the [`restricted`](#project-restricted:restricted) configuration option to `true`.
You can then use the various `restricted.*` options to pick individual features that would normally be blocked by [`restricted`](#project-restricted:restricted) and allow them, so they can be used by the instances of the project.

For example, to restrict a project and block all security-sensitive features, but allow container nesting, enter the following commands:

```none
lxc project set <project_name> restricted=true
lxc project set <project_name> restricted.containers.nesting=allow
```

Each security-sensitive feature has an associated `restricted.*` project configuration option.
If you want to allow the usage of a feature, change the value of its `restricted.*` option.
Most `restricted.*` configurations are binary switches that can be set to either `block` (the default) or `allow`.
However, some options support other values for more fine-grained control.

#### NOTE
You must set the `restricted` configuration to `true` for any of the `restricted.*` options to be effective.
If `restricted` is set to `false`, changing a `restricted.*` option has no effect.

Setting all `restricted.*` keys to `allow` is equivalent to setting `restricted` itself to `false`.

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="project-restricted:restricted"></a>
`restricted`

Whether to block access to security-sensitive features

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-restricted:restricted)

| **Key:**     | `restricted`   |
|--------------|----------------|
| **Type:**    | bool           |
| **Default:** | `false`        |

This option must be enabled to allow the `restricted.*` keys to take effect.
To temporarily remove the restrictions, you can disable this option instead of clearing the related keys.

<a id="project-restricted:restricted.backups"></a>
`restricted.backups`

When set to `block`, creating instance or volume backups is prevented

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-restricted:restricted.backups)

| **Key:**     | `restricted.backups`   |
|--------------|------------------------|
| **Type:**    | string                 |
| **Default:** | `block`                |

Possible values are `allow` or `block`.

<a id="project-restricted:restricted.cluster.groups"></a>
`restricted.cluster.groups`

Cluster groups that can be targeted

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-restricted:restricted.cluster.groups)

| **Key:**    | `restricted.cluster.groups`   |
|-------------|-------------------------------|
| **Type:**   | string                        |

If specified, this option prevents targeting cluster groups other than the provided ones.

<a id="project-restricted:restricted.cluster.target"></a>
`restricted.cluster.target`

When set to `block`, targeting of cluster members is prevented

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-restricted:restricted.cluster.target)

| **Key:**     | `restricted.cluster.target`   |
|--------------|-------------------------------|
| **Type:**    | string                        |
| **Default:** | `block`                       |

Possible values are `allow` or `block`.
When set to `allow`, this option allows targeting of cluster members (either directly or via a group) when creating or moving instances.

<a id="project-restricted:restricted.containers.interception"></a>
`restricted.containers.interception`

When set to `block`, using system call interception options is prevented

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-restricted:restricted.containers.interception)

| **Key:**     | `restricted.containers.interception`   |
|--------------|----------------------------------------|
| **Type:**    | string                                 |
| **Default:** | `block`                                |

Possible values are `allow`, `block`, or `full`.
When set to `allow`, interception options that are usually safe are allowed.
File system mounting remains blocked.

<a id="project-restricted:restricted.containers.lowlevel"></a>
`restricted.containers.lowlevel`

When set to `block`, using low-level container options is prevented

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-restricted:restricted.containers.lowlevel)

| **Key:**     | `restricted.containers.lowlevel`   |
|--------------|------------------------------------|
| **Type:**    | string                             |
| **Default:** | `block`                            |

Possible values are `allow` or `block`.
When set to `allow`, low-level container options like [`raw.lxc`](instance_options.md#instance-raw:raw.lxc), [`raw.idmap`](instance_options.md#instance-raw:raw.idmap), `volatile.*`, etc. can be used.

<a id="project-restricted:restricted.containers.nesting"></a>
`restricted.containers.nesting`

When set to `block`, running nested LXD is prevented

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-restricted:restricted.containers.nesting)

| **Key:**     | `restricted.containers.nesting`   |
|--------------|-----------------------------------|
| **Type:**    | string                            |
| **Default:** | `block`                           |

Possible values are `allow` or `block`.
When set to `allow`, [`security.nesting`](instance_options.md#instance-security:security.nesting) can be set to `true` for an instance.

<a id="project-restricted:restricted.containers.privilege"></a>
`restricted.containers.privilege`

Which settings for privileged containers to prevent

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-restricted:restricted.containers.privilege)

| **Key:**     | `restricted.containers.privilege`   |
|--------------|-------------------------------------|
| **Type:**    | string                              |
| **Default:** | `unprivileged`                      |

Possible values are `unprivileged`, `isolated`, and `allow`.

- When set to `unpriviliged`, this option prevents setting [`security.privileged`](instance_options.md#instance-security:security.privileged) to `true`.
- When set to `isolated`, this option prevents setting [`security.privileged`](instance_options.md#instance-security:security.privileged) to `true` and forces using a unique idmap per container using [`security.idmap.isolated`](instance_options.md#instance-security:security.idmap.isolated) set to `true`.
- When set to `allow`, there is no restriction.

<a id="project-restricted:restricted.devices.disk"></a>
`restricted.devices.disk`

Which disk devices can be used

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-restricted:restricted.devices.disk)

| **Key:**     | `restricted.devices.disk`   |
|--------------|-----------------------------|
| **Type:**    | string                      |
| **Default:** | `managed`                   |

Possible values are `allow`, `block`, or `managed`.

- When set to `block`, this option prevents using all disk devices except the root one.
- When set to `managed`, this option allows using disk devices only if `pool=` is set.
- When set to `allow`, there is no restriction on which disk devices can be used.

  #### IMPORTANT
  When allowing all disk devices, make sure to set
  [`restricted.devices.disk.paths`](#project-restricted:restricted.devices.disk.paths) to a list of
  path prefixes that you want to allow.
  If you do not restrict the allowed paths, users can attach any disk device, including
  shifted devices (`disk` devices with [`shift`](devices_disk.md#devices-disk-options) set to `true`),
  which can be used to gain root access to the system.

<a id="project-restricted:restricted.devices.disk.paths"></a>
`restricted.devices.disk.paths`

Which `source` can be used for `disk` devices

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-restricted:restricted.devices.disk.paths)

| **Key:**    | `restricted.devices.disk.paths`   |
|-------------|-----------------------------------|
| **Type:**   | string                            |

If [`restricted.devices.disk`](#project-restricted:restricted.devices.disk) is set to `allow`, this option controls which `source` can be used for `disk` devices.
Specify a comma-separated list of path prefixes that restrict the `source` setting.
If this option is left empty, all paths are allowed.

<a id="project-restricted:restricted.devices.gpu"></a>
`restricted.devices.gpu`

When set to `block`, using devices of type `gpu` is prevented

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-restricted:restricted.devices.gpu)

| **Key:**     | `restricted.devices.gpu`   |
|--------------|----------------------------|
| **Type:**    | string                     |
| **Default:** | `block`                    |

Possible values are `allow` or `block`.

<a id="project-restricted:restricted.devices.infiniband"></a>
`restricted.devices.infiniband`

When set to `block`, using devices of type `infiniband` is prevented

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-restricted:restricted.devices.infiniband)

| **Key:**     | `restricted.devices.infiniband`   |
|--------------|-----------------------------------|
| **Type:**    | string                            |
| **Default:** | `block`                           |

Possible values are `allow` or `block`.

<a id="project-restricted:restricted.devices.nic"></a>
`restricted.devices.nic`

Which network devices can be used

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-restricted:restricted.devices.nic)

| **Key:**     | `restricted.devices.nic`   |
|--------------|----------------------------|
| **Type:**    | string                     |
| **Default:** | `managed`                  |

Possible values are `allow`, `block`, or `managed`.

- When set to `block`, this option prevents using all network devices.
- When set to `managed`, this option allows using network devices only if `network=` is set.
- When set to `allow`, there is no restriction on which network devices can be used.

<a id="project-restricted:restricted.devices.pci"></a>
`restricted.devices.pci`

When set to `block`, using devices of type `pci` is prevented

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-restricted:restricted.devices.pci)

| **Key:**     | `restricted.devices.pci`   |
|--------------|----------------------------|
| **Type:**    | string                     |
| **Default:** | `block`                    |

Possible values are `allow` or `block`.

<a id="project-restricted:restricted.devices.proxy"></a>
`restricted.devices.proxy`

When set to `block`, using devices of type `proxy` is prevented

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-restricted:restricted.devices.proxy)

| **Key:**     | `restricted.devices.proxy`   |
|--------------|------------------------------|
| **Type:**    | string                       |
| **Default:** | `block`                      |

Possible values are `allow` or `block`.

<a id="project-restricted:restricted.devices.unix-block"></a>
`restricted.devices.unix-block`

When set to `block`, using devices of type `unix-block` is prevented

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-restricted:restricted.devices.unix-block)

| **Key:**     | `restricted.devices.unix-block`   |
|--------------|-----------------------------------|
| **Type:**    | string                            |
| **Default:** | `block`                           |

Possible values are `allow` or `block`.

<a id="project-restricted:restricted.devices.unix-char"></a>
`restricted.devices.unix-char`

When set to `block`, using devices of type `unix-char` is prevented

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-restricted:restricted.devices.unix-char)

| **Key:**     | `restricted.devices.unix-char`   |
|--------------|----------------------------------|
| **Type:**    | string                           |
| **Default:** | `block`                          |

Possible values are `allow` or `block`.

<a id="project-restricted:restricted.devices.unix-hotplug"></a>
`restricted.devices.unix-hotplug`

When set to `block`, using devices of type `unix-hotplug` is prevented

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-restricted:restricted.devices.unix-hotplug)

| **Key:**     | `restricted.devices.unix-hotplug`   |
|--------------|-------------------------------------|
| **Type:**    | string                              |
| **Default:** | `block`                             |

Possible values are `allow` or `block`.

<a id="project-restricted:restricted.devices.usb"></a>
`restricted.devices.usb`

When set to `block`, using devices of type `usb` is prevented

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-restricted:restricted.devices.usb)

| **Key:**     | `restricted.devices.usb`   |
|--------------|----------------------------|
| **Type:**    | string                     |
| **Default:** | `block`                    |

Possible values are `allow` or `block`.

<a id="project-restricted:restricted.idmap.gid"></a>
`restricted.idmap.gid`

Which host GID ranges are allowed in `raw.idmap`

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-restricted:restricted.idmap.gid)

| **Key:**    | `restricted.idmap.gid`   |
|-------------|--------------------------|
| **Type:**   | string                   |

This option specifies the host GID ranges that are allowed in the instance’s [`raw.idmap`](instance_options.md#instance-raw:raw.idmap) setting.

<a id="project-restricted:restricted.idmap.uid"></a>
`restricted.idmap.uid`

Which host UID ranges are allowed in `raw.idmap`

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-restricted:restricted.idmap.uid)

| **Key:**    | `restricted.idmap.uid`   |
|-------------|--------------------------|
| **Type:**   | string                   |

This option specifies the host UID ranges that are allowed in the instance’s [`raw.idmap`](instance_options.md#instance-raw:raw.idmap) setting.

<a id="project-restricted:restricted.networks.access"></a>
`restricted.networks.access`

Which network names are allowed for use in this project

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-restricted:restricted.networks.access)

| **Key:**    | `restricted.networks.access`   |
|-------------|--------------------------------|
| **Type:**   | string                         |

Specify a comma-delimited list of network names that are allowed for use in this project.
If this option is not set, all networks are accessible.

Note that this setting depends on the [`restricted.devices.nic`](#project-restricted:restricted.devices.nic) setting.

<a id="project-restricted:restricted.networks.subnets"></a>
`restricted.networks.subnets`

Which network subnets are allocated for use in this project

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-restricted:restricted.networks.subnets)

| **Key:**     | `restricted.networks.subnets`   |
|--------------|---------------------------------|
| **Type:**    | string                          |
| **Default:** | `block`                         |

Specify a comma-delimited list of CIDR network routes from the uplink network’s [`ipv4.routes`](network_physical.md#network-physical-network-conf:ipv4.routes) [`ipv6.routes`](network_physical.md#network-physical-network-conf:ipv6.routes) that are allowed for use in this project.
Use the form `<uplink>:<subnet>`.

Example value: `lxdbr0:192.0.168.0/24,lxdbr0:10.1.19.5/32`

<a id="project-restricted:restricted.networks.uplinks"></a>
`restricted.networks.uplinks`

Which network names can be used as uplink in this project

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-restricted:restricted.networks.uplinks)

| **Key:**     | `restricted.networks.uplinks`   |
|--------------|---------------------------------|
| **Type:**    | string                          |
| **Default:** | `block`                         |

Specify a comma-delimited list of network names that can be used as uplink for networks in this project.

<a id="project-restricted:restricted.networks.zones"></a>
`restricted.networks.zones`

Which network zones can be used in this project

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-restricted:restricted.networks.zones)

| **Key:**     | `restricted.networks.zones`   |
|--------------|-------------------------------|
| **Type:**    | string                        |
| **Default:** | `block`                       |

Specify a comma-delimited list of network zones that can be used (or something under them) in this project.

<a id="project-restricted:restricted.snapshots"></a>
`restricted.snapshots`

When set to `block`, creating instance or volume snapshots is prevented

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-restricted:restricted.snapshots)

| **Key:**     | `restricted.snapshots`   |
|--------------|--------------------------|
| **Type:**    | string                   |
| **Default:** | `block`                  |

<a id="project-restricted:restricted.virtual-machines.lowlevel"></a>
`restricted.virtual-machines.lowlevel`

When set to `block`, using low-level VM options is prevented

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-restricted:restricted.virtual-machines.lowlevel)

| **Key:**     | `restricted.virtual-machines.lowlevel`   |
|--------------|------------------------------------------|
| **Type:**    | string                                   |
| **Default:** | `block`                                  |

Possible values are `allow` or `block`.
When set to `allow`, low-level VM options like [`raw.qemu`](instance_options.md#instance-raw:raw.qemu), `volatile.*`, etc. can be used.

<a id="project-specific-config"></a>

## Project-specific configuration

There are some [Server configuration](../server.md#server) options that you can override for a project.
In addition, you can add user metadata for a project.

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="project-specific:backups.compression_algorithm"></a>
`backups.compression_algorithm`

Compression algorithm to use for backups

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-specific:backups.compression_algorithm)

| **Key:**    | `backups.compression_algorithm`   |
|-------------|-----------------------------------|
| **Type:**   | string                            |

Specify which compression algorithm to use for backups in this project.
Possible values are `bzip2`, `gzip`, `lzma`, `xz`, or `none`.

<a id="project-specific:images.auto_update_cached"></a>
`images.auto_update_cached`

Whether to automatically update cached images in the project

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-specific:images.auto_update_cached)

| **Key:**    | `images.auto_update_cached`   |
|-------------|-------------------------------|
| **Type:**   | bool                          |

<a id="project-specific:images.auto_update_interval"></a>
`images.auto_update_interval`

Interval at which to look for updates to cached images

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-specific:images.auto_update_interval)

| **Key:**    | `images.auto_update_interval`   |
|-------------|---------------------------------|
| **Type:**   | integer                         |

Specify the interval in hours.
To disable looking for updates to cached images, set this option to `0`.

<a id="project-specific:images.compression_algorithm"></a>
`images.compression_algorithm`

Compression algorithm to use for new images in the project

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-specific:images.compression_algorithm)

| **Key:**    | `images.compression_algorithm`   |
|-------------|----------------------------------|
| **Type:**   | string                           |

Possible values are `bzip2`, `gzip`, `lzma`, `xz`, or `none`.

<a id="project-specific:images.default_architecture"></a>
`images.default_architecture`

Default architecture to use in a mixed-architecture cluster

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-specific:images.default_architecture)

| **Key:**    | `images.default_architecture`   |
|-------------|---------------------------------|
| **Type:**   | string                          |

<a id="project-specific:images.remote_cache_expiry"></a>
`images.remote_cache_expiry`

When an unused cached remote image is flushed in the project

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-specific:images.remote_cache_expiry)

| **Key:**    | `images.remote_cache_expiry`   |
|-------------|--------------------------------|
| **Type:**   | integer                        |

Specify the number of days after which the unused cached image expires.

<a id="project-specific:user.*"></a>
`user.*`

User-provided free-form key/value pairs

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-specific:user.*)

| **Key:**    | `user.*`   |
|-------------|------------|
| **Type:**   | string     |

<a id="project-replica-config"></a>

## Replica configuration

The following options configure a project for use as a replication source or target with a [replicator](../howto/replicators_create.md#howto-replicators-setup).

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="project-replica:replica.cluster"></a>
`replica.cluster`

Cluster link allowed to replicate to this standby project.

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#project-replica:replica.cluster)

| **Key:**    | `replica.cluster`   |
|-------------|---------------------|
| **Type:**   | string              |

This setting is used on standby projects to identify which cluster link is allowed to replicate instances to this project.

## Related topics

How-to guides:

- [Projects](../projects.md#projects)

Explanation:

- [Instances grouping with projects](../explanation/projects.md#exp-projects)


# index.html.md

<a id="storage-powerflex"></a>

# Dell PowerFlex - `powerflex`

[Dell PowerFlex](https://www.dell.com/en-us/shop/powerflex/sf/powerflex) is a software-defined storage solution from [Dell Technologies](https://www.dell.com/). Among other things it offers the consumption of redundant block storage across the network.

LXD offers access to PowerFlex storage clusters using either NVMe/TCP or Dell’s Storage Data Client (SDC).
In addition, PowerFlex offers copy-on-write snapshots, thin provisioning and other features.

To use PowerFlex with NVMe/TCP, make sure you have the required kernel modules installed on your host system.
On Ubuntu these are `nvme_fabrics` and `nvme_tcp`, which come bundled in the `linux-modules-extra-$(uname -r)` package.
LXD takes care of connecting to the respective subsystem.

When using the SDC, LXD requires it to already be connected to the Dell Metadata Manager (MDM) beforehand.
As LXD doesn’t set up the SDC, follow the official guides from Dell for configuration details.

LXD supports both PowerFlex 4 and 5.

## Terminology

PowerFlex groups various so-called  under logical groups within a protection domain.
Those SDS are the hosts that contribute storage capacity to the PowerFlex cluster.
A *protection domain* contains storage pools, which represent a set of physical storage devices from different SDS.
LXD creates its volumes in those storage pools.

You can take a snapshot of any volume in PowerFlex, which will create an independent copy of the parent volume.
PowerFlex volumes get added as a drive to the respective LXD host the volume got mapped to.
In case of NVMe/TCP, the LXD host connects to one or multiple NVMe  provided by PowerFlex.
Those SDT run as components on the PowerFlex storage layer.
In case of SDC, the LXD hosts don’t set up any connection by themselves.
Instead they depend on the SDC to make the volumes available on the system for consumption.

## `powerflex` driver in LXD

The `powerflex` driver in LXD uses PowerFlex volumes for custom storage volumes, instances and snapshots.
For storage volumes with content type `filesystem` (containers and custom file-system volumes), the `powerflex` driver uses volumes with a file system on top (see [`block.filesystem`](#storage-powerflex-volume-conf:block.filesystem)).
By default, LXD creates thin-provisioned PowerFlex volumes.

LXD expects the PowerFlex protection domain and storage pool already to be set up.
Furthermore, LXD assumes that it has full control over the storage pool.
Therefore, you should never maintain any volumes that are not owned by LXD in a PowerFlex storage pool, because LXD might delete them.

This driver behaves differently than some of the other drivers in that it provides remote storage.
As a result and depending on the internal network, storage access might be a bit slower than for local storage.
On the other hand, using remote storage has big advantages in a cluster setup, because all cluster members have access to the same storage pools with the exact same contents, without the need to synchronize storage pools.

When creating a new storage pool using the `powerflex` driver in `nvme/tcp` mode, LXD tries to discover one of the SDT from the given storage pool.
Alternatively, you can specify which SDT to use with [`powerflex.sdt`](#storage-powerflex-pool-conf:powerflex.sdt).
LXD instructs the NVMe initiator to connect to all the other SDT when first connecting to the subsystem.

Due to the way copy-on-write works in PowerFlex, snapshots of any volume don’t rely on its parent.
As a result, volume snapshots are fully functional volumes themselves, and it’s possible to take additional snapshots from such volume snapshots.
This tree of dependencies is called the *PowerFlex vTree*.
Both volumes and their snapshots get added as standalone disks to the LXD host.

<a id="storage-powerflex-volume-names"></a>

### Volume names

Due to a [limitation](#storage-powerflex-limitations) in PowerFlex, volume names cannot exceed 31 characters.
Therefore the driver is using the volume’s [`volatile.uuid`](#storage-powerflex-volume-conf:volatile.uuid) to generate a fixed length volume name.
A UUID of `5a2504b0-6a6c-4849-8ee7-ddb0b674fd14` will render to the base64-encoded string `WiUEsGpsSEmO592wtnT9FA==`.

To be able to identify the volume types and snapshots, special identifiers are prepended to the volume names:

| Type            | Identifier   | Example                                                                                                                                                      |
|-----------------|--------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Container       | `c_`         | `c_WiUEsGpsSEmO592wtnT9FA==`                                                                                                                                 |
| Virtual machine | `v_`         | `v_WiUEsGpsSEmO592wtnT9FA==.b` (block volume) and `v_WiUEsGpsSEmO592wtnT9FA==` (file system volume)                                                          |
| Image (ISO)     | `i_`         | `i_WiUEsGpsSEmO592wtnT9FA==.i`                                                                                                                               |
| Custom volume   | `u_`         | `u_WiUEsGpsSEmO592wtnT9FA==` (file system volume) and `u_WiUEsGpsSEmO592wtnT9FA==.b` (block volume)                                                          |
| Snapshot        | `s`          | `sc_WiUEsGpsSEmO592wtnT9FA==` (container snapshot), `sv_WiUEsGpsSEmO592wtnT9FA==.b` (VM snapshot) and `su_WiUEsGpsSEmO592wtnT9FA==` (custom volume snapshot) |

<a id="storage-powerflex-limitations"></a>

### Limitations

The `powerflex` driver has the following limitations:

Limit of snapshots in a single vTree
: An internal limitation in the PowerFlex vTree does not allow to take more than 126 snapshots of any volume in PowerFlex.
  This limit also applies to any child of any of the parent volume’s snapshots.
  In PowerFlex 4 a single vTree can only have 126 branches.
  PowerFlex 5 supports having 1022 snapshots per volume family (formerly vTree).

Non-optimized image storage
: Due to the limit of snapshots in the vTree, the PowerFlex driver doesn’t come with support for optimized image storage.
  This would limit LXD to create only a finite number of instances from an image.
  Instead, when launching a new instance, the image’s contents get copied to the instance’s root volume.

Copying volumes
: PowerFlex does not support creating a copy of the volume so that it gets its own vTree.
  Therefore, LXD falls back to copying the volume on the local system.
  This implicates an increased use of bandwidth due to the volume’s contents being transferred over the network twice.
  Enabling [`powerflex.snapshot_copy`](#storage-powerflex-pool-conf:powerflex.snapshot_copy) creates a PowerFlex snapshot when performing a copy.
  Starting with PowerFlex 5, enabling [`powerflex.snapshot_copy`](#storage-powerflex-pool-conf:powerflex.snapshot_copy) will cause any
  volume copies to be performed on PowerFlex directly.

Volume size constraints
: In PowerFlex 4, the size (quota) of a volume must be in multiples of 8 GiB.
  PowerFlex 5 requires the size to be in multiples of 1 GiB.
  This results in the smallest possible volume size of 8 GiB or 1 GiB depending on the version of PowerFlex.
  However, if not specified otherwise, volumes are getting thin-provisioned by LXD.
  PowerFlex volumes can only be increased in size.
  When no volume size is set, it’s rounded to the next multiple which fits the instance image.

Sharing custom volumes between instances
: The PowerFlex driver “simulates” volumes with content type `filesystem` by putting a file system on top of a PowerFlex volume.
  Therefore, custom storage volumes can only be assigned to a single instance at a time.

Sharing the PowerFlex storage pool between installations
: Sharing the same PowerFlex storage pool between multiple LXD installations is not supported.

Incompatible instance images
: The Ubuntu Noble Numbat image cannot be used together with the [`powerflex.mode`](#storage-powerflex-pool-conf:powerflex.mode) set to `sdc`.
  This is due to a limitation of SDC not being able to manage volumes with more than 15 partitions.

## Configuration options

The following configuration options are available for storage pools that use the `powerflex` driver and for storage volumes in these pools.

<a id="storage-powerflex-pool-config"></a>

### Storage pool configuration

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="storage-powerflex-pool-conf:powerflex.domain"></a>
`powerflex.domain`

Name of the PowerFlex protection domain

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerflex-pool-conf:powerflex.domain)

| **Key:**    | `powerflex.domain`   |
|-------------|----------------------|
| **Type:**   | string               |
| **Scope:**  | global               |

This option is required only if [`powerflex.pool`](#storage-powerflex-pool-conf:powerflex.pool) is specified using its name.

<a id="storage-powerflex-pool-conf:powerflex.gateway"></a>
`powerflex.gateway`

Address of the PowerFlex Gateway

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerflex-pool-conf:powerflex.gateway)

| **Key:**    | `powerflex.gateway`   |
|-------------|-----------------------|
| **Type:**   | string                |
| **Scope:**  | global                |

<a id="storage-powerflex-pool-conf:powerflex.gateway.verify"></a>
`powerflex.gateway.verify`

Whether to verify the PowerFlex Gateway’s certificate

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerflex-pool-conf:powerflex.gateway.verify)

| **Key:**     | `powerflex.gateway.verify`   |
|--------------|------------------------------|
| **Type:**    | bool                         |
| **Default:** | `true`                       |
| **Scope:**   | global                       |

<a id="storage-powerflex-pool-conf:powerflex.mode"></a>
`powerflex.mode`

How volumes are mapped to the local server

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerflex-pool-conf:powerflex.mode)

| **Key:**     | `powerflex.mode`    |
|--------------|---------------------|
| **Type:**    | string              |
| **Default:** | the discovered mode |
| **Scope:**   | global              |

The mode gets discovered automatically if the system provides the necessary kernel modules.
This can be either `nvme/tcp` or `sdc`.

<a id="storage-powerflex-pool-conf:powerflex.pool"></a>
`powerflex.pool`

ID of the PowerFlex storage pool

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerflex-pool-conf:powerflex.pool)

| **Key:**    | `powerflex.pool`   |
|-------------|--------------------|
| **Type:**   | string             |
| **Scope:**  | global             |

If you want to specify the storage pool via its name, also set [`powerflex.domain`](#storage-powerflex-pool-conf:powerflex.domain).

<a id="storage-powerflex-pool-conf:powerflex.sdt"></a>
`powerflex.sdt`

Comma separated list of PowerFlex NVMe/TCP SDTs

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerflex-pool-conf:powerflex.sdt)

| **Key:**    | `powerflex.sdt`   |
|-------------|-------------------|
| **Type:**   | string            |
| **Scope:**  | global            |

<a id="storage-powerflex-pool-conf:powerflex.snapshot_copy"></a>
`powerflex.snapshot_copy`

Whether to use sparse snapshots for copies

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerflex-pool-conf:powerflex.snapshot_copy)

| **Key:**     | `powerflex.snapshot_copy`   |
|--------------|-----------------------------|
| **Type:**    | bool                        |
| **Default:** | `false`                     |
| **Scope:**   | global                      |

If this option is set to `true`, PowerFlex makes a sparse snapshot when copying an instance or custom volume.
See [Limitations](#storage-powerflex-limitations) for more information.

<a id="storage-powerflex-pool-conf:powerflex.user.name"></a>
`powerflex.user.name`

User for PowerFlex Gateway authentication

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerflex-pool-conf:powerflex.user.name)

| **Key:**     | `powerflex.user.name`   |
|--------------|-------------------------|
| **Type:**    | string                  |
| **Default:** | `admin`                 |
| **Scope:**   | global                  |

Must have at least SystemAdmin role to give LXD full control over managed storage pools.

<a id="storage-powerflex-pool-conf:powerflex.user.password"></a>
`powerflex.user.password`

Password for PowerFlex Gateway authentication

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerflex-pool-conf:powerflex.user.password)

| **Key:**    | `powerflex.user.password`   |
|-------------|-----------------------------|
| **Type:**   | string                      |
| **Scope:**  | global                      |

<a id="storage-powerflex-pool-conf:rsync.bwlimit"></a>
`rsync.bwlimit`

Upper limit on the socket I/O for `rsync`

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerflex-pool-conf:rsync.bwlimit)

| **Key:**     | `rsync.bwlimit`   |
|--------------|-------------------|
| **Type:**    | string            |
| **Default:** | `0` (no limit)    |
| **Scope:**   | global            |

When `rsync` must be used to transfer storage entities, this option specifies the upper limit
to be placed on the socket I/O.

<a id="storage-powerflex-pool-conf:rsync.compression"></a>
`rsync.compression`

Whether to use compression while migrating storage pools

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerflex-pool-conf:rsync.compression)

| **Key:**     | `rsync.compression`   |
|--------------|-----------------------|
| **Type:**    | bool                  |
| **Default:** | `true`                |
| **Scope:**   | global                |

<a id="storage-powerflex-pool-conf:volatile.powerflex.version"></a>
`volatile.powerflex.version`

Software version of the PowerFlex array.

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerflex-pool-conf:volatile.powerflex.version)

| **Key:**     | `volatile.powerflex.version`   |
|--------------|--------------------------------|
| **Type:**    | string                         |
| **Default:** | Discovered version             |
| **Scope:**   | global                         |

This field is automatically populated after querying the PowerFlex version.
It cannot be set by the user.

<a id="storage-powerflex-pool-conf:volume.size"></a>
`volume.size`

Size/quota of the storage volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerflex-pool-conf:volume.size)

| **Key:**    | `volume.size`   |
|-------------|-----------------|
| **Type:**   | string          |
| **Scope:**  | global          |

The size must be in multiples of 8 GiB for PowerFlex 4.
Starting with PowerFlex 5, the size can be in multiples of 1 GiB.
See [Limitations](#storage-powerflex-limitations) for more information.

<a id="storage-powerflex-vol-config"></a>

### Storage volume configuration

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="storage-powerflex-volume-conf:block.filesystem"></a>
`block.filesystem`

File system of the storage volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerflex-volume-conf:block.filesystem)

| **Key:**       | `block.filesystem`                                |
|----------------|---------------------------------------------------|
| **Type:**      | string                                            |
| **Default:**   | same as `volume.block.filesystem`                 |
| **Condition:** | block-based volume with content type `filesystem` |
| **Scope:**     | global                                            |

Valid options: `btrfs`, `ext4`, `xfs`
If not set, `ext4` is assumed.

<a id="storage-powerflex-volume-conf:block.mount_options"></a>
`block.mount_options`

Mount options for block-backed file system volumes

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerflex-volume-conf:block.mount_options)

| **Key:**       | `block.mount_options`                             |
|----------------|---------------------------------------------------|
| **Type:**      | string                                            |
| **Default:**   | same as `volume.block.mount_options`              |
| **Condition:** | block-based volume with content type `filesystem` |
| **Scope:**     | global                                            |

<a id="storage-powerflex-volume-conf:block.type"></a>
`block.type`

Whether to create a `thin` or `thick` provisioned volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerflex-volume-conf:block.type)

| **Key:**     | `block.type`                           |
|--------------|----------------------------------------|
| **Type:**    | string                                 |
| **Default:** | same as `volume.block.type` or `thick` |
| **Scope:**   | global                                 |

<a id="storage-powerflex-volume-conf:security.shared"></a>
`security.shared`

Enable volume sharing

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerflex-volume-conf:security.shared)

| **Key:**       | `security.shared`                           |
|----------------|---------------------------------------------|
| **Type:**      | bool                                        |
| **Default:**   | same as `volume.security.shared` or `false` |
| **Condition:** | virtual-machine or custom block volume      |
| **Scope:**     | global                                      |

Enable this option to allow the volume to be shared across multiple instances despite the possibility of data loss.

<a id="storage-powerflex-volume-conf:security.shifted"></a>
`security.shifted`

Enable ID shifting overlay

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerflex-volume-conf:security.shifted)

| **Key:**       | `security.shifted`                           |
|----------------|----------------------------------------------|
| **Type:**      | bool                                         |
| **Default:**   | same as `volume.security.shifted` or `false` |
| **Condition:** | custom volume                                |
| **Scope:**     | global                                       |

Enable this option to allow the volume to be attached to multiple isolated instances.

<a id="storage-powerflex-volume-conf:security.unmapped"></a>
`security.unmapped`

Disable ID mapping for the volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerflex-volume-conf:security.unmapped)

| **Key:**       | `security.unmapped`                           |
|----------------|-----------------------------------------------|
| **Type:**      | bool                                          |
| **Default:**   | same as `volume.security.unmapped` or `false` |
| **Condition:** | custom volume                                 |
| **Scope:**     | global                                        |

<a id="storage-powerflex-volume-conf:size"></a>
`size`

Size/quota of the storage volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerflex-volume-conf:size)

| **Key:**     | `size`                |
|--------------|-----------------------|
| **Type:**    | string                |
| **Default:** | same as `volume.size` |
| **Scope:**   | global                |

The size must be in multiples of 8 GiB for PowerFlex 4.
Starting with PowerFlex 5, the size can be in multiples of 1 GiB.
See [Limitations](#storage-powerflex-limitations) for more information.

<a id="storage-powerflex-volume-conf:snapshots.expiry"></a>
`snapshots.expiry`

Time until snapshots are deleted

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerflex-volume-conf:snapshots.expiry)

| **Key:**       | `snapshots.expiry`                |
|----------------|-----------------------------------|
| **Type:**      | string                            |
| **Default:**   | same as `volume.snapshots.expiry` |
| **Condition:** | custom volume                     |
| **Scope:**     | global                            |

Specify an expression like `1M 2H 3d 4w 5m 6y`.

<a id="storage-powerflex-volume-conf:snapshots.pattern"></a>
`snapshots.pattern`

Template for the snapshot name

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerflex-volume-conf:snapshots.pattern)

| **Key:**       | `snapshots.pattern`                            |
|----------------|------------------------------------------------|
| **Type:**      | string                                         |
| **Default:**   | same as `volume.snapshots.pattern` or `snap%d` |
| **Condition:** | custom volume                                  |
| **Scope:**     | global                                         |

You can specify a naming template for scheduled snapshots and unnamed snapshots.

The `snapshots.pattern` option takes a Pongo2 template string to format the snapshot name.

To add a time stamp to the snapshot name, use the Pongo2 context variable `creation_date`.
Make sure to format the date in your template string to avoid forbidden characters in the snapshot name.
For example, set `snapshots.pattern` to `{{ creation_date|date:'2006-01-02_15-04-05' }}` to name the snapshots after their time of creation, down to the precision of a second.

Another way to avoid name collisions is to use the placeholder `%d` in the pattern.
If no matching snapshots exist, the placeholder is replaced with `0`.
Otherwise, it is replaced with the next snapshot index, which is one higher than the highest existing matching snapshot index.

<a id="storage-powerflex-volume-conf:snapshots.schedule"></a>
`snapshots.schedule`

Schedule for automatic volume snapshots

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerflex-volume-conf:snapshots.schedule)

| **Key:**       | `snapshots.schedule`         |
|----------------|------------------------------|
| **Type:**      | string                       |
| **Default:**   | same as `snapshots.schedule` |
| **Condition:** | custom volume                |
| **Scope:**     | global                       |

Specify either a cron expression (`<minute> <hour> <dom> <month> <dow>`), a comma-separated list of schedule aliases (`@hourly`, `@daily`, `@midnight`, `@weekly`, `@monthly`, `@annually`, `@yearly`), or leave empty to disable automatic snapshots (the default).

<a id="storage-powerflex-volume-conf:volatile.devlxd.owner"></a>
`volatile.devlxd.owner`

ID of the DevLXD identity that owns the volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerflex-volume-conf:volatile.devlxd.owner)

| **Key:**     | `volatile.devlxd.owner`   |
|--------------|---------------------------|
| **Type:**    | string                    |
| **Default:** | DevLXD owner identity ID  |
| **Scope:**   | global                    |

<a id="storage-powerflex-volume-conf:volatile.idmap.last"></a>
`volatile.idmap.last`

JSON-serialized UID/GID map that has been applied to the volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerflex-volume-conf:volatile.idmap.last)

| **Key:**       | `volatile.idmap.last`   |
|----------------|-------------------------|
| **Type:**      | string                  |
| **Condition:** | filesystem              |

<a id="storage-powerflex-volume-conf:volatile.idmap.next"></a>
`volatile.idmap.next`

JSON-serialized UID/GID map that has been applied to the volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerflex-volume-conf:volatile.idmap.next)

| **Key:**       | `volatile.idmap.next`   |
|----------------|-------------------------|
| **Type:**      | string                  |
| **Condition:** | filesystem              |

<a id="storage-powerflex-volume-conf:volatile.uuid"></a>
`volatile.uuid`

Volume UUID

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerflex-volume-conf:volatile.uuid)

| **Key:**     | `volatile.uuid`   |
|--------------|-------------------|
| **Type:**    | string            |
| **Default:** | random UUID       |
| **Scope:**   | global            |


# index.html.md

<a id="cluster-member-config"></a>

# Cluster member configuration

Each cluster member has its own key/value configuration with the following supported namespaces:

- `user` (free form key/value for user metadata)
- `scheduler` (options related to how the member is automatically targeted by the cluster)

The following keys are currently supported:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="cluster-cluster:scheduler.instance"></a>
`scheduler.instance`

Controls how instances are scheduled to run on this member

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#cluster-cluster:scheduler.instance)

| **Key:**     | `scheduler.instance`   |
|--------------|------------------------|
| **Type:**    | string                 |
| **Default:** | `all`                  |

Possible values are `all`, `manual`, and `group`. See
[Automatic placement of instances](../explanation/clusters.md#clustering-instance-placement) for more information.

<a id="cluster-cluster:user.*"></a>
`user.*`

Free form user key/value storage

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#cluster-cluster:user.*)

| **Key:**    | `user.*`   |
|-------------|------------|
| **Type:**   | string     |

User keys can be used in search.

## Related topics

How-to guides:

- [Clustering](../clustering.md#clustering)

Explanation:

- [Clusters](../explanation/clusters.md#exp-clusters)


# index.html.md

<a id="network-macvlan"></a>

# Macvlan network

<!-- Include start macvlan intro -->

Macvlan is a virtual  that you can use if you want to assign several IP addresses to the same network interface, basically splitting up the network interface into several sub-interfaces with their own IP addresses.
You can then assign IP addresses based on the randomly generated MAC addresses.

<!-- Include end macvlan intro -->

The `macvlan` network type allows to specify presets to use when connecting instances to a parent interface.
In this case, the instance NICs can simply set the `network` option to the network they connect to without knowing any of the underlying configuration details.

#### NOTE
If you are using a `macvlan` network, communication between the LXD host and the instances is not possible.
Both the host and the instances can talk to the gateway, but they cannot communicate directly.

<a id="network-macvlan-options"></a>

## Configuration options

The following configuration key namespaces are currently supported for the `macvlan` network type:

- `user` (free-form key/value for user metadata)

#### NOTE
LXD uses the [CIDR notation](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing) where network subnet information is required, for example, `192.0.2.0/24` or `2001:db8::/32`. This does not apply to cases where a single address is required, for example, local/remote addresses of tunnels, NAT addresses or specific addresses to apply to an instance.

The following configuration options are available for the `macvlan` network type:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="network-macvlan-network-conf:gvrp"></a>
`gvrp`

Whether to use GARP VLAN Registration Protocol

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-macvlan-network-conf:gvrp)

| **Key:**     | `gvrp`   |
|--------------|----------|
| **Type:**    | bool     |
| **Default:** | `false`  |
| **Scope:**   | global   |

This option specifies whether to register the VLAN using the GARP VLAN Registration Protocol.

<a id="network-macvlan-network-conf:mtu"></a>
`mtu`

MTU of the new interface

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-macvlan-network-conf:mtu)

| **Key:**    | `mtu`   |
|-------------|---------|
| **Type:**   | integer |
| **Scope:**  | global  |

<a id="network-macvlan-network-conf:parent"></a>
`parent`

Parent interface to create `macvlan` NICs on

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-macvlan-network-conf:parent)

| **Key:**    | `parent`   |
|-------------|------------|
| **Type:**   | string     |
| **Scope:**  | local      |

<a id="network-macvlan-network-conf:user.*"></a>
`user.*`

User-provided free-form key/value pairs

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-macvlan-network-conf:user.*)

| **Key:**    | `user.*`   |
|-------------|------------|
| **Type:**   | string     |
| **Scope:**  | global     |

<a id="network-macvlan-network-conf:vlan"></a>
`vlan`

VLAN ID to attach to

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-macvlan-network-conf:vlan)

| **Key:**    | `vlan`   |
|-------------|----------|
| **Type:**   | integer  |
| **Scope:**  | global   |


# index.html.md

<a id="storage-btrfs"></a>

# Btrfs - `btrfs`


            <p class="youtube_link">
              <a href="https://www.youtube.com/watch?v=2r5FYuusxNc" target="_blank">
                <span title="Btrfs storage and LXD" class="play_icon">▶</span>
                <span title="Btrfs storage and LXD">Watch on YouTube</span>
              </a>
            </p>
        
 is a local file system based on the  principle.
COW means that data is stored to a different block after it has been modified instead of overwriting the existing data, reducing the risk of data corruption.
Unlike other file systems, Btrfs is extent-based, which means that it stores data in contiguous areas of memory.

In addition to basic file system features, Btrfs offers RAID and volume management, pooling, snapshots, checksums, compression and other features.

To use Btrfs, make sure you have `btrfs-progs` installed on your machine.

## Terminology

A Btrfs file system can have *subvolumes*, which are named binary subtrees of the main tree of the file system with their own independent file and directory hierarchy.
A *Btrfs snapshot* is a special type of subvolume that captures a specific state of another subvolume.
Snapshots can be read-write or read-only.

## `btrfs` driver in LXD

The `btrfs` driver in LXD uses a subvolume per instance, image and snapshot.
When creating a new entity (for example, launching a new instance), it creates a Btrfs snapshot.

Btrfs doesn’t natively support storing block devices.
Therefore, when using Btrfs for VMs, LXD creates a big file on disk to store the VM.
This approach is not very efficient and might cause issues when creating snapshots.

Btrfs can be used as a storage backend inside a container in a nested LXD environment.
In this case, the parent container itself must use Btrfs.
Note, however, that the nested LXD setup does not inherit the Btrfs quotas from the parent (see [Quotas](#storage-btrfs-quotas) below).

<a id="storage-btrfs-quotas"></a>

### Quotas

Btrfs supports storage quotas via qgroups.
Btrfs qgroups are hierarchical, but new subvolumes will not automatically be added to the qgroups of their parent subvolumes.
This means that users can trivially escape any quotas that are set.
Therefore, if strict quotas are needed, you should consider using a different storage driver (for example, ZFS with `refquota` or LVM with Btrfs on top).

When using quotas, you must take into account that Btrfs extents are immutable.
When blocks are written, they end up in new extents.
The old extents remain until all their data is dereferenced or rewritten.
This means that a quota can be reached even if the total amount of space used by the current files in the subvolume is smaller than the quota.

#### NOTE
This issue is seen most often when using VMs on Btrfs, due to the random I/O nature of using raw disk image files on top of a Btrfs subvolume.

Therefore, you should never use VMs with Btrfs storage pools.

If you really need to use VMs with Btrfs storage pools, set the instance root disk’s [`size.state`](devices_disk.md#device-disk-device-conf:size.state) property to twice the size of the root disk’s size.
This configuration allows all blocks in the disk image file to be rewritten without reaching the qgroup quota.
Setting the [`btrfs.mount_options`](#storage-btrfs-pool-conf:btrfs.mount_options) storage pool option to `compress-force` can also avoid this scenario, because a side effect of enabling compression is to reduce the maximum extent size such that block rewrites don’t cause as much storage to be double-tracked.
However, this is a storage pool option, and it therefore affects all volumes on the pool.

## Configuration options

The following configuration options are available for storage pools that use the `btrfs` driver and for storage volumes in these pools.

<a id="storage-btrfs-pool-config"></a>

### Storage pool configuration

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="storage-btrfs-pool-conf:btrfs.mount_options"></a>
`btrfs.mount_options`

Mount options for block devices

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-btrfs-pool-conf:btrfs.mount_options)

| **Key:**     | `btrfs.mount_options`    |
|--------------|--------------------------|
| **Type:**    | string                   |
| **Default:** | `user_subvol_rm_allowed` |
| **Scope:**   | global                   |

<a id="storage-btrfs-pool-conf:size"></a>
`size`

Size of the storage pool (for loop-based pools)

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-btrfs-pool-conf:size)

| **Key:**     | `size`                                                |
|--------------|-------------------------------------------------------|
| **Type:**    | string                                                |
| **Default:** | auto (20% of free disk space, >= 5 GiB and <= 30 GiB) |
| **Scope:**   | local                                                 |

When creating loop-based pools, specify the size in bytes ([suffixes](instance_units.md#instances-limit-units) are supported).
You can increase the size to grow the storage pool.

The default (`auto`) creates a storage pool that uses 20% of the free disk space,
with a minimum of 5 GiB and a maximum of 30 GiB.

<a id="storage-btrfs-pool-conf:source"></a>
`source`

Path to an existing block device, loop file, or Btrfs subvolume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-btrfs-pool-conf:source)

| **Key:**    | `source`   |
|-------------|------------|
| **Type:**   | string     |
| **Scope:**  | local      |

<a id="storage-btrfs-pool-conf:source.recover"></a>
`source.recover`

Whether to recover an existing `source`

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-btrfs-pool-conf:source.recover)

| **Key:**     | `source.recover`   |
|--------------|--------------------|
| **Type:**    | bool               |
| **Default:** | `false`            |
| **Scope:**   | local              |

Set this option to true to recover an existing source which was previously created by LXD.

<a id="storage-btrfs-pool-conf:source.wipe"></a>
`source.wipe`

Whether to wipe the block device before creating the pool

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-btrfs-pool-conf:source.wipe)

| **Key:**     | `source.wipe`   |
|--------------|-----------------|
| **Type:**    | bool            |
| **Default:** | `false`         |
| **Scope:**   | local           |

Set this option to `true` to wipe the block device specified in `source`
prior to creating the storage pool.

### Storage volume configuration

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="storage-btrfs-volume-conf:security.shared"></a>
`security.shared`

Enable volume sharing

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-btrfs-volume-conf:security.shared)

| **Key:**       | `security.shared`                           |
|----------------|---------------------------------------------|
| **Type:**      | bool                                        |
| **Default:**   | same as `volume.security.shared` or `false` |
| **Condition:** | virtual-machine or custom block volume      |
| **Scope:**     | global                                      |

Enable this option to allow the volume to be shared across multiple instances despite the possibility of data loss.

<a id="storage-btrfs-volume-conf:security.shifted"></a>
`security.shifted`

Enable ID shifting overlay

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-btrfs-volume-conf:security.shifted)

| **Key:**       | `security.shifted`                           |
|----------------|----------------------------------------------|
| **Type:**      | bool                                         |
| **Default:**   | same as `volume.security.shifted` or `false` |
| **Condition:** | custom volume                                |
| **Scope:**     | global                                       |

Enable this option to allow the volume to be attached to multiple isolated instances.

<a id="storage-btrfs-volume-conf:security.unmapped"></a>
`security.unmapped`

Disable ID mapping for the volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-btrfs-volume-conf:security.unmapped)

| **Key:**       | `security.unmapped`                           |
|----------------|-----------------------------------------------|
| **Type:**      | bool                                          |
| **Default:**   | same as `volume.security.unmapped` or `false` |
| **Condition:** | custom volume                                 |
| **Scope:**     | global                                        |

<a id="storage-btrfs-volume-conf:size"></a>
`size`

Size/quota of the storage volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-btrfs-volume-conf:size)

| **Key:**       | `size`                |
|----------------|-----------------------|
| **Type:**      | string                |
| **Default:**   | same as `volume.size` |
| **Condition:** | appropriate driver    |
| **Scope:**     | global                |

<a id="storage-btrfs-volume-conf:snapshots.expiry"></a>
`snapshots.expiry`

Time until snapshots are deleted

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-btrfs-volume-conf:snapshots.expiry)

| **Key:**       | `snapshots.expiry`                |
|----------------|-----------------------------------|
| **Type:**      | string                            |
| **Default:**   | same as `volume.snapshots.expiry` |
| **Condition:** | custom volume                     |
| **Scope:**     | global                            |

Specify an expression like `1M 2H 3d 4w 5m 6y`.

<a id="storage-btrfs-volume-conf:snapshots.pattern"></a>
`snapshots.pattern`

Template for the snapshot name

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-btrfs-volume-conf:snapshots.pattern)

| **Key:**       | `snapshots.pattern`                            |
|----------------|------------------------------------------------|
| **Type:**      | string                                         |
| **Default:**   | same as `volume.snapshots.pattern` or `snap%d` |
| **Condition:** | custom volume                                  |
| **Scope:**     | global                                         |

You can specify a naming template for scheduled snapshots and unnamed snapshots.

The `snapshots.pattern` option takes a Pongo2 template string to format the snapshot name.

To add a time stamp to the snapshot name, use the Pongo2 context variable `creation_date`.
Make sure to format the date in your template string to avoid forbidden characters in the snapshot name.
For example, set `snapshots.pattern` to `{{ creation_date|date:'2006-01-02_15-04-05' }}` to name the snapshots after their time of creation, down to the precision of a second.

Another way to avoid name collisions is to use the placeholder `%d` in the pattern.
If no matching snapshots exist, the placeholder is replaced with `0`.
Otherwise, it is replaced with the next snapshot index, which is one higher than the highest existing matching snapshot index.

<a id="storage-btrfs-volume-conf:snapshots.schedule"></a>
`snapshots.schedule`

Schedule for automatic volume snapshots

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-btrfs-volume-conf:snapshots.schedule)

| **Key:**       | `snapshots.schedule`         |
|----------------|------------------------------|
| **Type:**      | string                       |
| **Default:**   | same as `snapshots.schedule` |
| **Condition:** | custom volume                |
| **Scope:**     | global                       |

Specify either a cron expression (`<minute> <hour> <dom> <month> <dow>`), a comma-separated list of schedule aliases (`@hourly`, `@daily`, `@midnight`, `@weekly`, `@monthly`, `@annually`, `@yearly`), or leave empty to disable automatic snapshots (the default).

<a id="storage-btrfs-volume-conf:volatile.devlxd.owner"></a>
`volatile.devlxd.owner`

ID of the DevLXD identity that owns the volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-btrfs-volume-conf:volatile.devlxd.owner)

| **Key:**     | `volatile.devlxd.owner`   |
|--------------|---------------------------|
| **Type:**    | string                    |
| **Default:** | DevLXD owner identity ID  |
| **Scope:**   | global                    |

<a id="storage-btrfs-volume-conf:volatile.idmap.last"></a>
`volatile.idmap.last`

JSON-serialized UID/GID map that has been applied to the volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-btrfs-volume-conf:volatile.idmap.last)

| **Key:**       | `volatile.idmap.last`   |
|----------------|-------------------------|
| **Type:**      | string                  |
| **Condition:** | filesystem              |

<a id="storage-btrfs-volume-conf:volatile.idmap.next"></a>
`volatile.idmap.next`

JSON-serialized UID/GID map that has been applied to the volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-btrfs-volume-conf:volatile.idmap.next)

| **Key:**       | `volatile.idmap.next`   |
|----------------|-------------------------|
| **Type:**      | string                  |
| **Condition:** | filesystem              |

<a id="storage-btrfs-volume-conf:volatile.uuid"></a>
`volatile.uuid`

Volume UUID

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-btrfs-volume-conf:volatile.uuid)

| **Key:**     | `volatile.uuid`   |
|--------------|-------------------|
| **Type:**    | string            |
| **Default:** | random UUID       |
| **Scope:**   | global            |


# index.html.md

<a id="reference"></a>

# Reference

The reference material in this section provides technical descriptions of LXD.

<a id="reference-general"></a>

## General information

These guides include compatibility information for operating systems running in instances, and man pages for the `lxc` CLI.

* [Requirements](../requirements.md)
* [Architectures](../architectures.md)
* [Guest OS compatibility](../guest-os-compatibility.md)
* [Container environment](../container-environment.md)
* [Man pages](manpages.md)

## Releases

Release notes and details about the LXD release cadence and its snap.

* [Release notes](release-notes/index.md)
* [Releases and snap](releases-snap.md)

## Images

Reference information for remote image servers and the LXD image format.

* [Remote image servers](remote_image_servers.md)
* [Image format](image_format.md)

<a id="reference-config"></a>

## Configuration options

LXD is highly configurable, with options available for major entities as well as permissions for access control.

* [Configuration option index](../config-options.md)
* [Server configuration](../server.md)
* [Instance configuration](../explanation/instance_config.md)
* [Preseed YAML file fields](preseed_yaml_fields.md)
* [Project configuration](projects.md)
* [Storage drivers](storage_drivers.md)
* [Networks](networks.md)
* [Placement group configuration](placement_groups.md)
* [Clusters](clusters.md)
* [Replicator configuration](replicator_config.md)
* [Permissions](permissions.md)

<a id="reference-production"></a>

## Production setup

The LXD server can be optimized for production workloads and can monitor server metrics.

* [Production server settings](server_settings.md)
* [Provided metrics](provided_metrics.md)

<a id="reference-api"></a>

## API and integrations

LXD exposes a REST API for managing all resources. The LXD CSI driver integrates LXD storage backends with Kubernetes.

* [REST API](../restapi_landing.md)
* [LXD CSI driver reference](driver_csi.md)

<a id="reference-internal"></a>

## Internal implementation details

These guides are primarily of interest to advanced users, contributors, and developers.

* [Internals](../internals.md)


# index.html.md

<a id="permissions-reference"></a>

# Permissions

When managing user access via [Fine-grained authorization](../explanation/authorization.md#fine-grained-authorization), you add identities to groups and then grant entitlements against specific LXD API resources to these groups.

Each LXD API resource has a particular entity type, and each entity type has a set of entitlements that can be granted against API resources of that type.

Below is a description of each entity type, and a list of entitlements that can be granted against entities of that type.

## Server

> Entity type name: `server`

The `server` entity type is the top-level entity type for the LXD system.
Entitlements that are granted at this level might cascade to projects and other resources:

`admin`
: Grants full access to LXD as if via Unix socket.

`viewer`
: Grants access to view all resources in the LXD server.

`can_edit`
: Grants permission to edit server configuration, to edit cluster member configuration, to update the state of a cluster member, to create, edit, and delete cluster groups, to create, edit, and delete cluster links, to update cluster member certificates, and to edit or delete warnings.

`permission_manager`
: Grants permission to view permissions, to create, edit, and delete identities, to view, create, edit, and delete authorization groups, and to view, create, edit, and delete identity provider groups. Note that clients with this permission are able to elevate their own privileges.

`can_view_permissions`
: Grants permission to view permissions.

`can_create_identities`
: Grants permission to create identities.

`can_view_identities`
: Grants permission to view identities.

`can_edit_identities`
: Grants permission to edit identities. Note that clients with this permission are able to elevate their own privileges.

`can_delete_identities`
: Grants permission to delete identities.

`can_create_groups`
: Grants permission to create authorization groups.

`can_view_groups`
: Grants permission to view authorization groups.

`can_edit_groups`
: Grants permission to edit authorization groups. Note that clients with this permission are able to elevate their own privileges.

`can_delete_groups`
: Grants permission to delete authorization groups.

`can_create_identity_provider_groups`
: Grants permission to create identity provider groups.

`can_view_identity_provider_groups`
: Grants permission to view identity provider groups.

`can_edit_identity_provider_groups`
: Grants permission to edit identity provider groups. Note that clients with this permission are able to elevate their own privileges.

`can_delete_identity_provider_groups`
: Grants permission to delete identity provider groups.

`storage_pool_manager`
: Grants permission to create, edit, and delete storage pools.

`can_create_storage_pools`
: Grants permission to create storage pools.

`can_edit_storage_pools`
: Grants permission to edit storage pools.

`can_delete_storage_pools`
: Grants permission to delete storage pools.

`project_manager`
: Grants permission to create, view, edit, and delete projects, and to create, view, edit, and delete resources belonging to any project.

`can_create_projects`
: Grants permission to create projects.

`can_view_projects`
: Grants permission to view projects, and all resources within those projects.

`can_edit_projects`
: Grants permission to edit projects, and all resources within those projects.

`can_delete_projects`
: Grants permission to delete projects.

`can_override_cluster_target_restriction`
: If a project is configured with `restricted.cluster.target`, clients with this permission can override the restriction.

`can_view_events`
: Grants permission to view `logging` events, `ovn` events, and all `lifecycle` events that are not specific to a project.

`can_view_operations`
: Grants permission to view operations that are not specific to a project.

`can_view_resources`
: Grants permission to view server and storage pool resource usage information.

`can_view_metrics`
: Grants permission to view all server and project level metrics.

`can_view_warnings`
: Grants permission to view warnings.

`can_view_unmanaged_networks`
: Grants permission to view unmanaged networks on the LXD host machines.

`can_create_cluster_links`
: Grants permission to create cluster links.

`can_view_cluster_links`
: Grants permission to view cluster links.

`can_edit_cluster_links`
: Grants permission to edit cluster links.

`can_delete_cluster_links`
: Grants permission to delete cluster links.

## Project

> Entity type name: `project`

Entitlements that are granted at the `project` level might cascade to project specific resources (such as instances):

`operator`
: Grants permission to create, view, edit, and delete all resources belonging to the project, but does not grant permission to edit the project configuration itself.

`viewer`
: Grants permission to view all resources belonging to the project.

`can_view`
: Grants permission to view the project.

`can_edit`
: Grants permission to edit the project.

`can_delete`
: Grants permission to delete the project.

`image_manager`
: Grants permission to create, view, edit, and delete all images belonging to the project.

`can_create_images`
: Grants permission to create images.

`can_view_images`
: Grants permission to view images.

`can_edit_images`
: Grants permission to edit images.

`can_delete_images`
: Grants permission to delete images.

`image_alias_manager`
: Grants permission to create, view, edit, and delete all image aliases belonging to the project.

`can_create_image_aliases`
: Grants permission to create image aliases.

`can_view_image_aliases`
: Grants permission to view image aliases.

`can_edit_image_aliases`
: Grants permission to edit image aliases.

`can_delete_image_aliases`
: Grants permission to delete image aliases.

`instance_manager`
: Grants permission to create, view, edit, and delete all instances belonging to the project.

`can_create_instances`
: Grants permission to create instances.

`can_view_instances`
: Grants permission to view instances.

`can_edit_instances`
: Grants permission to edit instances.

`can_delete_instances`
: Grants permission to delete instances.

`can_operate_instances`
: Grants permission to view instances, manage their state, manage their snapshots and backups, start terminal or console sessions, and access their files.

`network_manager`
: Grants permission to create, view, edit, and delete all networks belonging to the project.

`can_create_networks`
: Grants permission to create networks.

`can_view_networks`
: Grants permission to view networks.

`can_edit_networks`
: Grants permission to edit networks.

`can_delete_networks`
: Grants permission to delete networks.

`network_acl_manager`
: Grants permission to create, view, edit, and delete all network ACLs belonging to the project.

`can_create_network_acls`
: Grants permission to create network ACLs.

`can_view_network_acls`
: Grants permission to view network ACLs.

`can_edit_network_acls`
: Grants permission to edit network ACLs.

`can_delete_network_acls`
: Grants permission to delete network ACLs.

`network_zone_manager`
: Grants permission to create, view, edit, and delete all network zones belonging to the project.

`can_create_network_zones`
: Grants permission to create network zones.

`can_view_network_zones`
: Grants permission to view network zones.

`can_edit_network_zones`
: Grants permission to edit network zones.

`can_delete_network_zones`
: Grants permission to delete network zones.

`profile_manager`
: Grants permission to create, view, edit, and delete all profiles belonging to the project.

`can_create_profiles`
: Grants permission to create profiles.

`can_view_profiles`
: Grants permission to view profiles.

`can_edit_profiles`
: Grants permission to edit profiles.

`can_delete_profiles`
: Grants permission to delete profiles.

`storage_volume_manager`
: Grants permission to create, view, edit, and delete all storage volumes belonging to the project.

`can_create_storage_volumes`
: Grants permission to create storage volumes.

`can_view_storage_volumes`
: Grants permission to view storage volumes.

`can_edit_storage_volumes`
: Grants permission to edit storage volumes.

`can_delete_storage_volumes`
: Grants permission to delete storage volumes.

`storage_bucket_manager`
: Grants permission to create, view, edit, and delete all storage buckets belonging to the project.

`can_create_storage_buckets`
: Grants permission to create storage buckets.

`can_view_storage_buckets`
: Grants permission to view storage buckets.

`can_edit_storage_buckets`
: Grants permission to edit storage buckets.

`can_delete_storage_buckets`
: Grants permission to delete storage buckets.

`placement_group_manager`
: Grants permission to create, view, edit, and delete all placement groups belonging to the project.

`can_create_placement_groups`
: Grants permission to create placement groups.

`can_view_placement_groups`
: Grants permission to view placement groups.

`can_edit_placement_groups`
: Grants permission to edit placement groups.

`can_delete_placement_groups`
: Grants permission to delete placement groups.

`replicator_manager`
: Grants permission to create, view, edit, and delete all replicators belonging to the project.

`can_create_replicators`
: Grants permission to create replicators.

`can_view_replicators`
: Grants permission to view replicators.

`can_edit_replicators`
: Grants permission to edit replicators.

`can_delete_replicators`
: Grants permission to delete replicators.

`can_view_operations`
: Grants permission to view operations relating to the project.

`can_view_events`
: Grants permission to view life cycle events relating to the project.

`can_view_metrics`
: Grants permission to view project level metrics.

## Storage pool

> Entity type name: `storage_pool`

`can_edit`
: Grants permission to edit the storage pool.

`can_delete`
: Grants permission to delete the storage pool.

## Identity

> Entity type name: `identity`

`can_view`
: Grants permission to view the identity.

`can_edit`
: Grants permission to edit the identity. To edit an identity, it is additionally required that the caller is able to view all groups that the identity is a member of.

`can_delete`
: Grants permission to delete the identity.

## Group

> Entity type name: `group`

`can_view`
: Grants permission to view the group. Identities can always view groups that they are a member of.

`can_edit`
: Grants permission to edit the group.

`can_delete`
: Grants permission to delete the group.

## Identity provider group

> Entity type name: `identity_provider_group`

`can_view`
: Grants permission to view the identity provider group.

`can_edit`
: Grants permission to edit the identity provider group.

`can_delete`
: Grants permission to delete the identity provider group.

## Certificate

> Entity type name: `certificate`

`can_view`
: Grants permission to view the certificate.

`can_edit`
: Grants permission to edit the certificate.

`can_delete`
: Grants permission to delete the certificate.

## Instance

> Entity type name: `instance`

`user`
: Grants permission to view the instance, to access files, and to start a terminal or console session.

`operator`
: Grants permission to view the instance, to access files, start a terminal or console session, and to manage snapshots and backups.

`can_edit`
: Grants permission to edit the instance.

`can_delete`
: Grants permission to delete the instance.

`can_view`
: Grants permission to view the instance and any snapshots or backups it might have.

`can_update_state`
: Grants permission to change the instance state.

`can_manage_snapshots`
: Grants permission to create and delete snapshots of the instance.

`can_manage_backups`
: Grants permission to create and delete backups of the instance.

`can_connect_sftp`
: Grants permission to get an SFTP client for the instance.

`can_access_files`
: Grants permission to push or pull files into or out of the instance.

`can_access_console`
: Grants permission to start a console session.

`can_exec`
: Grants permission to start a terminal session.

## Image

> Entity type name: `image`

`can_edit`
: Grants permission to edit the image.

`can_delete`
: Grants permission to delete the image.

`can_view`
: Grants permission to view the image.

## Image alias

> Entity type name: `image_alias`

`can_edit`
: Grants permission to edit the image alias.

`can_delete`
: Grants permission to delete the image alias.

`can_view`
: Grants permission to view the image alias.

## Network

> Entity type name: `network`

`can_edit`
: Grants permission to edit the network.

`can_delete`
: Grants permission to delete the network.

`can_view`
: Grants permission to view the network.

## Network ACL

> Entity type name: `network_acl`

`can_edit`
: Grants permission to edit the network ACL.

`can_delete`
: Grants permission to delete the network ACL.

`can_view`
: Grants permission to view the network ACL.

## Network zone

> Entity type name: `network_zone`

`can_edit`
: Grants permission to edit the network zone.

`can_delete`
: Grants permission to delete the network zone.

`can_view`
: Grants permission to view the network zone.

## Profile

> Entity type name: `profile`

`can_edit`
: Grants permission to edit the profile.

`can_delete`
: Grants permission to delete the profile.

`can_view`
: Grants permission to view the profile.

## Storage volume

> Entity type name: `storage_volume`

`can_edit`
: Grants permission to edit the storage volume.

`can_delete`
: Grants permission to delete the storage volume.

`can_view`
: Grants permission to view the storage volume and any snapshots or backups it might have.

`can_manage_snapshots`
: Grants permission to create and delete snapshots of the storage volume.

`can_manage_backups`
: Grants permission to create and delete backups of the storage volume.

## Storage bucket

> Entity type name: `storage_bucket`

`can_edit`
: Grants permission to edit the storage bucket.

`can_delete`
: Grants permission to delete the storage bucket.

`can_view`
: Grants permission to view the storage bucket.


# index.html.md

<a id="storage-ceph"></a>

# Ceph RBD - `ceph`


            <p class="youtube_link">
              <a href="https://youtube.com/watch?v=kVLGbvRU98A" target="_blank">
                <span title="Ceph and a LXD cluster" class="play_icon">▶</span>
                <span title="Ceph and a LXD cluster">Watch on YouTube</span>
              </a>
            </p>
        <!-- Include start Ceph intro -->

[Ceph](https://ceph.io/en/) is an open-source storage platform that stores its data in a storage cluster based on .
It is highly scalable and, as a distributed system without a single point of failure, very reliable.

Ceph provides different components for block storage and for file systems.

<!-- Include end Ceph intro -->

Ceph  is Ceph’s block storage component that distributes data and workload across the Ceph cluster.
It uses thin provisioning, which means that it is possible to over-commit resources.

## Terminology

<!-- Include start Ceph terminology -->

Ceph uses the term *object* for the data that it stores.
The daemon that is responsible for storing and managing data is the *Ceph* .
Ceph’s storage is divided into *pools*, which are logical partitions for storing objects.
They are also referred to as *data pools*, *storage pools* or *OSD pools*.

<!-- Include end Ceph terminology -->

Ceph block devices are also called *RBD images*, and you can create *snapshots* and *clones* of these RBD images.

## `ceph` driver in LXD

#### NOTE
To use the Ceph RBD driver, you must specify it as `ceph`.
This is slightly misleading, because it uses only Ceph RBD (block storage) functionality, not full Ceph functionality.
For storage volumes with content type `filesystem` (images, containers and custom file-system volumes), the `ceph` driver uses Ceph RBD images with a file system on top (see [`block.filesystem`](#storage-ceph-volume-conf:block.filesystem)).

Alternatively, you can use the [CephFS](storage_cephfs.md#storage-cephfs) driver to create storage volumes with content type `filesystem`.

<!-- Include start Ceph driver cluster -->

Unlike other storage drivers, this driver does not set up the storage system but assumes that you already have a Ceph cluster installed.

<!-- Include end Ceph driver cluster -->
<!-- Include start Ceph driver remote -->

This driver also behaves differently than other drivers in that it provides remote storage.
As a result and depending on the internal network, storage access might be a bit slower than for local storage.
On the other hand, using remote storage has big advantages in a cluster setup, because all cluster members have access to the same storage pools with the exact same contents, without the need to synchronize storage pools.

<!-- Include end Ceph driver remote -->

The `ceph` driver in LXD uses RBD images for images, and snapshots and clones to create instances and snapshots.

<!-- Include start Ceph driver control -->

LXD assumes that it has full control over the OSD storage pool.
Therefore, you should never maintain any file system entities that are not owned by LXD in a LXD OSD storage pool, because LXD might delete them.

<!-- Include end Ceph driver control -->

Due to the way copy-on-write works in Ceph RBD, parent RBD images can’t be removed until all children are gone.
As a result, LXD automatically renames any objects that are removed but still referenced.
Such objects are kept with a  `zombie_` prefix until all references are gone and the object can safely be removed.

### Limitations

The `ceph` driver has the following limitations:

Sharing custom volumes between instances
: Custom storage volumes with [content type](../explanation/storage.md#storage-content-types) `filesystem` can usually be shared between multiple instances different cluster members.
  However, because the Ceph RBD driver “simulates” volumes with content type `filesystem` by putting a file system on top of an RBD image, custom storage volumes can only be assigned to a single instance at a time.
  If you need to share a custom volume with content type `filesystem`, use the [CephFS](storage_cephfs.md#storage-cephfs) driver instead.

Sharing the OSD storage pool between installations
: Sharing the same OSD storage pool between multiple LXD installations is not supported.

Using an OSD pool of type “erasure”
: To use a Ceph OSD pool of type “erasure”, you must create the OSD pool beforehand.
  You must also create a separate OSD pool of type “replicated” that will be used for storing metadata.
  This is required because Ceph RBD does not support `omap`.
  To specify which pool is “erasure coded”, set the [`ceph.osd.data_pool_name`](#storage-ceph-pool-conf:ceph.osd.data_pool_name) configuration option to the erasure coded pool name and the [`ceph.osd.pool_name`](#storage-ceph-pool-conf:ceph.osd.pool_name) configuration option to the replicated pool name.

## Configuration options

The following configuration options are available for storage pools that use the `ceph` driver and for storage volumes in these pools.

<a id="storage-ceph-pool-config"></a>

### Storage pool configuration

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="storage-ceph-pool-conf:ceph.cluster_name"></a>
`ceph.cluster_name`

Name of the Ceph cluster in which to create new storage pools

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-ceph-pool-conf:ceph.cluster_name)

| **Key:**     | `ceph.cluster_name`   |
|--------------|-----------------------|
| **Type:**    | string                |
| **Default:** | `ceph`                |
| **Scope:**   | global                |

<a id="storage-ceph-pool-conf:ceph.osd.data_pool_name"></a>
`ceph.osd.data_pool_name`

Name of the OSD data pool

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-ceph-pool-conf:ceph.osd.data_pool_name)

| **Key:**    | `ceph.osd.data_pool_name`   |
|-------------|-----------------------------|
| **Type:**   | string                      |
| **Scope:**  | global                      |

<a id="storage-ceph-pool-conf:ceph.osd.pg_num"></a>
`ceph.osd.pg_num`

Number of placement groups for the OSD storage pool

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-ceph-pool-conf:ceph.osd.pg_num)

| **Key:**     | `ceph.osd.pg_num`   |
|--------------|---------------------|
| **Type:**    | string              |
| **Default:** | `32`                |
| **Scope:**   | global              |

<a id="storage-ceph-pool-conf:ceph.osd.pool_name"></a>
`ceph.osd.pool_name`

Name of the OSD storage pool

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-ceph-pool-conf:ceph.osd.pool_name)

| **Key:**     | `ceph.osd.pool_name`   |
|--------------|------------------------|
| **Type:**    | string                 |
| **Default:** | name of the pool       |
| **Scope:**   | global                 |

This option specifies the name of the OSD storage pool.
The OSD storage pool gets created if missing.

<a id="storage-ceph-pool-conf:ceph.osd.pool_size"></a>
`ceph.osd.pool_size`

Number of RADOS object replicas. Set to 1 for no replication.

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-ceph-pool-conf:ceph.osd.pool_size)

| **Key:**     | `ceph.osd.pool_size`   |
|--------------|------------------------|
| **Type:**    | string                 |
| **Default:** | `3`                    |

This option specifies the name for the file metadata OSD pool that should be used when
creating a file system automatically.

<a id="storage-ceph-pool-conf:ceph.rbd.clone_copy"></a>
`ceph.rbd.clone_copy`

Whether to use RBD lightweight clones

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-ceph-pool-conf:ceph.rbd.clone_copy)

| **Key:**     | `ceph.rbd.clone_copy`   |
|--------------|-------------------------|
| **Type:**    | bool                    |
| **Default:** | `true`                  |
| **Scope:**   | global                  |

Enable this option to use RBD lightweight clones rather than full dataset copies.

<a id="storage-ceph-pool-conf:ceph.rbd.du"></a>
`ceph.rbd.du`

Whether to use RBD `du`

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-ceph-pool-conf:ceph.rbd.du)

| **Key:**     | `ceph.rbd.du`   |
|--------------|-----------------|
| **Type:**    | bool            |
| **Default:** | `true`          |
| **Scope:**   | global          |

This option specifies whether to use RBD `du` to obtain disk usage data for stopped instances.

<a id="storage-ceph-pool-conf:ceph.rbd.features"></a>
`ceph.rbd.features`

Comma-separated list of RBD features to enable on the volumes

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-ceph-pool-conf:ceph.rbd.features)

| **Key:**     | `ceph.rbd.features`                      |
|--------------|------------------------------------------|
| **Type:**    | string                                   |
| **Default:** | Default features defined in Ceph cluster |
| **Scope:**   | global                                   |

<a id="storage-ceph-pool-conf:ceph.user.name"></a>
`ceph.user.name`

The Ceph user to use when creating storage pools and volumes

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-ceph-pool-conf:ceph.user.name)

| **Key:**     | `ceph.user.name`   |
|--------------|--------------------|
| **Type:**    | string             |
| **Default:** | `admin`            |
| **Scope:**   | global             |

<a id="storage-ceph-pool-conf:source.recover"></a>
`source.recover`

Whether to recover an existing `source`

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-ceph-pool-conf:source.recover)

| **Key:**     | `source.recover`   |
|--------------|--------------------|
| **Type:**    | bool               |
| **Default:** | `false`            |
| **Scope:**   | local              |

Set this option to true to recover an existing source which was previously created by LXD.

<a id="storage-ceph-pool-conf:volatile.pool.pristine"></a>
`volatile.pool.pristine`

Whether the pool was empty on creation time

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-ceph-pool-conf:volatile.pool.pristine)

| **Key:**     | `volatile.pool.pristine`   |
|--------------|----------------------------|
| **Type:**    | string                     |
| **Default:** | `true`                     |
| **Scope:**   | global                     |

<a id="storage-ceph-vol-config"></a>

### Storage volume configuration

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="storage-ceph-volume-conf:block.filesystem"></a>
`block.filesystem`

File system of the storage volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-ceph-volume-conf:block.filesystem)

| **Key:**       | `block.filesystem`                                |
|----------------|---------------------------------------------------|
| **Type:**      | string                                            |
| **Default:**   | same as `volume.block.filesystem`                 |
| **Condition:** | block-based volume with content type `filesystem` |
| **Scope:**     | global                                            |

Valid options: `btrfs`, `ext4`, `xfs`
If not set, `ext4` is assumed.

<a id="storage-ceph-volume-conf:block.mount_options"></a>
`block.mount_options`

Mount options for block-backed file system volumes

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-ceph-volume-conf:block.mount_options)

| **Key:**       | `block.mount_options`                             |
|----------------|---------------------------------------------------|
| **Type:**      | string                                            |
| **Default:**   | same as `volume.block.mount_options`              |
| **Condition:** | block-based volume with content type `filesystem` |
| **Scope:**     | global                                            |

<a id="storage-ceph-volume-conf:security.shared"></a>
`security.shared`

Enable volume sharing

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-ceph-volume-conf:security.shared)

| **Key:**       | `security.shared`                           |
|----------------|---------------------------------------------|
| **Type:**      | bool                                        |
| **Default:**   | same as `volume.security.shared` or `false` |
| **Condition:** | virtual-machine or custom block volume      |
| **Scope:**     | global                                      |

Enable this option to allow the volume to be shared across multiple instances despite the possibility of data loss.

<a id="storage-ceph-volume-conf:security.shifted"></a>
`security.shifted`

Enable ID shifting overlay

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-ceph-volume-conf:security.shifted)

| **Key:**       | `security.shifted`                           |
|----------------|----------------------------------------------|
| **Type:**      | bool                                         |
| **Default:**   | same as `volume.security.shifted` or `false` |
| **Condition:** | custom volume                                |
| **Scope:**     | global                                       |

Enable this option to allow the volume to be attached to multiple isolated instances.

<a id="storage-ceph-volume-conf:security.unmapped"></a>
`security.unmapped`

Disable ID mapping for the volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-ceph-volume-conf:security.unmapped)

| **Key:**       | `security.unmapped`                           |
|----------------|-----------------------------------------------|
| **Type:**      | bool                                          |
| **Default:**   | same as `volume.security.unmapped` or `false` |
| **Condition:** | custom volume                                 |
| **Scope:**     | global                                        |

<a id="storage-ceph-volume-conf:size"></a>
`size`

Size/quota of the storage volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-ceph-volume-conf:size)

| **Key:**       | `size`                |
|----------------|-----------------------|
| **Type:**      | string                |
| **Default:**   | same as `volume.size` |
| **Condition:** | appropriate driver    |
| **Scope:**     | global                |

<a id="storage-ceph-volume-conf:snapshots.expiry"></a>
`snapshots.expiry`

Time until snapshots are deleted

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-ceph-volume-conf:snapshots.expiry)

| **Key:**       | `snapshots.expiry`                |
|----------------|-----------------------------------|
| **Type:**      | string                            |
| **Default:**   | same as `volume.snapshots.expiry` |
| **Condition:** | custom volume                     |
| **Scope:**     | global                            |

Specify an expression like `1M 2H 3d 4w 5m 6y`.

<a id="storage-ceph-volume-conf:snapshots.pattern"></a>
`snapshots.pattern`

Template for the snapshot name

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-ceph-volume-conf:snapshots.pattern)

| **Key:**       | `snapshots.pattern`                            |
|----------------|------------------------------------------------|
| **Type:**      | string                                         |
| **Default:**   | same as `volume.snapshots.pattern` or `snap%d` |
| **Condition:** | custom volume                                  |
| **Scope:**     | global                                         |

You can specify a naming template for scheduled snapshots and unnamed snapshots.

The `snapshots.pattern` option takes a Pongo2 template string to format the snapshot name.

To add a time stamp to the snapshot name, use the Pongo2 context variable `creation_date`.
Make sure to format the date in your template string to avoid forbidden characters in the snapshot name.
For example, set `snapshots.pattern` to `{{ creation_date|date:'2006-01-02_15-04-05' }}` to name the snapshots after their time of creation, down to the precision of a second.

Another way to avoid name collisions is to use the placeholder `%d` in the pattern.
If no matching snapshots exist, the placeholder is replaced with `0`.
Otherwise, it is replaced with the next snapshot index, which is one higher than the highest existing matching snapshot index.

<a id="storage-ceph-volume-conf:snapshots.schedule"></a>
`snapshots.schedule`

Schedule for automatic volume snapshots

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-ceph-volume-conf:snapshots.schedule)

| **Key:**       | `snapshots.schedule`         |
|----------------|------------------------------|
| **Type:**      | string                       |
| **Default:**   | same as `snapshots.schedule` |
| **Condition:** | custom volume                |
| **Scope:**     | global                       |

Specify either a cron expression (`<minute> <hour> <dom> <month> <dow>`), a comma-separated list of schedule aliases (`@hourly`, `@daily`, `@midnight`, `@weekly`, `@monthly`, `@annually`, `@yearly`), or leave empty to disable automatic snapshots (the default).

<a id="storage-ceph-volume-conf:volatile.devlxd.owner"></a>
`volatile.devlxd.owner`

ID of the DevLXD identity that owns the volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-ceph-volume-conf:volatile.devlxd.owner)

| **Key:**     | `volatile.devlxd.owner`   |
|--------------|---------------------------|
| **Type:**    | string                    |
| **Default:** | DevLXD owner identity ID  |
| **Scope:**   | global                    |

<a id="storage-ceph-volume-conf:volatile.idmap.last"></a>
`volatile.idmap.last`

JSON-serialized UID/GID map that has been applied to the volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-ceph-volume-conf:volatile.idmap.last)

| **Key:**       | `volatile.idmap.last`   |
|----------------|-------------------------|
| **Type:**      | string                  |
| **Condition:** | filesystem              |

<a id="storage-ceph-volume-conf:volatile.idmap.next"></a>
`volatile.idmap.next`

JSON-serialized UID/GID map that has been applied to the volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-ceph-volume-conf:volatile.idmap.next)

| **Key:**       | `volatile.idmap.next`   |
|----------------|-------------------------|
| **Type:**      | string                  |
| **Condition:** | filesystem              |

<a id="storage-ceph-volume-conf:volatile.uuid"></a>
`volatile.uuid`

Volume UUID

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-ceph-volume-conf:volatile.uuid)

| **Key:**     | `volatile.uuid`   |
|--------------|-------------------|
| **Type:**    | string            |
| **Default:** | random UUID       |
| **Scope:**   | global            |


# index.html.md

<a id="devices-proxy"></a>

# Type: `proxy`


            <p class="youtube_link">
              <a href="https://www.youtube.com/watch?v=IbAKwRBW8V0" target="_blank">
                <span title="LXD proxy devices" class="play_icon">▶</span>
                <span title="LXD proxy devices">Watch on YouTube</span>
              </a>
            </p>
        
#### NOTE
The `proxy` device type is supported for both containers (NAT and non-NAT modes) and VMs (NAT mode only).
It supports hotplugging for both containers and VMs.

Proxy devices allow you to forward network connections between a host and an instance running on that host.

You can use them to:

- Forward traffic from an address on the host to an address inside the instance.
- Do the reverse, enabling an address inside the instance to connect through the host.

In [NAT mode](#devices-proxy-nat-mode), proxy devices support TCP and UDP proxying (traffic forwarding).
In non-NAT mode, proxy devices can also forward traffic between Unix sockets, which is useful for tasks such as forwarding a GUI or audio traffic from a container to the host system. Additionally, they can proxy traffic across different protocols—for example, forwarding traffic from a TCP listener on the host to a Unix socket inside a container.

The supported connection types are:

- `tcp <-> tcp`
- `udp <-> udp`
- `unix <-> unix`
- `tcp <-> unix`
- `unix <-> tcp`
- `tcp <-> udp`
- `unix <-> udp`

To add a `proxy` device, use the following command:

```none
lxc config device add <instance_name> <device_name> proxy listen=<type>:<addr>:<port>[-<port>][,<port>] connect=<type>:<addr>:<port> bind=<host/instance_name>
```

<a id="devices-proxy-nat-mode"></a>

## NAT mode

The proxy device supports a NAT mode (`nat=true`), which forwards packets using NAT instead of creating a separate proxy connection.

This mode has the benefit that the client address is maintained without requiring the target destination to support the HAProxy PROXY protocol. This is necessary for passing client addresses in non-NAT mode.

However, NAT mode is only available when the host running the instance also acts as the gateway. This is the typical case when using `lxdbr0`, for example.

In NAT mode, the supported connection types are:

- `tcp <-> tcp`
- `udp <-> udp`

When configuring a proxy device with `nat=true`, you must ensure that the target instance has a static IP configured on its NIC device.

## Specifying IP addresses

Use the following command to configure a static IP for an instance NIC:

```none
lxc config device set <instance_name> <nic_name> ipv4.address=<ipv4_address> ipv6.address=<ipv6_address>
```

To define a static IPv6 address, the parent managed network must have `ipv6.dhcp.stateful` enabled.

When defining IPv6 addresses, use square bracket notation. Example:

```none
connect=tcp:[2001:db8::1]:80
```

You can specify that the connect address should be the IP of the instance by setting the connect IP to the wildcard address, which is `0.0.0.0` for IPv4 and `[::]` for IPv6.

#### NOTE
The listen address can also use wildcard addresses in non-NAT mode.
However, when using NAT mode, you must specify an IP address on the LXD host.

## Device options

`proxy` devices have the following device options:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="device-proxy-device-conf:bind"></a>
`bind`

Which side to bind on

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-proxy-device-conf:bind)

| **Key:**      | `bind`   |
|---------------|----------|
| **Type:**     | string   |
| **Default:**  | `host`   |
| **Required:** | no       |

Possible values are `host` and `instance`.

<a id="device-proxy-device-conf:connect"></a>
`connect`

Address and port to connect to

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-proxy-device-conf:connect)

| **Key:**      | `connect`   |
|---------------|-------------|
| **Type:**     | string      |
| **Required:** | yes         |

Use the following format to specify the address and port: `<type>:<addr>:<port>[-<port>][,<port>]`

<a id="device-proxy-device-conf:gid"></a>
`gid`

GID of the owner of the listening Unix socket

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-proxy-device-conf:gid)

| **Key:**      | `gid`   |
|---------------|---------|
| **Type:**     | integer |
| **Default:**  | `0`     |
| **Required:** | no      |

<a id="device-proxy-device-conf:listen"></a>
`listen`

Address and port to bind and listen

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-proxy-device-conf:listen)

| **Key:**      | `listen`   |
|---------------|------------|
| **Type:**     | string     |
| **Required:** | yes        |

Use the following format to specify the address and port: `<type>:<addr>:<port>[-<port>][,<port>]`

<a id="device-proxy-device-conf:mode"></a>
`mode`

Mode for the listening Unix socket

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-proxy-device-conf:mode)

| **Key:**      | `mode`   |
|---------------|----------|
| **Type:**     | integer  |
| **Default:**  | `0644`   |
| **Required:** | no       |

<a id="device-proxy-device-conf:nat"></a>
`nat`

Whether to optimize proxying via NAT

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-proxy-device-conf:nat)

| **Key:**      | `nat`   |
|---------------|---------|
| **Type:**     | bool    |
| **Default:**  | `false` |
| **Required:** | no      |

This option requires that the instance NIC has a static IP address.

<a id="device-proxy-device-conf:proxy_protocol"></a>
`proxy_protocol`

Whether to use the HAProxy PROXY protocol

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-proxy-device-conf:proxy_protocol)

| **Key:**      | `proxy_protocol`   |
|---------------|--------------------|
| **Type:**     | bool               |
| **Default:**  | `false`            |
| **Required:** | no                 |

This option specifies whether to use the HAProxy PROXY protocol to transmit sender information.

<a id="device-proxy-device-conf:security.gid"></a>
`security.gid`

What GID to drop privilege to

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-proxy-device-conf:security.gid)

| **Key:**      | `security.gid`   |
|---------------|------------------|
| **Type:**     | integer          |
| **Default:**  | `0`              |
| **Required:** | no               |

<a id="device-proxy-device-conf:security.uid"></a>
`security.uid`

What UID to drop privilege to

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-proxy-device-conf:security.uid)

| **Key:**      | `security.uid`   |
|---------------|------------------|
| **Type:**     | integer          |
| **Default:**  | `0`              |
| **Required:** | no               |

<a id="device-proxy-device-conf:uid"></a>
`uid`

UID of the owner of the listening Unix socket

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#device-proxy-device-conf:uid)

| **Key:**      | `uid`   |
|---------------|---------|
| **Type:**     | integer |
| **Default:**  | `0`     |
| **Required:** | no      |

## Configuration examples

Add a `proxy` device that forwards traffic from one address (the `listen` address) to another address (the `connect` address) using NAT mode:

```none
lxc config device add <instance_name> <device_name> proxy nat=true listen=tcp:<ip_address>:<port> connect=tcp:<ip_address>:<port>
```

Add a `proxy` device that forwards traffic going to a specific IP to a Unix socket on an instance that might not have a network connection:

```none
lxc config device add <instance_name> <device_name> proxy listen=tcp:<ip_address>:<port> connect=unix:/<socket_path_on_instance>
```

Add a `proxy` device that forwards traffic going to a Unix socket on an instance that might not have a network connection to a specific IP address:

```none
lxc config device add <instance_name> <device_name> proxy bind=instance listen=unix:/<socket_path_on_instance> connect=tcp:<ip_address>:<port>
```

See [Configure devices](../howto/instances_configure.md#instances-configure-devices) for more information.


# index.html.md

<a id="storage-powerstore"></a>

# Dell PowerStore - `powerstore`

Dell PowerStore is a storage solution from [Dell Technologies](https://www.dell.com/).
It offers the consumption of block storage across the network.

LXD supports connecting to PowerStore storage through  (Internet Small Computer Systems Interface) or  (Fibre Channel).

For iSCSI, ensure that the required kernel modules and the iSCSI CLI (`iscsiadm`) are installed on your host system.

## Terminology

PowerStore does not have a concept of storage pools.
Instead, LXD scopes its volumes to a storage pool by prefixing each volume name with a deterministic storage pool identifier.
This prefix prevents name conflicts between volumes belonging to different LXD storage pools on the same PowerStore array.

LXD creates volumes on the PowerStore array and maps them to the respective LXD host.
When the first volume needs to be mapped to a specific LXD host, LXD discovers and connects to the available targets provided by PowerStore.

## The `powerstore` driver in LXD

The `powerstore` driver in LXD uses PowerStore volumes for custom storage volumes, instances, and snapshots.
All volumes created by LXD using the `powerstore` driver are thin-provisioned block volumes. If required (for example, for containers and custom file system volumes), LXD formats the volume with a desired file system.

LXD expects PowerStore to be pre-configured and accessible. When creating the LXD storage pool, the user must specify authentication credentials that allow LXD to connect to PowerStore. LXD also assumes that it has full control over the volumes it manages.

This driver provides remote storage.
As a result, and depending on the internal network, storage access might be a bit slower compared to local storage.
On the other hand, using remote storage has significant advantages in a cluster setup: all cluster members have access to the same storage pools with the exact same contents, without requiring the storage pools to be synchronized between members.

For iSCSI, when a volume is first mapped to the LXD host, LXD discovers the available targets from the PowerStore array and connects to them.
You can optionally restrict connections to specific targets using [`powerstore.target`](#storage-powerstore-pool-conf:powerstore.target).
For Fibre Channel, targets are discovered automatically through the FC  (Host Bus Adapter). The [`powerstore.target`](#storage-powerstore-pool-conf:powerstore.target) option does not apply to FC mode.

Volume snapshots are supported by PowerStore.
When a volume with at least one snapshot is copied, LXD sequentially creates snapshots on the destination volume from snapshots on the source volume.
Finally, once all snapshots are copied, the source volume is copied into the destination volume.

<a id="storage-powerstore-volume-names"></a>

### Volume names

The driver uses the volume’s [`volatile.uuid`](#storage-powerstore-volume-conf:volatile.uuid) to generate a volume name.
The pool-scoped prefix `lxd-<pool_name_hash>-` is prepended to all volume names along with special identifiers, such as `c_` or `v_`, to distinguish volume types.
Additional identifiers, such as `.i` or `.b`, may also be appended to further distinguish volume types.

| Type                     | Identifier   | Example                                                                                                                                                               |
|--------------------------|--------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Container                | `c_`         | `c_5a2504b0-6a6c-4849-8ee7-ddb0b674fd14`                                                                                                                              |
| Virtual machine          | `v_`         | `v_5a2504b0-6a6c-4849-8ee7-ddb0b674fd14.b` (block volume) and `v_5a2504b0-6a6c-4849-8ee7-ddb0b674fd14` (file system volume)                                           |
| Image (ISO)              | `i_`         | `i_5a2504b0-6a6c-4849-8ee7-ddb0b674fd14.i`                                                                                                                            |
| Custom volume            | `u_`         | `u_5a2504b0-6a6c-4849-8ee7-ddb0b674fd14` (file system volume) or `u_5a2504b0-6a6c-4849-8ee7-ddb0b674fd14.b` (block volume)                                            |
| Mountable snapshot clone | `s`          | `sc_5a2504b0-6a6c-4849-8ee7-ddb0b674fd14` (container), `sv_5a2504b0-6a6c-4849-8ee7-ddb0b674fd14.b` (VM), or `su_5a2504b0-6a6c-4849-8ee7-ddb0b674fd14` (custom volume) |

Snapshots in PowerStore are native children of their parent volume. Each snapshot is named using the snapshot’s own UUID with the same type prefix as the parent volume.
Mountable snapshot clones are temporary volumes created by LXD when a snapshot needs to be directly accessed (for example, during export). The `s` prefix is prepended to the volume type identifier to distinguish them from regular volumes.

<a id="storage-powerstore-limitations"></a>

### Limitations

The `powerstore` driver has the following limitations:

Volume size constraints
: The minimum volume size (quota) is `1MiB` and must be a multiple of `1MiB`. The maximum volume size is `256TiB`.

Volume shrinking
: The PowerStore driver does not allow shrinking volumes.

Sharing custom volumes between instances
: The PowerStore driver “simulates” volumes with content type `filesystem` by putting a file system on top of a PowerStore volume.
  Therefore, custom storage volumes can only be assigned to a single instance at a time.

Sharing a PowerStore storage pool between multiple LXD installations
: Sharing the same PowerStore storage pool between multiple LXD installations is not supported.

Recovering PowerStore storage pools
: Recovery of PowerStore storage pools using `lxd recover` is not supported.

<a id="storage-powerstore-options"></a>

## Configuration options

The following configuration options are available for storage pools that use the `powerstore` driver, as well as storage volumes in these pools.

<a id="storage-powerstore-pool-config"></a>

### Storage pool configuration

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="storage-powerstore-pool-conf:powerstore.gateway"></a>
`powerstore.gateway`

Address of the PowerStore Gateway

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerstore-pool-conf:powerstore.gateway)

| **Key:**    | `powerstore.gateway`   |
|-------------|------------------------|
| **Type:**   | string                 |
| **Scope:**  | global                 |

<a id="storage-powerstore-pool-conf:powerstore.gateway.verify"></a>
`powerstore.gateway.verify`

Whether to verify the PowerStore Gateway’s certificate

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerstore-pool-conf:powerstore.gateway.verify)

| **Key:**     | `powerstore.gateway.verify`   |
|--------------|-------------------------------|
| **Type:**    | bool                          |
| **Default:** | `true`                        |
| **Scope:**   | global                        |

<a id="storage-powerstore-pool-conf:powerstore.mode"></a>
`powerstore.mode`

How volumes are mapped to the local server

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerstore-pool-conf:powerstore.mode)

| **Key:**      | `powerstore.mode`   |
|---------------|---------------------|
| **Type:**     | string              |
| **Default:**  | the discovered mode |
| **Required:** | true                |
| **Scope:**    | global              |

The mode to use to map PowerStore volumes to the local server.
Supported values are `iscsi` and `scsi/fc`.

<a id="storage-powerstore-pool-conf:powerstore.target"></a>
`powerstore.target`

List of target addresses the LXD connects to.

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerstore-pool-conf:powerstore.target)

| **Key:**     | `powerstore.target`   |
|--------------|-----------------------|
| **Type:**    | string                |
| **Default:** | target addresses      |

A comma-separated list of target addresses. If empty, LXD discovers and connects to all available targets. Otherwise, it only connects to the specified addresses.

<a id="storage-powerstore-pool-conf:powerstore.user.name"></a>
`powerstore.user.name`

User for PowerStore Gateway authentication

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerstore-pool-conf:powerstore.user.name)

| **Key:**     | `powerstore.user.name`   |
|--------------|--------------------------|
| **Type:**    | string                   |
| **Default:** | `admin`                  |
| **Scope:**   | global                   |

Name of the PowerStore user with an admin role that gives LXD full control over managed storage pools.

<a id="storage-powerstore-pool-conf:powerstore.user.password"></a>
`powerstore.user.password`

Password for PowerStore Gateway authentication

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerstore-pool-conf:powerstore.user.password)

| **Key:**    | `powerstore.user.password`   |
|-------------|------------------------------|
| **Type:**   | string                       |
| **Scope:**  | global                       |

<a id="storage-powerstore-pool-conf:rsync.bwlimit"></a>
`rsync.bwlimit`

Upper limit on the socket I/O for `rsync`

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerstore-pool-conf:rsync.bwlimit)

| **Key:**     | `rsync.bwlimit`   |
|--------------|-------------------|
| **Type:**    | string            |
| **Default:** | `0` (no limit)    |
| **Scope:**   | global            |

When `rsync` must be used to transfer storage entities, this option specifies the upper limit
to be placed on the socket I/O.

<a id="storage-powerstore-pool-conf:rsync.compression"></a>
`rsync.compression`

Whether to use compression while migrating storage pools

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerstore-pool-conf:rsync.compression)

| **Key:**     | `rsync.compression`   |
|--------------|-----------------------|
| **Type:**    | bool                  |
| **Default:** | `true`                |
| **Scope:**   | global                |

<a id="storage-powerstore-pool-conf:volume.size"></a>
`volume.size`

Size/quota of the storage volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerstore-pool-conf:volume.size)

| **Key:**     | `volume.size`   |
|--------------|-----------------|
| **Type:**    | string          |
| **Default:** | `10GiB`         |
| **Scope:**   | global          |

The size must be in multiples of 1 MiB. The minimum size is 1 MiB and maximum is 256 TiB.

<a id="storage-powerstore-vol-config"></a>

### Storage volume configuration

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="storage-powerstore-volume-conf:block.filesystem"></a>
`block.filesystem`

File system of the storage volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerstore-volume-conf:block.filesystem)

| **Key:**       | `block.filesystem`                                |
|----------------|---------------------------------------------------|
| **Type:**      | string                                            |
| **Default:**   | same as `volume.block.filesystem`                 |
| **Condition:** | block-based volume with content type `filesystem` |
| **Scope:**     | global                                            |

Valid options: `btrfs`, `ext4`, `xfs`
If not set, `ext4` is assumed.

<a id="storage-powerstore-volume-conf:block.mount_options"></a>
`block.mount_options`

Mount options for block-backed file system volumes

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerstore-volume-conf:block.mount_options)

| **Key:**       | `block.mount_options`                             |
|----------------|---------------------------------------------------|
| **Type:**      | string                                            |
| **Default:**   | same as `volume.block.mount_options`              |
| **Condition:** | block-based volume with content type `filesystem` |
| **Scope:**     | global                                            |

<a id="storage-powerstore-volume-conf:security.shared"></a>
`security.shared`

Enable volume sharing

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerstore-volume-conf:security.shared)

| **Key:**       | `security.shared`                           |
|----------------|---------------------------------------------|
| **Type:**      | bool                                        |
| **Default:**   | same as `volume.security.shared` or `false` |
| **Condition:** | virtual-machine or custom block volume      |
| **Scope:**     | global                                      |

Enable this option to allow the volume to be shared across multiple instances despite the possibility of data loss.

<a id="storage-powerstore-volume-conf:security.shifted"></a>
`security.shifted`

Enable ID shifting overlay

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerstore-volume-conf:security.shifted)

| **Key:**       | `security.shifted`                           |
|----------------|----------------------------------------------|
| **Type:**      | bool                                         |
| **Default:**   | same as `volume.security.shifted` or `false` |
| **Condition:** | custom volume                                |
| **Scope:**     | global                                       |

Enable this option to allow the volume to be attached to multiple isolated instances.

<a id="storage-powerstore-volume-conf:security.unmapped"></a>
`security.unmapped`

Disable ID mapping for the volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerstore-volume-conf:security.unmapped)

| **Key:**       | `security.unmapped`                           |
|----------------|-----------------------------------------------|
| **Type:**      | bool                                          |
| **Default:**   | same as `volume.security.unmapped` or `false` |
| **Condition:** | custom volume                                 |
| **Scope:**     | global                                        |

<a id="storage-powerstore-volume-conf:size"></a>
`size`

Size/quota of the storage volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerstore-volume-conf:size)

| **Key:**     | `size`                |
|--------------|-----------------------|
| **Type:**    | string                |
| **Default:** | same as `volume.size` |
| **Scope:**   | global                |

The size must be in multiples of 1 MiB. The minimum size is 1 MiB and maximum is 256 TiB.

<a id="storage-powerstore-volume-conf:snapshots.expiry"></a>
`snapshots.expiry`

Time until snapshots are deleted

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerstore-volume-conf:snapshots.expiry)

| **Key:**       | `snapshots.expiry`                |
|----------------|-----------------------------------|
| **Type:**      | string                            |
| **Default:**   | same as `volume.snapshots.expiry` |
| **Condition:** | custom volume                     |
| **Scope:**     | global                            |

Specify an expression like `1M 2H 3d 4w 5m 6y`.

<a id="storage-powerstore-volume-conf:snapshots.pattern"></a>
`snapshots.pattern`

Template for the snapshot name

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerstore-volume-conf:snapshots.pattern)

| **Key:**       | `snapshots.pattern`                            |
|----------------|------------------------------------------------|
| **Type:**      | string                                         |
| **Default:**   | same as `volume.snapshots.pattern` or `snap%d` |
| **Condition:** | custom volume                                  |
| **Scope:**     | global                                         |

You can specify a naming template for scheduled snapshots and unnamed snapshots.

The `snapshots.pattern` option takes a Pongo2 template string to format the snapshot name.

To add a time stamp to the snapshot name, use the Pongo2 context variable `creation_date`.
Make sure to format the date in your template string to avoid forbidden characters in the snapshot name.
For example, set `snapshots.pattern` to `{{ creation_date|date:'2006-01-02_15-04-05' }}` to name the snapshots after their time of creation, down to the precision of a second.

Another way to avoid name collisions is to use the placeholder `%d` in the pattern.
If no matching snapshots exist, the placeholder is replaced with `0`.
Otherwise, it is replaced with the next snapshot index, which is one higher than the highest existing matching snapshot index.

<a id="storage-powerstore-volume-conf:snapshots.schedule"></a>
`snapshots.schedule`

Schedule for automatic volume snapshots

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerstore-volume-conf:snapshots.schedule)

| **Key:**       | `snapshots.schedule`         |
|----------------|------------------------------|
| **Type:**      | string                       |
| **Default:**   | same as `snapshots.schedule` |
| **Condition:** | custom volume                |
| **Scope:**     | global                       |

Specify either a cron expression (`<minute> <hour> <dom> <month> <dow>`), a comma-separated list of schedule aliases (`@hourly`, `@daily`, `@midnight`, `@weekly`, `@monthly`, `@annually`, `@yearly`), or leave empty to disable automatic snapshots (the default).

<a id="storage-powerstore-volume-conf:volatile.devlxd.owner"></a>
`volatile.devlxd.owner`

ID of the DevLXD identity that owns the volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerstore-volume-conf:volatile.devlxd.owner)

| **Key:**     | `volatile.devlxd.owner`   |
|--------------|---------------------------|
| **Type:**    | string                    |
| **Default:** | DevLXD owner identity ID  |
| **Scope:**   | global                    |

<a id="storage-powerstore-volume-conf:volatile.idmap.last"></a>
`volatile.idmap.last`

JSON-serialized UID/GID map that has been applied to the volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerstore-volume-conf:volatile.idmap.last)

| **Key:**       | `volatile.idmap.last`   |
|----------------|-------------------------|
| **Type:**      | string                  |
| **Condition:** | filesystem              |

<a id="storage-powerstore-volume-conf:volatile.idmap.next"></a>
`volatile.idmap.next`

JSON-serialized UID/GID map that has been applied to the volume

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerstore-volume-conf:volatile.idmap.next)

| **Key:**       | `volatile.idmap.next`   |
|----------------|-------------------------|
| **Type:**      | string                  |
| **Condition:** | filesystem              |

<a id="storage-powerstore-volume-conf:volatile.uuid"></a>
`volatile.uuid`

Volume UUID

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#storage-powerstore-volume-conf:volatile.uuid)

| **Key:**     | `volatile.uuid`   |
|--------------|-------------------|
| **Type:**    | string            |
| **Default:** | random UUID       |
| **Scope:**   | global            |


# index.html.md

<a id="grafana"></a>

# Set up a Grafana dashboard

To visualize the metrics and logs data, set up [Grafana](https://grafana.com/).
LXD provides a [Grafana dashboard](https://grafana.com/grafana/dashboards/19131-lxd/) that is configured to display the LXD metrics scraped by Prometheus and events sent to Loki.

#### NOTE
The dashboard requires Grafana 8.4 or later.

See the Grafana documentation for instructions on installing and signing in:

- [Install Grafana](https://grafana.com/docs/grafana/latest/setup-grafana/installation/)
- [Sign in to Grafana](https://grafana.com/docs/grafana/latest/setup-grafana/sign-in-to-grafana/)

Complete the following steps to import the [LXD dashboard](https://grafana.com/grafana/dashboards/19131-lxd/):

1. Configure Prometheus as a data source:
   1. From the Basic (quick setup) panel, choose Data Sources.

      ![Choose data source in Grafana](images/grafana_welcome.png)
   2. Select Prometheus.

      ![Select Prometheus as a data source](images/grafana_select_prometheus.png)
   3. In the URL field, enter the address of your Prometheus installation (`http://localhost:9090/` if running Prometheus locally).

      ![Enter Prometheus URL](images/grafana_configure_prometheus.png)
   4. Keep the default configuration for the other fields and click Save & test.
2. Configure Loki as another data source:
   1. Select Loki.

      ![Select Loki as another data source](images/grafana_select_loki.png)
   2. In the URL field, enter the address of your Loki installation (`http://localhost:3100/` if running Loki locally).

      ![Enter Loki URL](images/grafana_configure_loki.png)
   3. Keep the default configuration for the other fields and click Save & test.
3. Import the LXD dashboard:
   1. Go back to the Basic (quick setup) panel and now choose Dashboards > Import a dashboard.
   2. In the Find and import dashboards field, enter the dashboard ID `19131`.

      ![Enter the LXD dashboard ID](images/grafana_dashboard_import.png)
   3. Click Load.
   4. In the LXD drop-down menu, select the Prometheus and Loki data sources that you configured.

      ![Select the Prometheus data source](images/grafana_dashboard_select_datasource.png)
   5. Click Import.

You should now see the LXD dashboard.
You can select the project and filter by instances.

![Resource overview in the LXD Grafana dashboard](images/grafana_resources.png)

At the bottom of the page, you can see data for each instance.

![Instance data in the LXD Grafana dashboard](images/grafana_instances.png)

#### NOTE
For proper operation of the Loki part of the dashboard, you need to ensure that the `instance` field matches the Prometheus job name.
You can change the `instance` field through the [`loki.instance`](../server.md#server-loki:loki.instance) configuration key.

The Prometheus `job_name` value can be found in `/var/snap/prometheus/current/prometheus.yml` (if you are using the snap) or `/etc/prometheus/prometheus.yaml` (otherwise).

To set the `loki.instance` configuration key, run the following command:
`lxc config set loki.instance=<job_name_value>`

You can check that setting via:
`lxc config get loki.instance`

## Scripted setup and LXD UI integration

As an alternative to the manual steps above, we provide a script to set up the Grafana dashboard. This only supports a single-node LXD installation.

1. Launch a new instance on your LXD server:
   ```none
   lxc launch ubuntu:24.04 grafana --project default
   ```
2. Run the following commands to download and execute the script to set up Grafana on the `grafana` instance:
   ```none
   curl -s https://raw.githubusercontent.com/canonical/lxd/refs/heads/main/scripts/setup-grafana.sh -o /tmp/setup-grafana.sh
   chmod +x /tmp/setup-grafana.sh
   /tmp/setup-grafana.sh grafana default
   ```
3. After the script finishes, sign in to Grafana with the default credentials `admin`/`admin` and change the password.
4. Import the LXD dashboard as described in step 3 of the manual steps in the preceding section.

The script installs Grafana, Prometheus, and Loki on a LXD instance. It also configures LXD to send metrics to Prometheus and logs to Loki. Additionally, it configures the LXD UI to be aware of the Grafana dashboard. This enables the UI to render a deep link Metrics to the Grafana dashboard from instance details pages (available since LXD 6.3):

![Metrics link in the LXD UI instance detail page](images/grafana_lxd_ui_metrics_integration.png)

![Dashboard details for a running instance](images/grafana_lxd_ui_instance_dashboard.png)


# index.html.md

<a id="disaster-recovery"></a>

# How to recover instances in case of disaster


            <p class="youtube_link">
              <a href="https://www.youtube.com/watch?v=vJhTjhQYKJs&t=466s" target="_blank">
                <span title="LXD backup and disaster recovery" class="play_icon">▶</span>
                <span title="LXD backup and disaster recovery">Watch on YouTube</span>
              </a>
            </p>
        
LXD provides a tool for disaster recovery in case the [LXD database](../database.md#database) is corrupted or otherwise lost.

The tool scans the storage pools for instances and imports the instances, custom volumes and buckets that it finds back into the database.
You need to re-create the required entities that are missing (usually pools, profiles, projects, and networks).

#### IMPORTANT
This tool should be used for disaster recovery only.
Do not rely on this tool as an alternative to proper backups; you will lose data like profiles, network definitions, or server configuration.

The tool must be run interactively and cannot be used in automated scripts.

The tool is available through the `lxd recover` command (note the `lxd` command rather than the normal `lxc` command).

## Recovery process

When you run the tool, it scans all storage pools that still exist in the database, looking for missing volumes that can be recovered.
Any unknown storage pools (those that exist on disk but do not exist in the database) which are discovered whilst scanning existing and unknown volumes
are printed so they can be created manually using the `lxc storage create ... source.recover=true` command.
Concrete examples for each storage driver can be found in [Recover a storage pool](storage_pools.md#howto-storage-pools-recover).

After mounting the specified storage pools (if not already mounted), the tool scans them for unknown volumes that look like they are associated with LXD.
LXD maintains a `backup.yaml` file in each instance’s storage volume, which contains all necessary information to recover a given instance (including instance configuration, attached devices, storage volume, and pool configuration).
This data can be used to rebuild the instance, storage volume, attached custom volumes, and storage pool database records.
Before recovering an instance, the tool performs some consistency checks to compare what is in the `backup.yaml` file with what is actually on disk (such as matching snapshots).
If all checks out, the database records are re-created.

The tool asks you to re-create missing entities like networks.
However, the tool does not know how the instance was configured.
That means that if some configuration was specified through the `default` profile, you must also re-add the required configuration to the profile.
For example, if the `lxdbr0` bridge is used in an instance and you are prompted to re-create it, you must add it back to the `default` profile so that the recovered instance uses it.

## Example

This is how a recovery process could look.
We start by adding the `default` pool we still know about. On this pool we expect an instance `v1` which might use volumes from others unknown pools:

`user@host:~$ ``lxc storage create default zfs source=/dev/sdb zfs.pool_name=default source.recover=true
`
```text
Storage pool default created
```

`user@host:~$ ``lxd recover
`
```text
This LXD server currently has the following storage pools:
 - Pool "default" using driver "zfs"
Would you like to continue with scanning for lost volumes? (yes/no) [default=yes]:
Scanning for unknown volumes...
The following unknown volumes have been found:
 - Virtual-Machine "v1" on pool "default" in project "default" (includes 0 snapshots)
 - Volume "vol1" on pool "backup" in project "default" (includes 0 snapshots)
You are currently missing the following:
 - Pool "backup" using driver "lvm" (lvm.thinpool_name="LXDThinPool" lvm.vg_name="backup" source="backup" volatile.initial_source="/dev/sdc")
Please create those missing entries and then hit ENTER:
```

The instance `v1` was discovered successfully.
It has an additional custom volume `vol1` attached from pool `backup` which isn’t yet known.
In another terminal create the missing pool after copying the pool’s configuration and adding the `source.recover=true` configuration item:

`user@host:~$ ``lxc storage create backup lvm lvm.thinpool_name="LXDThinPool" lvm.vg_name="backup" source="backup" volatile.initial_source="/dev/sdc" source.recover=true
`
```text
Storage pool backup created
```

Go back to the original terminal and hit ENTER:

`user@host:~$ ``lxd recover
`
```text
...

This LXD server currently has the following storage pools:
 - Pool "backup" using driver "lvm"
 - Pool "default" using driver "zfs"
Would you like to continue with scanning for lost volumes? (yes/no) [default=yes]:
Scanning for unknown volumes...
The following unknown volumes have been found:
 - Container "u1" on pool "backup" in project "default" (includes 0 snapshots)
 - Container "u2" on pool "backup" in project "default" (includes 0 snapshots)
 - Volume "vol1" on pool "backup" in project "default" (includes 0 snapshots)
 - Virtual-Machine "v1" on pool "default" in project "default" (includes 0 snapshots)
You are currently missing the following:
 - Network "lxdbr0" in project "default"
Please create those missing entries and then hit ENTER:
```

As we are now scanning one additional pool, we were able to identify even more missing resources.
Create the missing network in another terminal:

`user@host:~$ ``lxc network create lxdbr0
`
```text
Network lxdbr0 created
```

In the original terminal hit ENTER one last time:

`user@host:~$ ``lxd recover
`
```text
...

This LXD server currently has the following storage pools:
 - Pool "backup" using driver "lvm"
 - Pool "default" using driver "zfs"
Would you like to continue with scanning for lost volumes? (yes/no) [default=yes]:
Scanning for unknown volumes...
The following unknown volumes have been found:
 - Volume "vol1" on pool "backup" in project "default" (includes 0 snapshots)
 - Container "u1" on pool "backup" in project "default" (includes 0 snapshots)
 - Container "u2" on pool "backup" in project "default" (includes 0 snapshots)
 - Virtual-Machine "v1" on pool "default" in project "default" (includes 0 snapshots)
Would you like those to be recovered? (yes/no) [default=no]: yes
Starting recovery...
```

`user@host:~$ ``lxc list
`
```text
+------+---------+------+------+-----------------+-----------+
| NAME |  STATE  | IPV4 | IPV6 |      TYPE       | SNAPSHOTS |
+------+---------+------+------+-----------------+-----------+
| u1   | STOPPED |      |      | CONTAINER       | 0         |
+------+---------+------+------+-----------------+-----------+
| u2   | STOPPED |      |      | CONTAINER       | 0         |
+------+---------+------+------+-----------------+-----------+
| v1   | STOPPED |      |      | VIRTUAL-MACHINE | 0         |
+------+---------+------+------+-----------------+-----------+
```

`user@host:~$ ``lxc profile device add default eth0 nic network=lxdbr0 name=eth0
`
```text
Device eth0 added to default
```

`user@host:~$ ``lxc start u1
``user@host:~$ ``lxc list
`
```text
+------+---------+----------------------+-----------------------------------------------+-----------------+-----------+
| NAME |  STATE  |         IPV4         |                     IPV6                      |      TYPE       | SNAPSHOTS |
+------+---------+----------------------+-----------------------------------------------+-----------------+-----------+
| u1   | RUNNING | 192.0.2.2 (eth0)     | 2001:db8:cff3:5089:216:3eff:fef0:549f (eth0)  | CONTAINER       | 0         |
+------+---------+----------------------+-----------------------------------------------+-----------------+-----------+
| u2   | STOPPED |                      |                                               | CONTAINER       | 0         |
+------+---------+----------------------+-----------------------------------------------+-----------------+-----------+
| v1   | STOPPED |                      |                                               | VIRTUAL-MACHINE | 0         |
+------+---------+----------------------+-----------------------------------------------+-----------------+-----------+
```


# index.html.md

<a id="lxc-alias"></a>

# How to add command aliases

#### NOTE
Command aliases are a concept in the LXD CLI.
They are not applicable to the UI or API.

The LXD command-line client supports adding aliases for commands that you use frequently.
You can use aliases as shortcuts for longer commands, or to automatically add flags to existing commands.

To manage command aliases, you use the [`lxc alias`]() command.

For example, to always ask for confirmation when deleting an instance, create an alias for `lxc delete` that always runs `lxc delete -i`:

```none
lxc alias add delete "delete -i"
```

To see all configured aliases, run [`lxc alias list`](../reference/manpages/lxc/alias/list.md#lxc-alias-list-md).

To [view all aliases in YAML format](../reference/manpages/lxc/alias/show.md#lxc-alias-show-md) (useful for exporting or inspection), run:

```bash
lxc alias show
```

To [edit all aliases](../reference/manpages/lxc/alias/edit.md#lxc-alias-edit-md) interactively or via file input, run:

```bash
lxc alias edit
```

This command opens your system’s default text editor and allows you to modify all aliases at once.

You can also pipe alias configurations to this command. Examples:

```bash
# Export aliases to a file
lxc alias show > aliases.yaml

# Import aliases from a file
lxc alias edit < aliases.yaml

# Import from pipe
cat aliases.yaml | lxc alias edit
```

Run [`lxc alias --help`]() to see all available subcommands.


# index.html.md

<a id="network-zones"></a>

# How to configure network zones

#### NOTE
Network zones are available for the [OVN network](../reference/network_ovn.md#network-ovn) and the [Bridge network](../reference/network_bridge.md#network-bridge).


            <p class="youtube_link">
              <a href="https://www.youtube.com/watch?v=2MqpJOogNVQ" target="_blank">
                <span title="LXD network zones" class="play_icon">▶</span>
                <span title="LXD network zones">Watch on YouTube</span>
              </a>
            </p>
        
Network zones can be used to serve DNS records for LXD networks.

You can use network zones to automatically maintain valid forward and reverse records for all your instances.
This can be useful if you are operating a LXD cluster with multiple instances across many networks.

Having DNS records for each instance makes it easier to access network services running on an instance.
It is also important when hosting, for example, an outbound SMTP service.
Without correct forward and reverse DNS entries for the instance, sent mail might be flagged as potential spam.

Each network can be associated to different zones:

- Forward DNS records - multiple comma-separated zones (no more than one per project)
- IPv4 reverse DNS records - single zone
- IPv6 reverse DNS records - single zone

LXD will then automatically manage forward and reverse records for all instances, network gateways and downstream network ports and serve those zones for zone transfer to the operator’s production DNS servers.

## Project views

Projects have a [`features.networks.zones`](../reference/projects.md#project-features:features.networks.zones) feature, which is disabled by default.
This controls which project new networks zones are created in.
When this feature is enabled new zones are created in the project, otherwise they are created in the default project.

This allows projects that share a network in the default project (i.e those with `features.networks=false`) to have their own project level DNS zones that give a project oriented
“view” of the addresses on that shared network (which only includes addresses from instances in their project).

## Generated records

### Forward records

If you configure a zone with forward DNS records for `lxd.example.net` for your network, it generates records that resolve the following DNS names:

- For all instances in the network: `<instance_name>.lxd.example.net`
- For the network gateway: `<network_name>.gw.lxd.example.net`
- For downstream network ports (for network zones set on an uplink network with a downstream OVN network): `<project_name>-<downstream_network_name>.uplink.lxd.example.net`
- Manual records added to the zone.

You can check the records that are generated with your zone setup with the `dig` command.

This assumes that [`core.dns_address`](../server.md#server-core:core.dns_address) was set to `<DNS_server_IP>:<DNS_server_PORT>`. (Setting that configuration
option causes the backend to immediately start serving on that address.)

In order for the `dig` request to be allowed for a given zone, you must set the
`peers.NAME.address` configuration option for that zone. `NAME` can be anything random. The value must match the
IP address where your `dig` is calling from. You must leave `peers.NAME.key` for that same random `NAME` unset.

For example: `lxc network zone set lxd.example.net peers.whatever.address=192.0.2.1`.

#### NOTE
It is not enough for the address to be of the same machine that `dig` is calling from; it needs to
match as a string with what the DNS server in `lxd` thinks is the exact remote address. `dig` binds to
`0.0.0.0`, therefore the address you need is most likely the same that you provided to [`core.dns_address`](../server.md#server-core:core.dns_address).

For example, running `dig @<DNS_server_IP> -p <DNS_server_PORT> axfr lxd.example.net` might give the following output:

`user@host:~$ ``dig @192.0.2.200 -p 1053 axfr lxd.example.net
`
```text
lxd.example.net.                        3600 IN SOA  lxd.example.net. ns1.lxd.example.net. 1669736788 120 60 86400 30
lxd.example.net.                        300  IN NS   ns1.lxd.example.net.
lxdtest.gw.lxd.example.net.             300  IN A    192.0.2.1
lxdtest.gw.lxd.example.net.             300  IN AAAA fd42:4131:a53c:7211::1
default-ovntest.uplink.lxd.example.net. 300  IN A    192.0.2.20
default-ovntest.uplink.lxd.example.net. 300  IN AAAA fd42:4131:a53c:7211:216:3eff:fe4e:b794
c1.lxd.example.net.                     300  IN AAAA fd42:4131:a53c:7211:216:3eff:fe19:6ede
c1.lxd.example.net.                     300  IN A    192.0.2.125
manualtest.lxd.example.net.             300  IN A    8.8.8.8
lxd.example.net.                        3600 IN SOA  lxd.example.net. ns1.lxd.example.net. 1669736788 120 60 86400 30
```

### Reverse records

If you configure a zone for IPv4 reverse DNS records for `2.0.192.in-addr.arpa` for a network using `192.0.2.0/24`, it generates reverse `PTR` DNS records for addresses from all projects that are referencing that network via one of their forward zones.

For example, running `dig @<DNS_server_IP> -p <DNS_server_PORT> axfr 2.0.192.in-addr.arpa` might give the following output:

`user@host:~$ ``dig @192.0.2.200 -p 1053 axfr 2.0.192.in-addr.arpa
`
```text
2.0.192.in-addr.arpa.                  3600 IN SOA  2.0.192.in-addr.arpa. ns1.2.0.192.in-addr.arpa. 1669736828 120 60 86400 30
2.0.192.in-addr.arpa.                  300  IN NS   ns1.2.0.192.in-addr.arpa.
1.2.0.192.in-addr.arpa.                300  IN PTR  lxdtest.gw.lxd.example.net.
20.2.0.192.in-addr.arpa.               300  IN PTR  default-ovntest.uplink.lxd.example.net.
125.2.0.192.in-addr.arpa.              300  IN PTR  c1.lxd.example.net.
2.0.192.in-addr.arpa.                  3600 IN SOA  2.0.192.in-addr.arpa. ns1.2.0.192.in-addr.arpa. 1669736828 120 60 86400 30
```

<a id="network-dns-server"></a>

## Enable the built-in DNS server

To make use of network zones, you must enable the built-in DNS server.

To do so, set the [`core.dns_address`](../server.md#server-core:core.dns_address) configuration option to a local address on the LXD server.
To avoid conflicts with an existing DNS we suggest not using the port 53.
This is the address on which the DNS server will listen.
Note that in a LXD cluster, the address may be different on each cluster member.

#### NOTE
The built-in DNS server supports only zone transfers through AXFR.
It cannot be directly queried for DNS records.
Therefore, the built-in DNS server must be used in combination with an external DNS server (`bind9`, `nsd`, …), which will transfer the entire zone from LXD, refresh it upon expiry and provide authoritative answers to DNS requests.

Authentication for zone transfers is configured on a per-zone basis, with peers defined in the zone configuration and a combination of IP address matching and TSIG-key based authentication.

## Create and configure a network zone

Use the following command to create a network zone:

```bash
lxc network zone create <network_zone> [configuration_options...]
```

The following examples show how to configure a zone for forward DNS records, one for IPv4 reverse DNS records and one for IPv6 reverse DNS records, respectively:

```bash
lxc network zone create lxd.example.net
lxc network zone create 2.0.192.in-addr.arpa
lxc network zone create 1.0.0.0.1.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa
```

#### NOTE
Zones must be globally unique, even across projects.
If you get a creation error, it might be due to the zone already existing in another project.

You can either specify the configuration options when you create the network or configure them afterwards with the following command:

```bash
lxc network zone set <network_zone> <key>=<value>
```

Use the following command to edit a network zone in YAML format:

```bash
lxc network zone edit <network_zone>
```

### Configuration options

The following configuration options are available for network zones:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="network-zone-config-options:dns.nameservers"></a>
`dns.nameservers`

Comma-separated list of DNS server FQDNs (for NS records)

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-zone-config-options:dns.nameservers)

| **Key:**      | `dns.nameservers`   |
|---------------|---------------------|
| **Type:**     | string set          |
| **Required:** | no                  |

<a id="network-zone-config-options:network.nat"></a>
`network.nat`

Whether to generate records for NAT-ed subnets

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-zone-config-options:network.nat)

| **Key:**      | `network.nat`   |
|---------------|-----------------|
| **Type:**     | bool            |
| **Default:**  | true            |
| **Required:** | no              |

<a id="network-zone-config-options:peers.NAME.address"></a>
`peers.NAME.address`

IP address of a DNS server

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-zone-config-options:peers.NAME.address)

| **Key:**      | `peers.NAME.address`   |
|---------------|------------------------|
| **Type:**     | string                 |
| **Required:** | no                     |

<a id="network-zone-config-options:peers.NAME.key"></a>
`peers.NAME.key`

TSIG key for the server

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-zone-config-options:peers.NAME.key)

| **Key:**      | `peers.NAME.key`   |
|---------------|--------------------|
| **Type:**     | string             |
| **Required:** | no                 |

<a id="network-zone-config-options:user.*"></a>
`user.*`

User-provided free-form key/value pairs

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-zone-config-options:user.*)

| **Key:**      | `user.*`   |
|---------------|------------|
| **Type:**     | string     |
| **Required:** | no         |

#### NOTE
When generating the TSIG key using `tsig-keygen`, the key name must follow the format `<zone_name>_<peer_name>.`.
For example, if your zone name is `lxd.example.net` and the peer name is `bind9`, then the key name must be `lxd.example.net_bind9.`.
If this format is not followed, zone transfer might fail.

## Add a network zone to a network

To add a zone to a network, set the corresponding configuration option in the network configuration:

- For forward DNS records: `dns.zone.forward`
- For IPv4 reverse DNS records: `dns.zone.reverse.ipv4`
- For IPv6 reverse DNS records: `dns.zone.reverse.ipv6`

For example:

```bash
lxc network set <network_name> dns.zone.forward="lxd.example.net"
```

Zones belong to projects and are tied to the `networks` features of projects.
You can restrict projects to specific domains and sub-domains through the [`restricted.networks.zones`](../reference/projects.md#project-restricted:restricted.networks.zones) project configuration key.

## Add custom records

A network zone automatically generates forward and reverse records for all instances, network gateways and downstream network ports.
If required, you can manually add custom records to a zone.

To do so, use the [`lxc network zone record`](../reference/manpages/lxc/network/zone/record.md#lxc-network-zone-record-md) command.

### Create a record

Use the following command to create a record:

```bash
lxc network zone record create <network_zone> <record_name>
```

This command creates an empty record without entries and adds it to a network zone.

#### Record properties

Records have the following properties:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="network-zone-record-properties:config"></a>
`config`

User-provided free-form key/value pairs

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-zone-record-properties:config)

| **Key:**      | `config`   |
|---------------|------------|
| **Type:**     | string set |
| **Required:** | no         |

The only supported keys are `user.*` custom keys.

<a id="network-zone-record-properties:description"></a>
`description`

Description of the record

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-zone-record-properties:description)

| **Key:**      | `description`   |
|---------------|-----------------|
| **Type:**     | string          |
| **Required:** | no              |

<a id="network-zone-record-properties:entries"></a>
`entries`

List of DNS entries

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-zone-record-properties:entries)

| **Key:**      | `entries`   |
|---------------|-------------|
| **Type:**     | entry list  |
| **Required:** | no          |

<a id="network-zone-record-properties:name"></a>
`name`

Unique name of the record

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-zone-record-properties:name)

| **Key:**      | `name`   |
|---------------|----------|
| **Type:**     | string   |
| **Required:** | yes      |

### Add or remove entries

To add an entry to the record, use the following command:

```bash
lxc network zone record entry add <network_zone> <record_name> <type> <value> [--ttl <TTL>]
```

This command adds a DNS entry with the specified type and value to the record.

For example, to create a dual-stack web server, add a record with two entries similar to the following:

```bash
lxc network zone record entry add <network_zone> <record_name> A 1.2.3.4
lxc network zone record entry add <network_zone> <record_name> AAAA 1234::1234
```

You can use the `--ttl` flag to set a custom time-to-live (in seconds) for the entry.
Otherwise, the default of 300 seconds is used.

You cannot edit an entry (except if you edit the full record with [`lxc network zone record edit`](../reference/manpages/lxc/network/zone/record/edit.md#lxc-network-zone-record-edit-md)), but you can delete entries with the following command:

```bash
lxc network zone record entry remove <network_zone> <record_name> <type> <value>
```


# index.html.md

<a id="howto-cluster-groups"></a>

# How to set up cluster groups


            <p class="youtube_link">
              <a href="https://www.youtube.com/watch?v=t_3YJo_xItM" target="_blank">
                <span title="LXD cluster groups" class="play_icon">▶</span>
                <span title="LXD cluster groups">Watch on YouTube</span>
              </a>
            </p>
        
Cluster members can be assigned to [Cluster groups](../explanation/clusters.md#cluster-groups).
By default, all cluster members belong to the `default` group.

To create a cluster group, use the [`lxc cluster group create`](../reference/manpages/lxc/cluster/group/create.md#lxc-cluster-group-create-md) command.
For example:

```none
lxc cluster group create gpu
```

To assign a cluster member to one or more groups, use the [`lxc cluster group assign`](../reference/manpages/lxc/cluster/group/assign.md#lxc-cluster-group-assign-md) command.
This command removes the specified cluster member from all the cluster groups it currently is a member of and then adds it to the specified group or groups.

For example, to assign `server1` to only the `gpu` group, use the following command:

```none
lxc cluster group assign server1 gpu
```

To assign `server1` to the `gpu` group and also keep it in the `default` group, use the following command:

```none
lxc cluster group assign server1 default,gpu
```

To add a cluster member to a specific group without removing it from other groups, use the [`lxc cluster group add`](../reference/manpages/lxc/cluster/group/add.md#lxc-cluster-group-add-md) command.

For example, to add `server1` to the `gpu` group and also keep it in the `default` group, use the following command:

```none
lxc cluster group add server1 gpu
```

## Launch an instance on a cluster group member

With cluster groups, you can target an instance to run on one of the members of the cluster group, instead of targeting it to run on a specific member.

#### NOTE
[`scheduler.instance`](../reference/cluster_member_config.md#cluster-cluster:scheduler.instance) must be set to either `all` (the default) or `group` to allow instances to be targeted to a cluster group.

See [Automatic placement of instances](../explanation/clusters.md#clustering-instance-placement) for more information.

To launch an instance on a member of a cluster group, follow the instructions in [Launch an instance on a specific cluster member](cluster_manage_instance.md#cluster-target-instance), but use the group name prefixed with `@` for the `--target` flag.
For example:

```none
lxc launch ubuntu:24.04 c1 --target=@gpu
```


# index.html.md

<a id="server-expose"></a>

# How to expose LXD to the network

By default, LXD can be used only by local users through a Unix socket and is not accessible over the network.

To expose LXD to the network, you must configure it to listen to addresses other than the local Unix socket.
To do so, set the [`core.https_address`](../server.md#server-core:core.https_address) server configuration option.

For example, allow access to the LXD server on port `8443`:

CLI

```none
lxc config set core.https_address :8443
```

API

```none
lxc query --request PATCH /1.0 --data '{
  "config": {
    "core.https_address": ":8443"
  }
}'
```

UI

#### NOTE
The UI requires LXD to be exposed to the network.
Therefore, you must use the CLI or API to originally expose LXD to the network.

Once you have access to the UI, you can use it to update the setting.
However, be careful when changing the configured value, because using an invalid value might cause you to lose access to the UI.

Go to Settings and edit the value for `core.https_address`.

To allow access through a specific IP address, use `ip addr` to find an available address and then set it.
For example:

`user@host:~$ ``ip addr
`
```text
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: enp5s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:16:3e:e3:f3:3f brd ff:ff:ff:ff:ff:ff
    inet 10.68.216.12/24 metric 100 brd 10.68.216.255 scope global dynamic enp5s0
       valid_lft 3028sec preferred_lft 3028sec
    inet6 fd42:e819:7a51:5a7b:216:3eff:fee3:f33f/64 scope global mngtmpaddr noprefixroute
       valid_lft forever preferred_lft forever
    inet6 fe80::216:3eff:fee3:f33f/64 scope link
       valid_lft forever preferred_lft forever
3: lxdbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
    link/ether 00:16:3e:8d:f3:72 brd ff:ff:ff:ff:ff:ff
    inet 10.64.82.1/24 scope global lxdbr0
       valid_lft forever preferred_lft forever
    inet6 fd42:f4ab:4399:e6eb::1/64 scope global
       valid_lft forever preferred_lft forever
```

`user@host:~$ ``lxc config set core.https_address 10.68.216.12
`

All remote clients can then connect to LXD and access any image that is marked for public use.

<a id="server-authenticate"></a>

## Authenticate with the LXD server

To be able to access the remote API, clients must authenticate with the LXD server.
There are several authentication methods; see [Remote API authentication](../authentication.md#authentication) for detailed information.

The recommended method is to add the client’s TLS certificate to the server’s trust store through a trust token.
There are two ways to create a token.
Create a *pending fine-grained TLS identity* if you would like to manage client permissions via [Fine-grained authorization](../explanation/authorization.md#fine-grained-authorization).
Create a *certificate add token* if you would like to grant the client full access to LXD, or manage their permissions via [Restricted TLS certificates](../explanation/authorization.md#restricted-tls-certs).

See [How to access the LXD web UI](access_ui.md#access-ui) for instructions on how to authenticate with the LXD server using the UI.
To authenticate a CLI or API client using a trust token, complete the following steps:

1. On the server, generate a trust token.

   CLI

   There are currently two ways to retrieve a trust token in LXD.

   **Create a certificate add token**

   To generate a trust token, enter the following command on the server:
   ```none
   lxc config trust add
   ```

   Enter the name of the client that you want to add.
   The command generates and prints a token that can be used to add the client certificate.

   #### NOTE
   The recipient of this token will have full access to LXD.
   To restrict the access of the client, you must use the `--restricted` flag.
   See [Confine users to specific projects on the HTTPS API](projects_confine.md#projects-confine-https) for more details.

   **Create a pending fine-grained TLS identity**

   To create a pending fine-grained TLS identity, enter the following command on the server:
   ```none
   lxc auth identity create tls/<client_name>
   ```

   The command generates and prints a token that can be used to add the client certificate.

   #### NOTE
   The recipient of this token is not authorized to perform any actions in the LXD server.
   To grant access, the identity must be added to one or more groups with permissions assigned.
   See [Fine-grained authorization](../explanation/authorization.md#fine-grained-authorization).

   API

   **Create a certificate add token**

   To generate a trust token, send a POST request to the `/1.0/certificates` endpoint:
   ```none
   lxc query --request POST /1.0/certificates --data '{
     "name": "<client_name>",
     "token": true,
     "type": "client"
   }'
   ```

   <!-- include start token API -->

   See [`POST /1.0/certificates`](/api/#/certificates/certificates_post) for more information.

   The return value of this query contains an operation that has the information that is required to generate the trust token:
   ```none
   {
    "class": "token",
    ...
    "metadata": {
       "addresses": [
          "<server_address>"
       ],
       "fingerprint": "<fingerprint>",
       ...
       "secret": "<secret>"
    },
    ...
   }
   ```

   Use this information to generate the trust token:
   ```none
   echo -n '{"client_name":"<client_name>","fingerprint":"<fingerprint>",'\
   '"addresses":["<server_address>"],'\
   '"secret":"<secret>","expires_at":"0001-01-01T00:00:00Z"}' | base64 -w0
   ```

   <!-- include end token API -->

   **Create a pending fine-grained TLS identity**

   To generate a trust token, send a POST request to the `/1.0/auth/identities/tls` endpoint:
   ```none
   lxc query --request POST /1.0/auth/identities/tls --data '{
     "name": "<client_name>",
     "token": true
   }'
   ```

   <!-- include start tls identity API -->

   See [`POST /1.0/auth/identities/tls`](/api/#/auth/identitites/identities_post_tls) for more information.

   The return value of this query contains the information that is required to generate the trust token:
   ```none
   {
       "client_name": "<client_name>",
       "addresses": [
          "<server_address>"
       ],
       "expires_at": "<expiry_date>"
       "fingerprint": "<fingerprint>",
       "type": "<type>",
       "secret": "<secret>"
   }
   ```

   Use this information to generate the trust token:
   ```none
   echo -n '{"client_name":"<client_name>","fingerprint":"<fingerprint>",'\
   '"addresses":["<server_address>"],'\
   '"secret":"<secret>","expires_at":"0001-01-01T00:00:00Z","type":"<type>"}' | base64 -w0
   ```

   <!-- include end tls identity API -->
2. Authenticate the client.

   CLI

   On the client, add the server with the following command:
   ```none
   lxc remote add <remote_name> <token>
   ```

   #### NOTE
   If your LXD server is behind NAT, you must specify its external public address when adding it as a remote for a client:
   ```none
   lxc remote add <name> <IP_address>
   ```

   When you are prompted for the token, specify the generated token from the previous step.
   Alternatively, use the `--token` flag:
   ```none
   lxc remote add <name> <IP_address> --token <token>
   ```

   When generating the token on the server, LXD includes a list of IP addresses that the client can use to access the server.
   However, if the server is behind NAT, these addresses might be local addresses that the client cannot connect to.
   In this case, you must specify the external address manually.

   API
   <!-- include start gen cert -->

   On the client, generate a certificate to use for the connection:
   ```none
   openssl req -x509 -newkey rsa:2048 -keyout "<keyfile_name>" -nodes \
   -out "<crtfile_name>" -subj "/CN=<client_name>"
   ```

   <!-- include end gen cert -->

   **Trust store entries**
   <!-- include start cert token -->

   Then send a POST request to the `/1.0/certificates?public` endpoint to authenticate:
   ```none
   curl -k -s --key "<keyfile_name>" --cert "<crtfile_name>" \
   -X POST https://<server_address>/1.0/certificates \
   --data '{ "trust_token": "<trust_token>" }'
   ```

   See [`POST /1.0/certificates?public`](/api/#/certificates/certificates_post_untrusted) for more information.
   <!-- include end cert token -->

   **TLS identities**
   <!-- include start identity token -->

   Send a POST request to the `/1.0/auth/identities/tls?public` endpoint to authenticate:
   ```none
   curl --insecure --key "<keyfile_name>" --cert "<crtfile_name>" \
   -X POST https://<server_address>/1.0/auth/identities/tls \
   --data '{ "trust_token": "<trust_token>" }'
   ```

   See [`POST /1.0/auth/identities/tls?public`](/api/#/auth/identities/identities_post_tls_untrusted) for more information.
   <!-- include end identity token -->

See [Remote API authentication](../authentication.md#authentication) for detailed information and other authentication methods.


# index.html.md

<a id="oidc-pocket-id"></a>

# How to configure Pocket ID as login method for LXD

Pocket ID is a modern, self-hosted OIDC provider distributed as a single Go binary. It supports only passkeys (no passwords), allowing you to sign into LXD.

## Using Pocket ID to access LXD

1. Set up [Pocket ID](https://pocket-id.org/docs) using their [installation guide](https://pocket-id.org/docs/setup/installation). This guide assumes that Pocket ID is available over HTTPS.
2. Create an admin account at `https://<your-app-url>/setup`.
3. From the main navigation, go to Administration > OIDC Clients.
4. From the Create OIDC Client section, click Add OIDC Client.
   - Enter a name such as `lxd-client`.
   - In the field for Callback URLs, enter your LXD UI address, followed by `/oidc/callback`.
     - Example: `https://example.com:8443/oidc/callback`
     - You can use an IP address instead of a domain name.
     - Note `:8443` is the default listening port for the LXD server. It might differ for your setup. You can verify the LXD configuration value `core.https_address` to find the correct port for your LXD server.
   - Enable the PKCE option.
   - Optionally, to require users to authenticate again on each authorization, turn on the Requires Re-Authentication option.
   - Click Save.
5. In the Administration > OIDC Clients page, click Show more details to see your client configuration.
   ![image](images/auth/pocket-id/pocket-id-show-more-details.png)![image](images/auth/pocket-id/pocket-id-client.png)
   - Copy the Client ID, Issuer URL, Client Secret and set them in LXD server configuration:
     ```bash
     lxc config set oidc.client.id=<Client ID>
     lxc config set oidc.issuer=<Issuer URL>
     lxc config set oidc.client.secret=<Client Secret>
     ```
6. From the main navigation, go to Administration > Users.
   - From the Create User section, click Add User. Enter and save the user information.
7. From the main navigation, go to Administration > User Groups.
   - From the Create User Group section, click Add Group. Enter and save the group information.
   - From the Users section, select the user created in step 6 to the group and click Save.
   - From the Allowed OIDC Clients section, select the client created in step 4 and click Save.

Now you can access the LXD UI with any browser and use  login. To use OIDC on the LXD CLI, run `lxc remote add <remote-name> <LXD address> --auth-type oidc` and point a browser to the displayed URL to authenticate.

By default, Pocket ID only has an admin user. Follow the [Pocket ID guide](https://pocket-id.org/docs/setup/user-management) to add users manually or sync with an LDAP source.

Users will have no permissions by default. To grant access to projects and instances, you have two options:

1. Set up [LXD authorization groups](../explanation/authorization.md#manage-permissions) to map a LXD authorization group to the user directly. Note, that the user object in LXD will only be created on the first login of that user to LXD.
2. Configure roles in Pocket ID and use automatic mapping to LXD authorization groups as described below.

<a id="oidc-pocket-id-automatic-group-mapping"></a>

## Set up automatic group mappings

An admin can set up groups in Pocket ID and allocate roles to those groups. When a user in a group logs in via OIDC, their allocated Pocket ID roles can be mapped to LXD authorization groups through custom claims. This section details the steps for configuring roles in Pocket ID and setting up a custom claim so that LXD can map those roles to their authorization groups.

1. From the main navigation, go to Administration > User Groups.
   - From the Manage User Groups section, select the group you want to assign roles to.
   - From the Users section, add and save users to the group.
   - From the Custom Claims section, click Add custom claim.
   - Enter and save a custom claim key and a Pocket ID role value in the key and value fields, respectively (for example, `lxd-role-claim` as the key and `pocketID-admin` as the role), and remember these values for the next steps.

   ![image](images/auth/pocket-id/pocket-id-custom-claims.png)
2. Tell LXD to use the custom claim from the previous step to extract Pocket ID roles. Replace `<claim_name>` with the exact custom claim key you configured in Pocket ID (for example, `lxd-role-claim`):
   ```bash
   lxc config set oidc.groups.claim=<claim_name>
   ```
3. Map the Pocket ID role from step 1 to a LXD authorization group. Replace `<pocket-id-role-name>` with the exact role string you configured as the custom claim value in Pocket ID (for example, `pocketID-admin`):
   ```bash
   lxc auth identity-provider-group create <pocket-id-role-name>
   lxc auth identity-provider-group group add <pocket-id-role-name> <LXD-group-name>
   ```

During the OIDC flow, LXD automatically extracts the custom claim from the user’s `id_token` based on the LXD `oidc.groups.claim` configuration value. The extracted custom claim is an array of roles for your user from Pocket ID. Those roles are then mapped to LXD authorization groups using the identity provider group created in step 3.


# index.html.md

<a id="devlxd-authenticate"></a>

# How to authenticate to the DevLXD API

The DevLXD API is available inside guest instances to allow limited interaction with the host (see [Communication between instance and host](../dev-lxd.md#dev-lxd)).

This API is available unauthenticated, since LXD determines the source instance and returns information only for that workload.
However, advanced use cases may require the caller to be authenticated.

To authenticate over the DevLXD API, first create a `DevLXD token bearer` identity:

CLI

```none
lxc auth identity create devlxd/<name> [[--group <group> ]]
```

API

```none
lxc query --request POST /1.0/auth/identities/bearer --data '{
  "name": "<name>",
  "type": "DevLXD token bearer"
  "groups": [
    "<group>"
  ]
}'
```

Next, issue a token for the identity:

CLI

```none
lxc auth identity token issue devlxd/<name> [--expiry <expiry> ]
```

API

```none
lxc query --request POST /1.0/auth/identities/bearer/<name>/token --data '{
  "expiry": "<expiry>"
}'
```

The returned token can be used to authenticate with LXD over the DevLXD socket.
It must be set as a bearer token in the `Authorization` header.

You can verify trust by checking the `auth` field in the response of `GET /1.0`:

```none
$ lxc exec c1 --env TOKEN=${token} -- bash
root@c1# curl -H "Authorization: Bearer ${TOKEN}" -s --unix-socket /dev/lxd/sock http://custom.socket/1.0
{"state":"Started","api_version":"1.0","instance_type":"container","location":"my-host","auth":"trusted"}
```


# index.html.md

<a id="server-configure"></a>

# How to configure the LXD server

See [Server configuration](../server.md#server) for all configuration options that are available for the LXD server.

If the LXD server is part of a cluster, some of the options apply to the cluster, while others apply only to the local server, thus the cluster member.
In the [Server configuration](../server.md#server) option tables, options that apply to the cluster are marked with a `global` scope, while options that apply to the local server are marked with a `local` scope.

## Configure server options

CLI

You can configure a server option with the following command:

```none
lxc config set <key> <value>
```

For example, to allow remote access to the LXD server on port 8443, enter the following command:

```none
lxc config set core.https_address :8443
```

In a cluster setup, to configure a server option for a cluster member only, add the `--target` flag.
For example, to configure where to store image tarballs on a specific cluster member, enter a command similar to the following:

```none
lxc config set storage.images_volume my-pool/my-volume --target member02
```

API

Send a PATCH request to the `/1.0` endpoint to update one or more server options:

```none
lxc query --request PATCH /1.0 --data '{
  "config": {
    "<key>": "<value>",
    "<key>": "<value>"
  }
}'
```

For example, to allow remote access to the LXD server on port 8443, send the following request:

```none
lxc query --request PATCH /1.0 --data '{
  "config": {
    "core.https_address": ":8443"
  }
}'
```

In a cluster setup, to configure a server option for a cluster member only, add the `target` parameter to the query.
For example, to configure where to store image tarballs on a specific cluster member, send a request similar to the following:

```none
lxc query --request PATCH /1.0?target=member02 --data '{
  "config": {
    "storage.images_volume": "my-pool/my-volume"
  }
}'
```

See [`PATCH /1.0`](/api/#/server/server_patch) for more information.

UI

Go to Settings to configure the server options.

In a cluster setup, server options that apply to the local server are updated only for the server on which you are accessing the UI.
For example, if you access the UI on `server1` and update the location for storing image tarballs ([`storage.images_volume`](../server.md#server-miscellaneous:storage.images_volume), which has a `local` scope) from `local/pool1` to `local/pool2`, `storage.images_volume` will still be configured to `local/pool1` on `server2`.

## Display the server configuration

CLI

To display the current server configuration, enter the following command:

```none
lxc config show
```

In a cluster setup, to show the local configuration for a specific cluster member, add the `--target` flag.

API

Send a GET request to the `/1.0` endpoint to display the current server environment and configuration:

```none
lxc query --request GET /1.0
```

In a cluster setup, to show the local environment and configuration for a specific cluster member, add the `target` parameter to the query:

```none
lxc query --request GET /1.0?target=<cluster_member>
```

See [`GET /1.0`](/api/#/server/server_get) for more information.

UI

Go to Settings to view the current server configuration.

In a cluster setup, this view shows the local configuration for the cluster member on which you are accessing the UI.

## Edit the full server configuration

CLI

To edit the full server configuration as a YAML file, enter the following command:

```none
lxc config edit
```

In a cluster setup, to edit the local configuration for a specific cluster member, add the `--target` flag.

API

To update the full server configuration, send a PUT request to the `/1.0` endpoint:

```none
lxc query --request PUT /1.0 --data '<server_configuration>'
```

In a cluster setup, to update the full server configuration for a specific cluster member, add the `target` parameter to the query:

```none
lxc query --request PUT /1.0?target=<cluster_member> '<server_configuration>'
```

See [`PUT /1.0`](/api/#/server/server_put) for more information.

UI

The UI does not currently support editing the full server configuration.


# index.html.md

<a id="howto-instances-migrate"></a>

# How to migrate LXD instances between servers

If you use the LXD client, you can migrate or copy instances from one LXD server (remote or local) to another.

#### NOTE
[Remote servers](../remotes.md#remotes) are a concept of the LXD client.
Therefore, there is no direct equivalent for migrating instances between servers in the API or the UI.

However, you can [export an instance](instances_backup.md#instances-backup-export-instance) from one server and [import it](instances_backup.md#instances-backup-import-instance) to another server.

## Migrate instances

To migrate an instance (move it from one LXD server to another) using the CLI, use the [`lxc move`](../reference/manpages/lxc/move.md#lxc-move-md) command:

```none
lxc move [<source_remote>:]<source_instance_name> <target_remote>:[<target_instance_name>]
```

When migrating a container, you must stop it first.

When migrating a virtual machine, you must either enable [Live migration](#live-migration) or stop it first.

## Copy instances

Use the [`lxc copy`](../reference/manpages/lxc/copy.md#lxc-copy-md) command if you want to duplicate the instance instead of migrating it:

```none
lxc copy [<source_remote>:]<source_instance_name> <target_remote>:[<target_instance_name>]
```

If the volume already exists in the target location, use the `--refresh` flag to update the copy. To learn about the benefits, see: [Optimized volume transfer](../reference/storage_drivers.md#storage-optimized-volume-transfer).

## Migrate and copy options

For both migrating and copying instances, you don’t need to specify the source remote if it is your default remote, and you can leave out the target instance name if you want to use the same instance name on the target remote server.

If you want to migrate the instance to a specific cluster member, specify that member’s name with the `--target` flag.
In this case, do not specify the source and target remote.

You can add the `--mode` flag to choose a transfer mode, depending on your network setup:

`pull` (default)
: Instruct the target server to connect to the source server and pull the respective instance.

`push`
: Instruct the source server to connect to the target server and push the instance.

`relay`
: Instruct the client to connect to both the source and the target server and transfer the data through the client.

If you need to adapt the configuration for the instance to run on the target server, you can either specify the new configuration directly (using `--config`, `--device`, `--storage` or `--target-project`) or through profiles (using `--no-profiles` or `--profile`). See [`lxc move --help`](../reference/manpages/lxc/move.md#lxc-move-md) for all available flags.

<a id="live-migration"></a>

## Live migration

Live migration means migrating an instance to another server while it is running, avoiding any downtime. This method is supported for virtual machines.

For a virtual machine to be eligible for live migration, it must meet the following criteria:

- It must have support for stateful migration enabled. To enable this, set [`migration.stateful`](../reference/instance_options.md#instance-migration:migration.stateful) to `true` on the virtual machine. This setting can only be updated when the machine is stopped. Thus, be sure to configure this setting before you need to live-migrate:
  ```default
  lxc config set <instance-name> migration.stateful=true
  ```

  #### NOTE
  When [`migration.stateful`](../reference/instance_options.md#instance-migration:migration.stateful) is enabled in LXD, virtiofs shares are disabled, and files are only shared via the 9P protocol. Consequently, guest OSes lacking 9P support, such as CentOS 8, cannot share files with the host unless stateful migration is disabled. Additionally, the `lxd-agent` will not function for these guests under these conditions.
- When using a local pool, the [`size.state`](../reference/devices_disk.md#device-disk-device-conf:size.state) of the virtual machine’s root disk device must be set to at least the size of the virtual machine’s [`limits.memory`](../reference/instance_options.md#instance-resource-limits:limits.memory) setting.

  #### NOTE
  If you are using a remote storage pool like Ceph RBD to back your instance, you don’t need to set [`size.state`](../reference/devices_disk.md#device-disk-device-conf:size.state) to perform live migration.
- The virtual machine must not depend on any resources specific to its current host, such as local storage or a local (non-OVN) bridge network.

## Temporarily migrate all instances from a cluster member

For LXD servers that are members of a cluster, you can use the evacuate and restore operations to temporarily migrate all instances from one cluster member to another. These operations can also live-migrate eligible instances.

For more information, see: [Evacuate and restore cluster members](cluster_manage.md#cluster-evacuate-restore).

## Related topics

How-to guides:

- [Migrate instances in a cluster](cluster_manage_instance.md#howto-cluster-manage-instance-migrate)
- [Move an instance to another project](projects_work.md#howto-projects-work-move-instance)
- [Import machines to LXD instances](import_machines_to_instances.md#import-machines-to-instances)
- [Secondary backup LXD server](../backup.md#secondary-backup-server)
- [Export an instance](instances_backup.md#instances-backup-export-instance)
- [Restore an instance from an export file](instances_backup.md#instances-backup-import-instance)
- [Move or copy storage volumes](storage_move_volume.md#howto-storage-move-volume)


# index.html.md

<a id="network-acls"></a>

# How to configure network ACLs

#### NOTE
Network ACLs are available for the [OVN NIC type](../reference/devices_nic.md#nic-ovn), the [OVN network](../reference/network_ovn.md#network-ovn) and the [Bridge network](../reference/network_bridge.md#network-bridge) (with some exceptions; see [Bridge limitations](#network-acls-bridge-limitations)).


            <p class="youtube_link">
              <a href="https://www.youtube.com/watch?v=mu34G0cX6Io" target="_blank">
                <span title="LXD network ACLs" class="play_icon">▶</span>
                <span title="LXD network ACLs">Watch on YouTube</span>
              </a>
            </p>
        
Network  define rules for controlling traffic:

- Between instances connected to the same network
- To and from other networks

Network ACLs can be assigned directly to the  of an instance, or to a network. When assigned to a network, the ACL applies indirectly to all NICs connected to that network.

When an ACL is assigned to multiple instance NICs, either directly or indirectly, those NICs form a logical port group. You can use the name of that ACL to refer to that group in the traffic rules of other ACLs. For more information, see: [Subject name selectors (ACL groups)](#network-acls-selectors-subject-name).

<a id="network-acls-list"></a>

## List ACLs

CLI

To list all ACLs, run:

```bash
lxc network acl list
```

<!-- End of group-tab CLI -->

API

To list all ACLs, query the [`GET /1.0/network-acls`](/api/#/network-acls/network_acls_get) endpoint:

```bash
lxc query --request GET /1.0/network-acls
```

You can also use [recursion](../rest-api.md#rest-api-recursion) to list the ACLs with a higher level of detail:

```bash
lxc query --request GET /1.0/network-acls?recursion=1
```

<!-- End of group-tab API -->

UI

View ACL information from the Networking section of the main navigation.

<!-- End of group-tab UI -->

<a id="network-acls-show"></a>

## Show an ACL

CLI

To show details about a specific ACL, run:

```bash
lxc network acl show <ACL-name>
```

Example:

```bash
lxc network acl show my-acl
```

<!-- End of group-tab CLI -->

API

For details about a specific ACL, query the [`GET /1.0/network-acls/{ACL-name}`](/api/#/network-acls/network_acl_get) endpoint\`:

```bash
lxc query --request GET /1.0/network-acls/{ACL-name}
```

Example:

```bash
lxc query --request GET /1.0/network-acls/my-acl
```

<!-- End of group-tab API -->

UI

To show the detail page of an ACL, select the desired ACL from the ACLs page.

![A Network ACL in LXD](images/networks/network_ACLs.png)
<!-- End of group-tab UI -->

<a id="network-acls-create"></a>

## Create an ACL

<a id="network-acls-name-requirements"></a>

### Name requirements

Network ACL names must meet the following requirements:

- Must be between 1 and 63 characters long.
- Can contain only ASCII letters (a–z, A–Z), numbers (0–9), and dashes (-).
- Cannot begin with a digit or a dash.
- Cannot end with a dash.

### Instructions

CLI

To create an ACL, run:

```bash
lxc network acl create <ACL-name> [user.KEY=value ...]
```

- You must provide an ACL name that meets the [Name requirements](#network-acls-name-requirements).
- You can optionally provide one or more custom `user` keys to store metadata or other information.

ACLs have no rules upon creation via command line, so as a next step, [add rules](#network-acls-rules) to the ACL. You can also [edit the ACL configuration](#network-acls-edit), or [assign the ACL to a network or NIC](#network-acls-assign).

Another way to create ACLs from the command line is to provide a YAML configuration file:

```bash
lxc network acl create <ACL-name> < <filename.yaml>
```

This file can include any other [ACL properties](#network-acls-properties), including the `egress` and `ingress` properties for defining [ACL rules](#network-acls-rules). See the second example in the set below.

### Examples

Create an ACL with the name `my-acl` and an optional custom user key:

```bash
lxc network acl create my-acl user.my-key=my-value
```

Create an ACL using a YAML configuration file:

First, create a file named `config.yaml` with the following content:

```yaml
description: Allow web traffic from internal network
config:
  user.owner: devops
ingress:
  - action: allow
    description: Allow HTTP/HTTPS from internal
    protocol: tcp
    source: "@internal"
    destination_port: "80,443"
    state: enabled
```

Note that the custom user keys are stored under the `config` property.

The following command creates an ACL from that file’s configuration:

```bash
lxc network acl create my-acl < config.yaml
```

<!-- End of group-tab CLI -->

API

To create an ACL, query the [`POST /1.0/network-acls`](/api/#/network-acls/network_acls_post) endpoint:

```bash
lxc query --request POST /1.0/network-acls --data '{
  "name": "<ACL-name>",
  "config": {
    "user.<custom-key-name>": "<custom-key-value>"
  },
  "description": "<description of the ACL>",
  "egress": [{<egress rule object>}, {<another egress rule object>, ...}],
  "ingress": [{<ingress rule object>}, {<another ingress rule object>, ...}]
}'
```

- You must provide an ACL name that meets the [Name requirements](#network-acls-name-requirements).
- You can optionally provide one or more custom `config.user.*` keys to store metadata or other information.
- The `ingress` and `egress` lists contain rules for inbound and outbound traffic. See [ACL rules](#network-acls-rules) for details.

### Examples

Create an ACL with the name `my-acl`, a custom user key of `my-key`, and a `description`:

```bash
lxc query --request POST /1.0/network-acls --data '{
  "name": "my-acl",
  "config": {
    "user.my-key": "my-value"
  },
  "description": "Web servers"
}'
```

Create an ACL with the name `my-acl` and an `ingress` rule:

```bash
lxc query --request POST /1.0/network-acls --data '{
  "name": "my-acl",
  "ingress": [
    {
      "action": "drop",
      "state": "enabled"
    }
  ]
}'
```

<!-- End of group-tab API -->

UI

To create an ACL, navigate to ACLs from the Networking tab in the main navigation, then click the Create ACL button in the upper-right corner.

![Create an ACL in LXD](images/networks/network_ACL_create.png)
<!-- End of group-tab UI -->

<a id="network-acls-properties"></a>

### ACL properties

ACLs have the following properties:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="network-acl-acl-properties:config"></a>
`config`

User-provided free-form key/value pairs

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-acl-acl-properties:config)

| **Key:**      | `config`   |
|---------------|------------|
| **Type:**     | string set |
| **Required:** | no         |

The only supported keys are `user.*` custom keys.

<a id="network-acl-acl-properties:description"></a>
`description`

Description of the network ACL

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-acl-acl-properties:description)

| **Key:**      | `description`   |
|---------------|-----------------|
| **Type:**     | string          |
| **Required:** | no              |

<a id="network-acl-acl-properties:egress"></a>
`egress`

Egress traffic rules

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-acl-acl-properties:egress)

| **Key:**      | `egress`   |
|---------------|------------|
| **Type:**     | rule list  |
| **Required:** | no         |

<a id="network-acl-acl-properties:ingress"></a>
`ingress`

Ingress traffic rules

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-acl-acl-properties:ingress)

| **Key:**      | `ingress`   |
|---------------|-------------|
| **Type:**     | rule list   |
| **Required:** | no          |

<a id="network-acl-acl-properties:name"></a>
`name`

Unique name of the network ACL in the project

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-acl-acl-properties:name)

| **Key:**      | `name`   |
|---------------|----------|
| **Type:**     | string   |
| **Required:** | yes      |

<a id="network-acls-rules"></a>

## ACL rules

Each ACL contains two lists of rules:

- Rules in the `egress` list apply to outbound traffic from the NIC.
- Rules in the `ingress` list apply to inbound traffic to the NIC.

For both `egress` and `ingress`, the rule configuration looks like this:

YAML

```yaml
action: <allow|reject|drop>
description: <description>
destination: <destination-IP-range>
destination_port: <destination-port-number>
icmp_code: <ICMP-code>
icmp_type: <ICMP-type>
protocol: <icmp4|icmp6|tcp|udp>
source: <source-of-traffic>
source_port: <source-port-number>
state: <enabled|disabled|logged>
```

<!-- End of group-tab YAML -->

JSON

```default
{
  "action": "<allow|reject|drop>",
  "description": "<description>",
  "destination": "<destination-IP-range>",
  "destination_port": "<destination-port-number>",
  "icmp_code": "<ICMP-code>",
  "icmp_type": "<ICMP-type>",
  "protocol": "<icmp4|icmp6|tcp|udp>",
  "source": "<source-of-traffic>",
  "source_port": "<source-port-number>",
  "state": "<enabled|disabled|logged>"
}
```

<!-- End of group-tab JSON -->
- The **`action`** property is required.
- The **`source`** and **`destination`** properties can be specified as one or more CIDR blocks, IP ranges, or [selectors](#network-acls-selectors). If left empty, they match any source or destination. Comma-separate multiple values.
- If the **`protocol`** is unset, it matches any protocol.
- The **`destination_port`** and **`source_port`** properties and **`icmp_code`** and **`icmp_type`** properties are mutually exclusive sets. Although both sets are shown in the same rule above to demonstrate the syntax, they never appear together in practice.
  - The **`destination_port`** and **`source_port`** properties are only available when the **`protocol`** for the rule is `tcp` or `udp`.
  - The [**`icmp_code`**](https://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml#icmp-parameters-codes) and [**`icmp_type`**](https://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml#icmp-parameters-types) properties are only available when the **`protocol`** is `icmp4` or `icmp6`.
- The **`state`** is `enabled` by default. The `logged` value is used to [log traffic](#network-acls-log) to a rule.

For more information, see: [Rule properties](#network-acls-rule-properties).

### Add a rule

CLI

To add a rule to an ACL, run:

```bash
lxc network acl rule add <ACL-name> <egress|ingress> [properties...]
```

### Example

Add an `egress` rule with an `action` of `drop` to `my-acl`:

```bash
lxc network acl rule add my-acl egress action=drop
```

<!-- End of group-tab CLI -->

API

There is no specific endpoint for adding a rule. Instead, you must [edit the full ACL](#network-acls-edit), which contains the `egress` and `ingress` lists.

<!-- End of group-tab API -->

UI

To add an ingress or egress rule to an ACL, go to its [detail page](#network-acls-show).

Click Add rule, then configure your ingress or egress settings.

![Add a rule to an ACL in LXD](images/networks/network_ACL_addrule.png)

Note that the Save changes button displays the number of changes you have made. Save your changes.

<!-- End of group-tab UI -->

### Remove a rule

CLI

To remove a rule from an ACL, run:

```bash
lxc network acl rule remove <ACL-name> <egress|ingress> [properties...]
```

You must either specify all properties needed to uniquely identify a rule or add `--force` to the command to delete all matching rules.

<!-- End of group-tab CLI -->

API

There is no specific endpoint for removing a rule. Instead, you must [edit the full ACL](#network-acls-edit), which contains the `egress` and `ingress` lists.

<!-- End of group-tab API -->

UI

To remove a rule from an ACL, go to the ACL’s [detail page](#network-acls-show). From the row of the rule to remove, click the Delete button.

![Add a rule to an ACL in LXD](images/networks/network_ACL_remove_edit.png)

Note that the Save changes button displays the number of changes you have made. Save your changes.

<!-- End of group-tab UI -->

### Edit a rule

You cannot edit a rule directly. Instead, you must [edit the full ACL](#network-acls-edit), which contains the `egress` and `ingress` lists.

### Rule ordering and application of actions

ACL rules are defined as lists, but their order within the list does not affect how they are applied.

LXD automatically prioritizes rules based on the action property, in the following order:

- `drop`
- `reject`
- `allow`
- The default action for unmatched traffic (defaults to `reject`, see [Configure default actions](#network-acls-defaults))

When you assign multiple ACLs to a NIC, you do not need to coordinate rule order across them. As soon as a rule matches, its action is applied and no further rules are evaluated.

<a id="network-acls-rule-properties"></a>

### Rule properties

ACL rules have the following properties:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="network-acl-rule-properties:action"></a>
`action`

Action to take for matching traffic

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-acl-rule-properties:action)

| **Key:**      | `action`   |
|---------------|------------|
| **Type:**     | string     |
| **Required:** | yes        |

Possible values are `allow`, `reject`, and `drop`.

<a id="network-acl-rule-properties:description"></a>
`description`

Description of the rule

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-acl-rule-properties:description)

| **Key:**      | `description`   |
|---------------|-----------------|
| **Type:**     | string          |
| **Required:** | no              |

<a id="network-acl-rule-properties:destination"></a>
`destination`

Comma-separated list of destinations

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-acl-rule-properties:destination)

| **Key:**      | `destination`   |
|---------------|-----------------|
| **Type:**     | string          |
| **Required:** | no              |

Destinations can be specified as CIDR or IP ranges, destination subject name selectors (for egress rules), or be left empty for any.

<a id="network-acl-rule-properties:destination_port"></a>
`destination_port`

Destination ports or port ranges

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-acl-rule-properties:destination_port)

| **Key:**      | `destination_port`   |
|---------------|----------------------|
| **Type:**     | string               |
| **Required:** | no                   |

This option is valid only if the protocol is `udp` or `tcp`.
Specify a comma-separated list of ports or port ranges (start-end inclusive), or leave the value empty for any.

<a id="network-acl-rule-properties:icmp_code"></a>
`icmp_code`

ICMP message code

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-acl-rule-properties:icmp_code)

| **Key:**      | `icmp_code`   |
|---------------|---------------|
| **Type:**     | string        |
| **Required:** | no            |

This option is valid only if the protocol is `icmp4` or `icmp6`.
Specify the ICMP code number, or leave the value empty for any.

<a id="network-acl-rule-properties:icmp_type"></a>
`icmp_type`

Type of ICMP message

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-acl-rule-properties:icmp_type)

| **Key:**      | `icmp_type`   |
|---------------|---------------|
| **Type:**     | string        |
| **Required:** | no            |

This option is valid only if the protocol is `icmp4` or `icmp6`.
Specify the ICMP type number, or leave the value empty for any.

<a id="network-acl-rule-properties:protocol"></a>
`protocol`

Protocol to match

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-acl-rule-properties:protocol)

| **Key:**      | `protocol`   |
|---------------|--------------|
| **Type:**     | string       |
| **Required:** | no           |

Possible values are `icmp4`, `icmp6`, `tcp`, and `udp`.
Leave the value empty to match any protocol.

<a id="network-acl-rule-properties:source"></a>
`source`

Comma-separated list of sources

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-acl-rule-properties:source)

| **Key:**      | `source`   |
|---------------|------------|
| **Type:**     | string     |
| **Required:** | no         |

Sources can be specified as CIDR or IP ranges, source subject name selectors (for ingress rules), or be left empty for any.

<a id="network-acl-rule-properties:source_port"></a>
`source_port`

Source ports or port ranges

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-acl-rule-properties:source_port)

| **Key:**      | `source_port`   |
|---------------|-----------------|
| **Type:**     | string          |
| **Required:** | no              |

This option is valid only if the protocol is `udp` or `tcp`.
Specify a comma-separated list of ports or port ranges (start-end inclusive), or leave the value empty for any.

<a id="network-acl-rule-properties:state"></a>
`state`

State of the rule

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-acl-rule-properties:state)

| **Key:**      | `state`   |
|---------------|-----------|
| **Type:**     | string    |
| **Default:**  | `enabled` |
| **Required:** | yes       |

Possible values are `enabled`, `disabled`, and `logged`.

<a id="network-acls-selectors"></a>

### Use selectors in rules

#### NOTE
This feature is supported only for the [OVN NIC type](../reference/devices_nic.md#nic-ovn) and the [OVN network](../reference/network_ovn.md#network-ovn).

In ACL rules, the `source` and `destination` properties support using selectors instead of CIDR blocks or IP ranges. You can only use selectors in the `source` of `ingress` rules, and in the `destination` of `egress` rules.

Using selectors allows you to define rules for groups of instances instead of managing lists of IP addresses or subnets manually.

There are two types of selectors:

- subject name selectors (ACL groups)
- network subject selectors

<a id="network-acls-selectors-subject-name"></a>

#### Subject name selectors (ACL groups)

When an ACL is assigned to multiple instance NICs, either directly or through their networks, those NICs form a logical port group. You can use the name of that ACL as a *subject name selector* to refer to that group in the egress and ingress lists of other ACLs.

For example, if you have an ACL with the name `my-acl`, you can specify the group of instance NICs that are assigned this ACL as an egress or ingress rule’s source by setting `source` to `my-acl`.

<a id="network-acls-selectors-network-subject"></a>

#### Network subject selectors

Use *network subject selectors* to define rules based on the network that the traffic is coming from or going to.

All network subject selectors begin with the `@` symbol. There are two special network subject selectors called `@internal` and `@external`. They represent the network’s local and external traffic, respectively.

Here’s an example ACL rule (in YAML) that allows all internal traffic with the specified destination port:

```yaml
ingress:
  - action: allow
    description: Allow HTTP/HTTPS from internal
    protocol: tcp
    source: "@internal"
    destination_port: "80,443"
    state: enabled
```

If your network supports [network peers](network_ovn_peers.md), you can reference traffic to or from the peer connection by using a network subject selector in the format `@<network-name>/<peer-name>`. Example:

```yaml
source: "@my-network/my-peer"
```

When using a network subject selector, the network that has the ACL assigned to it must have the specified peer connection.

<a id="network-acls-log"></a>

### Log traffic

ACL rules are primarily used to control network traffic between instances and networks. However, they can also be used to log specific types of traffic, which is useful for monitoring or testing rules before enabling them.

To configure a rule so that it only logs traffic, configure its `state` to `logged` when you [add the rule](#network-acls-rules) or [edit the ACL](#network-acls-edit).

#### View logs

CLI

To display the logs for all `logged` rules in an ACL, run:

```bash
lxc network acl show-log <ACL-name>
```

<!-- End of group-tab CLI -->

API

To display the logs for all `logged` rules in an ACL, query the [`GET /1.0/network-acls/{ACL-name}/log`](/api/#/network-acls/network_acl_log_get) endpoint:

```bash
lxc query --request GET /1.0/network-acls/{ACL-name}/log
```

### Example

```bash
lxc query --request GET /1.0/network-acls/my-acl/log
```

<!-- End of group-tab API -->

UI

Download a `.log` file of your ACL’s logs from its [detail page](#network-acls-show) by clicking the Download logs button in the upper-right corner.

<!-- End of group-tab UI -->

#### NOTE
If your attempt to view logs returns no data, that means either:

- No `logged` rules have matched any traffic yet.
- The ACL does not contain any rules with a `state` of `logged`.

When displaying logs for an ACL, LXD intentionally displays all existing logs for that ACL, including logs from formerly `logged` rules that are no longer set to log traffic. Thus, if you see logs from an ACL rule, that does not necessarily mean that its `state` is *currently* set to `logged`.

<a id="network-acls-edit"></a>

## Edit an ACL

<a id="network-acls-edit-rename"></a>

### Rename an ACL

Requirements:

- You can only rename an ACL that is not currently [assigned to a NIC or network](#network-acls-assign).
- The new name must meet the [Name requirements](#network-acls-name-requirements).

CLI

To rename an ACL, run:

```bash
lxc network acl rename <old-ACL-name> <new-ACL-name>
```

<!-- End of group-tab CLI -->

API

To rename an ACL, query the [`POST /1.0/network-acls/{ACL-name}`](/api/#/network-acls/network_acl_post) endpoint:

```bash
lxc query --request POST /1.0/network-acls/{ACL-name} --data '{
  "name": "<new-ACL-name>"
}'
```

### Example

Rename an ACL named `web-traffic` to `internal-web-traffic`:

```bash
lxc query --request POST /1.0/network-acls/web-traffic --data '{
  "name": "internal-web-traffic"
}'
```

<!-- End of group-tab API -->

UI

To rename an ACL, go to its [detail page](#network-acls-show) and select its name in the header.

<!-- End of group-tab UI -->

<a id="network-acls-edit-properties"></a>

### Edit other properties

CLI

Run:

```bash
lxc network acl edit <ACL-name>
```

This command opens the ACL configuration in YAML format for editing. You can edit any part of the configuration *except* for the ACL name, including the custom user keys.

<!-- End of group-tab CLI -->

API

You can update any ACL property except for `name`, including the custom user keys, by querying the [`PUT /1.0/network-acls/{ACL-name}`](/api/#/network-acls/network_acl_put) endpoint:

```bash
lxc query --request PUT /1.0/network-acls/{ACL-name} --data '{
  "config": {
    "user.<custom key name>": "<custom key value>"
  },
  "description": "<description of the ACL>",
  "egress": [<egress rule>, <another egress rule...>,...],
  "ingress": [<ingress rule>, <another ingress rule...>,...]
}'
```

If you *only* want to update the `config` custom user keys, see: [Edit a custom user key via PATCH API](#network-acls-edit-custom-api).

### Example

Consider an ACL named `my-acl` with the following properties (shown in JSON):

```json
{
  "name": "my-acl",
  "config": {
    "user.my-key": "my-value"
  },
  "description": "My test ACL",
  "egress": [
    {
      "action": "allow",
      "state": "logged"
    }
  ]
  "ingress": [
    {
      "action": "drop",
      "state": "enabled"
    }
  ]
}
```

This query updates that ACL’s `egress` rule `state` from `logged` to `enabled`:

```bash
lxc query --request PUT /1.0/network-acls/my-acl --data '{
  "egress": [
    {
      "action": "allow",
      "state": "enabled"
    }
  ]
}'
```

After the above query is run, `my-acl` contains the following properties:

```json
{
  "name": "test",
  "config": {},
  "description": "",
  "egress": [
    {
      "action": "allow",
      "state": "enabled"
    }
  ],
  "ingress": []
}
```

Note that the `description` and `ingress` properties have been reset to defaults because they were not provided in the API request.

To avoid this behavior and preserve the values of any existing properties, you must include them in the `PUT` request along with the updated property:

```bash
lxc query --request PUT /1.0/network-acls/my-acl --data '{
  "description": "My test ACL",
  "egress": [
    {
      "action": "allow",
      "state": "enabled"
    }
  ],
  "ingress": [
    {
      "action": "drop",
      "state": "enabled"
    }
  ]
}'
```

<!-- End of group-tab API -->

UI

To edit an ACL, navigate to its [detail page](#network-acls-show). From here, you can add or remove ingress or egress rules, as well as configure other settings.

<!-- End of group-tab UI -->

<a id="network-acls-edit-custom-api"></a>

### Edit a custom user key via PATCH API

There’s one more way to add or update a custom `config.user.*` key when using the API. Instead of the PUT method shown in the [Edit other properties](#network-acls-edit-properties) section above, you can query the [`PATCH /1.0/network-acls/{ACL-name}`](/api/#/network-acls/network_acl_patch) endpoint:

```bash
lxc query --request PATCH /1.0/network-acls/{ACL-name} --data '{
  "config": {
    "user.<custom-key-name>": "<custom-key-value>"
  }
}'
```

This `PATCH` endpoint allows you to add or update custom `config.user.*` keys without affecting other existing `config.user.*` entries. However, this [partial update behavior](../rest-api.md#rest-api-patch) applies *only* to the `config` property. For the `description`, `egress`, and `ingress` properties, this request behaves like a [PUT request](../rest-api.md#rest-api-put): it replaces any provided values and resets any omitted properties to their defaults. Thus, ensure you include any properties you want to keep.

#### Example

Consider an ACL named `my-acl` with the following properties (shown in JSON):

```json
{
  "name": "my-acl",
  "description": "My test ACL",
  "config": {
    "user.my-key1": "1"
  },
}
```

The following query adds a `config.user.my-key2` key with the value of `2`:

```bash
lxc query --request PATCH /1.0/network-acls/my-acl --data '{
  "config": {
    "user.my-key2": "2"
  }
}'
```

After sending the above request, `my-acl`’s properties are updated to:

```json
{
  "name": "my-acl",
  "description": "",
  "config": {
    "user.my-key1": "1",
    "user.my-key2": "2"
  }
}
```

Note that the request *inserted* the new `user.my-key2` key without affecting the pre-existing `user.my-key1` key. Also notice that the `description` property was not sent in the request, and thus was reset to an empty value.

<a id="network-acls-delete"></a>

## Delete an ACL

You can only delete an ACL that is not [assigned to a NIC or network](#network-acls-assign).

CLI

To delete an ACL, run:

```bash
lxc network acl delete <ACL-name>
```

<!-- End of group-tab CLI -->

API

To delete an ACL, query the [`DELETE /1.0/network-acls/{ACL-name}`](/api/#/network-acls/network_acl_delete) endpoint:

```bash
lxc query --request DELETE /1.0/network-acls/{ACL-name}
```

<!-- End of group-tab API -->

UI

To delete an ACL, ensure that it is not assigned to an NIC or network. You can then delete it from its [detail page](#network-acls-show).

<!-- End of group-tab UI -->

<a id="network-acls-assign"></a>

## Assign an ACL

An ACL is inactive until it is assigned to one of the following targets:

- a [OVN network](../reference/network_ovn.md#network-ovn)
- a [Bridge network](../reference/network_bridge.md#network-bridge)
- an [OVN NIC type of an instance](../reference/devices_nic.md#nic-ovn)

To assign an ACL, you must update the `security.acls` option within its target’s configuration.

Assigning one or more ACLs to a NIC or network adds a default rule that rejects all unmatched traffic. See [Configure default actions](#network-acls-defaults) for details.

### Assign an ACL to a bridge or OVN network

CLI

To set the network’s `security.acls`, run the following command. Set the value to a string that contains the ACL name or names you want to add, and comma-separate multiple names:

Set the network’s `security.acls` to a string that contains the ACL name or names you want to add. Comma-separate multiple names:

```bash
lxc network set <network-name> security.acls="<ACL-name>[,<ACL-name>,...]"
```

For more information about using `lxc network set`, see: [How to configure a network](network_configure.md#network-configure).

### Example

Set the `my-network` network’s `security.acls` to contain three ACLs:

```bash
lxc network set my-network security.acls="my-acl1,my-acl2,my-acl3"
```

<!-- End of group-tab CLI -->

API

To set the network’s `security.acls`, query the [`PATCH /1.0/networks/{network-name}`](/api/#/networks/network_patch) endpoint. Set the value to a string that contains the ACL name or names you want to add, and comma-separate multiple names:

```bash
lxc query --request PATCH /1.0/networks/{network-name} --data '{
  "config": {
    "security.acls": "<ACL-name>[,<ACL-name>,...]"
  }
}'
```

### Example

Set the `my-network` network’s `security.acls` to contain three ACLs:

```bash
lxc query --request PATCH /1.0/networks/my-network --data '{
  "config": {
    "security.acls": "my-acl1,my-acl2,my-acl3"
  }
}'
```

<!-- End of group-tab API -->

UI

You can assign an ACL to a bridge or OVN network when [creating](network_create.md#network-create) or [editing](network_configure.md#network-configure) the network. In either case, select your pre-configured ACL from the ACLs dropdown.

![Create a network in LXD](images/networks/network_create.png)
<!-- End of group-tab UI -->

### Assign an ACL to the OVN NIC of an instance

For , ACLs can only be used with the [OVN NIC type](../reference/devices_nic.md#nic-ovn).

An NIC is considered a type of instance [device](../reference/devices.md#devices). For general information about configuring instance devices, see: [Configure devices](instances_configure.md#instances-configure-devices).

CLI

To assign an ACL to an instance’s OVN NIC, run:

```bash
lxc config device set <instance-name> <NIC-name> security.acls="<ACL-name>[,ACL-name,...]"
```

### Example

Assign three ACLs to an instance’s OVN NIC:

```bash
lxc config device set my-instance my-ovn-nic security.acls="my-acl1,my-acl2,my-acl3"
```

<!-- End of group-tab CLI -->

API

To assign an ACL to an instance’s OVN NIC, query the [`PATCH /1.0/instances/{instance-name}`](/api/#/instances/instance_patch) endpoint. Set `security.acls` to a string that contains the ACL name or names you want to add, and comma-separate multiple names:

```bash
lxc query --request PATCH /1.0/instances/{instance-name} --data '{
  "devices": {
    "<NIC-name>": {
      "network": <network-name>,
      "type": "nic",
      "security.acls": "<ACL-name>[,<ACL-name>,...]",
      <other options>
    }
  }
}'
```

The `type` and `network` options are required in the body (see: instances-configure-devices-api-required).

### Example

For `my-instance`, set its `my-ovn-nic` device’s `security.acls` to contain three ACLs:

```bash
lxc query --request PATCH /1.0/instances/my-instance --data '{
  "devices": {
    "my-ovn-nic": {
      "network": "my-ovn-network",
      "type": "nic",
      "security.acls": "my-acl1,my-acl2,my-acl3"
    }
  }
}'
```

<!-- End of group-tab API -->

<a id="network-acls-assign-additional"></a>

### Additional options

To view additional options for the `security.acls` lists, refer to the configuration options for the target network or NIC:

- Bridget network’s [`security.acls`](../reference/network_bridge.md#network-bridge-network-conf:security.acls)
- OVN network’s [`security.acls`](../reference/network_ovn.md#network-ovn-network-conf:security.acls)
- Instance’s OVN NIC [`security.acls`](../reference/devices_nic.md#device-nic-ovn-device-conf:security.acls)

<a id="network-acls-defaults"></a>

## Configure default actions

When one or more ACLs are assigned to a NIC—either directly or through its network—a default reject rule is added to the NIC.
This rule rejects all traffic that doesn’t match any of the rules in the assigned ACLs.

You can change this behavior with the network- and NIC-level `security.acls.default.ingress.action` and `security.acls.default.egress.action` settings. The NIC-level settings override the network-level settings.

CLI

### Configure a default action for a network

To set the default action for a network’s egress or ingress traffic, run:

```bash
lxc network set <network-name> security.acls.default.<egress|ingress>.action=<allow|reject|drop>
```

### Example

To set the default action for inbound traffic to `allow` for all instances on the `my-network` network, run:

```bash
lxc network set my-network security.acls.default.ingress.action=allow
```

### Configure a default action for an instance OVN NIC device

To set the default action for an instance OVN NIC’s egress or ingress traffic, run:

```bash
lxc config device set <instance-name> <NIC-name> security.acls.default.<egress|ingress>.action=<allow|reject|drop>
```

### Example

To set the default action for inbound traffic to `allow` for the `my-ovn-nic` device of `my-instance`, run:

```bash
lxc config device set my-instance my-ovn-nic security.acls.default.ingress.action=allow
```

<!-- End of group-tab CLI -->

API

### Configure a default action for a network

To set the default action for a network’s egress or ingress traffic, query the [`PATCH /1.0/networks/{network-name}`](/api/#/networks/network_patch) endpoint:

```bash
lxc query --request PATCH /1.0/networks/{network-name} --data '{
  "config": {
    "security.acls.default.egress.action": "<allow|reject|drop>",
    "security.acls.default.ingress.action": "<allow|reject|drop>",
  }
}'
```

### Example

Set the `my-network` network’s default egress action to `allow`:

```bash
lxc query --request PATCH /1.0/networks/my-network --data '{
  "config": {
    "security.acls.default.egress.action": "allow"
  }
}'
```

### Configure a default action for an instance’s OVN NIC device

To set the default action for an instance’s OVN NIC’s traffic, query the [`PATCH /1.0/instances/{instance-name}`](/api/#/instances/instance_patch) endpoint:

```bash
lxc query --request PATCH /1.0/instances/{instance-name} --data '{
  "devices": {
    "<NIC-name>": {
      "network": <network-name>,
      "type": "nic",
      "security.acls.default.<egress|ingress>.action": "<allow|reject|drop>"
      <other-options>
    }
  }
}'
```

The `type` and `network` options are required in the body (see: instances-configure-devices-api-required).

### Example

This request sets the default action for inbound traffic to `allow` for the `my-ovn-nic` device of `my-instance`:

```bash
lxc query --request PATCH /1.0/instances/my-instance --data '{
  "devices": {
    "my-ovn-nic": {
      "network": "my-network",
      "type": "nic",
      "security.acls.default.ingress.action": "allow"
    }
  }
}'
```

<!-- End of group-tab API -->

<a id="network-acls-bridge-limitations"></a>

## Bridge limitations

When using network ACLs with a bridge network, be aware of the following limitations:

- Unlike OVN ACLs, bridge ACLs apply only at the boundary between the bridge and the LXD host. This means they can enforce network policies only for traffic entering or leaving the host. <spellexception>Intra-bridge</spellexception> firewalls (rules controlling traffic between instances on the same bridge) are not supported.
- [ACL groups and network selectors](#network-acls-selectors) are not supported.
- If you’re using the `iptables` firewall driver, you cannot use IP range subjects (such as `192.0.2.1-192.0.2.10`).
- Baseline network service rules are added before ACL rules in their respective INPUT/OUTPUT chains. Because we cannot differentiate between INPUT/OUTPUT and FORWARD traffic after jumping into the ACL chain, ACL rules cannot block these baseline rules.


# index.html.md

<a id="network-bridge-resolved"></a>

# How to integrate with `systemd-resolved`

#### IMPORTANT
This guide applies to managed bridge networks only.

If the system that runs LXD uses `systemd-resolved` to perform DNS lookups, you should notify `resolved` of the domains that LXD can resolve.
To do so, add the DNS servers and domains provided by a LXD network bridge to the `resolved` configuration.

#### NOTE
The [`dns.mode`](../reference/network_bridge.md#network-bridge-network-conf:dns.mode) option must be set to `managed` or `dynamic` if you want to use this feature.

Depending on the configured [`dns.domain`](../reference/network_bridge.md#network-bridge-network-conf:dns.domain), you might need to disable DNSSEC in `resolved` to allow for DNS resolution.
This can be done through the `DNSSEC` option in `resolved.conf`.

<a id="network-bridge-resolved-configure"></a>

## Configure resolved

To add a network bridge to the `resolved` configuration, specify the DNS addresses and domains for the respective bridge.

DNS address
: You can use the IPv4 address, the IPv6 address or both.
  The address must be specified without the subnet netmask.
  <br/>
  To retrieve the IPv4 address for the bridge, use the following command:
  <br/>
  ```none
  lxc network get <network_bridge> ipv4.address
  ```
  <br/>
  To retrieve the IPv6 address for the bridge, use the following command:
  <br/>
  ```none
  lxc network get <network_bridge> ipv6.address
  ```

DNS domain
: To retrieve the DNS domain name for the bridge, use the following command:
  <br/>
  ```none
  lxc network get <network_bridge> dns.domain
  ```
  <br/>
  If this option is not set, the default domain name is `lxd`.

Use the following commands to configure `resolved`:

```none
resolvectl dns <network_bridge> <dns_address>
resolvectl domain <network_bridge> ~<dns_domain>
```

#### NOTE
When configuring `resolved` with the DNS domain name, you should prefix the name with `~`.
The `~` tells `resolved` to use the respective name server to look up only this domain.

Depending on which shell you use, you might need to include the DNS domain in quotes to prevent the `~` from being expanded.

For example:

```none
resolvectl dns lxdbr0 192.0.2.10
resolvectl domain lxdbr0 '~lxd'
```

#### NOTE
Alternatively, you can use the `systemd-resolve` command.
This command has been deprecated in newer releases of `systemd`, but it is still provided for backwards compatibility.

```none
systemd-resolve --interface <network_bridge> --set-domain ~<dns_domain> --set-dns <dns_address>
```

The `resolved` configuration persists as long as the bridge exists.
You must repeat the commands after each reboot and after LXD is restarted, or make it persistent as described below.

## Make the `resolved` configuration persistent

There are two approaches to automating `systemd-resolved` configuration to ensure that it persists when the LXD bridge network is re-created. Use only one of these approaches, described below.

The first approach is recommended because it is more resilient. It applies your desired configuration whenever your system is rebooted, *and* whenever the LXD bridge network is re-created outside of a system reboot. For example, updating and restarting LXD can occasionally cause its bridge network to be re-created.

If you are unable to use the recommended approach, the alternative approach can be used. The alternative approach applies your desired configuration only when your system is rebooted. If LXD re-creates its bridge network outside of a system reboot, you must reapply the configuration manually.

### Recommended approach

#### Create a `systemd` network file

Get the network bridge address with the following command:

```bash
lxc network get lxdbr0 ipv4.address
```

Create a `systemd` network file named `/etc/systemd/network/<network_bridge>.network` with the following content:

```default
[Match]
Name=<network_bridge>
[Network]
Address=<network_bridge_address>
DNS=<dns_address>
Domains=~<dns_domain>
```

Example file content for `/etc/systemd/network/lxdbr0.network` (insert your own DNS value):

```default
[Match]
Name=lxdbr0
[Network]
Address=10.167.146.1/24
DNS=10.167.146.1
Domains=~lxd
```

#### Apply the updated configuration

If you have rebooted since you first installed LXD, you only need to reload `systemd-resolved`:

```none
systemctl restart systemd-resolved.service
```

If you have *not* rebooted your system since you first installed LXD, you must either:

1. reboot the system, or
2. reload `systemd-networkd` (to reload the `.network` files) and restart `lxd` (to add the routing):

```default
networkctl reload
snap restart lxd
```

You can test that the updated configuration was applied by running:

```default
resolvectl status
```

The output should contain a section similar to the example shown below. You should see the configured DNS server and the `~lxd` domain:

```default
[...]
Link 4 (lxdbr0)
    Current Scopes: DNS
         Protocols: -DefaultRoute +LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
Current DNS Server: 10.167.146.1
       DNS Servers: 10.167.146.1
        DNS Domain: ~lxd
[...]
```

### Alternative approach

#### WARNING
This approach only automates applying your desired configuration when your system is rebooted. If LXD re-creates its bridge network outside of a system reboot, you must reapply the configuration manually with the following command:

```none
systemctl restart lxd-dns-<bridge_network>.service
```

Example:

```none
systemctl restart lxd-dns-lxdbr0.service
```

Create a `systemd` unit file named `/etc/systemd/system/lxd-dns-<network_bridge>.service` with the following content:

```default
[Unit]
Description=LXD per-link DNS configuration for <network_bridge>
BindsTo=sys-subsystem-net-devices-<network_bridge>.device
After=sys-subsystem-net-devices-<network_bridge>.device

[Service]
Type=oneshot
ExecStart=/usr/bin/resolvectl dns <network_bridge> <dns_address>
ExecStart=/usr/bin/resolvectl domain <network_bridge> '~<dns_domain>'
ExecStopPost=/usr/bin/resolvectl revert <network_bridge>
RemainAfterExit=yes

[Install]
WantedBy=sys-subsystem-net-devices-<network_bridge>.device
```

Replace `<network_bridge>` in the file name and content with the name of your bridge (for example, `lxdbr0`).
Also replace `<dns_address>` and `<dns_domain>` as described in [Configure resolved](#network-bridge-resolved-configure).

Example file content for `/etc/systemd/system/lxd-dns-lxdbr0.service` (insert your own DNS value):

```default
Description=LXD per-link DNS configuration for lxdbr0
BindsTo=sys-subsystem-net-devices-lxdbr0.device
After=sys-subsystem-net-devices-lxdbr0.device

[Service]
Type=oneshot
ExecStart=/usr/bin/resolvectl dns lxdbr0 192.0.2.1  # FIXME: replace with your LXD DNS address
ExecStart=/usr/bin/resolvectl domain lxdbr0 '~lxd'
ExecStopPost=/usr/bin/resolvectl revert lxdbr0
RemainAfterExit=yes

[Install]
WantedBy=sys-subsystem-net-devices-lxdbr0.device
```

Then enable and start the service with the following commands:

```none
sudo systemctl daemon-reload
sudo systemctl enable --now lxd-dns-<network_bridge>
```

If the respective bridge already exists (because LXD is already running), you can use the following command to check that the new service has started:

```none
sudo systemctl status lxd-dns-<network_bridge>.service
```

You should see output similar to the following:

`user@host:~$ ``sudo systemctl status lxd-dns-lxdbr0.service
`
```text
● lxd-dns-lxdbr0.service - LXD per-link DNS configuration for lxdbr0
     Loaded: loaded (/etc/systemd/system/lxd-dns-lxdbr0.service; enabled; vendor preset: enabled)
     Active: inactive (dead) since Mon 2021-06-14 17:03:12 BST; 1min 2s ago
    Process: 9433 ExecStart=/usr/bin/resolvectl dns lxdbr0 n.n.n.n (code=exited, status=0/SUCCESS)
    Process: 9434 ExecStart=/usr/bin/resolvectl domain lxdbr0 ~lxd (code=exited, status=0/SUCCESS)
   Main PID: 9434 (code=exited, status=0/SUCCESS)
```

To check that `resolved` has applied the settings, use `resolvectl status <network_bridge>`:

`user@host:~$ ``resolvectl status lxdbr0
`
```text
Link 6 (lxdbr0)
      Current Scopes: DNS
DefaultRoute setting: no
       LLMNR setting: yes
MulticastDNS setting: no
  DNSOverTLS setting: no
      DNSSEC setting: no
    DNSSEC supported: no
  Current DNS Server: n.n.n.n
         DNS Servers: n.n.n.n
          DNS Domain: ~lxd
```


# index.html.md

<a id="instances-configure"></a>

# How to configure instances

You can configure instances by setting [Instance properties](../reference/instance_properties.md#instance-properties), [Instance options](../reference/instance_options.md#instance-options), or by adding and configuring [Devices](../reference/devices.md#devices).

See the following sections for instructions.

#### NOTE
To store and reuse different instance configurations, use [profiles](../profiles.md#profiles).

<a id="instances-configure-options"></a>

## Configure instance options

You can specify instance options when you [create an instance](instances_create.md#instances-create).
Alternatively, you can update the instance options after the instance is created.

CLI

Use the [`lxc config set`](../reference/manpages/lxc/config/set.md#lxc-config-set-md) command to update instance options.
Specify the instance name and the key and value of the instance option:

```none
lxc config set <instance_name> <option_key>=<option_value> <option_key>=<option_value> ...
```

API

Send a PATCH request to the instance to update instance options.
Specify the instance name and the key and value of the instance option:

```none
lxc query --request PATCH /1.0/instances/<instance_name> --data '{
  "config": {
    "<option_key>": "<option_value>",
    "<option_key>": "<option_value>"
  }
}'
```

See [`PATCH /1.0/instances/{name}`](/api/#/instances/instance_patch) for more information.

UI

To update instance options, go to the Configuration tab of the instance detail page and click Edit instance.

Find the configuration option that you want to update and change its value.
Click Save changes to save the updated configuration.

To configure instance options that are not displayed in the UI, follow the instructions in [Edit the full instance configuration](#instances-configure-edit).

See [Instance options](../reference/instance_options.md#instance-options) for a list of available options and information about which options are available for which instance type.

For example, change the memory limit for your container:

CLI

To set the memory limit to 8 GiB, enter the following command:

```none
lxc config set my-container limits.memory=8GiB
```

API

To set the memory limit to 8 GiB, send the following request:

```none
lxc query --request PATCH /1.0/instances/my-container --data '{
  "config": {
    "limits.memory": "8GiB"
  }
}'
```

UI

To set the memory limit to 8 GiB, go to the Configuration tab of the instance detail page and select Advanced > Resource limits.
Then click Edit instance.

Select Override for the **Memory limit** and enter 8 GiB as the absolute value.

![Setting the memory limit for an instance to 8 GiB](images/UI/limits_memory_example.png)

#### NOTE
Some of the instance options are updated immediately while the instance is running.
Others are updated only when the instance is restarted.

See the “Live update” information in the [Instance options](../reference/instance_options.md#instance-options) reference for information about which options are applied immediately while the instance is running.

<a id="instances-configure-properties"></a>

## Configure instance properties

CLI

To update instance properties after the instance is created, use the [`lxc config set`](../reference/manpages/lxc/config/set.md#lxc-config-set-md) command with the `--property` flag.
Specify the instance name and the key and value of the instance property:

```none
lxc config set <instance_name> <property_key>=<property_value> <property_key>=<property_value> ... --property
```

Using the same flag, you can also unset a property just like you would unset a configuration option:

```none
lxc config unset <instance_name> <property_key> --property
```

You can also retrieve a specific property value with:

```none
lxc config get <instance_name> <property_key> --property
```

API

To update instance properties through the API, use the same mechanism as for configuring instance options.
The only difference is that properties are on the root level of the configuration, while options are under the `config` field.

Therefore, to set an instance property, send a PATCH request to the instance:

```none
lxc query --request PATCH /1.0/instances/<instance_name> --data '{
  "<property_key>": "<property_value>",
  "<property_key>": "property_value>"
  }
}'
```

To unset an instance property, send a PUT request that contains the full instance configuration that you want except for the property that you want to unset.

See [`PATCH /1.0/instances/{name}`](/api/#/instances/instance_patch) and [`PUT /1.0/instances/{name}`](/api/#/instances/instance_put) for more information.

UI

The LXD UI does not distinguish between instance options and instance properties.
Therefore, you can configure instance properties in the same way as you [configure instance options](#instances-configure-options).

<a id="instances-configure-devices"></a>

## Configure devices

Generally, devices can be added or removed for a container while it is running.
VMs support hotplugging for some device types, but not all.

See [Devices](../reference/devices.md#devices) for a list of available device types and their options.

#### NOTE
Every device entry is identified by a name unique to the instance.

Devices from profiles are applied to the instance in the order in which the profiles are assigned to the instance.
Devices defined directly in the instance configuration are applied last.
At each stage, if a device with the same name already exists from an earlier stage, the whole device entry is overridden by the latest definition.

Device names are limited to a maximum of 64 characters.

CLI

To add and configure an instance device for your instance, use the [`lxc config device add`](../reference/manpages/lxc/config/device/add.md#lxc-config-device-add-md) command.

Specify the instance name, a device name, the device type and maybe device options (depending on the [device type](../reference/devices.md#devices)):

```none
lxc config device add <instance_name> <device_name> <device_type> <device_option_key>=<device_option_value> <device_option_key>=<device_option_value> ...
```

For example, to add the storage at `/share/c1` on the host system to your instance at path `/opt`, enter the following command:

```none
lxc config device add my-container disk-storage-device disk source=/share/c1 path=/opt
```

To configure instance device options for a device that you have added earlier, use the [`lxc config device set`](../reference/manpages/lxc/config/device/set.md#lxc-config-device-set-md) command:

```none
lxc config device set <instance_name> <device_name> <device_option_key>=<device_option_value> <device_option_key>=<device_option_value> ...
```

Device options for a device inherited from a profile cannot be updated within the instance. Use the [`lxc config device override`](../reference/manpages/lxc/config/device/override.md#lxc-config-device-override-md) command to create a copy of the profile device with updated device options. The newly created instance device will override the inherited device.

Specify the instance name, device name and the device options that should be overridden:

```none
lxc config device override <instance_name> <device_name> <device_option_key>=<device_option_value> <device_option_key>=<device_option_value> ...
```

#### NOTE
You can also specify device options by using the `--device` flag when [creating an instance](instances_create.md#instances-create).
This is useful if you want to override device options for a device that is provided through a [profile](../profiles.md#profiles).

To remove a device, use the [`lxc config device remove`](../reference/manpages/lxc/config/device/remove.md#lxc-config-device-remove-md) command.
See [`lxc config device --help`](../reference/manpages/lxc/config/device.md#lxc-config-device-md) for a full list of available commands.

API

To add or configure an instance device for your instance, use the same mechanism of patching the instance configuration.
The device configuration is located under the `devices` field of the configuration.

Specify the instance name, a device name, and any instances-configure-devices-api-required (depending on the [device type](../reference/devices.md#devices)):

```none
lxc query --request PATCH /1.0/instances/<instance_name> --data '{
  "devices": {
    "<device_name>": {
      "type": "<device_type>",
      "<device_option_key>": "<device_option_value>",
      "<device_option_key>": "device_option_value>"
    }
  }
}'
```

For example, to add the storage at `/share/c1` on the host system to your instance at path `/opt`, enter the following command:

```none
lxc query --request PATCH /1.0/instances/my-container --data '{
  "devices": {
    "disk-storage-device": {
      "type": "disk",
      "source": "/share/c1",
      "path": "/opt"
    }
  }
}'
```

See [`PATCH /1.0/instances/{name}`](/api/#/instances/instance_patch) for more information.

<a id="id1"></a>

### Required device options

When using a PATCH request to update an instance’s `devices` property, you must include any required options for each device in the request body. The device’s `type` option is always required. To find any other required keys for a specific device type, view the [Devices](../reference/devices.md#devices) reference guides. For example, for an OVN NIC device, the [`network`](../reference/devices_nic.md#device-nic-ovn-device-conf:network) key is required.

<a id="id3"></a>

### Effects of patching device options

For any device in your PATCH request, the request acts similar to a conventional PUT: it replaces all options for that device. This means that if you omit a non-required option, it is unset. Thus, include not only the options you want to add or update in your patch, but also any other existing options whose values you want to keep.

This behavior only affects the specific device or devices that you are patching; if there are other devices, you don’t need to include them. It also does not affect any other instance properties, with one exception: if the instance includes a `description` property, that property must be passed along with `devices`; otherwise, it is unset.

For example, consider an instance that contains this `devices` property:

```bash
"devices": {
  "my-bridge-nic": {
    "name": "my-bridge-nic-name",
    "network": "my-bridge-network",
    "type": "nic"
  },
  "my-ovn-nic": {
    "name": "my-ovn-nic-name",
    "network": "my-ovn-network",
    "type": "nic"
  }
}
```

Let’s say the following PATCH request is sent for this instance:

```bash
lxc query --request PATCH /1.0/instances/my-instance --data '{
  "devices": {
    "my-bridge-nic": {
      "type": "nic",
      "network": "test-bridge",
      "ipv4.address": "192.0.2.10"
    }
  }
}'
```

This PATCH request updates only the `my-bridge-nic` device, without affecting the `my-ovn-nic` device. The device options defined in the request body replace the existing options. After the request, this is the `devices` property’s configuration:

```bash
"devices": {
  "my-bridge-nic": {
    "network": "my-bridge-network",
    "type": "nic",
    "ipv4.address": "192.0.2.10"
  },
  "my-ovn-nic": {
    "name": "my-ovn-nic-name",
    "network": "my-ovn-network",
    "type": "nic"
  }
}
```

Notice that in the updated `my-bridge-nic` device, the `name` option is unset and no longer appears, due to not being sent in the PATCH request.

UI

The UI does not support all device types yet, but you can configure disk and network devices for your instances.

To attach a device to your instance, or modify an existing device, update your instance configuration (in the same way as you [configure instance options](#instances-configure-options)).
Select Advanced > Disk devices > Attach disk device or Advanced > Network devices > Attach network to create a device and attach it to your instance.

#### NOTE
Some of the devices that are displayed in the instance configuration are inherited from a [profile](../profiles.md#profiles) or defined through a [project](../projects.md#projects).
Depending on the type of device, it might not be possible to edit these devices for an instance.

To add and configure devices that are not currently supported in the UI, follow the instructions in [Edit the full instance configuration](#instances-configure-edit).

## Display instance configuration

CLI

To display the current configuration of your instance, including writable instance properties, instance options, devices and device options, enter the following command:

```none
lxc config show <instance_name> --expanded
```

API

To retrieve the current configuration of your instance, including writable instance properties, instance options, devices and device options, send a GET request to the instance:

```none
lxc query --request GET /1.0/instances/<instance_name>
```

See [`GET /1.0/instances/{name}`](/api/#/instances/instance_get) for more information.

UI

To view the current configuration of your instance, go to Instances, select your instance, and then switch to the Configuration tab.

To see the full configuration including instance properties, instance options, devices and device options (also the ones that aren’t yet supported by the UI), select YAML configuration.
This view shows the full YAML of the instance configuration.

<a id="instances-configure-edit"></a>

## Edit the full instance configuration

CLI

To edit the full instance configuration, including writable instance properties, instance options, devices and device options, enter the following command:

```none
lxc config edit <instance_name>
```

#### NOTE
For convenience, the [`lxc config edit`](../reference/manpages/lxc/config/edit.md#lxc-config-edit-md) command displays the full configuration including read-only instance properties.
However, you cannot edit those properties.
Any changes are ignored.

API

To update the full instance configuration, including writable instance properties, instance options, devices and device options, send a PUT request to the instance:

```none
lxc query --request PUT /1.0/instances/<instance_name> --data '<instance_configuration>'
```

See [`PUT /1.0/instances/{name}`](/api/#/instances/instance_put) for more information.

#### NOTE
If you include changes to any read-only instance properties in the configuration you provide, they are ignored.

UI

Instead of using the UI forms to configure your instance, you can choose to edit the YAML configuration of the instance.
You must use this method if you need to update any configurations that are not available in the UI.

#### IMPORTANT
When doing updates, do not navigate away from the YAML configuration without saving your changes.
If you do, your updates are lost.

To edit the YAML configuration of your instance, go to the instance detail page, switch to the Configuration tab and select YAML configuration.
Then click Edit instance.

Edit the YAML configuration as required.
Then click Save changes to save the updated configuration.

#### NOTE
For convenience, the YAML contains the full configuration including read-only instance properties.
However, you cannot edit those properties.
Any changes are ignored.


# index.html.md

<a id="troubleshoot"></a>

# Troubleshooting

## Fix common issues

Commonly encountered issues include firewall conflicts (such as with Docker), instance errors, and Dqlite database problems.

* [Configure your firewall](network_bridge_firewalld.md)
* [Troubleshoot instances](instances_troubleshoot.md)
* [Troubleshoot networks](network_ipam.md)
* [Troubleshoot Dqlite](dqlite_troubleshoot.md)
* [Frequently asked](../faq.md)

## Dig deeper

LXD provides multiple debugging methods, including CLI tools and core dump files.

* [Debug LXD](../debugging.md)
* [Track a bugfix in the LXD snap](snap_track_fix.md)

If the issue cannot be resolved, see [How to get support](../support.md#support) for information about where to get help.


# index.html.md

<a id="instances-ubuntu-pro-attach"></a>

# How to configure Ubuntu Pro guest attachment

If [Ubuntu Pro](https://ubuntu.com/pro) is enabled on a LXD host, guest instances can be automatically attached to the Pro subscription on that host.

<a id="instances-ubuntu-pro-attach-requirements"></a>

## Requirements

- Ubuntu Pro must be enabled on the LXD host server.
- The Pro client must be updated to the latest version.

<a id="instances-ubuntu-pro-attach-configure"></a>

## Configure guest attachment

On the LXD host, run:

```bash
sudo pro config set lxd_guest_attach=<on|off|available>
```

The allowed values are:

- `on`: New LXD guest instances are automatically attached to the host’s Pro subscription.
- `off`: Default if unset. LXD guest instances cannot be attached to the host’s Pro subscription.
- `available`: New LXD guest instances on the host are not attached automatically, but can be attached using the `pro auto-attach` command in the guest.

<a id="instances-ubuntu-pro-attach-auto"></a>

## Automatic attachment

If `lxd_guest_attach=on` is set, instances automatically attach to its host’s Pro subscription at startup. The initial attach process can take some time. To confirm the subscription, run:

```bash
lxc exec <guest-instance> -- pro status
```

If the attach process has not completed, you will see the following lines within the output:

```bash
NOTICES
Operation in progress: pro.daemon.attempt_auto_attach
```

<a id="instances-ubuntu-pro-attach-force"></a>

## Force attachment

Guest instances that were started prior to setting `lxd_guest_attach=on` on the host will not automatically attach to the host’s Pro subscription. Neither will any instances on a host set to `lxd_guest_attach=available`.

To force such instances to attach, run:

```bash
lxc exec <guest-instance> -- pro auto-attach
```

<a id="instances-ubuntu-pro-attach-override"></a>

## Instance-level override

The `lxd_guest_attach` setting on the host can be overridden at the instance level, through the [`ubuntu_pro.guest_attach`](../reference/instance_options.md#instance-miscellaneous:ubuntu_pro.guest_attach) configuration option. The `ubuntu_pro.guest_attach` configuration key has three options: `on`, `off`, and `available`.

For example, if `lxd_guest_attach` is set to `on` on the host and you want to prevent Pro attachment in a new guest instance you are launching, run:

```bash
lxc launch ubuntu:24.04 <guest-instance> -c ubuntu_pro.guest_attach=off
```

To set this key on an instance that has already been created, see: [Configure instance options](instances_configure.md#instances-configure-options).

All options for Pro guest attachment are described below.

|                     | `on (host)`                 | `available (host)`          | `off (host)`              | `unset (host)`            |
|---------------------|-----------------------------|-----------------------------|---------------------------|---------------------------|
| `on (guest)`        | auto-attach on start        | auto-attach on start        | guest attachment disabled | guest attachment disabled |
| `available (guest)` | attach on `pro auto-attach` | attach on `pro-auto-attach` | guest attachment disabled | guest attachment disabled |
| `off (guest)`       | guest attachment disabled   | guest attachment disabled   | guest attachment disabled | guest attachment disabled |
| `unset (guest)`     | auto-attach on start        | attach on `pro-auto-attach` | guest attachment disabled | guest attachment disabled |


# index.html.md

<a id="network-ovn-peers"></a>

# How to create OVN peer routing relationships

#### IMPORTANT
This guide applies to OVN networks only.

By default, traffic between two OVN networks goes through the uplink network.
This path is inefficient, however, because packets must leave the OVN subsystem and transit through the host’s networking stack (and, potentially, an external network) and back into the OVN subsystem of the target network.
Depending on how the host’s networking is configured, this might limit the available bandwidth (if the OVN overlay network is on a higher bandwidth network than the host’s external network).

Therefore, LXD allows creating peer routing relationships between two OVN networks.
Using this method, traffic between the two networks can go directly from one OVN network to the other and thus stays within the OVN subsystem, rather than transiting through the uplink network.

## Create a routing relationship between networks

To add a peer routing relationship between two networks, you must create a network peering for both networks.
The relationship must be mutual.
If you set it up on only one network, the routing relationship will be in pending state, but not active.

When creating the peer routing relationship, specify a peering name that identifies the relationship for the respective network.
The name can be chosen freely, and you can use it later to edit or delete the relationship.

CLI

Use the following commands to create a peer routing relationship between networks in the same project:

```none
lxc network peer create <network1> <peering_name> <network2> [configuration_options]
lxc network peer create <network2> <peering_name> <network1> [configuration_options]
```

You can also create peer routing relationships between OVN networks in different projects:

```none
lxc network peer create <network1> <peering_name> <project2/network2> [configuration_options] --project=<project1>
lxc network peer create <network2> <peering_name> <project1/network1> [configuration_options] --project=<project2>
```

UI

From the Networks page of the [web UI](access_ui.md#access-ui), select the desired OVN network. On the network’s Local Peerings tab, click Create local peering.

Fill in all required fields in the Create local peering panel.

![View a list of local peerings on a network](images/networks/network_create_local_peerings.png)

Target projects and networks for which you have read permission are available from the dropdown selectors. If you want to use a project or network not available in the dropdown, choose the Manually enter option.

To create a mutual peering between two networks, click the Create mutual peering checkbox. You must have edit permissions for both networks, and you cannot manually enter the target project or the network.

### Peering properties

Peer routing relationships have the following properties:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="network-peering-peering-properties:config"></a>
`config`

User-provided free-form key/value pairs

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-peering-peering-properties:config)

| **Key:**      | `config`   |
|---------------|------------|
| **Type:**     | string set |
| **Required:** | no         |

The only supported keys are `user.*` custom keys.

<a id="network-peering-peering-properties:description"></a>
`description`

Description of the network peering

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-peering-peering-properties:description)

| **Key:**      | `description`   |
|---------------|-----------------|
| **Type:**     | string          |
| **Required:** | no              |

<a id="network-peering-peering-properties:name"></a>
`name`

Name of the network peering on the local network

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-peering-peering-properties:name)

| **Key:**      | `name`   |
|---------------|----------|
| **Type:**     | string   |
| **Required:** | yes      |

<a id="network-peering-peering-properties:status"></a>
`status`

Status indicating if pending or created

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-peering-peering-properties:status)

| **Key:**      | `status`   |
|---------------|------------|
| **Type:**     | string     |
| **Required:** | –          |

Indicates if mutual peering exists with the target network.
This property is read-only and cannot be updated.

<a id="network-peering-peering-properties:target_network"></a>
`target_network`

Which network to create a peering with

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-peering-peering-properties:target_network)

| **Key:**      | `target_network`   |
|---------------|--------------------|
| **Type:**     | string             |
| **Required:** | yes                |

This option must be set at create time.

<a id="network-peering-peering-properties:target_project"></a>
`target_project`

Which project the target network exists in

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-peering-peering-properties:target_project)

| **Key:**      | `target_project`   |
|---------------|--------------------|
| **Type:**     | string             |
| **Required:** | yes                |

This option must be set at create time.

## List routing relationships

CLI

To list all network peerings for a network, use the following command:

```none
lxc network peer list <network>
```

UI

From the Networks page of the [web UI](access_ui.md#access-ui), select the desired OVN network. View the network’s Local peerings tab:

![View a list of local peerings on a network](images/networks/network_list_local_peerings.png)

## Edit a routing relationship

CLI

Use the following command to edit a network peering:

```none
lxc network peer edit <network> <peering_name>
```

This command opens the network peering in YAML format for editing.

UI

From the Networks page of the [web UI](access_ui.md#access-ui), select the desired OVN network. You can edit peerings from the network’s Local peerings tab. Only the Description field can be edited.

![Edit a local peering on a network](images/networks/network_edit_local_peerings.png)


# index.html.md

<a id="network-bgp"></a>

# How to configure LXD as a BGP server

#### NOTE
The BGP server feature is available for the [Bridge network](../reference/network_bridge.md#network-bridge) and the [Physical network](../reference/network_physical.md#network-physical).
These network types are often used as the uplink network for an [OVN network](../reference/network_ovn.md#network-ovn), and you must configure the BGP peers on the uplink network.
See [Configure BGP peers for OVN networks](#network-bgp-ovn) for instructions.


            <p class="youtube_link">
              <a href="https://www.youtube.com/watch?v=C9zU-FEqtTw" target="_blank">
                <span title="LXD and BGP" class="play_icon">▶</span>
                <span title="LXD and BGP">Watch on YouTube</span>
              </a>
            </p>
        
 is a protocol that allows exchanging routing information between autonomous systems.

If you want to directly route external addresses to specific LXD servers or instances, you can configure LXD as a BGP server.
LXD will then act as a BGP peer and advertise relevant routes and next hops to external routers, for example, your network router.
It automatically establishes sessions with upstream BGP routers and announces the addresses and subnets that it’s using.

The BGP server feature can be used to allow a LXD server or cluster to directly use internal/external address space by getting the specific subnets or addresses routed to the correct host.
This way, traffic can be forwarded to the target instance.

For bridge networks, the following addresses and networks are being advertised:

- Network `ipv4.address` or `ipv6.address` subnets (if the matching `nat` property isn’t set to `true`)
- Network `ipv4.nat.address` or `ipv6.nat.address` subnets (if the matching `nat` property is set to `true`)
- Network forward addresses
- Addresses or subnets specified in `ipv4.routes.external` or `ipv6.routes.external` on an instance NIC that is connected to the bridge network

Make sure to add your subnets to the respective configuration options.
Otherwise, they won’t be advertised.

For physical networks, no addresses are advertised directly at the level of the physical network.
Instead, the networks, forwards and routes of all downstream networks (the networks that specify the physical network as their uplink network through the `network` option) are advertised in the same way as for bridge networks.

#### NOTE
At this time, it is not possible to announce only some specific routes/addresses to particular peers.
If you need this, filter prefixes on the upstream routers.

## Configure the BGP server

To configure LXD as a BGP server, set the following server configuration options on all cluster members:

- [`core.bgp_address`](../server.md#server-core:core.bgp_address) - the IP address for the BGP server
- [`core.bgp_asn`](../server.md#server-core:core.bgp_asn) - the  for the local server
- [`core.bgp_routerid`](../server.md#server-core:core.bgp_routerid) - the unique identifier for the BGP server

For example, set the following values:

```bash
lxc config set core.bgp_address=192.0.2.50:179
lxc config set core.bgp_asn=65536
lxc config set core.bgp_routerid=192.0.2.50
```

Once these configuration options are set, LXD starts listening for BGP sessions.

### Configure next-hop (`bridge` only)

For bridge networks, you can override the next-hop configuration.
By default, the next-hop is set to the address used for the BGP session.

To configure a different address, set `bgp.ipv4.nexthop` or `bgp.ipv6.nexthop`.

<a id="network-bgp-ovn"></a>

### Configure BGP peers for OVN networks

If you run an OVN network with an uplink network (`physical` or `bridge`), the uplink network is the one that holds the list of allowed subnets and the BGP configuration.
Therefore, you must configure BGP peers on the uplink network that contain the information that is required to connect to the BGP server.

Set the following configuration options on the uplink network:

- `bgp.peers.<name>.address` - the peer address to be used by the downstream networks
- `bgp.peers.<name>.asn` - the  for the local server
- `bgp.peers.<name>.password` - an optional password for the peer session
- `bgp.peers.<name>.holdtime` - an optional hold time for the peer session (in seconds)

Once the uplink network is configured, downstream OVN networks will get their external subnets and addresses announced over BGP.
The next-hop is set to the address of the OVN router on the uplink network.


# index.html.md

<a id="instances-access-files"></a>

# How to access files in an instance

You can manage files inside an instance using the LXD client or the API without needing to access the instance through the network.
Files can be individually edited or deleted, pushed from or pulled to the local machine.
Alternatively, if you’re using the LXD client, you can mount the instance’s file system onto the local machine.

#### NOTE
The UI does not currently support accessing files in an instance.

For containers, these file operations always work and are handled directly by LXD.
For virtual machines, the `lxd-agent` process must be running inside of the virtual machine for them to work.

## Edit instance files

CLI

To edit an instance file from your local machine, enter the following command:

```none
lxc file edit <instance_name>/<path_to_file>
```

For example, to edit the `/etc/hosts` file in the instance, enter the following command:

```none
lxc file edit my-instance/etc/hosts
```

#### NOTE
The file must already exist on the instance.
You cannot use the `edit` command to create a file on the instance.

API

There is no API endpoint that lets you edit files directly on an instance.
Instead, you need to [pull the content of the file from the instance](#instances-access-files-pull), edit it, and then [push the modified content back to the instance](#instances-access-files-push).

## Delete files from the instance

CLI

To delete a file from your instance, enter the following command:

```none
lxc file delete <instance_name>/<path_to_file>
```

API

Send the following DELETE request to delete a file from your instance:

```none
lxc query --request DELETE /1.0/instances/<instance_name>/files?path=<path_to_file>
```

See [`DELETE /1.0/instances/{name}/files`](/api/#/instances/instance_files_delete) for more information.

<a id="instances-access-files-pull"></a>

## Pull files from the instance to the local machine

CLI

To pull a file from your instance to your local machine, enter the following command:

```none
lxc file pull <instance_name>/<path_to_file> <local_file_path>
```

For example, to pull the `/etc/hosts` file to the current directory, enter the following command:

```none
lxc file pull my-instance/etc/hosts .
```

Instead of pulling the instance file into a file on the local system, you can also pull it to stdout and pipe it to stdin of another command.
This can be useful, for example, to check a log file:

```none
lxc file pull my-instance/var/log/syslog - | less
```

To pull a directory with all contents, enter the following command:

```none
lxc file pull -r <instance_name>/<path_to_directory> <local_location>
```

API

Send the following request to pull the contents of a file from your instance to your local machine:

```none
lxc query --request GET /1.0/instances/<instance_name>/files?path=<path_to_file>
```

You can then write the contents to a local file, or pipe them to stdin of another command.

For example, to pull the contents of the `/etc/hosts` file and write them to a `my-instance-hosts` file in the current directory, enter the following command:

```none
lxc query --request GET /1.0/instances/my-instance/files?path=/etc/hosts > my-instance-hosts
```

To examine a log file, enter the following command:

```none
lxc query --request GET /1.0/instances/<instance_name>/files?path=<file_path> | less
```

To pull the contents of a directory, send the following request:

```none
lxc query --request GET /1.0/instances/<instance_name>/files?path=<path_to_directory>
```

This request returns a list of files in the directory, and you can then pull the contents of each file.

See [`GET /1.0/instances/{name}/files`](/api/#/instances/instance_files_get) for more information.

<a id="instances-access-files-push"></a>

## Push files from the local machine to the instance

CLI

To push a file from your local machine to your instance, enter the following command:

```none
lxc file push <local_file_path> <instance_name>/<path_to_file>
```

You can specify the file permissions by adding the `--gid`, `--uid`, and `--mode` flags.

To push a directory with all contents, enter the following command:

```none
lxc file push -r <local_location> <instance_name>/<path_to_directory>
```

API

Send the following request to write content to a file on your instance:

```none
lxc query --request POST /1.0/instances/<instance_name>/files?path=<path_to_file> --data <content>
```

See [`POST /1.0/instances/{name}/files`](/api/#/instances/instance_files_post) for more information.

To push content directly from a file, you must use a tool that can send raw data from a file, which [`lxc query`](../reference/manpages/lxc/query.md#lxc-query-md) does not support.
For example, with curl:

```none
curl -X POST -H "Content-Type: application/octet-stream" --data-binary @<local_file_path> \
--unix-socket /var/snap/lxd/common/lxd/unix.socket \
lxd/1.0/instances/<instance_name>/files?path=<path_to_file>
```

## Mount a file system from the instance

CLI

You can mount an instance file system into a local path on your client.

To do so, make sure that you have `sshfs` installed.
Then run the following command (note that if you’re using the snap, the command requires root permissions):

```none
lxc file mount <instance_name>/<path_to_directory> <local_location>
```

You can then access the files from your local machine.

### Set up an SSH SFTP listener

Alternatively, you can set up an SSH SFTP listener.
This method allows you to connect with any SFTP client and with a dedicated user name.
Also, if you’re using the snap, it does not require root permission.

To do so, first set up the listener by entering the following command:

```none
lxc file mount <instance_name> [--listen <address>:<port>]
```

For example, to set up the listener on a random port on the local machine (for example, `127.0.0.1:45467`):

```none
lxc file mount my-instance
```

If you want to access your instance files from outside your local network, you can pass a specific address and port:

```none
lxc file mount my-instance --listen 192.0.2.50:2222
```

To set up the listener on a specific address and a random port:

```none
lxc file mount my-instance --listen 192.0.2.50:0
```

The command prints out the assigned port and a user name and password for the connection.

Use this information to access the file system.
For example, if you want to use `sshfs` to connect, enter the following command:

```none
sshfs <user_name>@<address>:<path_to_directory> <local_location> -p <port>
```

For example:

```none
sshfs xFn8ai8c@127.0.0.1:/home my-instance-files -p 35147
```

You can then access the file system of your instance at the specified location on the local machine.

API

Mounting a file system is not directly supported through the API, but requires additional processing logic on the client side.


# index.html.md

<a id="howto-storage-csi"></a>

# How to use the LXD CSI driver with Kubernetes

Learn how to get the LXD Container Storage Interface (CSI) driver running in your Kubernetes cluster.

<a id="howto-storage-csi-prerequisites"></a>

## Prerequisites

The primary requirement is a Kubernetes cluster (of any size), running on LXD instances inside a dedicated LXD [project](../explanation/projects.md#exp-projects).

This guide assumes you have administrative access to both LXD and the Kubernetes cluster.

<a id="howto-storage-csi-authorization"></a>

## Authorization

By default, the [DevLXD API](../dev-lxd.md#dev-lxd) is not allowed to manage storage volumes or attach them to instances.
You must enable this by setting [`security.devlxd.management.volumes`](../reference/instance_options.md#instance-security:security.devlxd.management.volumes) to `true` on all LXD instances where the CSI driver will be running:

```sh
lxc config set <instance-name> --project <project-name> security.devlxd.management.volumes=true
```

For example, to enable DevLXD volume management on instance `node-1` in a project named `lxd-csi-project`, run:

```sh
lxc config set node-1 --project lxd-csi-project security.devlxd.management.volumes=true
```

You can also use a LXD profile to apply this setting to multiple instances at once.

At this point, DevLXD is allowed to access the LXD endpoint for volume management, but the LXD CSI still needs to prove it is authorized to perform such actions.
You must create a DevLXD identity with sufficient permissions and issue a bearer token for it.

The identity must have permissions in the project where the Kubernetes nodes are running to:

+ view the project,
+ manage (view, create, edit, delete) storage volumes,
+ edit instances.

First, create a new authorization group with the required permissions:

```sh
lxc auth group create <group-name>
lxc auth group permission add <group-name> project <project-name> can_view
lxc auth group permission add <group-name> project <project-name> storage_volume_manager
lxc auth group permission add <group-name> project <project-name> can_edit_instances
```

Example using a group named `csi-group` and a project named `lxd-csi-project`:

```sh
lxc auth group create csi-group
lxc auth group permission add csi-group project lxd-csi-project can_view
lxc auth group permission add csi-group project lxd-csi-project storage_volume_manager
lxc auth group permission add csi-group project lxd-csi-project can_edit_instances
```

Next, create a DevLXD identity and assign the previously created group to it:

```sh
lxc auth identity create devlxd/<identity-name> --group <group-name>
```

Example with a DevLXD identity named `csi` and a group named `csi-group`:

```sh
lxc auth identity create devlxd/csi --group csi-group
```

Finally, issue a new bearer token to be used by the CSI driver:

```sh
token=$(lxc auth identity token issue devlxd/<identity-name> --quiet)
```

To issue a bearer token for DevLXD identity named `csi`, run:

```sh
token=$(lxc auth identity token issue devlxd/csi --quiet)
```

<a id="howto-storage-csi-deploy"></a>

## Deploy the CSI driver

First, create a new Kubernetes namespace named `lxd-csi`:

```sh
kubectl create namespace lxd-csi --save-config
```

Afterwards, create a Kubernetes secret `lxd-csi-secret` containing a previously created bearer token:

```sh
kubectl create secret generic lxd-csi-secret \
    --namespace lxd-csi \
    --from-literal=token="${token}"
```

<a id="howto-storage-csi-deploy-helm"></a>

### Deploy the CSI driver using a Helm chart

You can deploy the LXD CSI using a Helm chart:

```sh
helm install lxd-csi-driver oci://ghcr.io/canonical/charts/lxd-csi-driver \
  --version v0 \
  --namespace lxd-csi
```

Optionally, you can enabled support for volume snapshots by setting `snapshotter.enabled` to `true`:

```sh
helm install lxd-csi-driver oci://ghcr.io/canonical/charts/lxd-csi-driver \
  --version v0 \
  --namespace lxd-csi \
  --set snapshotter.enabled=true
```

The chart is configured to work out of the box. It deploys the CSI node server as a DaemonSet, with the CSI controller server as a single replica Deployment, and ensures minimal required access is granted to the CSI driver.

You can tweak the chart to create your desired storage classes, set resource limits, and increase the controller replica count by providing custom chart values.
To get available values, fetch the chart’s default values:

```sh
helm show values oci://ghcr.io/canonical/charts/lxd-csi-driver --version v0 > values.yaml
```

<a id="howto-storage-csi-usage"></a>

## Usage examples

This section provides practical examples of configuring StorageClass and PersistentVolumeClaim (PVC) resources when using the LXD CSI driver.

The examples cover:

+ Creating different types of storage classes,
+ Defining volume claims that request storage from those classes,
+ Demonstrating how different Kubernetes resources consume the volumes.

<a id="howto-storage-csi-usage-storageclass"></a>

### StorageClass configuration

The following example demonstrates how to configure a Kubernetes StorageClass that uses the LXD CSI driver for provisioning volumes.

In the StorageClass, the fields `provisioner` and `parameters.storagePool` are required.
The first specifies the name of the LXD CSI driver, which defaults to `lxd.csi.canonical.com`, and the second references a target storage pool where the driver will create volumes.

```yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: lxd-csi-fs
provisioner: lxd.csi.canonical.com  # Name of the LXD CSI driver.
parameters:
  storagePool: my-lxd-pool          # Name of the target LXD storage pool.
```

<a id="howto-storage-csi-usage-storageclass-default"></a>

#### Default StorageClass

The default StorageClass is used when `storageClass` is not explicitly set in the PVC configuration.
You can mark a Kubernetes StorageClass as the default by setting the `storageclass.kubernetes.io/is-default-class: "true"` annotation.

```yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: lxd-csi-sc
  annotations:
    storageclass.kubernetes.io/is-default-class: "true"
provisioner: lxd.csi.canonical.com
parameters:
  storagePool: my-lxd-pool
```

<a id="howto-storage-csi-usage-storageclass-volume-binding"></a>

#### Immediate volume binding

By default, volume binding is set to `WaitForFirstConsumer`, which delays volume creation until the Pod is scheduled.
Setting the volume binding mode to `Immediate` instructs Kubernetes to provision the volume as soon as the PVC is created.

```yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: lxd-csi-immediate
provisioner: lxd.csi.canonical.com
volumeBindingMode: Immediate        # Default is "WaitForFirstConsumer"
parameters:
  storagePool: my-lxd-pool
```

<a id="howto-storage-csi-usage-storageclass-volume-reclaim"></a>

#### Prevent volume deletion

By default, the volume is deleted when its PVC is removed.
Setting the reclaim policy to `Retain` prevents the CSI driver from deleting the underlying LXD volume, allowing for manual cleanup or data recovery later.

```yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: lxd-csi-retain
provisioner: lxd.csi.canonical.com
reclaimPolicy: Retain               # Default is "Delete"
parameters:
  storagePool: my-lxd-pool
```

#### Volume expansion

Volume expansion can be enabled through StorageClass configuration.
When enabled, storage volume capacity can be increased once the volume is created.

```yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: lxd-csi-retain
provisioner: lxd.csi.canonical.com
allowVolumeExpansion: true          # Default is "false".
parameters:
  storagePool: my-lxd-pool
```

For filesystem volumes, expansion is performed online and does not require shutting down any Pod using the PVC.
Block volumes, however, only support offline expansion, meaning the Pod consuming the volume must be stopped before the volume’s capacity can be increased.

<a id="howto-storage-csi-usage-storageclass-helm"></a>

#### Configure StorageClass using Helm chart

The LXD CSI Helm chart allows defining multiple storage classes as part of the deployment.
Each entry in the `storageClasses` list must include at least `name` and `storagePool`.

```yaml
# values.yaml
storageClasses:
- name: lxd-csi-fs            # (required) Name of the StorageClass.
  storagePool: my-pool        # (required) Name of the target LXD storage pool.
- name: lxd-csi-fs-retain
  storagePool: my-pool
  reclaimPolicy: Retain       # (optional) Reclaim policy for released volume. Defaults to "Delete".
  allowVolumeExpansion: true  # (optional) Whether to allow volume expansion. Defaults to "true".
```

<a id="howto-storage-csi-usage-pvc"></a>

### PersistentVolumeClaim configuration

A PVC requests a storage volume from a StorageClass.
Specify the access modes, volume size (capacity), and volume mode.

```yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: app-data
spec:
  accessModes:
    - ReadWriteOnce             # Allowed storage volume access modes.
  storageClassName: lxd-csi-sc  # Storage class name.
  resources:
    requests:
      storage: 10Gi             # Storage volume size.
  volumeMode: Filesystem        # Storage volume mode (content type in LXD terminology). Can be "Filesystem" or "Block".
```

<a id="howto-storage-csi-usage-pvc-access-modes"></a>

#### Access modes

[Access modes ↗](https://kubernetes.io/docs/concepts/storage/persistent-volumes/#access-modes) define how a volume can be mounted by Pods.

| Access mode        | Supported drivers                                                                                                                                                                                      | Description                                                                      |
|--------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------|
| `ReadWriteOnce`    | [Local](../reference/storage_drivers.md#storage-drivers-local), [Remote](../reference/storage_drivers.md#storage-drivers-remote), and [Shared](../reference/storage_drivers.md#storage-drivers-shared) | Mounted as read-write by a single node. Multiple Pods on that node can share it. |
| `ReadWriteOncePod` | [Local](../reference/storage_drivers.md#storage-drivers-local), [Remote](../reference/storage_drivers.md#storage-drivers-remote), and [Shared](../reference/storage_drivers.md#storage-drivers-shared) | Mounted as read-write by a single Pod on a single node.                          |
| `ReadOnlyMany`     | [Shared](../reference/storage_drivers.md#storage-drivers-shared)                                                                                                                                       | Mounted as read-only by many Pods across nodes.                                  |
| `ReadWriteMany`    | [Shared](../reference/storage_drivers.md#storage-drivers-shared)                                                                                                                                       | Mounted as read-write by many Pods across nodes.                                 |

<a id="howto-storage-csi-usage-pvc-cloning"></a>

#### Volume cloning

[Volume cloning ↗](https://kubernetes.io/docs/concepts/storage/volume-pvc-datasource/) allows you to create a new PVC from an existing one.
The source and target PVCs must have the same `volumeMode`, and the target’s requested size must be equal to or larger than the source. Also note that Kubernetes allows volumes to be cloned only within the same namespace.

To create a clone, reference the source PVC under the `dataSource` field, as shown below:

```yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: app-data
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: lxd-csi-sc
  resources:
    requests:
      storage: 10Gi             # Must be equal to or larger than the size of the source volume.
  volumeMode: Filesystem        # Must match the source volume mode.
  dataSource:
    kind: PersistentVolumeClaim
    name: pvc-1                 # Name of the source PVC.
```

<a id="howto-storage-csi-usage-vsclass"></a>

### VolumeSnapshotClass configuration

The following example demonstrates how to configure a Kubernetes VolumeSnapshotClass that uses the LXD CSI driver for provisioning volume snapshots.

In a VolumeSnapshotClass, the only required fields are `driver` and `deletionPolicy`. The former identifies the LXD CSI driver, and the latter determines whether the underlying LXD snapshot is removed when the corresponding VolumeSnapshot object is deleted in Kubernetes.

```yaml
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotClass
metadata:
  name: lxd-csi-snapshotclass
driver: lxd.csi.canonical.com       # Name of the LXD CSI driver.
deletionPolicy: Delete              # Possible values are "Retain" and "Delete" (default).
```

<a id="howto-storage-csi-usage-vsclass-default"></a>

#### Default VolumeSnapshotClass

The default VolumeSnapshotClass is used when `volumeSnapshotClassName` is not explicitly set in the VolumeSnapshot configuration.
To mark a Kubernetes VolumeSnapshotClass as the default, set the `snapshot.storage.kubernetes.io/is-default-class: "true"` annotation.

```yaml
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotClass
metadata:
  name: lxd-csi-snapshotclass-default
  annotations:
    snapshot.storage.kubernetes.io/is-default-class: "true"
driver: lxd.csi.canonical.com
```

<a id="howto-storage-csi-usage-vsclass-reclaim"></a>

#### Prevent volume snapshot deletion

By default, the volume snapshot is deleted when the corresponding VolumeSnapshot is removed.
To prevent the CSI driver from deleting the underlying LXD volume snapshot and the corresponding Kubernetes `VolumeSnapshotContent` object, set the deletion policy to `Retain`. This allows for manual cleanup or data recovery later.

```yaml
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotClass
metadata:
  name: lxd-csi-snapshotclass
driver: lxd.csi.canonical.com
deletionPolicy: Retain              # Default is "Delete".
```

<a id="howto-storage-csi-usage-vs"></a>

### VolumeSnapshot configuration

A VolumeSnapshot requests a snapshot of the volume bound to the referenced PVC.
Set the fields `spec.volumeSnapshotClassName` and `spec.source.persistentVolumeClaimName` to the LXD CSI snapshot class to handle the snapshot and the PVC to snapshot, respectively.

If the snapshot is taken successfully, a corresponding VolumeSnapshotContent object is created.
It is bound to the VolumeSnapshot and represents the actual LXD volume snapshot.

```yaml
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
  name: lxd-csi-pvc-snapshot
spec:
  volumeSnapshotClassName: lxd-csi-snapshotclass
  source:
    persistentVolumeClaimName: lxd-csi-pvc
```

<a id="howto-storage-csi-usage-example"></a>

### End-to-end examples

<a id="howto-storage-csi-usage-example-deployment"></a>

#### Referencing PVC in Deployment

This pattern is used when multiple Pods share the same persistent volume.
The PVC is created first and then referenced by name in the Deployment.

Each replica mounts the same volume, which is only safe when:

+ the volume’s access mode allows multi-node access (`ReadWriteMany`, `ReadOnlyMany`), or
+ the Deployment has a single replica (`replicas: 1`), as shown below.

```yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: app-data
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: lxd-csi-sc
  resources:
    requests:
      storage: 10Gi
  volumeMode: Filesystem

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app
spec:
  replicas: 1 # Use a single replica for non-shared storage volumes.
  selector:
    matchLabels:
      app: app
  template:
    metadata:
      labels:
        app: app
    spec:
      containers:
        - name: app
          image: nginx:stable
          ports:
            - containerPort: 80
          volumeMounts:
            - name: data
              mountPath: /usr/share/nginx/html
      volumes:
        - name: data
          persistentVolumeClaim:
            claimName: app-data  # References PVC named "app-data".
```

<a id="howto-storage-csi-usage-example-statefulset"></a>

#### Referencing PVC in StatefulSet

This pattern is used when each Pod requires its own persistent volume.
The `volumeClaimTemplates` section dynamically creates a PVC per Pod (e.g. `data-app-0`, `data-app-1`, `data-app-2`).
This ensures each Pod retains its volume through restarts and rescheduling.

```yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: app
spec:
  serviceName: app
  replicas: 3
  selector:
    matchLabels:
      app: app
  template:
    metadata:
      labels:
        app: app
    spec:
      containers:
        - name: app
          image: nginx:stable
          ports:
            - containerPort: 80
          volumeMounts:
            - name: data
              mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
    # PVC template used for each replica in a stateful set.
    - metadata:
        name: data
      spec:
        accessModes:
          - ReadWriteOnce
        storageClassName: lxd-csi-sc
        resources:
          requests:
            storage: 5Gi
```

## Related topics

Explanation:

- [The LXD CSI driver](../explanation/csi.md#exp-csi)

Reference:

- [LXD CSI driver reference](../reference/driver_csi.md#ref-csi)


# index.html.md

<a id="cluster-recover"></a>

# How to recover a cluster

It might happen that one or several members of your cluster go offline or become unreachable.
If too many cluster members go offline, no operations will be possible on the cluster.
See [Offline members and fault tolerance](../explanation/clusters.md#clustering-offline-members) and [Cluster healing](cluster_manage.md#cluster-automatic-evacuation) for more information.

If you can bring the offline cluster members back up, operation resumes as normal.
If the cluster members are lost permanently (e.g. disk failure), it is possible
to recover any remaining cluster members.

#### NOTE
When your cluster is in a state that needs recovery, most `lxc` commands do not
work because the LXD database does not respond when a majority of database
voters are inaccessible.

The commands to recover a cluster are provided directly by the LXD daemon (`lxd`)
because they modify database files directly instead of making requests to the
LXD daemon.

Run `lxd cluster --help` for an overview of all available commands.

## Database members

Every LXD cluster has a specific number of members (configured through [`cluster.max_voters`](../server.md#server-cluster:cluster.max_voters)) that serve as voting members of the distributed database.
If the cluster uses [control plane mode](../explanation/clusters.md#clustering-control-plane), only cluster members with the `control-plane` role act as voters.
If you lose a majority of these cluster members (for example, you have a three-member cluster and you lose two members), the cluster loses quorum and becomes unavailable.

To determine which members have (or had) database roles, log on to any surviving member of your cluster and run the following command:

```none
sudo lxd cluster list-database
```

## Recover from quorum loss

#### NOTE
LXD automatically takes a backup of the database before making changes (see [Automated Backups](#automated-backups)).

If only one cluster member with the database role survives, complete the following
steps. See [Reconfigure the cluster]() below for recovering
more than one member.

1. Make sure that the LXD daemon is not running on the machine.
   For example, if you’re using the snap:
   ```none
   sudo snap stop lxd
   ```
2. Use the following command to reconfigure the database:
   ```none
   sudo lxd cluster recover-from-quorum-loss
   ```
3. Start the LXD daemon again. For example, if you’re using the snap:
   ```none
   sudo snap start lxd
   ```

The database should now be back online.
No information has been deleted from the database.
All information about the cluster members that you have lost is still there, including the metadata about their instances.
This can help you with further recovery steps if you need to re-create the lost instances.

To permanently delete the cluster members that you have lost, force-remove them.
See [Delete cluster members](cluster_manage.md#cluster-manage-delete-members).

## Reconfigure the cluster

#### NOTE
LXD automatically takes a backup of the database before making changes (see [Automated Backups](#automated-backups)).

If some members of your cluster are no longer reachable, or if the cluster itself is unreachable due to a change in IP address or listening port number, you can reconfigure the cluster.

To do so, choose the [most up-to-date database member](#up-to-date-cluster-member) to edit the cluster configuration.
Once the cluster edit is complete you will need to manually copy the reconfigured global database to every other surviving member.

You can change the IP addresses or listening port numbers for each member as required.
You cannot add or remove any members during this process.
The cluster configuration must contain the description of the full cluster.

You can edit the [Member roles](../explanation/clusters.md#clustering-member-roles) of the members, but with the following limitations:

- A cluster member that does not have a `database-voter`, `database-standby`, or `database-leader` role cannot become a voter, because it might lack a global database.
- At least two members must remain voters (except in the case of a two-member cluster, where one voter suffices), or there will be no quorum.

Before performing the recovery, stop the LXD daemon on all surviving cluster members.
For example, if you’re using the snap:

```none
sudo snap stop lxd
```

Complete the following steps on one database member:

1. Run the following command:
   ```none
   sudo lxd cluster edit
   ```
2. Edit the YAML representation of the information that this cluster member has about the rest of the cluster:
   ```yaml
   # Latest dqlite segment ID: 1234

   members:
     - id: 1             # Internal ID of the member (Read-only)
       name: server1     # Name of the cluster member (Read-only)
       address: 192.0.2.10:8443 # Last known address of the member (Writeable)
       role: voter              # Last known role of the member (Writeable)
     - id: 2             # Internal ID of the member (Read-only)
       name: server2     # Name of the cluster member (Read-only)
       address: 192.0.2.11:8443 # Last known address of the member (Writeable)
       role: stand-by           # Last known role of the member (Writeable)
     - id: 3             # Internal ID of the member (Read-only)
       name: server3     # Name of the cluster member (Read-only)
       address: 192.0.2.12:8443 # Last known address of the member (Writeable)
       role: spare              # Last known role of the member (Writeable)
   ```

   You can edit the addresses and the roles.
3. When the cluster configuration has been changed on one member, LXD will create
   a tarball of the global database (`/var/snap/lxd/common/lxd/database/lxd_recovery_db.tar.gz`
   for snap installations or `/var/lib/lxd/database/lxd_recovery_db.tar.gz`).
   Copy this recovery tarball to the same path on all remaining cluster members.

   #### NOTE
   The tarball can be removed from the first member after it is generated, but
   it does not have to be.
4. Once the tarball has been copied to all remaining cluster members, start the
   LXD daemon on all members again. LXD will load the recovery tarball on startup.

   If you’re using the snap:
   ```none
   sudo snap start lxd
   ```

The cluster should now be fully available again with all surviving members reporting in.
No information has been deleted from the database.
All information about the cluster members and their instances is still there.

<a id="automated-backups"></a>

## Automated Backups

LXD automatically creates a backup of the database before making changes during
recovery. The backup is just a tarball of `/var/snap/lxd/common/lxd/database`
(for snap users) or `/var/lib/lxd/lxd/database` (otherwise). To reset the state
of the database in case of a failure, simply delete the database directory and
unpack the tarball in its place:

```none
cd /var/snap/lxd/common/lxd
sudo rm -r database
sudo tar -xf db_backup.TIMESTAMP.tar.gz
```

<a id="up-to-date-cluster-member"></a>

## Find the most up-to-date cluster member

On every shutdown, LXD’s [database members](../explanation/clusters.md#clustering-member-roles) log
the Raft term and index:

```none
Dqlite last entry    index=1039 term=672
```

To determine which database member is most up to date:

- If two members have different terms, the member with the higher term is more up to date.
- If two members have the same term, the member with the higher index is more up to date.

## Manually alter Raft membership

In some situations, you might need to manually alter the Raft membership configuration of the cluster because of some unexpected behavior.

For example, if you have a cluster member that was removed uncleanly, it might not show up in [`lxc cluster list`](../reference/manpages/lxc/cluster/list.md#lxc-cluster-list-md) but still be part of the Raft configuration.
To see the Raft configuration, run the following command:

```none
lxd sql local "SELECT * FROM raft_nodes"
```

In that case, run the following command to remove the leftover node:

```none
lxd cluster remove-raft-node <address>
```


# index.html.md

<a id="cluster-form"></a>

# How to form a cluster

When forming a LXD cluster, you start with a bootstrap server.
This bootstrap server can be an existing LXD server or a newly installed one.

After initializing the bootstrap server, you can join additional servers to the cluster.
See [Cluster members](../explanation/clusters.md#clustering-members) for more information.

You can form the LXD cluster interactively by providing configuration information during the initialization process or by using preseed files that contain the full configuration.

To quickly and automatically set up a basic LXD cluster, you can use [MicroCloud](#use-microcloud).

## Configure the cluster interactively

To form your cluster, you must first run `lxd init` on the bootstrap server. After that, run it on the other servers that you want to join to the cluster.

When forming a cluster interactively, you answer the questions that `lxd init` prompts you with to configure the cluster.

### Initialize the bootstrap server

To initialize the bootstrap server, run `lxd init` and answer the questions according to your desired configuration.

You can accept the default values for most questions, but make sure to answer the following questions accordingly:

- `Would you like to use LXD clustering?`

  Select **yes**.
- `What IP address or DNS name should be used to reach this server?`

  Make sure to use an IP or DNS address that other servers can reach.
- `Are you joining an existing cluster?`

  Select **no**.

<details>
<summary>Expand to see a full example for <code>lxd init</code> on the bootstrap server</summary>
`user@host:~$ ``lxd init
`
```text
Would you like to use LXD clustering? (yes/no) [default=no]: yes
What IP address or DNS name should be used to reach this server? [default=192.0.2.101]:
Are you joining an existing cluster? (yes/no) [default=no]: no
What member name should be used to identify this server in the cluster? [default=server1]:
Do you want to configure a new local storage pool? (yes/no) [default=yes]:
Name of the storage backend to use (btrfs, dir, lvm, zfs) [default=zfs]:
Create a new ZFS pool? (yes/no) [default=yes]:
Would you like to use an existing empty block device (e.g. a disk or partition)? (yes/no) [default=no]:
Size in GiB of the new loop device (1GiB minimum) [default=9GiB]:
Do you want to configure a new remote storage pool? (yes/no) [default=no]:
Would you like to configure LXD to use an existing bridge or host interface? (yes/no) [default=no]:
Would you like to create a new Fan overlay network? (yes/no) [default=yes]:
What subnet should be used as the Fan underlay? [default=auto]:
Would you like stale cached images to be updated automatically? (yes/no) [default=yes]:
Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]:
```

</details>

After the initialization process finishes, your first cluster member should be up and available on your network.
You can check this with [`lxc cluster list`](../reference/manpages/lxc/cluster/list.md#lxc-cluster-list-md).

### Join additional servers

You can now join further servers to the cluster.

#### NOTE
The servers that you add should be newly installed LXD servers.
If you are using existing servers, make sure to clear their contents before joining them, because any existing data on them will be lost.

To join a server to the cluster, run `lxd init` on the cluster.
Joining an existing cluster requires root privileges, so make sure to run the command as root or with `sudo`.

Basically, the initialization process consists of the following steps:

1. Request to join an existing cluster.

   Answer the first questions that `lxd init` asks accordingly:
   - `Would you like to use LXD clustering?`

     Select **yes**.
   - `What IP address or DNS name should be used to reach this server?`

     Make sure to use an IP or DNS address that other servers can reach.
   - `Are you joining an existing cluster?`

     Select **yes**.
2. Authenticate with the cluster.

   Generate a cluster join token for each new member.
   To do so, run the following command on an existing cluster member (for example, the bootstrap server):
   ```none
   lxc cluster add <new_member_name>
   ```

   This command returns a single-use join token that is valid for a configurable time (see [`cluster.join_token_expiry`](../server.md#server-cluster:cluster.join_token_expiry)).
   Enter this token when `lxd init` prompts you for the join token.

   The join token contains the addresses of the existing online members, as well as a single-use secret and the fingerprint of the cluster certificate.
   This reduces the amount of questions that you must answer during `lxd init`, because the join token can be used to answer these questions automatically.
3. Confirm that all local data for the server is lost when joining a cluster.
4. Configure server-specific settings (see [Member configuration](../explanation/clusters.md#clustering-member-config) for more information).

   You can specify custom values for each server.
   In case you are restoring a lost server but you were able to recover the storage pool’s disk, you might want to accept the default
   values which should help telling LXD how to access the existing underlying storage pool.

<details>
<summary>Expand to see full examples for <code>lxd init</code> on additional servers</summary>
`user@host:~$ ``sudo lxd init
`
```text
Would you like to use LXD clustering? (yes/no) [default=no]: yes
What IP address or DNS name should be used to reach this server? [default=192.0.2.102]:
Are you joining an existing cluster? (yes/no) [default=no]: yes
Do you have a join token? (yes/no/[token]) [default=no]: yes
Please provide join token: eyJzZXJ2ZXJfbmFtZSI6InJwaTAxIiwiZmluZ2VycHJpbnQiOiIyNjZjZmExZDk0ZDZiMjk2Nzk0YjU0YzJlYzdjOTMwNDA5ZjIzNjdmNmM1YjRhZWVjOGM0YjAxYTc2NjU0MjgxIiwiYWRkcmVzc2VzIjpbIjE3Mi4xNy4zMC4xODM6ODQ0MyJdLCJzZWNyZXQiOiJmZGI1OTgyNjgxNTQ2ZGQyNGE2ZGE0Mzg5MTUyOGM1ZGUxNWNmYmQ5M2M3OTU3ODNkNGI5OGU4MTQ4MWMzNmUwIn0=
All existing data in the local database is lost when joining a cluster, continue? (yes/no) [default=no] yes
Choose "size" property for storage pool "local" [default=9GiB]:
Choose "source" property for storage pool "local":
Choose "zfs.pool_name" property for storage pool "local" [default=local]:
Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]:
```

</details>

After the initialization process finishes, your server is added as a new cluster member.
You can check this with [`lxc cluster list`](../reference/manpages/lxc/cluster/list.md#lxc-cluster-list-md).

In case you have restored a cluster member with a disk that was recovered from a previous cluster member, run
the `lxd recover` command on this cluster member to recover instances and volumes located on the disk’s storage pool.

## Configure the cluster through preseed files

To form your cluster, you must first run `lxd init` on the bootstrap server.
After that, run it on the other servers that you want to join to the cluster.

Instead of answering the `lxd init` questions interactively, you can provide the required information through preseed files.
You can feed a file to `lxd init` with the following command:

```none
cat <preseed-file> | lxd init --preseed
```

You need a different preseed file for every server.

### Initialize the bootstrap server

To enable clustering, the preseed file for the bootstrap server must contain the following fields:

```yaml
config:
  core.https_address: <IP_address_and_port>
cluster:
  server_name: <server_name>
  enabled: true
```

Here is an example preseed file for the bootstrap server:

```yaml
config:
  core.https_address: 192.0.2.101:8443
  images.auto_update_interval: 15
storage_pools:
- name: default
  driver: dir
- name: my-pool
  driver: zfs
networks:
- name: lxdbr0
  type: bridge
profiles:
- name: default
  devices:
    root:
      path: /
      pool: my-pool
      type: disk
    eth0:
      name: eth0
      nictype: bridged
      parent: lxdbr0
      type: nic
cluster:
  server_name: server1
  enabled: true
```

See [Preseed YAML file fields](../reference/preseed_yaml_fields.md#preseed-yaml-file-fields) for the complete fields of the preseed YAML file.

### Join additional servers

The preseed files for new cluster members require only a `cluster` section with data and configuration values that are specific to the joining server.

The preseed file for additional servers must include the following fields:

```yaml
cluster:
  enabled: true
  server_address: <IP_address_of_server>
  cluster_token: <join_token>
```

Here is an example preseed file for a new cluster member:

```yaml
cluster:
  enabled: true
  server_address: 192.0.2.102:8443
  cluster_token: eyJzZXJ2ZXJfbmFtZSI6Im5vZGUyIiwiZmluZ2VycHJpbnQiOiJjZjlmNmVhMWIzYjhiNjgxNzQ1YTY1NTY2YjM3ZGUwOTUzNjRmM2MxMDAwMGNjZWQyOTk5NDU5YzY2MGIxNWQ4IiwiYWRkcmVzc2VzIjpbIjE3Mi4xNy4zMC4xODM6ODQ0MyJdLCJzZWNyZXQiOiIxNGJmY2EzMDhkOTNhY2E3MGJmYThkMzE0NWM4NWY3YmE0ZmU1YmYyNmJiNDhmMmUwNzhhOGZhMDczZDc0YTFiIn0=
  member_config:
  - entity: storage-pool
    name: default
    key: source
    value: ""
  - entity: storage-pool
    name: my-pool
    key: source
    value: ""
  - entity: storage-pool
    name: my-pool
    key: driver
    value: "zfs"

```

See [Preseed YAML file fields](../reference/preseed_yaml_fields.md#preseed-yaml-file-fields) for the complete fields of the preseed YAML file.

<a id="use-microcloud"></a>

## Use MicroCloud


            <p class="youtube_link">
              <a href="https://www.youtube.com/watch?v=M0y0hQ16YuE" target="_blank">
                <span title="MicroCloud LTS Demo" class="play_icon">▶</span>
                <span title="MicroCloud LTS Demo">Watch on YouTube</span>
              </a>
            </p>
        
Instead of setting up your LXD cluster manually, you can use [MicroCloud](https://canonical.com/microcloud) to get a fully highly available LXD cluster with OVN and with Ceph storage up and running.

To install the required snaps, run the following command:

```none
snap install lxd microceph microovn microcloud
```

Then start the bootstrapping process with the following command:

```none
microcloud init
```

If you want to set up a multi-machine MicroCloud, run the following command on all the other machines:

```none
microcloud join
```

Following the CLI prompts, a working MicroCloud will be ready within minutes.

When the initialization is complete, you’ll have an OVN cluster, a Ceph cluster and a LXD cluster, and LXD itself will have been configured with both networking and storage suitable for use in a cluster.

See the [MicroCloud documentation](https://documentation.ubuntu.com/microcloud/latest/) for more information.


# index.html.md

<a id="images-profiles"></a>

# How to associate profiles with an image

You can associate one or more profiles with a specific image.
Instances that are created from the image will then automatically use the associated profiles in the order they were specified.

To associate a list of profiles with an image, add the profiles to the image configuration in the `profiles` section (see [Edit image properties](images_manage.md#images-manage-edit)).

CLI

Use the [`lxc image edit`](../reference/manpages/lxc/image/edit.md#lxc-image-edit-md) command to edit the `profiles` section:

```yaml
profiles:
- default
```

API

To update the full image properties, including the `profiles` section, send a PUT request with the full image data:

```none
lxc query --request PUT /1.0/images/<fingerprint> --data '<image_configuration>'
```

See [`PUT /1.0/images/{fingerprint}`](/api/#/images/image_put) for more information.

UI

The UI does not currently support editing the image configuration.
Therefore, you cannot associate profiles with an image through the UI.

Most provided images come with a profile list that includes only the `default` profile.
To prevent any profile (including the `default` profile) from being associated with an image, pass an empty list.

#### NOTE
Passing an empty list is different than passing `nil`.
If you pass `nil` as the profile list, only the `default` profile is associated with the image.

You can override the associated profiles for an image when creating an instance by adding the `--profile` or the `--no-profiles` flag to the launch or init command (when using the CLI), or by specifying a list of profiles in the request data (when using the API).


# index.html.md

<a id="howto-security-harden"></a>

# How to harden security for LXD

To increase the security posture of your LXD deployment, review the following hardening recommendations and apply those relevant to your setup.

## General

<a id="howto-security-harden-supported"></a>

### Use a supported version

Use only supported LTS releases or the latest feature release of LXD, and ensure that you update it regularly to receive security updates and bugfixes. See: [Releases](../reference/releases-snap.md#ref-releases).

<a id="howto-security-harden-delete-unused"></a>

### Delete unused resources

Delete unused networks and storage pools to reduce the attack surface.

## Access

<a id="howto-security-harden-group"></a>

### Secure the `lxd` group

Users in the `lxd` group who access LXD through the local Unix socket are given full administrative control over LXD. Thus, ensure that only trusted users are members of the `lxd` group (or any custom group you configure via `snap.lxd.daemon.group`). Audit group membership regularly.

Also see: [Use a restricted group for non-admin users](#howto-security-harden-restricted-group).

<a id="howto-security-harden-remote"></a>

### Harden remote API access

For [Remote API authentication](../authentication.md#authentication), LXD can use either  client certificates or OpenID Connect:

- Client certificates:
  - Ensure that only clients with certificates issued by your trusted Certificate Authority (CA) can connect. The [`core.trust_ca_certificates`](../server.md#server-core:core.trust_ca_certificates) option is `false` by default. To prevent auto-trusting of CA-signed certificates, ensure it remains disabled.
  - Regularly audit and remove unused client certificates from the trust store.
  - Ensure that private CAs issue short-lived certificates.
  - When [using a PKI system](../authentication.md#authentication-pki), regularly audit and revoke unused client certificates using a [certificate revocation list](../authentication.md#authentication-revoke-certificates).
- OpenID Connect:
  - Only set `oidc.client.secret` if required by the identity provider.
  - Configure your OIDC provider to issue short-lived access tokens.
  - Require multi-factor authentication (MFA) in your identity provider.

For [Remote API authorization](../explanation/authorization.md#authorization), use [Restricted TLS certificates](../explanation/authorization.md#restricted-tls-certs) or [Fine-grained authorization](../explanation/authorization.md#fine-grained-authorization) where relevant to your setup.

Refer to the [Remote API authentication](../authentication.md#authentication) and [Remote API authorization](../explanation/authorization.md#authorization) pages for details.

<a id="howto-security-harden-auth-expiry"></a>

### Decrease token expiry

Decrease the expiry times for LXD cluster join tokens and remote authentication tokens, such as to 15 minutes each:

```bash
sudo lxc config set cluster.join_token_expiry 15M
sudo lxc config set core.remote_token_expiry 15M
```

<a id="howto-security-harden-network"></a>

## Network security

Control traffic on LXD networks.

<a id="howto-security-harden-acls"></a>

### Configure ACLs

[Network Access Control Lists](network_acls.md#network-acls) (ACLs) are used to control traffic between instances and external networks, as well as traffic between instances on the same network. Set ACL rules to limit traffic to only what is necessary.

<a id="howto-security-harden-use-ip"></a>

### Limit network exposure

By default, LXD is only accessible locally through a Unix socket.
If you need to [expose LXD to the network](server_expose.md#server-expose), you must set the LXD server’s [`core.https_address`](../server.md#server-core:core.https_address).

To reduce the attack surface, provide a full socket address with IP address and port number.
If you only need local HTTPS access, use a loopback address and port, such as `127.0.0.1:8443`.
For external HTTPS access, set a trusted IP address on the LXD management interface along with a port, such as `192.0.2.10:8443`.

**Do not** specify a port number alone, such as `:8443`, as this exposes the LXD API to every interface on the host.

<a id="howto-security-harden-restrict-outbound"></a>

### Restrict outbound requests

An authenticated user with the `can_create_images` entitlement can probe internal networks by directing the LXD daemon to download images from internal network addresses.
The requests will fail, but error messages may provide information about internal services.

To prevent users from probing internal networks, restrict IP addresses or domains available to LXD for outbound HTTP and HTTPS requests.
First, set up a proxy to filter requests.
Then [configure the LXD server](server_configure.md#server-configure) to use the proxy by setting **both** [`core.proxy_http`](../server.md#server-core:core.proxy_http) and [`core.proxy_https`](../server.md#server-core:core.proxy_https) to the proxy address.

<a id="howto-security-harden-instance"></a>

## Instance security

Along with the recommendations below, review all [instance security options](../reference/instance_options.md#instance-options-security) for further options that might be relevant to your setup.

Rather than applying these options on a per-instance basis, use either [Projects](../projects.md#projects), [profiles](images_profiles.md#images-profiles), or both. See the section on [using profiles](#howto-security-profiles) below.

<a id="howto-security-harden-unprivileged"></a>

### Use unprivileged containers

By default, LXD containers are unprivileged. If you need to use privileged containers, make sure to put appropriate security measures in place. For more information, see: [Container security](../explanation/security.md#container-security).

<a id="howto-security-harden-instance-resource-limits"></a>

### Set instance resource limits

There are multiple [Resource limits](../reference/instance_options.md#instance-options-limits) that can be configured for instances. To decrease the potential damage from DoS attacks, set reasonable limits.

This is especially important for containers and their [`limits.cpu`](../reference/instance_options.md#instance-resource-limits:limits.cpu), [`limits.memory`](../reference/instance_options.md#instance-resource-limits:limits.memory), and [`limits.processes`](../reference/instance_options.md#instance-resource-limits:limits.processes) options, which by default are set without limits. Review the [Resource limits](../reference/instance_options.md#instance-options-limits) reference guide for other options you might want to restrict.

<a id="howto-security-harden-nesting-disable"></a>

### Disable container nesting

The instance configuration option [`security.nesting`](../reference/instance_options.md#instance-security:security.nesting) enables nested container capability. This increases complexity and can broaden the attack surface. The default for this setting is `false`. Do not set this to `true` unless absolutely needed.

Setting this option to `true` is especially dangerous in combination with [`security.privileged`](../reference/instance_options.md#instance-security:security.privileged) set to `true` because it provides root access to the host.

<a id="howto-security-harden-isolate"></a>

### Isolate containers

If a set of containers do not need to share data with each other, enable the instance option [`security.idmap.isolated`](../reference/instance_options.md#instance-security:security.idmap.isolated) on each one. This configures them to use unique UID/GID maps, preventing potential  attacks from one container to another. Only unprivileged containers can use this option.

<a id="howto-security-profiles"></a>

### Use profiles

Instead of applying [Instance options](../reference/instance_options.md#instance-options) on a per-instance basis, use either [Projects](../projects.md#projects), [profiles](images_profiles.md#images-profiles), or both. This enables you to use a consistent hardened configuration.

The set of commands to create and use a profile below are provided as an example only, including the instance options explicitly mentioned in this guide. Review all instance options and decide if there are other options you want to set for your hardened profile.

```bash
sudo lxc profile create hardened1
sudo lxc profile set hardened1 limits.cpu=2 limits.memory=4GiB limits.processes=500
sudo lxc profile set hardened1 security.idmap.isolated=true security.nesting=false
sudo lxc profile add <my-container> hardened1
```

<a id="howto-security-harden-device"></a>

## Device security

<a id="howto-security-harden-passthrough"></a>

### Limit device passthrough

PCI, USB, and disk device passthroughs give the container significant access to the host. Avoid adding devices to instances unless strictly necessary. Set [disk device](../reference/devices_disk.md#devices-disk) mounts to [`readonly`](../reference/devices_disk.md#device-disk-device-conf:readonly) where possible.

<a id="howto-security-harden-spoof"></a>

### Prevent spoofing

With bridged NICs, the default configuration allows MAC or IP spoofing. For details on how to prevent this, see [Bridged NIC security](../explanation/security.md#exp-security-bridged).

<a id="howto-security-harden-storage"></a>

## Storage device security

The Linux kernel might ignore mount options if a block-based filesystem (like `ext4`) is already mounted with different options. Thus, sharing the same disk device across multiple storage pools can lead to unexpected mount behavior.

To avoid security issues, either dedicate a disk device per storage pool or ensure that all pools sharing a device use the same mount options. For more information, see the [Security considerations](../reference/storage_drivers.md#storage-drivers-security) section of the [Storage drivers](../reference/storage_drivers.md#storage-drivers) reference guide.

<a id="howto-security-harden-logging"></a>

## Logging

Increase logging and regularly audit the logs for suspicious activity.

<a id="howto-security-harden-logging-system"></a>

### Use system logging

Enable system logging for the LXD daemon and set it to the `verbose` level:

```bash
sudo snap set lxd daemon.syslog=true
sudo snap set lxd daemon.verbose=true
```

Regularly check these logs using:

```bash
sudo snap logs lxd.daemon
```

By default, only the last 10 lines are output. To see more, use the `-n=[all|<#>]` flag.

For example, to see all logs, run:

```bash
sudo snap logs -n=all lxd.daemon
```

<a id="howto-security-harden-logging-auditd"></a>

### Use `auditd` rules

Use `auditd` rules to track LXD command execution and configuration file changes.

Configure the audit daemon to track all commands to the LXD daemon:

```bash
-a always,exit -F path=/snap/bin/lxc -p x -k lxd_execution
-a always,exit -F path=/snap/bin/lxd -p x -k lxd_execution
-a always,exit -F path=/snap/bin/lxd.buginfo -p x -k lxd_execution
-a always,exit -F path=/snap/bin/lxd.check-kernel -p x -k lxd_execution
-a always,exit -F path=/snap/bin/lxd.lxc -p x -k lxd_execution
```

<a id="howto-security-harden-logging-events"></a>

### Monitor LXD events

LXD emits [events](../events.md#events), including [security events](../events.md#events-security), with information about actions that have occurred. You can use the CLI, REST API, or Loki to [monitor security events](security_events.md#howto-security-events).

<a id="howto-security-harden-multi-user"></a>

## Multi-user environment

These settings are relevant if your LXD server is used by multiple users, such as in a lab setting.

<a id="howto-security-harden-restricted-group"></a>

### Use a restricted group for non-admin users

By default, both the `daemon.group` and `daemon.user.group` are set to `lxd`. This gives all users in the `lxd` group full local access to LXD through the Unix socket. This includes the ability to attach file system paths or devices to any instance, or tweak any instance’s security features.

Only users who are trusted with `sudo` access to your system should be in the `daemon.group`. Define and use a separate group for users who should not have admin access, such as `lxdusers`:

```bash
sudo groupadd lxdusers
sudo snap set lxd daemon.user.group=lxdusers
```

<a id="howto-security-harden-projects"></a>

### Confine users to projects

You can confine users to specific projects, which can be configured with stricter restrictions to prevent misuse. For details, see: [Confine users to specific LXD projects via Unix socket](projects_confine.md#projects-confine-users), [Instances grouping with projects](../explanation/projects.md#exp-projects), and [Restricted TLS certificates](../explanation/authorization.md#restricted-tls-certs).

<a id="howto-security-harden-name-leakage"></a>

### Prevent name leakage

The default server configuration makes it possible to list all cgroups on a system, and by extension, all running containers. Prevent container name leakage by blocking access to `/sys/kernel/slab` and `/proc/sched_debug` before you start any containers. To do so, run:

```bash
chmod 400 /proc/sched_debug
chmod 700 /sys/kernel/slab/
```

<a id="howto-security-harden-host"></a>

## Harden the LXD host OS

To harden your deployment, also harden the host’s operating system (OS). These are some ways you can harden the host OS:

- Keep your OS updated and install all available security patches.
- Use a firewall to drop unexpected inbound traffic and restrict outbound traffic as needed. Ensure only the necessary ports are open.
- For Ubuntu systems, subscribe to [Ubuntu Pro](https://ubuntu.com/pro).
- Use the latest [CIS hardening benchmarks](https://www.cisecurity.org/cis-benchmarks) for your OS.

<a id="howto-security-harden-cis"></a>

### Ubuntu CIS hardening

For Ubuntu LTS releases subscribed to Ubuntu Pro, use the [Ubuntu Security Guide (USG)](https://documentation.ubuntu.com/security/compliance/usg/) tool for CIS hardening. The tool can audit the host system and fix many issues automatically. Depending on how your system is configured, there might be other issues that you must remediate manually.

There are known issues with three of the auditing tool’s rule IDs when auditing LXD hosts with the `cis_level1_server` profile. One is that it generates a false failure report for the following rule ID, flagging that no UEFI boot loader password is set even when it is:

```default
xccdf_org.ssgproject.content_rule_grub2_uefi_password
```

As long as you have set this password and can confirm that the UEFI boot process requests it, you can ignore this failure report.

Furthermore, if the Ubuntu system is running LXD containers, the USG audit will report failure on the following rule IDs:

```default
xccdf_org.ssgproject.content_rule_no_files_unowned_by_user
xccdf_org.ssgproject.content_rule_file_permissions_ungroupowned
```

By design, LXD’s unprivileged containers run inside a user namespace for greater isolation. This causes some files and directories under `/sys/fs/cgroup/lxc.payload.<container_name>` to appear as having no owner. Since this is expected, the USG tool’s failure report for this can be ignored.

You can customize the tool’s CIS profile to always ignore these three rule IDs. To do so, follow the instructions in the [Customizing CIS profiles](https://documentation.ubuntu.com/security/compliance/usg/cis-customize/) section of the Ubuntu security documentation.

## Related topics

How-to guides:

- [How to configure your firewall](network_bridge_firewalld.md#network-bridge-firewall)
- [How to confine users to specific projects](projects_confine.md#projects-confine)

Explanation:

- [Security](../explanation/security.md#exp-security)
- [Remote API authentication](../authentication.md#authentication)
- [Remote API authorization](../explanation/authorization.md#authorization)

Reference:

- [Instance-level security options](../reference/instance_options.md#instance-options-security)


# index.html.md

<a id="instances-troubleshoot"></a>

# How to troubleshoot failing instances

If your instance fails to start and ends up in an error state, this usually indicates a bigger issue related to either the image that you used to create the instance or the server configuration.

To troubleshoot the problem, complete the following steps:

1. Save the relevant log files and debug information:

   Instance log
   : Display the instance log:
     <br/>
     CLI
     ```none
     lxc info <instance_name> --show-log
     ```
     <br/>
     API
     ```none
     lxc query --request GET /1.0/instances/<instance_name>/logs/lxc.log
     ```
     <br/>
     UI
     <br/>
     Navigate to the instance detail page and switch to the Logs tab to view the available log files.

   Console log
   : Display the console log:
     <br/>
     CLI
     ```none
     lxc console <instance_name> --show-log
     ```
     <br/>
     This command is available only for containers.
     <br/>
     API
     ```none
     lxc query --request GET /1.0/instances/<instance_name>/console
     ```
     <br/>
     This endpoint is available only for containers.
     <br/>
     UI
     <br/>
     Navigate to the instance detail page and switch to the Console tab to view the console.
     The console is displayed only when the instance is running.

   Detailed server information
   : The LXD snap includes a tool that collects the relevant server information for debugging.
     Enter the following command to run it:
     ```none
     sudo lxd.buginfo
     ```
2. Reboot the machine that runs your LXD server.
3. Try starting your instance again.
   If the error occurs again, compare the logs to check if it is the same error.

   If it is, and if you cannot figure out the source of the error from the log information, open a question in the [forum](https://discourse.ubuntu.com/c/project/lxd/126).
   Make sure to include the log files you collected.

## Troubleshooting examples

See the following sections for some typical methods of troubleshooting an instance.

### Debug `systemd` `init`

Here is how to enable `systemd` [debug level messages](https://systemd.io/DEBUGGING/) for the `c1` container:

```sh
lxc config set c1 raw.lxc 'lxc.init.cmd = /sbin/init systemd.log_level=debug'

lxc start c1
```

Now that the container has started, you can check for the debug messages in the journal:

```sh
lxc exec c1 -- journalctl
```

### Emergency `systemd` shell

Here is how to get an `emergency` shell on an instance using `systemd`:

```sh
lxc config set c1 raw.lxc 'lxc.init.cmd = /sbin/init emergency'

lxc start c1
```

Now that the container has started, you can enter the emergency shell using the console (hit the `Enter` key once in):

```sh
lxc console c1
```

### Issue starting RHEL 7 container

In this example, let’s investigate a RHEL 7 system in which `systemd` cannot start.

`user@host:~$ ``lxc console --show-log rhel7
`
```text
Console log:

Failed to insert module 'autofs4'
Failed to insert module 'unix'
Failed to mount sysfs at /sys: Operation not permitted
Failed to mount proc at /proc: Operation not permitted
[!!!!!!] Failed to mount API filesystems, freezing.
```

The errors here say that `/sys` and `/proc` cannot be mounted - which is correct in an unprivileged container.
However, LXD mounts these file systems automatically if it can.

The [container requirements](../container-environment.md) specify that every container must come with an empty `/dev`, `/proc` and `/sys` directory, and that `/sbin/init` must exist.
If those directories don’t exist, LXD cannot mount them, and `systemd` will then try to do so.
As this is an unprivileged container, `systemd` does not have the ability to do this, and it then freezes.

So you can see the environment before anything is changed, and you can explicitly change the init system in a container using the [`raw.lxc`](../reference/instance_options.md#instance-raw:raw.lxc) configuration parameter.
This is equivalent to setting `init=/bin/bash` on the Linux kernel command line.

```none
lxc config set rhel7 raw.lxc 'lxc.init.cmd = /bin/bash'
```

Here is what it looks like:

`user@host:~$ ``lxc config set rhel7 raw.lxc 'lxc.init.cmd = /bin/bash'
``user@host:~$ ``lxc start rhel7
``user@host:~$ ``lxc console --show-log rhel7
`
```text
Console log:

[root@rhel7 /]#
```

Now that the container has started, you can check it and see that things are not running as well as expected:

`user@host:~$ ``lxc exec rhel7 -- bash
`
```text
[root@rhel7 ~]# ls
[root@rhel7 ~]# mount
mount: failed to read mtab: No such file or directory
[root@rhel7 ~]# cd /
[root@rhel7 /]# ls /proc/
sys
[root@rhel7 /]# exit
```

Because LXD tries to auto-heal, it created some of the directories when it was starting up.
Shutting down and restarting the container fixes the problem, but the original cause is still there - the template does not contain the required files.


# index.html.md

<a id="network-configure"></a>

# How to configure a network

CLI

To configure an existing network, use either the [`lxc network set`](../reference/manpages/lxc/network/set.md#lxc-network-set-md) and [`lxc network unset`](../reference/manpages/lxc/network/unset.md#lxc-network-unset-md) commands (to configure single settings) or the `lxc network edit` command (to edit the full configuration).
To configure settings for specific cluster members, add the `--target` flag.

For example, the following command configures a DNS server for a physical network:

```bash
lxc network set UPLINK dns.nameservers=8.8.8.8
```

The available configuration options differ depending on the network type.
See [Network types](network_create.md#network-types) for links to the configuration options for each network type.

UI

To edit the configuration of a network, navigate to the overview page for the network, and observe its attributes and settings.

Within the Configuration tab, you can edit key settings of the network by clicking on the Edit pencil icon inline with the desired configuration setting.

![LXD Network overview page](images/networks/network_configuration.png)

There are separate commands to configure advanced networking features.
See the following documentation:

- [How to configure network ACLs](network_acls.md)
- [How to configure network forwards](network_forwards.md)
- [How to configure network load balancers](network_load_balancers.md)
- [How to configure network zones](network_zones.md)
- [How to create OVN peer routing relationships](network_ovn_peers.md) (OVN only)


# index.html.md

<a id="images-copy"></a>

# How to copy and import images

To add images to an image store, you can either copy them from another server or import them from files (either local files or files on a web server).

#### NOTE
The UI does not currently support copying or importing images.

There is support for importing custom ISO files, but these ISO files are different from images.
When you create an instance from a custom ISO file, the ISO file is mounted as a storage volume in a new empty VM, and you can then install the VM from the ISO file.
See [Content type `iso`](../explanation/storage.md#storage-content-types) and [Create a VM that boots from an ISO](instances_create.md#instances-create-iso) for more information.

## Copy an image from a remote

CLI

To copy an image from one server to another, enter the following command:

```none
lxc image copy [<source_remote>:]<image> <target_remote>:
```

#### NOTE
To copy the image to your local image store, specify `local:` as the target remote.

See [`lxc image copy --help`](../reference/manpages/lxc/image/copy.md#lxc-image-copy-md) for a list of all available flags.
The most relevant ones are:

`--alias`
: Assign an alias to the copy of the image.

`--copy-aliases`
: Copy the aliases that the source image has.

`--auto-update`
: Keep the copy up-to-date with the original image.

`--vm`
: When copying from an alias, copy the image that can be used to create virtual machines.

API

To copy an image from one server to another, [export it to your local machine](images_manage.md#images-manage-export) and then [import it to the other server](#images-copy-import).

<a id="images-copy-import"></a>

## Import an image from files

If you have image files that use the required [Image format](../reference/image_format.md#image-format), you can import them into your image store.

There are several ways of obtaining such image files:

- Exporting an existing image (see [Export an image to a set of files](images_manage.md#images-manage-export))
- Building your own image using LXD image builder (see [Build an image](images_create.md#images-create-build))
- Downloading image files from a [remote image server](../reference/remote_image_servers.md#remote-image-servers) (note that it is usually easier to [use the remote image](images_remote.md#images-remote) directly instead of downloading it to a file and importing it)

### Import from the local file system

CLI

To import an image from the local file system, use the [`lxc image import`](../reference/manpages/lxc/image/import.md#lxc-image-import-md) command.
This command supports both [unified images](../reference/image_format.md#image-format-unified) (compressed file or directory) and [split images](../reference/image_format.md#image-format-split) (two files).

To import a unified image from one file or directory, enter the following command:

```none
lxc image import <image_file_or_directory_path> [<target_remote>:]
```

To import a split image, enter the following command:

```none
lxc image import <metadata_tarball_path> <rootfs_tarball_path> [<target_remote>:]
```

In both cases, you can assign an alias with the `--alias` flag.
See [`lxc image import --help`](../reference/manpages/lxc/image/import.md#lxc-image-import-md) for all available flags.

API

To import an image from the local file system, send a POST request to the `/1.0/images` endpoint.

For example, to import a unified image from one file:

```none
curl -X POST -H 'Content-Type: application/octet-stream' --unix-socket /var/snap/lxd/common/lxd/unix.socket lxd/1.0/images \
--data-binary @<image_file_path>
```

To import a split image from a metadata file and a container `rootfs` file:

```none
curl -X POST -H 'Content-Type: multipart/form-data' --unix-socket /var/snap/lxd/common/lxd/unix.socket lxd/1.0/images \
--form metadata=@<metadata_tarball_path> --form rootfs=@<rootfs_tarball_path>
```

To import a split image from a metadata file and a VM `rootfs.img` file:

```none
curl -X POST -H 'Content-Type: multipart/form-data' --unix-socket /var/snap/lxd/common/lxd/unix.socket lxd/1.0/images \
--form metadata=@<metadata_tarball_path> --form rootfs.img=@<rootfs_tarball_path>
```

#### NOTE
For a split image, you must send the metadata tarball first and the rootfs image after.

See [`POST /1.0/images`](/api/#/images/images_post) for more information.


# index.html.md

<a id="initialize"></a>

# How to initialize LXD

Before you can create a LXD instance, you must configure and initialize LXD.

## Interactive configuration

Run the following command to start the interactive configuration process:

```none
lxd init
```

#### NOTE
For simple configurations, you can run this command as a normal user.
However, some more advanced operations during the initialization process (for example, joining an existing cluster) require root privileges.
In this case, run the command with `sudo` or as root.

The tool asks a series of questions to determine the required configuration.
The questions are dynamically adapted to the answers that you give.
They cover the following areas:

Clustering (see [Clusters](../explanation/clusters.md#exp-clusters) and [How to form a cluster](cluster_form.md#cluster-form))
: A cluster combines several LXD servers.
  The cluster members share the same distributed database and can be managed uniformly using the LXD client ([`lxc`](../reference/manpages/lxc.md#lxc-md)) or the REST API.
  <br/>
  The default answer is `no`, which means clustering is not enabled.
  If you answer `yes`, you can either connect to an existing cluster or create one.

Networking (see [Networking setups](../explanation/networks.md#networks) and [Network devices](../reference/devices_nic.md#devices-nic))
: Provides network access for the instances.
  <br/>
  You can let LXD create a new bridge (recommended) or use an existing network bridge or interface.
  <br/>
  You can create additional bridges and assign them to instances later.
  <br/>
  #### WARNING
  Creating a managed bridge (or a Fan overlay) enables IPv4 forwarding (`net.ipv4.ip_forward=1`) on the host; if the bridge also has an IPv6 subnet, IPv6 forwarding is enabled on every interface (`net.ipv6.conf.<iface>.forwarding=1`).
  This is a global toggle: it affects *all* interfaces, not just the LXD bridge, effectively making a multi-homed host an IP router.

Storage pools (see [Storage pools, volumes, and buckets](../explanation/storage.md#exp-storage) and  [Storage drivers](../reference/storage_drivers.md#storage-drivers))
: Instances (and other data) are stored in storage pools.
  <br/>
  For testing purposes, you can create a loop-backed storage pool.
  For production use, however, you should use an empty partition (or full disk) instead of loop-backed storage (because loop-backed pools are slower and their size/quota can’t be reduced).
  <br/>
  The recommended backends are `zfs` and `btrfs`.
  <br/>
  You can create additional storage pools later.

Remote access (see [Access to the remote API](../explanation/security.md#security-remote-access) and [Remote API authentication](../authentication.md#authentication))
: Allows remote access to the server over the network.
  <br/>
  The default answer is `no`, which means remote access is not allowed.
  If you answer `yes`, you can connect to the server over the network.
  <br/>
  You can choose to add client certificates to the server either manually or through tokens.

Automatic image update (see [Local and remote images](../image-handling.md#about-images))
: You can download images from image servers.
  In this case, images can be updated automatically.
  <br/>
  The default answer is `yes`, which means that LXD will update the downloaded images regularly.

YAML `lxd init` preseed (see [Non-interactive configuration](#initialize-preseed))
: If you answer `yes`, the command displays a summary of your chosen configuration options in the terminal.

### Minimal setup

To create a minimal setup with default options, you can skip the configuration steps by adding the `--minimal` flag to the `lxd init` command:

```none
lxd init --minimal
```

#### NOTE
The minimal setup provides a basic configuration, but the configuration is not optimized for speed or functionality.
The [`dir` storage driver](../reference/storage_dir.md#storage-dir), which is chosen by default in the minimal setup using `--minimal`, is slower than other drivers and doesn’t provide fast snapshots, fast copy/launch, quotas and optimized backups.

If you want to use an optimized setup, go through the interactive configuration process instead.

<a id="initialize-preseed"></a>

## Non-interactive configuration

The `lxd init` command supports a `--preseed` command line flag that makes it possible to fully configure the LXD daemon settings, storage pools, network devices and profiles, in a non-interactive way through a preseed YAML file.

For example, starting from a brand new LXD installation, you could configure LXD with the following command:

```bash
    cat <<EOF | lxd init --preseed
config:
  core.https_address: 192.0.2.1:9999
  images.auto_update_interval: 15
networks:
- name: lxdbr0
  type: bridge
  config:
    ipv4.address: auto
    ipv6.address: none
EOF
```

This preseed configuration initializes the LXD daemon to listen for HTTPS connections on port 9999 of the 192.0.2.1 address, to automatically update images every 15 hours and to create a network bridge device named `lxdbr0`, which gets assigned an IPv4 address automatically.

#### WARNING
Creating a managed bridge with an IPv4 or IPv6 subnet enables the corresponding host-wide forwarding sysctls (`net.ipv4.ip_forward=1` and/or `net.ipv6.conf.<iface>.forwarding=1`), which turn on forwarding for *all* interfaces on the host.

### Re-configuring an existing LXD installation

If you are configuring a new LXD installation, the preseed command applies the configuration as specified (as long as the given YAML contains valid keys and values).
There is no existing state that might conflict with the specified configuration.

However, if you are re-configuring an existing LXD installation using the preseed command, the provided YAML configuration might conflict with the existing configuration.
To avoid such conflicts, the following rules are in place:

- The provided YAML configuration overwrites existing entities.
  This means that if you are re-configuring an existing entity, you must provide the full configuration for the entity and not just the different keys.
- If the provided YAML configuration contains entities that do not exist, they are created.

This is the same behavior as for a `PUT` request in the [REST API](../rest-api.md).

#### Rollback

If some parts of the new configuration conflict with the existing state (for example, they try to change the driver of a storage pool from `dir` to `zfs`), the preseed command fails and automatically attempts to roll back any changes that were applied so far.

For example, it deletes entities that were created by the new configuration and reverts overwritten entities back to their original state.

Failure modes when overwriting entities are the same as for the `PUT` requests in the [REST API](../rest-api.md).

#### NOTE
The rollback process might potentially fail, although rarely (typically due to backend bugs or limitations).
You should therefore be careful when trying to reconfigure a LXD daemon via preseed.

### Default profile

Unlike the interactive initialization mode, the `lxd init --preseed` command does not modify the default profile, unless you explicitly express that in the provided YAML payload.

For instance, you will typically want to attach a root disk device and a network interface to your default profile.
See the following section for an example.

### Configuration format

The supported keys and values of the various entities are the same as the ones documented in the [REST API](../rest-api.md), but converted to YAML for convenience.
However, you can also use JSON, since YAML is a superset of JSON.

The following snippet gives an example of a preseed payload that contains most of the possible configurations.
You can use it as a template for your own preseed file and add, change or remove what you need:

```yaml

# Daemon settings
config:
  core.https_address: 192.0.2.1:9999
  images.auto_update_interval: 6

# Storage pools
storage_pools:
- name: data
  driver: zfs
  config:
    source: my-zfs-pool/my-zfs-dataset

# Storage volumes
storage_volumes:
- name: my-vol
  pool: data

# Network devices
networks:
- name: lxd-my-bridge
  type: bridge
  config:
    ipv4.address: auto
    ipv6.address: none

# Profiles
profiles:
- name: default
  devices:
    root:
      path: /
      pool: data
      type: disk
- name: test-profile
  description: "Test profile"
  config:
    limits.memory: 2GiB
  devices:
    test0:
      name: test0
      nictype: bridged
      parent: lxd-my-bridge
      type: nic
```

See [Preseed YAML file fields](../reference/preseed_yaml_fields.md#preseed-yaml-file-fields) for the complete fields of the preseed YAML file.


# index.html.md

# How to troubleshoot (some) Dqlite errors

Dqlite is the distributed database that LXD uses to store information
that must be synchronized across a cluster.
See [The LXD Dqlite database](../database.md#database) for more information.

This how-to guide describes strategies for how to respond to Dqlite-related
errors.

## Recognizing Dqlite-related errors

If LXD fails to start up or crashes, you should suspect a Dqlite-related error
if the error message mentions keywords like `Dqlite`, `raft`, or `segment`.

A known risk factor for some of the errors covered below is a previous LXD
crash caused by running out of disk space.

## The Dqlite data directory

When investigating Dqlite-related errors, it’s essential to look at the
contents of the [Dqlite data directory](../database.md#database-location) for the affected node. This is the
directory where the local instance of Dqlite stores all its data.
You can find this directory at `/var/snap/lxd/common/lxd/database/global` (if you use
the snap) or `/var/lib/lxd/database/global` (otherwise).

The data directory contains several types of file. The most important types are:

- Closed segments: These have filenames like
  `0000000000056436-0000000000056501`. The two numbers are the *start index*
  and *end index*. Both indices are inclusive.
- Open segments: These have filenames like `open-1`.
- Snapshot files: These have names like `snapshot-1-59392-27900`. The first
  number is the *snapshot index*.
- Snapshot metadata files: These have names like `snapshot-1-59392-27900.meta`
  and are paired with snapshot files.

## Spotting anomalies

When looking at the contents of the data directory, watch for the following
symptoms:

1. Closed segments whose index ranges overlap (remember that these ranges are
   inclusive).
2. A closed segment with end index X where the next closed segment has start
   index greater than X + 1.
3. A snapshot file with snapshot index X where the next closed segment has
   start index greater than X + 1.
4. A snapshot file whose size is less than the size of a previous
   (lower-numbered) snapshot.

When scanning for these symptoms, start with the most recent snapshots and
closed segments (those with the highest indices) since the problem is more
likely to be there.

## Specific error messages

- `closed segment [...] is past last snapshot [...]`: This indicates that you
  have symptom 3 above (missing entries after a snapshot), possibly combined
  with symptom 1 (overlapping segments).
- `load closed segment [...]: entries count in preamble is zero`: This
  indicates that the mentioned segment is corrupt.

## Interventions

#### IMPORTANT
Before taking any of the actions below, back up the entire
Dqlite data directory, so you don’t lose data in case something goes wrong.

Here are some actions you can take in response to specific Dqlite errors. They
are not guaranteed to work in any specific case.

- If you have overlapping closed segments (symptom 1), try deleting some of
  them to remove the overlap, without creating gaps in the sequence of indices
  or removing any index that was previously represented.
- If the snapshot file with the highest index is unexpectedly small (symptom
  4), and there are still closed segments covering all the indices up to and
  including this snapshot’s index, delete the snapshot and its corresponding
  metadata file.
- If the last (highest-numbered) closed segment is corrupt, try deleting it.
  (Deleting closed segments before the last one will create a gap and generally
  prevent Dqlite from starting.)

## Get help

If the tips above don’t help with your situation, you can always post on the
LXD support forum. Make sure to mention Dqlite in your post and include the error
message or messages you’re seeing, LXD logs, and the output of the following command (if
you’re using the LXD snap):

```default
sudo ls -lah /var/snap/lxd/common/lxd/database/global
```

Also mention any troubleshooting steps you’ve already taken and what
you learned.


# index.html.md

<a id="oidc-keycloak"></a>

# How to configure Keycloak as login method for LXD

Keycloak is a self-hosted open source tool for authentication. Keycloak supports OIDC and can be used to authenticate users for LXD UI and CLI. This guide shows you how to set up Keycloak as the login method for LXD.

## Using Keycloak to access LXD

1. Set up Keycloak. For this guide, it is assumed that Keycloak is available over HTTPS.
   - If you already have Keycloak installed, follow their guide on [configuring Keycloak for production](https://www.keycloak.org/server/configuration-production).
   - Alternatively, run the development version:
     - Download [Keycloak `.zip`](https://www.keycloak.org/downloads).
     - Extract the files and run `bin/kc.sh start-dev`.
     - Open [`http://localhost:8080`](http://localhost:8080) in your browser and create an admin user with a password.
2. Open the Keycloak Admin Console. For the development version, you can access this at [`http://localhost:8080/admin`](http://localhost:8080/admin). Sign in with the admin user that you created.
3. From the Keycloak dropdown in the top left corner of the Admin Console, select Create realm. Enter a Realm name, such as `lxd-ui-realm`, then click Create.
4. From the main navigation, select Clients, then click Create client. Enter a Client ID, such as `lxd-ui-client`, then click Next.
5. Under Capability config, enable the OAuth 2.0 Device Authorization Grant authentication flow to allow both LXD UI and CLI logins.

   Optionally, to enforce additional authentication via a secret, turn on Client authentication. The secret will be available from the client’s Credentials tab after you finish creating the client, and instructions for sharing it with your LXD server are provided later in this guide. Note: Turning this option on permits UI login only.

   Click Next.
6. In the field for Valid redirect URIs, enter your LXD UI address, followed by `/oidc/callback`.
   - Example: `https://example.com:8443/oidc/callback`
   - An IP address can be used instead of a domain name.
   - Note `:8443` is the default listening port for the LXD server. It might differ for your setup. You can verify the LXD configuration value `core.https_address` to find the correct port for your LXD server.

   Click Save.
7. From the main navigation, select Users, then click Create new user. Enter a Username, then click Create.
8. Select the Credentials tab for the new user and click Set password. Save the new password.
9. Configure the issuer on your LXD server via the CLI. For `<keycloak-realm>`, use the name that you created in step 2. For the `<keycloak-frontend-url>`, use the URL for your Keycloak server, such as `http://192.0.2.1:8080`. If you are running the development version of Keycloak, use `http://localhost:8080`.
   ```none
   lxc config set oidc.issuer=<keycloak-frontend-url>/realms/<keycloak-realm>
   ```
10. Configure the client in LXD with the command below. Use the client id from step 4.
    ```none
    lxc config set oidc.client.id=<keycloak-client-id>
    ```
11. If you have Client authentication on, you need to share the generated secret with your server.
    ```none
    lxc config set oidc.client.secret=<keycloak-client-secret>
    ```

Now you can access the LXD UI with any browser and use  login. To use OIDC on the LXD CLI, run `lxc remote add <remote-name> <LXD address> --auth-type oidc` and point a browser to the displayed URL (with user_code) to authenticate.

Users authenticated through Keycloak have no default permissions in the LXD UI. Set up [LXD authorization groups](../explanation/authorization.md#manage-permissions) to grant access to projects and instances and map a LXD authorization group to the user. Note that the user object in LXD is only created on the first login of that user to LXD.


# index.html.md

<a id="howto-cluster-vip"></a>

# How to set up a highly available virtual IP for clusters

This page describes how to enhance the high availability (HA) of the control plane for a LXD cluster, through setting up a virtual IP (VIP) as a single access point.

By [exposing cluster members to the network](server_expose.md#server-expose) and configuring them as [remote servers](../remotes.md#remotes) on a client machine, you can control the cluster over the network. This provides high availability: if one cluster member becomes unavailable, you can access the cluster through another.

You can enhance HA by adding a routing service that uses the Virtual Router Redundancy Protocol (VRRP) to configure a single VIP as the access point for the cluster. While the implementation differs, the concept is similar to a floating IP in cloud platforms.

For more information about HA in LXD clusters, including both the control and data planes, see: [High availability](../explanation/clusters.md#clusters-high-availability).

<a id="howto-cluster-vip-keepalived"></a>

## Use Keepalived

While VRRP is implemented by various tools, [**Keepalived**](https://keepalived.org/documentation/) is the most commonly used implementation in Linux environments. The VIP configured with Keepalived is only active on one cluster member at a given time (called the `MASTER`), and Keepalived performs regular checks to reassign the VIP to another member (a `BACKUP`) if the `MASTER` fails to respond.

To install Keepalived, run the following commands on each cluster member:

```bash
sudo apt update
sudo apt -y install keepalived --no-install-recommends
```

The configuration file for Keepalived is typically stored at `/etc/keepalived/keepalived.conf`. You must create a configuration file for each cluster member, with one member set with `state MASTER` and the rest with `state BACKUP`.

<a id="howto-cluster-vip-keepalived-example-config"></a>

### Example minimal configuration

Example of a minimal Keepalived configuration for three LXD cluster members (`m1`, `m2`, and `m3`):

```default
vrrp_instance VI_1 {
    state MASTER
    interface enp5s0
    virtual_router_id 41
    priority 200
    advert_int 1
    virtual_ipaddress {
        192.0.2.50/24
    }
}
```

```default
vrrp_instance VI_1 {
    state BACKUP
    interface enp5s0
    virtual_router_id 41
    priority 100
    advert_int 1
    virtual_ipaddress {
        192.0.2.50/24
    }
}
```

Restart the `keepalived` service on each cluster member after creating or editing its configuration file:

```bash
sudo systemctl restart keepalived
```

On `m1` (the cluster member designated as `MASTER`), run the following command, using the interface you configured in `keepalived.conf`:

`ubuntu@m1:~$ ``ip -br addr show <interface>
`

Confirm that in the output, you can see the VIP as an IP address of the interface.

<a id="howto-cluster-vip-keepalived-example-test"></a>

### Test the example configuration

This section describes how to conduct a basic test of the example Keepalived configuration, using the CLI.

First, [create a container](instances_create.md#instances-create) on each of the cluster members. This can be performed from any of the cluster members, using the `--target` flag. Example:

`ubuntu@m1:~$ ``lxc init ubuntu:24.04 c1 --target m1
`
```text
Creating c1
```

`ubuntu@m1:~$ ``lxc init ubuntu:24.04 c2 --target m2
`
```text
Creating c2
```

`ubuntu@m1:~$ ``lxc init ubuntu:24.04 c3 --target m3
`
```text
Creating c3
```

Run the following command from any cluster member to list the created instances:

```bash
lxc list
```

Confirm that the containers each exist on a different cluster member.

Next, you need a client LXD server that can access the network used by the cluster for external connectivity. On it, add the VIP as a [remote server](../remotes.md#remotes):

`ubuntu@my-client:~$ ``lxc remote add my-cluster 192.0.2.50
`

Then check the list of instances running on the cluster from the client machine. Example:

`ubuntu@my-client:~$ ``lxc list my-cluster:
`

The output shown should match what you see when you run `lxc list` on any of the cluster members.

Finally, take the cluster member configured as the Keepalived `MASTER` offline so that it is no longer reachable. This should cause Keepalived to automatically move the VIP to one of the `BACKUP` servers.

From the client server, list the instances running on the cluster once more, using the same command as before. You should see the same list as before, with the exception that the container running on the offline cluster member now displays an `ERROR` state. This confirms that you can still run remote commands on the client, meaning that Keepalived has reassigned the `MASTER` role to another cluster member.

<a id="howto-cluster-vip-keepalived-example-config-keys"></a>

#### Configuration keys

In this section, we provide brief descriptions of the configuration keys used in this guide. Keep in mind that our example minimal configuration does not include authentication and other settings that might be relevant in production. For full configuration details, refer to the [official Keepalived documentation](https://keepalived.org/documentation/user-guide/configuration-synopsis/).

`state`:
: Only one cluster member can be designated the `MASTER` state. The rest must be set as `BACKUP`.

`interface`
: This is the interface that carries the subnet used for client access to the cluster. On clusters using OVN networking, this is the uplink network.

`virtual_router_id`
: The `virtual_router_id` must be the same in all cluster members. This assigns the cluster members to the same virtual router.

`priority`
: This determines the order in which the VIP is allocated to a cluster member. The `MASTER` must always have a higher priority number than any `BACKUP`. The `BACKUP` servers can use the same number to let Keepalived choose the priority, or you can set a specific priority for each server.

`advert_int`
: The `advert_int` key sets the **advertisement internal** (in seconds). The `MASTER` sends VRRP advertisements at this interval to tell `BACKUP` servers that it’s online. The `BACKUP` servers assume that the `MASTER` is offline if it stops sending these.

`virtual_ipaddress`
: This is the VIP exposed for access to the cluster. Select an unused IP from the subnet used for external access by the cluster. It must be identical on all cluster members.

<a id="howto-cluster-vip-load-balancing"></a>

## Load balancing

Using a VIP to route requests to a single cluster member can cause high load on that machine. Keepalived also provides a framework for load balancing, using the Linux Virtual Server (IPVS) kernel module. For details, see the [Keepalived documentation](https://keepalived.org/documentation/).

Alternatively, consider combining Keepalived with an implementation of [HAProxy](https://www.haproxy.org/). HAProxy is a reverse proxy that can redirect traffic for both TCP and HTTP protocols, which means that it can handle load balancing both API and UI traffic for LXD clusters.

HAProxy can also support the use of ACME (Automatic Certificate Management Environment) services such as [Let’s Encrypt](https://letsencrypt.org/) to automate renewing certificates for UI access. For details, see: [TLS server certificate](../authentication.md#authentication-server-certificate).

## Related topics

How-to guides:

- [Clustering](../clustering.md#clustering)

Reference:

- [Clusters](../reference/clusters.md#ref-clusters)

Explanation:

- [Clusters](../explanation/clusters.md#exp-clusters)


# index.html.md

<a id="logs-loki"></a>

# How to send logs to Loki

<!-- Include start logs_loki intro -->

LXD publishes information about its activity in the form of events. The `lxc monitor` command allows you to view this information in your shell. There are several categories of LXD events: `logging`, `operation`, `lifecycle`, `ovn`, and `security`. The `lxc monitor --type=logging --pretty` command will filter and display log type events like activity of the raft cluster, for instance, while `lxc monitor --type=lifecycle --pretty` will only display lifecycle events like instances starting or stopping. The `lxc monitor --type=security --pretty` command shows security-related events such as authentication attempts and authorization decisions.

In a production environment, you might want to keep a log of these events in a dedicated system. [Loki](https://grafana.com/oss/loki/) is one such system, and LXD provides a configuration option to forward selected event types to Loki (`logging`, `lifecycle`, `ovn`, and `security`). Note that operation events are not forwarded to Loki.

<!-- Include end logs_loki intro -->

## Configure LXD to send logs

See the Loki documentation for instructions on installing it:

- [Install Loki](https://grafana.com/docs/loki/latest/setup/install/)

Once you have a Loki server up and running, you can instruct LXD to send logs to your Loki server by setting the following option:

```none
lxc config set loki.api.url=http://<loki_server_IP>:3100
```

#### NOTE
If Loki logs are to be viewed in the Grafana dashboard, ensure the `loki.instance` configuration key matches the name of the Prometheus job. See [Set up a Grafana dashboard](grafana.md#grafana).

To forward security events to Loki, use: `lxc config set loki.types=logging,lifecycle,security`

## Query Loki logs

Loki logs are typically viewed/queried using Grafana but Loki provides a command line utility called LogCLI allowing to query logs from your Loki server without the need for Grafana.

See the LogCLI documentation for instructions on installing it:

- [Install LogCLI](https://grafana.com/docs/loki/latest/query/logcli/)

With your LogCLI utility up and running, first configure it to query the server you have installed before by setting the appropriate environment variable:

```none
export LOKI_ADDR=http://<loki_server_IP>:3100
```

You can then query the Loki server to validate that your LXD events are getting through. LXD events all have the `app` key set to `lxd` so you can use the following `logcli` command to see LXD logs in Loki.

`user@host:~$ ``logcli query -t '{app="lxd"}'
`
```text
2024-02-14T21:31:20Z {app="lxd", instance="node3", type="logging"} level="info" Updating instance types
2024-02-14T21:31:20Z {app="lxd", instance="node3", type="logging"} level="info" Expiring log files
2024-02-14T21:31:20Z {app="lxd", instance="node3", type="logging"} level="info" Pruning resolved warnings
2024-02-14T21:31:20Z {app="lxd", instance="node3", type="logging"} level="info" Updating images
2024-02-14T21:31:20Z {app="lxd", instance="node3", type="logging"} level="info" Done pruning resolved warnings
2024-02-14T21:31:20Z {app="lxd", instance="node3", type="logging"} level="info" Done expiring log files
2024-02-14T21:31:20Z {app="lxd", instance="node3", type="logging"} level="info" Done updating images
...
```

## Add labels

LXD pushes log entries with a set of predefined labels like `app`, `project`, `instance` and `name`. To see all existing labels, you can use `logcli labels`. Some log entries might contain information in their message that you would like to access as if they were keys. In the example below, you might want to have `requester-username` as a key to query.

```default
2024-02-15T22:52:25Z {app="lxd", instance="node3", location="node3", name="c1", project="default", type="lifecycle"} requester-username="ubuntu" action="instance-started" source="/1.0/instances/c1" requester-address="@" requester-protocol="unix" instance-started
...
```

Use the following command to instruct LXD to move all occurrences of `requester-username="<user>"` into the label section:

```none
lxc config set loki.labels="requester-username"
```

This will transform the above log entry into:

```default
2024-02-09T21:26:32Z {app="lxd", instance="node3", location="node3", name="c2", project="default", requester_username="ubuntu", type="lifecycle"} action="instance-started" source="/1.0/instances/c2" requester-address="@" requester-protocol="unix" instance-started
...
```

Note the replacement of `-` by `_`, as `-` cannot be used in keys. As `requester_username` is now a key, you can query Loki using it like this:

```none
logcli query -t '{requester_username="ubuntu"}'
```


# index.html.md

<a id="cluster-placement-groups"></a>

# How to use placement groups

Placement groups allow you to control how instances are distributed across cluster members.
You can either spread instances across different members for high availability, or compact them onto the same member(s) for performance and locality.

#### NOTE
Placement groups are only available in clustered LXD deployments and are scoped to individual projects.

## Create a placement group

Placement groups require two configuration keys: `policy` and `rigor`.

### Policy options

**Spread policy**
: Distributes instances across different cluster members to maximize availability and distribute load.

**Compact policy**
: Co-locates instances on the same cluster member to minimize network latency and maximize resource sharing.

### Rigor options

**Strict rigor**
: Enforces the placement policy strictly. Instance creation fails if the policy cannot be satisfied.

**Permissive rigor**
: Attempts to follow the placement policy but allows fallback if constraints cannot be met.

### Create with spread policy

CLI

To create a placement group with a strict spread policy:

```none
lxc placement-group create my-pg-spread policy=spread rigor=strict
```

To create a placement group with a permissive spread policy that allows fallback:

```none
lxc placement-group create my-pg-spread policy=spread rigor=permissive
```

API

To create a placement group with a strict spread policy, send a POST request:

```none
lxc query --request POST /1.0/placement-groups --data '{
  "name": "my-pg-spread",
  "config": {
    "policy": "spread",
    "rigor": "strict"
  }
}'
```

To create a placement group with a permissive spread policy:

```none
lxc query --request POST /1.0/placement-groups --data '{
  "name": "my-pg-spread",
  "config": {
    "policy": "spread",
    "rigor": "permissive"
  }
}'
```

### Create with compact policy

CLI

To create a placement group with a strict compact policy:

```none
lxc placement-group create my-pg-compact policy=compact rigor=strict
```

To create a placement group with a permissive compact policy that allows fallback:

```none
lxc placement-group create my-pg-compact policy=compact rigor=permissive
```

API

To create a placement group with a strict compact policy, send a POST request:

```none
lxc query --request POST /1.0/placement-groups --data '{
  "name": "my-pg-compact",
  "config": {
    "policy": "compact",
    "rigor": "strict"
  }
}'
```

To create a placement group with a permissive compact policy:

```none
lxc query --request POST /1.0/placement-groups --data '{
  "name": "my-pg-compact",
  "config": {
    "policy": "compact",
    "rigor": "permissive"
  }
}'
```

## Assign instances to a placement group

### During instance creation

CLI

Specify the placement group when creating an instance:

```none
lxc launch ubuntu:24.04 my-instance -c placement.group=my-pg-spread
```

API

To create an instance with a placement group, send a POST request:

```none
lxc query --request POST /1.0/instances --data '{
  "name": "my-instance",
  "image": "ubuntu:24.04",
  "config": {
    "placement.group": "my-pg-spread"
  }
}'
```

### For existing instances

CLI

Add a placement group to an existing instance:

```none
lxc config set my-instance placement.group=my-pg-spread
```

API

To add a placement group to an existing instance, send a PATCH request:

```none
lxc query --request PATCH /1.0/instances/my-instance --data '{
  "config": {
    "placement.group": "my-pg-spread"
  }
}'
```

#### NOTE
Changing the placement group of an existing instance does not move the instance.
The new placement policy applies only to future LXD scheduling events (e.g., evacuation).

### Using profiles

CLI

Apply a placement group to all instances using a profile:

```none
lxc profile set default placement.group=my-pg-spread
```

API

To set a placement group on a profile, send a PATCH request:

```none
lxc query --request PATCH /1.0/profiles/default --data '{
  "config": {
    "placement.group": "my-pg-spread"
  }
}'
```

## View placement groups

### List placement groups

CLI

List all placement groups in the current project:

```none
lxc placement-group list
```

List placement groups from all projects:

```none
lxc placement-group list --all-projects
```

API

To retrieve all placement groups in a project, send a GET request:

```none
lxc query --request GET /1.0/placement-groups
```

To retrieve placement groups from all projects, send a GET request:

```none
lxc query --request GET /1.0/placement-groups?recursion=1&all-projects=true
```

### Show details of a placement group

CLI

View details of a specific placement group:

```none
lxc placement-group show my-pg-spread
```

The `used_by` field shows all instances and profiles referencing this placement group.

API

To retrieve details of a specific placement group, send a GET request:

```none
lxc query --request GET /1.0/placement-groups/my-pg-spread
```

The `used_by` field shows all instances and profiles referencing this placement group.

## Modify a placement group

### Edit interactively

CLI

Open the placement group configuration in your default editor:

```none
lxc placement-group edit my-pg-spread
```

API

To update the full placement group configuration, send a PUT request:

```none
lxc query --request PUT /1.0/placement-groups/my-pg-spread --data '<placement_group_configuration>'
```

### Update specific keys

CLI

Change the policy:

```none
lxc placement-group set my-pg-spread policy=compact
```

Change the rigor:

```none
lxc placement-group set my-pg-spread rigor=permissive
```

Get a configuration value:

```none
lxc placement-group get my-pg-spread policy
```

API

To update specific keys in a placement group, send a PATCH request:

```none
lxc query --request PATCH /1.0/placement-groups/my-pg-spread --data '{
  "config": {
    "policy": "compact",
    "rigor": "permissive"
  }
}'
```

To retrieve a specific configuration value, send a GET request and parse the response:

```none
lxc query --request GET /1.0/placement-groups/my-pg-spread
```

### Add user metadata

CLI

Add custom metadata to a placement group:

```none
lxc placement-group set my-pg-spread user.department=engineering
lxc placement-group set my-pg-spread user.cost-center=12345
```

API

To add custom metadata to a placement group, send a PATCH request:

```none
lxc query --request PATCH /1.0/placement-groups/my-pg-spread --data '{
  "config": {
    "user.department": "engineering",
    "user.cost-center": "12345"
  }
}'
```

## Rename a placement group

CLI

```bash
lxc placement-group rename my-pg-spread my-pg-ha
```

API

To rename a placement group, send a POST request:

```none
lxc query --request POST /1.0/placement-groups/my-pg-spread --data '{
  "name": "my-pg-ha"
}'
```

## Delete a placement group

CLI

```none
lxc placement-group delete my-pg-spread
```

To find what’s using a placement group before deletion:

```none
lxc placement-group show my-pg-spread | grep used_by
```

API

To delete a placement group, send a DELETE request:

```none
lxc query --request DELETE /1.0/placement-groups/my-pg-spread
```

To find what’s using a placement group before deletion:

```none
lxc query --request GET /1.0/placement-groups/my-pg-spread
```

#### NOTE
You cannot delete a placement group that is in use. Remove it from all instances and profiles first.

## Placement behavior

### During instance creation

When you create an instance with a placement group:

1. LXD filters cluster members according to the placement policy
2. From the filtered members, LXD selects the member with the fewest instances
3. If strict rigor is set and filtering returns no eligible members, instance creation fails
4. If permissive rigor is set and filtering returns no eligible members, LXD uses all available members

### Spread policy behavior

**Strict spread**
: Places at most one instance per cluster member

: Fails if there aren’t enough eligible members

**Permissive spread**
: Spreads instances as evenly as possible

: Ensures instance count per member differs by at most one

### Compact policy behavior

**Strict compact**
: Places all instances on the same cluster member

: When instances already exist, new instances are placed on the member with the most instances from the placement group

: Fails if the preferred member is unavailable

**Permissive compact**
: Prefers to place all instances on the same cluster member

: When instances already exist, new instances are placed on the member with the most instances from the placement group

: Allows fallback to other members if the preferred member is unavailable

#### NOTE
If instances in a compact placement group are distributed across multiple members (for example, due to manual placement with `--target`), LXD will prefer the member with the most instances from that placement group when placing new instances.

### During cluster evacuation

When evacuating a cluster member, LXD respects placement groups:

- **Spread policy**: Distributes evacuated instances across remaining members
- **Compact policy**: Attempts to keep instances from the same placement group together

If strict placement cannot be satisfied during evacuation, LXD falls back to the least-loaded member (unlike instance creation, which would fail).

## Troubleshooting

### Instance creation fails with strict rigor

If instance creation fails with a strict placement group:

1. Check available cluster members: `lxc cluster list`
2. Check instance distribution: `lxc list -c nL`
3. Consider using permissive rigor or adding more cluster members

## Related topics

- [Automatic placement of instances](../explanation/clusters.md#clustering-instance-placement)
- [Placement group configuration](../reference/placement_groups.md#ref-placement-groups)
- [`placement.group`](../reference/instance_options.md#instance-placement:placement.group)


# index.html.md

<a id="howto-storage-backup-volume"></a>

# How to back up custom storage volumes

There are different ways of backing up your custom storage volumes:

- [Use snapshots for volume backup](#storage-backup-snapshots)
- [Use export files for volume backup](#storage-backup-export)
- [Copy custom storage volumes](storage_move_volume.md#storage-copy-volume)

<!-- Include start backup types -->

Which method to choose depends both on your use case and on the storage driver you use.

In general, snapshots are quick and space efficient (depending on the storage driver), but they are stored in the same storage pool as the volume and therefore not too reliable.
Export files can be stored on different disks and are therefore more reliable.
They can also be used to restore the volume into a different storage pool.
If you have a separate, network-connected LXD server available, regularly copying volumes to this other server gives high reliability as well, and this method can also be used to back up snapshots of the volume.

<!-- Include end backup types -->

#### NOTE
Custom storage volumes might be attached to an instance, but they are not part of the instance.
Therefore, the content of a custom storage volume is not stored when you [back up your instance](instances_backup.md#instances-backup).
You must back up the data of your storage volume separately.

<a id="storage-backup-snapshots"></a>

## Use snapshots for volume backup

A snapshot saves the state of the storage volume at a specific time, which makes it easy to restore the volume to a previous state.
It is stored in the same storage pool as the volume itself.

<!-- Include start optimized snapshots -->

Most storage drivers support optimized snapshot creation (see [Feature comparison](../reference/storage_drivers.md#storage-drivers-features)).
For these drivers, creating snapshots is both quick and space-efficient.
For the `dir` driver, snapshot functionality is available but not very efficient.
For the `lvm` driver, snapshot creation is quick, but restoring snapshots is efficient only when using thin-pool mode.

<!-- Include end optimized snapshots -->

### Create a snapshot of a custom storage volume

CLI

Use the following command to create a snapshot for a custom storage volume:

```none
lxc storage volume snapshot <pool_name> <volume_name> [<snapshot_name>]
```

<!-- Include start create snapshot options -->

The snapshot name is optional.
If you don’t specify one, the name follows the naming pattern defined in `snapshots.pattern`.

Add the `--reuse` flag in combination with a snapshot name to replace an existing snapshot.

By default, snapshots are kept forever, unless the `snapshots.expiry` configuration option is set.
To retain a specific snapshot even if a general expiry time is set, use the `--no-expiry` flag.

<!-- Include end create snapshot options -->

UI

To create a snapshot of a custom storage volume, navigate to the Snapshots tab for the target volume and click Create snapshot.

![LXD Storage Volumes - Snapshots tab](images/storage/storage_volumes_snapshots_tab.png)

In the modal that appears, you can provide the snapshot with a name and expiry date and time. If the name is left blank, a name is automatically assigned to the snapshot based on the global snapshot configuration. If the expiry date and time are left blank, the snapshot does not expire.

![LXD Storage Volumes - Create snapshot](images/storage/storage_volumes_snapshots_create.png)

<a id="storage-edit-snapshots"></a>

### View, edit or delete snapshots

CLI

Use the following command to display the snapshots for a storage volume:

```none
lxc storage volume info <pool_name> <volume_name>
```

You can view or modify snapshots in a similar way to custom storage volumes, by referring to the snapshot with `<volume_name>/<snapshot_name>`.

To show information about a snapshot, use the following command:

```none
lxc storage volume show <pool_name> <volume_name>/<snapshot_name>
```

To edit a snapshot (for example, to add a description or change the expiry date), use the following command:

```none
lxc storage volume edit <pool_name> <volume_name>/<snapshot_name>
```

To delete a snapshot, use the following command:

```none
lxc storage volume delete <pool_name> <volume_name>/<snapshot_name>
```

UI

To view, edit or delete a storage volume snapshot, navigate to the Snapshots tab for the target volume.

Hover over a snapshot row to highlight possible actions, including edit, restore and delete.

![LXD Storage Volumes - Snapshots list](images/storage/storage_volumes_snapshots_list.png)

### Schedule snapshots of a custom storage volume

CLI

You can configure a custom storage volume to automatically create snapshots at specific times.
To do so, set the `snapshots.schedule` configuration option for the storage volume (see [Configure storage volume settings](storage_volumes.md#storage-configure-volume)).

For example, to configure daily snapshots, use the following command:

```none
lxc storage volume set <pool_name> <volume_name> snapshots.schedule @daily
```

To configure taking a snapshot every day at 6 am, use the following command:

```none
lxc storage volume set <pool_name> <volume_name> snapshots.schedule "0 6 * * *"
```

When scheduling regular snapshots, consider setting an automatic expiry (`snapshots.expiry`) and a naming pattern for snapshots (`snapshots.pattern`).
See the [Storage drivers](../reference/storage_drivers.md#storage-drivers) documentation for more information about those configuration options.

UI

To schedule a snapshot of a storage volume, navigate to the Overview tab of the target volume. Select the Snapshots tab and click See configuration.

![LXD Storage Volumes - Snapshots list](images/storage/storage_volumes_snapshots_configuration.png)

In the resulting modal, you can override the default schedule for automatic volume snapshots. Select the time frame via the [Cron expression syntax](https://en.wikipedia.org/wiki/Cron#Cron_expression) or a time interval.

### Restore a snapshot of a custom storage volume

CLI

You can restore a custom storage volume to the state of any of its snapshots.

To do so, you must first stop all instances that use the storage volume.
Then use the following command:

```none
lxc storage volume restore <pool_name> <volume_name> <snapshot_name>
```

You can also restore a snapshot into a new custom storage volume, either in the same storage pool or in a different one (even a remote storage pool).
To do so, use the following command:

```none
lxc storage volume copy <source_pool_name>/<source_volume_name>/<source_snapshot_name> <target_pool_name>/<target_volume_name>
```

UI

To restore a storage volume, navigate to the Snapshots tab for the target volume, then hover over a snapshot row to view possible actions. Click the restore button.

<a id="storage-backup-export"></a>

## Use export files for volume backup

You can export the full content of your custom storage volume to a standalone file that can be stored at any location.
For highest reliability, store the backup file on a different file system to ensure that it does not get lost or corrupted.

### Export a custom storage volume

CLI

Use the following command to export a custom storage volume to a compressed file (for example, `/path/to/my-backup.tgz`):

```none
lxc storage volume export <pool_name> <volume_name> [<file_path>]
```

If you do not specify a file path, the export file is saved as `backup.tar.gz` in the working directory.

#### WARNING
If the output file already exists, the command overwrites the existing file without warning.

<!-- Include start export info -->

You can add any of the following flags to the command:

`--compression`
: By default, the output file uses `gzip` compression.
  You can specify a different compression algorithm (for example, `bzip2`) or turn off compression with `--compression=none`.

`--optimized-storage`
: If your storage pool uses the `btrfs` or the `zfs` driver, add the `--optimized-storage` flag to store the data as a driver-specific binary blob instead of an archive of individual files.
  In this case, the export file can only be used with pools that use the same storage driver.
  <br/>
  Exporting a volume in optimized mode is usually quicker than exporting the individual files.
  Snapshots are exported as differences from the main volume, which decreases their size (quota) and makes them easily accessible.

`--export-version`
: If you intend to import the backup to an older version of LXD, set the version to `1` which will use the original (old) backup metadata format.
  Backups using the old format can always be imported on newer versions of LXD.
  If the flag is not specified and the server has support for the `backup_metadata_version` API extension, version `2` is used by default.

<!-- Include end export info -->

`--volume-only`
: By default, the export file contains all snapshots of the storage volume.
  Add this flag to export the volume without its snapshots.

UI

To export a storage volume, navigate to the Overview tab for the target volume and select the Export button.

In the resulting modal, configure the export file for the storage volume, including its compression mode and expiration.

![LXD Storage Volumes - Export Volume](images/storage/storage_volumes_export.png)

### Restore a custom storage volume from an export file

CLI

You can import an export file (for example, `/path/to/my-backup.tgz`) as a new custom storage volume.
To do so, use the following command:

```none
lxc storage volume import <pool_name> <file_path> [<volume_name>]
```

If you do not specify a volume name, the original name of the exported storage volume is used for the new volume.
If a volume with that name already (or still) exists in the specified storage pool, the command returns an error.
In that case, either delete the existing volume before importing the backup or specify a different volume name for the import.

UI

To restore a storage volume from an export file, select Volumes from the main navigation, then click the Create volume button.

Choose the volume file to upload, and select the storage pool for the volume to be created using the export file.

![LXD Storage Volumes - Upload Volume](images/storage/storage_volumes_import.png)


# index.html.md

<a id="cluster-manage"></a>

# How to manage a cluster

After your cluster is formed, use [`lxc cluster list`](../reference/manpages/lxc/cluster/list.md#lxc-cluster-list-md) to see a list of its members and their status. Example output:

`user@host:~$ ``lxc cluster list
`
```text

+---------+----------------------------+------------------+--------------+----------------+-------------+--------+-------------------+
| NAME    |            URL             |      ROLES       | ARCHITECTURE | FAILURE DOMAIN | DESCRIPTION | STATE  |      MESSAGE      |
+---------+----------------------------+------------------+--------------+----------------+-------------+--------+-------------------+
| server1 | https://192.0.2.101:8443   | database-leader  | x86_64       | default        |             | ONLINE | Fully operational |
+---------+----------------------------+------------------+--------------+----------------+-------------+--------+-------------------+
| server2 | https://192.0.2.102:8443   | database-voter   | aarch64      | default        |             | ONLINE | Fully operational |
+---------+----------------------------+------------------+--------------+----------------+-------------+--------+-------------------+
| server3 | https://192.0.2.103:8443   | database-standby | aarch64      | default        |             | ONLINE | Fully operational |
+---------+----------------------------+------------------+--------------+----------------+-------------+--------+-------------------+
```

To see more detailed information about an individual cluster member, run the following command:

```none
lxc cluster show <member_name>
```

To see state and usage information for a cluster member, run the following command:

```none
lxc cluster info <member_name>
```

## Configure your cluster

To configure your cluster, use [`lxc config`](../reference/manpages/lxc/config.md#lxc-config-md):

```none
lxc config set <server-config-option> <value>
```

Example:

```none
lxc config set cluster.max_voters 5
```

All LXD [server configuration options](../server.md#server) can be applied to cluster members.

Keep in mind that some options are global in scope, and others are local. When you configure an option with global scope on any cluster member, the changes are propagated to the other cluster members through the distributed database. The locally scoped options are set only on the cluster member where you configure them, unless you use the `--target` flag to specify a different cluster member.

In addition to the server configuration, there are [cluster member configuration options](../reference/cluster_member_config.md#cluster-member-config) that are specific to each cluster member. To set these configuration values, use [`lxc cluster set`](../reference/manpages/lxc/cluster/set.md#lxc-cluster-set-md):

```none
lxc cluster set <member-name> <member-config-option> <value>
```

Example:

```none
lxc cluster set server1 scheduler.instance manual
```

Alternatively, you can use the [use the edit command](#cluster-edit).

### Assign member roles

To add or remove a [member role](../explanation/clusters.md#clustering-member-roles) for a cluster member, use the [`lxc cluster role`](../reference/manpages/lxc/cluster/role.md#lxc-cluster-role-md) command:

```none
lxc cluster role add <member-name> <role>
```

Example:

```none
lxc cluster role add server1 control-plane
```

#### NOTE
You can add or remove only those roles that are not assigned automatically by LXD. Database roles (`database-voter`, `database-standby`, `database-leader`) are automatically assigned and cannot be added or removed manually.

To find out more about which roles are automatically assigned, see: [Member roles](../explanation/clusters.md#clustering-member-roles).

<a id="cluster-manage-control-plane"></a>

### Use control plane mode

The `control-plane` role is useful for auto-scaling clusters where you want fixed database members and dynamic worker members. To use it:

1. Assign the role to at least 3 members:
   ```none
   lxc cluster role add <member1> control-plane
   lxc cluster role add <member2> control-plane
   lxc cluster role add <member3> control-plane
   ```
2. Verify activation by running `lxc cluster list` — only members with the `control-plane` role will display database roles.
3. New members join the cluster as spares by default. To make them eligible for database roles, assign the `control-plane` role to them.

You can assign `control-plane` to more members than [`cluster.max_voters`](../server.md#server-cluster:cluster.max_voters) to create a pool of eligible candidates. For example, having 5 `control-plane` members when [`cluster.max_voters`](../server.md#server-cluster:cluster.max_voters) is 3 means 3 of the 5 candidates become voters. If one of the voters becomes unavailable, one of the remaining two candidates takes its place.

For more information, see: [Control plane mode](../explanation/clusters.md#clustering-control-plane).

<a id="cluster-manage-failure-domains"></a>

### Manage failure domains

To manage the [failure domain](../explanation/clusters.md#clustering-failure-domains) for a cluster member, use the [`lxc cluster failure-domain`](../reference/manpages/lxc/cluster/failure-domain.md#lxc-cluster-failure-domain-md) command:

```none
lxc cluster failure-domain set <member-name> <domain>
```

Example:

```none
lxc cluster failure-domain set server1 rack1
```

To view the current failure domain:

```none
lxc cluster failure-domain get <member-name>
```

To reset the failure domain to the default:

```none
lxc cluster failure-domain unset <member-name>
```

<a id="cluster-edit"></a>

### Edit the cluster member configuration

To edit all properties of a cluster member, including the member-specific configuration, the member roles, the failure domain and the cluster groups, use the following command:

```none
lxc cluster edit
```

For more information, see: [`lxc cluster edit`](../reference/manpages/lxc/cluster/edit.md#lxc-cluster-edit-md).

<a id="cluster-evacuate-restore"></a>

## Evacuate and restore cluster members

There are scenarios where you might need to empty a given cluster member of all its instances (for example, for routine maintenance like applying system updates that require a reboot, or to perform hardware changes). The [evacuate](#cluster-evacuate) and [restore](#cluster-restore) commands simplify this process.

<a id="cluster-evacuate"></a>

### Evacuate a cluster member

The evacuation process migrates all instances on a given cluster member to other members in its cluster. The given member is then set to an “evacuated” state, which prevents the creation of any instances on it.

To begin this process, use the [`lxc cluster evacuate`](../reference/manpages/lxc/cluster/evacuate.md#lxc-cluster-evacuate-md) command:

```none
lxc cluster evacuate <member_name>
```

Use `--yes` to skip the confirmation prompt.
Use `--force` only if you want to permit evacuation even when it would leave too few online Raft voters to maintain quorum.

<a id="cluster-restore"></a>

### Restore an evacuated cluster member

When the evacuated cluster member is available again, use the [`lxc cluster restore`](../reference/manpages/lxc/cluster/restore.md#lxc-cluster-restore-md) command to return it to a normal running state:

```none
lxc cluster restore <member_name>
```

This command removes the cluster member’s “evacuated” state, migrates the evacuated instances back from the cluster members that were temporarily holding them (using live migration if applicable), then restarts any instances that were shut down.

<a id="cluster-evacuation-mode"></a>

### Evacuation mode and live migration

You can control how each instance is migrated, via the [`cluster.evacuate`](../reference/instance_options.md#instance-miscellaneous:cluster.evacuate) instance configuration key. This key applies to the migrations performed during both evacuation and restoration. By default, any instances that are suitable for [live migration](instances_migrate.md#live-migration) will be live-migrated, and any that are not suitable will be shut down. See the [`cluster.evacuate`](../reference/instance_options.md#instance-miscellaneous:cluster.evacuate) reference documentation for further information.

If you force `cluster.evacuate=live-migrate`, LXD attempts live migration for all instances on the member. Live migration is supported for virtual machines only. If no target member is available for an instance, that instance is skipped. If a live migration attempt fails (for example, when trying to live-migrate a container), the evacuation operation fails.

If an instance is not suitable for live migration, it will be shut down cleanly before evacuation, respecting the [`boot.host_shutdown_timeout`](../reference/instance_options.md#instance-boot:boot.host_shutdown_timeout) configuration key.

#### NOTE
Any instance that you plan to live-migrate must have its [`migration.stateful`](../reference/instance_options.md#instance-migration:migration.stateful) configuration option set to `true`. Be aware that this option can only be set while the instance is stopped. Thus, for any instance to have the ability to be live-migrated in the future, this option must be set to `true` ahead of time.

<a id="cluster-healing"></a>

<a id="cluster-automatic-evacuation"></a>

## Cluster healing

To enable cluster healing, set the [`cluster.healing_threshold`](../server.md#server-cluster:cluster.healing_threshold) configuration to a non-zero value (in seconds). If a cluster member is offline for longer than this threshold, LXD automatically sets its state to “evacuated” and starts its instances on another member. This behavior only applies to instances that use shared storage and have no local devices attached.

Syntax:

```bash
lxc config set cluster.healing_threshold <value in seconds>
```

When the healed cluster member is available again, you must manually [restore](#cluster-restore) it to remove its “evacuated” state and return instances to it.

#### WARNING
Enabling the cluster healing threshold carries the risk that LXD might incorrectly judge a cluster member as offline while it is still running workloads. Short-lived network issues or temporary high load might cause a cluster member to briefly stop responding to heartbeat or ICMP packets. If a healing threshold is set, LXD might then start that member’s instances on another cluster member even though they’re still active on the original. Since cluster members share the same storage, this can lead to data corruption.

To avoid this, it’s critical to ensure that any server marked as offline is actually offline and not still running instances. You can automate this by monitoring for `cluster-member-healed` events and shutting off the affected server through its remote power interface, such as a Baseboard Management Controller (BMC) or Power Distribution Unit (PDU).

To reduce the chance of false healing events, set [`cluster.healing_threshold`](../server.md#server-cluster:cluster.healing_threshold) as high as possible within your availability targets.

<a id="cluster-manage-delete-members"></a>

## Delete cluster members

To cleanly delete a member from the cluster, use the following command:

```none
lxc cluster remove <member_name>
```

You can only cleanly delete members that are online and that don’t have any instances located on them.

### Deal with offline cluster members

If a cluster member goes permanently offline, you can force-remove it from the cluster.
Make sure to do so as soon as you discover that you cannot recover the member.
If you keep an offline member in your cluster, you might encounter issues when upgrading your cluster to a newer version.

To force-remove a cluster member, enter the following command on one of the cluster members that is still online:

```none
lxc cluster remove --force <member_name>
```

<a id="howto-cluster-manage-update-upgrade"></a>

## Update or upgrade cluster members

To update or upgrade a cluster, you must perform the same operation on all of its members, ensuring that they all use the same version of LXD.

To update or upgrade the cluster, you must apply the change to each cluster member’s LXD installation. If you are using the snap, see [Manage updates](snap.md#howto-snap-updates) for update instructions about updates, and [Change the snap channel](snap.md#howto-snap-change) for upgrade instructions.

If the new version of the daemon has database schema or API changes, the upgraded member might transition into a “blocked” state.
In this case, the member does not serve any LXD API requests (which means that `lxc` commands don’t work on that member anymore), but any running instances will continue to run.

This happens if there are other cluster members that have not been updated or upgraded, resulting in mismatched versions.
Run [`lxc cluster list`](../reference/manpages/lxc/cluster/list.md#lxc-cluster-list-md) on a cluster member that is not blocked to see if any members are blocked.

As you proceed updating or upgrading the rest of the cluster members, they will all transition to the “blocked” state.
When you update or upgrade the last member, the blocked members will notice that all LXD versions now match, and the blocked members become operational again.

## Update the cluster certificate

In a LXD cluster, the API on all servers responds with the same shared certificate, which is usually a standard self-signed certificate with an expiry set to ten years.

The certificate is stored at `/var/snap/lxd/common/lxd/cluster.crt` (if you use the snap) or `/var/lib/lxd/cluster.crt` (otherwise) and is the same on all cluster members.

You can replace the standard certificate with another one, such as a valid certificate obtained through ACME services (see [TLS server certificate](../authentication.md#authentication-server-certificate) for more information).
To do so, run the following command on any cluster member:

```none
lxc cluster update-certificate
```

This command replaces the certificate on all cluster members. For more information, see: [`lxc cluster update-certificate`](../reference/manpages/lxc/cluster/update-certificate.md#lxc-cluster-update-certificate-md).


# index.html.md

<a id="access-ui"></a>

# How to access the LXD web UI

#### NOTE
The LXD web UI is available as part of the LXD snap.

See the [LXD-UI GitHub repository](https://github.com/canonical/lxd-ui) for the source code.

![Graphical console of an instance in the LXD web UI](images/UI/console.png)
            <p class="youtube_link">
              <a href="https://www.youtube.com/watch?v=wqEH_d8LC1k" target="_blank">
                <span title="Early look at the LXD web UI" class="play_icon">▶</span>
                <span title="Early look at the LXD web UI">Watch on YouTube</span>
              </a>
            </p>
        
The LXD web UI provides you with a graphical interface to manage your LXD server and instances.
It does not provide full functionality yet, but it is constantly evolving, already covering many of the features of the LXD command-line client.

Complete the following steps to access the LXD web UI:

<a id="access-ui-expose"></a>

## Expose the server to the network

Make sure that your LXD server is [exposed to the network](server_expose.md#server-expose).
You can expose the server during [initialization](initialize.md#initialize), or afterwards by setting the [`core.https_address`](../server.md#server-core:core.https_address) server configuration option.

<a id="access-ui-browser"></a>

## Access the UI in your browser

Access the UI in your browser by entering the server address (for example, [`https://127.0.0.1:8443`](https://127.0.0.1:8443) for a local server, or an address like `https://192.0.2.10:8443` for a server running on `192.0.2.10`).

If you have already set up access to the UI, you will see the Instances page. For setup instructions, continue below.

<a id="access-ui-setup"></a>

## Set up access

Access to the UI can be obtained in two ways:

- Initial access via a UI access link (bearer token, valid for 1 day).
- Permanent access using a browser certificate and trust token.

<a id="access-ui-setup-initial-access-link"></a>

### UI access using initial link

The `lxd init` command guides you through the LXD initialization process.
When the server address is configured during the initialization process, LXD offers an option to generate an initial UI access link. If you agree with that option, an initial LXD UI access URL that is valid for 24 hours is printed at the end of the process, as shown below.

```bash
...
Would you like the LXD server to be available over the network? (yes/no) [default=no]: yes
Address to bind LXD to (not including port) [default=all]:
Port to bind LXD to [default=8443]:
Would you like to create an initial LXD UI access link? (yes/no) [default=no]: yes
...
UI initial identity (type: Initial UI token bearer): ui-admin-initial
UI initial access link (expires: 2026-01-17 16:36): https://127.0.0.1:8443/?token=<bearer_token>
```

Open this URL in your browser to immediately access the UI as an admin.
This method is intended for initial access and setup only. After logging in, configure the permanent authentication (mTLS or OIDC) for continued access.

To obtain a new initial UI access link, run `lxd init` again.
For convenience, the `--ui-initial-access-link` flag can be used to non-interactively generate a new one.

```bash
lxd init --ui-initial-access-link
```

<a id="access-ui-setup-certificate"></a>

### Permanent UI access using browser certificate

Permanent access to the UI requires both a browser certificate and a trust token.

<!-- Include start access UI -->

If you have not set up a secure [TLS server certificate](../authentication.md#authentication-server-certificate), LXD uses a self-signed certificate, which will cause a security warning in your browser. Use your browser’s mechanism to continue this time despite the security warning.

For example, in Chrome, click **Advanced**, then follow the link to **Proceed** at the bottom as shown below:

![Example for a security warning in Chrome](images/ui_security_warning.png)

In Firefox, click **Advanced**, then follow the link to **Accept the risk and continue**.

#### Set up the browser certificate

Follow the instructions in the LXD UI browser page to install and select the browser certificate, also called a client certificate.

If you have previously installed a certificate for the LXD UI, your browser will offer you the option to use it. Confirm that the installed certificate’s issuer is listed in the LXD UI, then select it.

After you have selected your certificate, follow the LXD UI’s on-page instructions to set up the trust token.

Finally, click Connect in the UI to complete gaining access. You should then see the Instances page.

<!-- Include end access UI -->

Now you can start creating instances, editing profiles, or configuring your server.

For detailed information about the authentication process, see: [Remote API authentication](../authentication.md#authentication).


# index.html.md

<a id="howto-snap"></a>

# How to manage the LXD snap

The recommended way to manage LXD is its [snap package](https://snapcraft.io/lxd).

For the installation guide, see: [Install the LXD snap package](../installing.md#installing-snap-package). For details about the LXD snap, including its [channels](../reference/releases-snap.md#ref-snap-channels), [tracks](../reference/releases-snap.md#ref-snap-tracks), and [release processes](../reference/releases-snap.md#ref-releases), see: [Releases and snap](../reference/releases-snap.md#ref-releases-snap).

<a id="howto-snap-info"></a>

## View snap information

To view information about the LXD snap, including the available channels and installed version, run:

```bash
snap info lxd
```

To view information about the installed version only, run:

```bash
snap list lxd
```

Sample output:

`root@instance:~# ``snap list lxd
`
```text
Name  Version         Rev    Tracking     Publisher   Notes
lxd   5.21.3-c5ae129  33110  5.21/stable  canonical✓  -
```

The first part of the version string corresponds to the LXD release (in this sample, `5.21.3`).

<a id="howto-snap-updates-upgrades"></a>

## Updates versus upgrades

[Updates](../reference/releases-snap.md#ref-snap-updates) of the LXD snap occur within the same channel, whereas [upgrades](../reference/releases-snap.md#ref-snap-upgrades) refer to [changing the tracked snap channel](#howto-snap-change) to use a newer track.

For details, see our [Updates and upgrades](../reference/releases-snap.md#ref-snap-updates-upgrades) reference guide, including its section on [Downgrades](../reference/releases-snap.md#ref-snap-downgrades).

<a id="howto-snap-updates"></a>

## Manage updates

When LXD is [installed as a snap](../installing.md#installing-snap-package), it begins tracking the specified snap channel, or the most recent stable LTS track if not specified. Whenever a new version is published to that channel, the LXD version on your system automatically updates.

For control over the update schedule, use either of the following approaches:

- [Schedule updates with the refresh timer](#howto-snap-updates-schedule).
- [Hold updates](#howto-snap-updates-hold) and perform [Manual updates](#howto-snap-updates-manual) as needed.

For clustered LXD installations, also follow the instructions below to [synchronize updates for cluster members](#howto-snap-updates-sync).

For more information about snap updates in general, see the Snap documentation: [Manage updates](https://snapcraft.io/docs/how-to-guides/manage-snaps/manage-updates/#how-to-guides-work-with-snaps-manage-updates).

<a id="howto-snap-updates-schedule"></a>

### Schedule updates with the refresh timer

Snaps can use a refresh timer to regularly update snaps at specific times.
This enables you to schedule automatic updates during times that don’t disturb normal operation. The `refresh.timer` option is set system-wide; you cannot set it for the LXD snap only. It does not apply to snaps that are held indefinitely.

For example, to configure your system to update snaps only between 8:00 am and 9:00 am on Mondays, set the following option:

```bash
  sudo snap set system refresh.timer=mon,8:00-9:00
```

You can also use the `refresh.hold` option to hold all snap updates for up to 90 days, after which they automatically update.

For details on how to use the `refresh.timer` and `refresh.hold` options, see the Snap documentation: [Manage updates](https://snapcraft.io/docs/how-to-guides/manage-snaps/manage-updates/#how-to-guides-work-with-snaps-manage-updates).

<a id="howto-snap-updates-hold"></a>

### Hold updates

You can hold snap updates for the LXD snap, either indefinitely or for a specific duration. If you want to fully control updates to your LXD snap, you should set up an indefinite hold.

To indefinitely hold updates, run:

```bash
sudo snap refresh --hold lxd
```

Then you can perform [manual updates](#howto-snap-updates-manual) on a schedule that you control.

The [Manage updates](https://snapcraft.io/docs/how-to-guides/manage-snaps/manage-updates/#how-to-guides-work-with-snaps-manage-updates) page in the Snap documentation provides details about how to pause or stop automatic updates.

<a id="howto-snap-updates-manual"></a>

### Manual updates

For an LXD snap installed as part of a cluster, see the section on [synchronizing cluster updates](#howto-snap-updates-sync) below.

Otherwise, run:

```bash
sudo snap refresh lxd
```

This updates your LXD snap to the latest release within its channel.

<a id="howto-snap-updates-sync"></a>

### Synchronize updates for a LXD cluster cohort

All [LXD cluster members](../explanation/clusters.md#exp-clusters) must run the same LXD version, and ideally the same snap revision of the version. To synchronize updates, set the `--cohort="+"` flag on all cluster members.

You only need to set this flag once per LXD snap. This can occur during [installation](../installing.md#installing-snap-package), or the first time you [perform a manual update](#howto-snap-updates-manual).

To set this flag during installation:

```bash
sudo snap install lxd --cohort="+"
```

To set this flag later, during a manual update:

```bash
sudo snap refresh lxd --cohort="+"
```

After you set this flag, `snap list lxd` shows `in-cohort` in the `Notes` column. Example:

`root@instance:~# ``snap list lxd
`
```text
Name  Version         Rev    Tracking     Publisher   Notes
lxd   5.21.3-c5ae129  33110  5.21/stable  canonical✓  in-cohort
```

Subsequent updates to this snap automatically use the `--cohort="+"` flag, even if you [change its channel](#howto-snap-change) or use automated or [scheduled](#howto-snap-updates-schedule) updates. Thus, once the snap is `in-cohort`, you can omit that flag for future updates.

### Manage updates with an Enterprise Store proxy

If you manage a large LXD cluster and require absolute control over when updates are applied, consider using the [Enterprise Store](https://ubuntu.com/enterprise-store/docs/). This proxy application sits between your machines’ snap clients and the Snap Store, giving you control over which snap revisions are available for installation.

To get started, follow the Enterprise Store documentation to [install](https://ubuntu.com/enterprise-store/docs/how-to/install/) and [register](https://ubuntu.com/enterprise-store/docs/how-to/register/) the service. Once it’s running, configure all cluster members to use the proxy; see [Configure devices](https://ubuntu.com/enterprise-store/docs/how-to/devices/) for instructions. You can then [override the revision](https://ubuntu.com/enterprise-store/docs/how-to/overrides/) for the LXD snap to control which version is installed:

```bash
sudo enterprise-store override lxd <channel>=<revision>
```

Example:

```bash
sudo enterprise-store override lxd stable=25846
```

<a id="howto-snap-change"></a>

## Change the snap channel

You can change the tracked channel’s [track](../reference/releases-snap.md#ref-snap-tracks), its [risk level](../reference/releases-snap.md#ref-snap-risk), or both. A change to a higher track is considered an [upgrade](../reference/releases-snap.md#ref-snap-upgrades).

Downgrading is not supported from higher to lower tracks, and neither is changing from a higher to a lower risk level in the [latest](../reference/releases-snap.md#ref-snap-tracks-latest) or [current feature](../reference/releases-snap.md#ref-snap-track-feature) track. For details, see: [Downgrades](../reference/releases-snap.md#ref-snap-downgrades).

To change the [channel](../reference/releases-snap.md#ref-snap-channels) and immediately use the most recent release in the target channel, run:

```bash
sudo snap refresh lxd --channel=<target channel> [--cohort="+"]
```

Include the optional `--cohort="+"` flag only for cluster members who have not previously set this flag before. See: [Synchronize updates for a LXD cluster cohort](#howto-snap-updates-sync).

If you upgrade LXD on cluster members, all members must be upgraded to the same version. For details, see: [Update or upgrade cluster members](cluster_manage.md#howto-cluster-manage-update-upgrade).

### Examples

If your current channel is `6/stable`, the following command changes the [risk level](../reference/releases-snap.md#ref-snap-risk) only:

```bash
sudo snap refresh lxd --channel=6/edge
```

If your current channel is `5.21/edge`, the following command upgrades LXD to the `6/stable` channel:

```bash
sudo snap refresh lxd --channel=6/stable
```

<a id="howto-snap-configure"></a>

## Configure the snap

The LXD snap has several configuration options that control the behavior of the installed LXD server.
For example, you can define a LXD user group to achieve a multi-user environment for LXD. For more information, see: [Confine users to specific LXD projects via Unix socket](projects_confine.md#projects-confine-users).

See the [LXD snap page](https://snapcraft.io/lxd) for a list of available configuration options.

To set any of these options, run:

```bash
sudo snap set lxd <key>=<value>
```

Example:

```bash
sudo snap set lxd daemon.user.group=lxd-users
```

To see all configuration options that are explicitly set on the snap, run:

```bash
sudo snap get lxd
```

For more information about snap configuration options, visit [Configure snaps](https://snapcraft.io/docs/how-to-guides/manage-snaps/configure-snaps/#how-to-guides-work-with-snaps-configure-snaps) in the Snap documentation.

<a id="howto-snap-daemon"></a>

## Manage the LXD daemon

Installing LXD as a snap creates the LXD daemon as a **snap service**. Use the following `snap` commands to manage this daemon.

To view the status of the daemon, run:

```bash
snap services lxd
```

To stop the daemon, run:

```bash
sudo snap stop lxd
```

Stopping the daemon also stops all running LXD instances.

To start the LXD daemon, run:

```bash
sudo snap start lxd
```

Starting the daemon also starts all previously running LXD instances.

To restart the daemon, run:

```bash
sudo snap restart lxd
```

This also stops and starts all running LXD instances. To keep the instances running as you restart the daemon, use the `--reload` flag:

```bash
sudo snap restart --reload lxd
```

For more information about managing snap services, visit [Control services](https://snapcraft.io/docs/how-to-guides/manage-snaps/control-services/#how-to-guides-manage-snaps-control-services) in the Snap documentation.

## Related topics

How-to guide:

- [Install the LXD snap package](../installing.md#installing-snap-package)
- [Track a bugfix in the LXD snap](snap_track_fix.md#snap-track-bugfix)

Reference:

- [Releases and snap](../reference/releases-snap.md#ref-releases-snap)


# index.html.md

<a id="howto-storage-move-volume"></a>

# How to move or copy storage volumes

You can [copy](#storage-copy-volume) or [move](#storage-move-volume) custom storage volumes from one storage pool to another, or copy or rename them within the same storage pool.

To move instance storage volumes from one storage pool to another, [move the corresponding instance](#storage-move-instance) to another pool.

When copying or moving a volume between storage pools that use different drivers, the volume is automatically converted.

<a id="storage-copy-volume"></a>

## Copy custom storage volumes

CLI

Use the following command to copy a custom storage volume:

```none
lxc storage volume copy <source_pool_name>/<source_volume_name> <target_pool_name>/<target_volume_name>
```

Add the `--volume-only` flag to copy only the volume and skip any snapshots that the volume might have.
If the volume already exists in the target location, use the `--refresh` flag to update the copy (see [Optimized volume transfer](../reference/storage_drivers.md#storage-optimized-volume-transfer) for the benefits).

Specify the same pool as the source and target pool to copy the volume within the same storage pool.
You must specify different volume names for source and target in this case.

When copying from one storage pool to another, you can either use the same name for both volumes or rename the new volume.

UI

To copy a custom storage volume, navigate to the Overview page of the storage volume you wish to copy, and click Copy.

![LXD Custom Storage Volume overview page](images/storage/storage_volumes_overview.png)

In the Copy volume modal, you can define a new name for the copied volume as well as a number of other attributes.

![LXD Custom Storage Volume copy volume modal](images/storage/storage_volumes_copy_modal.png)

<a id="storage-move-volume"></a>

## Move or rename custom storage volumes

CLI

Before you can move or rename a custom storage volume, all instances that use it must be [stopped](instances_manage.md#instances-manage-stop).

Use the following command to move or rename a storage volume:

```none
lxc storage volume move <source_pool_name>/<source_volume_name> <target_pool_name>/<target_volume_name>
```

Specify the same pool as the source and target pool to rename the volume while keeping it in the same storage pool.
You must specify different volume names for source and target in this case.

When moving from one storage pool to another, you can either use the same name for both volumes or rename the new volume.

UI

To rename a custom storage volume, navigate to its Overview page and select its name in the header to edit it.

![LXD Rename Custom Storage Volume](images/storage/storage_volumes_rename.png)

<a id="howto-storage-move-volume-cluster"></a>

## Copy or migrate between cluster members

CLI

For most storage drivers (except for `ceph` and `ceph-fs`), storage volumes exist only on the cluster member for which they were created.

To copy or migrate a custom storage volume from one cluster member to another, add the `--target` and `--destination-target` flags to specify the source cluster member and the target cluster member, respectively.

UI

You can use the LXD UI to copy storage volumes between cluster members, but not to migrate them.

To copy a storage volume, navigate to the Overview page of the storage volume within a clustered environment, then click Copy.

In the Copy volume modal, select the target cluster member from the Cluster member dropdown.

## Copy or move between projects

CLI

Add the `--target-project` to copy or move a custom storage volume to a different project.

UI

To copy a storage volume between projects, navigate to the Overview page of the storage volume, then click Copy.

In the Copy volume modal, select the target from the Target project dropdown.

## Copy or migrate between LXD servers

You can copy a custom volume from one LXD server to another, or migrate it (move it between servers), by specifying the remote for each pool:

```none
lxc storage volume copy <source_remote>:<source_pool_name>/<source_volume_name> <target_remote>:<target_pool_name>/<target_volume_name>
lxc storage volume move <source_remote>:<source_pool_name>/<source_volume_name> <target_remote>:<target_pool_name>/<target_volume_name>
```

You can add the `--mode` flag to choose a transfer mode, depending on your network setup:

`pull` (default)
: Instruct the target server to pull the respective storage volume.

`push`
: Push the storage volume from the source server to the target server.

`relay`
: Pull the storage volume from the source server to the local client, and then push it to the target server.

If the volume already exists in the target location, use the `--refresh` flag to update the copy (see [Optimized volume transfer](../reference/storage_drivers.md#storage-optimized-volume-transfer) for the benefits).

<a id="storage-move-instance"></a>

## Move instance storage volumes to another pool

To move an instance storage volume to another storage pool, [stop the instance](instances_manage.md#instances-manage-stop) that contains the storage volume you want to move.

CLI

Use the following command to move the instance to a different pool:

```none
lxc move <instance_name> --storage <target_pool_name>
```

UI

Navigate to the overview page of the selected instance, and click on the Migrate button in the top right corner.

![LXD Instance overview page](images/instances/instance_overview_page.png)

Within the move modal, click Move instance root storage to a different pool to view available storage pools to move to.

![LXD Instance root storage move method modal](images/instances/move_instance_modal.png)

Click Select in the row of the target storage pool for the move.

![LXD Instance root storage move pool selection modal](images/instances/move_instance_modal_2.png)

On the resulting confirmation modal, click Move to finalize the process.

![LXD Instance root storage confirmation modal](images/instances/move_confirmation_modal.png)


# index.html.md

<a id="oidc-auth0"></a>

# How to configure Auth0 as login method for the LXD UI and CLI

Auth0 is a flexible, drop-in solution to add authentication and authorization services to your applications. Auth0 supports OIDC and can be used to authenticate users for the LXD UI and CLI. This guide shows you how to set up Auth0.com as the login method for the LXD UI and CLI.

## Using Auth0.com to access LXD

1. Open a free account on [Auth0.com](https://auth0.com/).
2. Once logged into the Auth0 web interface, select Applications > Applications in the side panel.
   - You need to create two applications. One is for the LXD UI and the other is for the LXD CLI.
3. First, create an application that will be used for authentication in the LXD UI by selecting + Create Application.
   - Give the application a name, e.g. `LXD UI`.
   - Select Regular Web Application.
   - Click Create.
4. Go to the Settings tab of your new application.
   - Scroll to the Allowed Callback URLs field in this tab and enter your LXD UI address, followed by `/oidc/callback`.
     - Example: `https://example.com:8443/oidc/callback`
     - An IP address can be used instead of a domain name.
       - Note `:8443` is the default listening port for the LXD server. It might differ for your setup. You can verify the LXD configuration value `core.https_address` to find the correct port for your LXD server.
   - Enable Allow Refresh Token Rotation.
   - Scroll down to Advanced Settings and select the Grant Types tab.
   - Enable Authorization code and Refresh Token. Other grant types can be disabled.
   - Select Save.
5. Navigate to Basic Information near the top of the Settings tab.
   - Locate the Domain field. Copy the value and add the `https://` prefix and the `/` suffix as in the example below.
     This is your OIDC issuer for LXD. Set this value in your LXD server configuration with the command:
     ```none
     lxc config set oidc.issuer=https://dev-example.us.auth0.com/
     ```
   - Locate the Client ID and Client Secret fields. Copy the values and use them in your LXD server configuration:
     ```none
     lxc config set oidc.client.id=<Client ID>
     lxc config set oidc.client.secret=<Client Secret>
     ```
   - Now you can access the LXD UI with any browser and use  login. Enter the credentials for Auth0.
6. Now create an application to be used by the LXD CLI. To do this, go back to Applications > Applications in the side panel and click + Create Application.
   - Give the application a name, e.g. `LXD CLI`.
   - Select the default Native application type.
   - Click Create.
7. Go to the Settings tab of your new application.
   - Enable Allow Refresh Token Rotation.
   - Scroll down to Advanced Settings and select the Grant Types tab.
   - Enable Device Code and Refresh Token. Other grant types can be disabled.
   - Select Save.
8. Navigate to Basic Information near the top of the Settings tab.
   - Locate the Client ID field and use it in your LXD server configuration:
     ```none
     lxc config set oidc.device.client.id=<Client ID>
     ```
   - You can now access LXD using the CLI with
     ```none
     lxc remote add <remote-name> <LXD-address> --auth-type oidc
     ```

     This will open a browser where you must confirm the device code displayed in the terminal window, and log in with the credentials for Auth0.

Users will have no permissions by default. You must set up [LXD authorization groups](../explanation/authorization.md#manage-permissions) to grant access to projects and instances. For connecting the LXD authorization groups to a user you have two options:

1. Map a LXD authorization group to the user directly. Note, that the user object in LXD will only be created on the first login of that user to LXD.
2. Configure roles in Auth0 and use automatic mapping to LXD authorization groups as described below.

<a id="oidc-auth0-automatic-group-mapping"></a>

## Set up automatic group mappings

An admin can set up multiple users in Auth0 and allocate roles to those users. When a user logs in via OIDC, their allocated Auth0 roles can be mapped to LXD authorization groups through custom claims. This section details the steps for configuring roles in Auth0 and setting up a custom claim so that LXD can map those roles to its authorization groups.

1. In the left panel of the Auth0 interface, select User Management > Roles, create some roles with suitable names. Note that these roles are global for the Auth0 tenant.
2. Under User Management > Users, click Create User. Provide an email and password and create the user.
3. Select on the Roles tab in the user detail page, then click the Assign Roles button. Select the roles you created in step 1.
4. You must set up a custom action on Auth0 to set the custom claim on both the `id_token` and `access_token` during the OIDC login flow.
   - In the main navigation, under Actions > Library, click the Create Action button. Select Create Custom Action.
     - **Name**: Give the action a suitable name like `roles-in-id-token`.
     - **Trigger**: Login / Post Login
     - **Runtime**: The recommended default
   - Click Create. This causes a code editor to open.
   - In the code editor, insert the code snippet shown below:

   ```javascript
   exports.onExecutePostLogin = async (event, api) => {
     if (event.authorization) {
       api.idToken.setCustomClaim(`global-roles`, event.authorization.roles);
       api.accessToken.setCustomClaim(`global-roles`, event.authorization.roles);
     }
   };
   ```

   - Select Deploy.
   - Once the action is deployed, go to Actions > Triggers > post-login. Under the Add Action > Custom tab, drag the action you just created and drop it in between the Start and Complete nodes of the Login flow. Select Apply to save the changes.
5. Navigate to the LXD UI. First authenticate with the UI using a trusted certificate so that you can configure server settings without permission issues.
6. In the LXD UI, under settings, find `oidc.groups.claim`. Set it to the custom claim configured in step 4. Using the current example, the custom claim is `global-roles`. Alternatively, use the command line: `lxc config set oidc.groups.claim=global-roles`.
7. Continuing in the LXD UI, navigate to Permissions > IDP groups and click Create IDP Group. Here you can map roles from Auth0 to LXD authorization groups. For each [identity provider group](../explanation/authorization.md#identity-provider-groups) created in LXD, the name of the identity provider group must match a role you have created in Auth0, and it should also map to one or more LXD authorization groups. Alternatively, use the command line:
   ```none
   lxc auth identity-provider-group create <auth0-role-name>
   lxc auth identity-provider-group group add <auth0-role-name> <LXD-group-name>
   ```
8. Lastly, you log in as a user with roles assigned in Auth0. During the OIDC flow, LXD extracts the roles set by Auth0 based on the LXD `oidc.groups.claim` configuration value. The extracted custom claim is an array of roles for your user from Auth0. Those roles are then mapped to LXD authorization groups using the identity provider group created in step 7.


# index.html.md

<a id="cluster-manage-instance"></a>

# How to manage instances in a cluster

In a cluster setup, each instance lives on one of the cluster members.
You can operate each instance from any cluster member, so you do not need to log on to the cluster member on which the instance is located.

<a id="cluster-target-instance"></a>

## Launch an instance on a specific cluster member

When you launch an instance, you can target it to run on a specific cluster member.
You can do this from any cluster member.

For example, to launch an instance named `c1` on the cluster member `server2`, use the following command:

```none
lxc launch ubuntu:24.04 c1 --target server2
```

You can launch instances on specific cluster members or on specific [cluster groups](cluster_groups.md#howto-cluster-groups).

If you do not specify a target, the instance is assigned to a cluster member automatically.
See [Automatic placement of instances](../explanation/clusters.md#clustering-instance-placement) for more information.

## Check where an instance is located

To check on which member an instance is located, list all instances in the cluster:

```none
lxc list
```

The location column indicates the member on which each instance is running.

<a id="howto-cluster-manage-instance-migrate"></a>

## Migrate an instance

You can migrate an existing instance to another cluster member.
For example, to migrate the instance `c1` to the cluster member `server1`, use the following commands:

```none
lxc stop c1
lxc move c1 --target server1
lxc start c1
```

See [How to migrate LXD instances between servers](instances_migrate.md#howto-instances-migrate) for more information.

To migrate an instance to a member of a cluster group, use the group name prefixed with `@` for the `--target` flag.
For example:

```none
lxc move c1 --target @group1
```


# index.html.md

<a id="container-gpu-passthrough-with-docker"></a>

# How to pass an NVIDIA GPU to a container

## Steps

If you have an NVIDIA GPU (either discrete (dGPU) or integrated (iGPU)) and you want to pass the runtime libraries and configuration installed on your host to your container, you should add a [LXD GPU device](../reference/devices_gpu.md#devices-gpu).
Consider the following scenario:

Your host is an NVIDIA single board computer that has a Tegra SoC with an iGPU, and you have the Tegra SDK installed on the host. You want to create a LXD container and run an application inside the container using the iGPU as a compute backend. You want to run this application inside a Docker container (or another OCI-compliant runtime).
To achieve this, complete the following steps:

1. Running a Docker container inside a LXD container can potentially consume a lot of disk space if the outer container is not well configured. Here are two options you can use to optimize the consumed disk space:
   - Either you create a BTRFS storage pool to back the LXD container so that the Docker image later used does not use the VFS storage driver which is very space inefficient, then you initialize the LXD container with [`security.nesting`](../reference/instance_options.md#instance-security:security.nesting) enabled (needed for running a Docker container inside a LXD container) and using the BTRFS storage pool:
     ```none
     lxc storage create p1 btrfs size=15GiB
     lxc init ubuntu:24.04 t1 --config security.nesting=true -s p1
     ```
   - Or you use the `overlayFS` storage driver in Docker but you need to specify the following syscall interceptions, still with the [`security.nesting`](../reference/instance_options.md#instance-security:security.nesting) enabled:
     ```none
     lxc init ubuntu:24.04 t1 --config security.nesting=true --config security.syscalls.intercept.mknod=true --config security.syscalls.intercept.setxattr=true
     ```
2. Add the GPU device to your container:
   - If you want to do an iGPU pass-through:
     ```none
     lxc config device add t1 igpu0 gpu gputype=physical id=nvidia.com/igpu=0
     ```
   - If you want to do a dGPU pass-through:
     ```none
     lxc config device add t1 gpu0 gpu gputype=physical id=nvidia.com/gpu=0
     ```

After adding the device, let’s try to run a basic [MNIST](https://en.wikipedia.org/wiki/MNIST_database) inference job inside our LXD container.

1. Create a `cloud-init` script that installs the Docker runtime, the [NVIDIA Container Toolkit](https://github.com/NVIDIA/nvidia-container-toolkit), and a script to run a test [TensorRT](https://github.com/NVIDIA/TensorRT) workload:
   ```none
    #cloud-config
    package_update: true
    write_files:
      # `run_tensorrt.sh` compiles samples TensorRT applications and run the the `sample_onnx_mnist` program which loads an ONNX model into the TensorRT inference server and execute a digit recognition job.
      - path: /root/run_tensorrt.sh
        permissions: "0755"
        owner: root:root
        content: |
          #!/bin/bash
          echo "OS release,Kernel version"
          (. /etc/os-release; echo "${PRETTY_NAME}"; uname -r) | paste -s -d,
          echo
          nvidia-smi -q
          echo
          exec bash -o pipefail -c "
          cd /workspace/tensorrt/samples
          make -j4
          cd /workspace/tensorrt/bin
          ./sample_onnx_mnist
          retstatus=\${PIPESTATUS[0]}
          echo \"Test exited with status code: \${retstatus}\" >&2
          exit \${retstatus}
          "
    runcmd:
      # Install Docker to run the AI workload
      - curl -fsSL https://get.docker.com -o install-docker.sh
      - sh install-docker.sh --version 24.0
      # The following installs the NVIDIA container toolkit
      # as explained in the official doc website: https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html#installing-with-apt
      - curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg
      - curl -fsSL https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | sed -e 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' -e '/experimental/ s/^#//g' | tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
      # Now that an new apt source/key was added, update the package definitions.
      - apt-get update
      # Install NVIDIA container toolkit
      - DEBIAN_FRONTEND=noninteractive apt-get install -y nvidia-container-toolkit
      # Ultimately, we need to tell Docker, our container runtime, to use `nvidia-ctk` as a runtime.
      - nvidia-ctk runtime configure --runtime=docker --config=/etc/docker/daemon.json
      - systemctl restart docker
   ```
2. Apply this `cloud-init` setup to your instance:
   ```none
    lxc config set t1 cloud-init.user-data - < cloud-init.yml
   ```
3. Start the instance:
   ```none
    lxc start t1
   ```
4. Wait for the `cloud-init` process to finish:
   ```none
    lxc exec t1 -- cloud-init status --wait
   ```
5. Once `cloud-init` is finished, open a shell in the instance:
   ```none
    lxc exec t1 -- bash
   ```
6. Edit the NVIDIA container runtime to avoid using `cgroups`:
   ```none
    sudo nvidia-ctk config  --in-place --set nvidia-container-cli.no-cgroups
   ```
7. If you use an iGPU and your NVIDIA container runtime is not automatically enabled with CSV mode (needed for NVIDIA Tegra board), enable it manually:
   ```none
    sudo nvidia-ctk config --in-place --set nvidia-container-runtime.mode=csv
   ```
8. Now, run the inference workload with Docker:
   - If you set up a dGPU pass-through:
     ```none
     docker run --gpus all --runtime nvidia --rm -v $(pwd):/sh_input nvcr.io/nvidia/tensorrt:24.02-py3 bash /sh_input/run_tensorrt.sh
     ```
   - If you set up an iGPU pass-through:
     ```none
     docker run --gpus all --runtime nvidia --rm -v $(pwd):/sh_input nvcr.io/nvidia/tensorrt:24.02-py3-igpu bash /sh_input/run_tensorrt.sh
     ```

In the end you should see something like:

```none
    @@@@@@@@@@@@@@@@@@@@@@@@@@@@
    @@@@@@@@@@@@@@@@@@@@@@@@@@@@
    @@@@@@@@@@@@@@@@@@@@@@@@@@@@
    @@@@@@@@@@@@@@@@@@@@@@@@@@@@
    @@@@@@@@@@=   ++++#++=*@@@@@
    @@@@@@@@#.            *@@@@@
    @@@@@@@@=             *@@@@@
    @@@@@@@@.   .. ...****%@@@@@
    @@@@@@@@: .%@@#@@@@@@@@@@@@@
    @@@@@@@%  -@@@@@@@@@@@@@@@@@
    @@@@@@@%  -@@*@@@*@@@@@@@@@@
    @@@@@@@#  :#- ::. ::=@@@@@@@
    @@@@@@@-             -@@@@@@
    @@@@@@%.              *@@@@@
    @@@@@@#     :==*+==   *@@@@@
    @@@@@@%---%%@@@@@@@.  *@@@@@
    @@@@@@@@@@@@@@@@@@@+  *@@@@@
    @@@@@@@@@@@@@@@@@@@=  *@@@@@
    @@@@@@@@@@@@@@@@@@*   *@@@@@
    @@@@@%+%@@@@@@@@%.   .%@@@@@
    @@@@@*  .******=    -@@@@@@@
    @@@@@*             .#@@@@@@@
    @@@@@*            =%@@@@@@@@
    @@@@@@%#+++=     =@@@@@@@@@@
    @@@@@@@@@@@@@@@@@@@@@@@@@@@@
    @@@@@@@@@@@@@@@@@@@@@@@@@@@@
    @@@@@@@@@@@@@@@@@@@@@@@@@@@@

    [07/31/2024-13:19:21] [I] Output:
    [07/31/2024-13:19:21] [I]  Prob 0  0.0000 Class 0:
    [07/31/2024-13:19:21] [I]  Prob 1  0.0000 Class 1:
    [07/31/2024-13:19:21] [I]  Prob 2  0.0000 Class 2:
    [07/31/2024-13:19:21] [I]  Prob 3  0.0000 Class 3:
    [07/31/2024-13:19:21] [I]  Prob 4  0.0000 Class 4:
    [07/31/2024-13:19:21] [I]  Prob 5  1.0000 Class 5: **********
    [07/31/2024-13:19:21] [I]  Prob 6  0.0000 Class 6:
    [07/31/2024-13:19:21] [I]  Prob 7  0.0000 Class 7:
    [07/31/2024-13:19:21] [I]  Prob 8  0.0000 Class 8:
    [07/31/2024-13:19:21] [I]  Prob 9  0.0000 Class 9:
    [07/31/2024-13:19:21] [I]
    &&&& PASSED TensorRT.sample_onnx_mnist [TensorRT v8603] # ./sample_onnx_mnist
```

## Related topics

- [GPU devices reference](../reference/devices_gpu.md#devices-gpu)
- [Why does my VM stop responding when I try to pass through a GPU?](../faq.md#faq-gpu-passthrough-stop)


# index.html.md

<a id="cluster-config-networks"></a>

# How to configure networks for a cluster

All members of a cluster must have identical networks defined.
The only configuration keys that may differ between networks on different members are [`bridge.external_interfaces`](../reference/network_bridge.md#network-bridge-network-conf:bridge.external_interfaces), [`parent`](../reference/network_physical.md#network-physical-network-conf:parent), [`bgp.ipv4.nexthop`](../reference/network_bridge.md#network-bridge-network-conf:bgp.ipv4.nexthop), and [`bgp.ipv6.nexthop`](../reference/network_bridge.md#network-bridge-network-conf:bgp.ipv6.nexthop).
See [Member configuration](../explanation/clusters.md#clustering-member-config) for more information.

Creating additional networks is a two-step process:

1. Define and configure the new network across all cluster members.
   For example, for a cluster that has three members:
   ```none
   lxc network create --target server1 my-network
   lxc network create --target server2 my-network
   lxc network create --target server3 my-network
   ```

   #### NOTE
   You can pass only the member-specific configuration keys `bridge.external_interfaces`, `parent`, `bgp.ipv4.nexthop` and `bgp.ipv6.nexthop`.
   Passing other configuration keys results in an error.

   These commands define the network, but they don’t create it.
   If you run [`lxc network list`](../reference/manpages/lxc/network/list.md#lxc-network-list-md), you can see that the network is marked as “pending”.
2. Run the following command to instantiate the network on all cluster members:
   ```none
   lxc network create my-network
   ```

   #### NOTE
   You can add configuration keys that are not member-specific to this command.

   If you missed a cluster member when defining the network, or if a cluster member is down, you get an error.

Also see network-create-cluster.

<a id="cluster-https-address"></a>

## Separate REST API and clustering networks

You can configure different networks for the REST API endpoint of your clients and for internal traffic between the members of your cluster.
This separation can be useful, for example, to use a virtual address for your REST API, with DNS round robin.

To do so, you must specify different addresses for [`cluster.https_address`](../server.md#server-cluster:cluster.https_address) (the address for internal cluster traffic) and [`core.https_address`](../server.md#server-core:core.https_address) (the address for the REST API):

1. Create your cluster as usual, and make sure to use the address that you want to use for internal cluster traffic as the cluster address.
   This address is set as the `cluster.https_address` configuration.
2. After joining your members, set the `core.https_address` configuration to the address for the REST API.
   For example:
   ```none
   lxc config set core.https_address 0.0.0.0:8443
   ```

   #### NOTE
   `core.https_address` is specific to the cluster member, so you can use different addresses on different members.
   You can also use a wildcard address to make the member listen on multiple interfaces.


# index.html.md

<a id="howtos"></a>

# How-to guides

These how-to guides cover key operations and processes in LXD.

## Set up the LXD server and initial access

LXD can be installed and initialized in multiple ways. Afterward, the server can be configured for network access through the CLI or UI client.

* [Getting started](../getting_started.md)
* [LXD server and client](../operation.md)

## Work with LXD

Instances are created from images and can be either [system containers or virtual machines](../explanation/instances.md#containers-and-vms). Projects are useful for grouping related instances and managing user access.

* [Instances](../instances.md)
* [Images](../images.md)
* [Projects](../projects.md)
* [Storage](../storage.md)
* [Networking](../networks.md)

## Get ready for production

For production deployments, clusters of LXD servers help support higher loads. The production setup guides also cover performance, monitoring, backup, and disaster recovery.

* [Clustering](../clustering.md)
* [Production setup](../production-setup.md)

## Perform server administration

* [Manage the snap](snap.md)
* [Harden security](security_harden.md)
* [Troubleshooting](troubleshoot.md)

## Authenticate to the APIs

Bearer tokens can be used to authenticate to the LXD API; refer to [Remote API authentication](../authentication.md#authentication) for other methods. The DevLXD API is used for communication between instances and their host.

* [Authenticate to the LXD API using bearer tokens](auth_bearer.md)
* [Authenticate to the DevLXD API](devlxd_authenticate.md)

## Engage with us

* [Get support](../support.md)
* [Contribute to LXD](../contributing.md)


# index.html.md

<a id="cluster-recover-volumes"></a>

# How to recover orphaned volume database entries

When a [cluster instance migration](cluster_manage_instance.md#howto-cluster-manage-instance-migrate) or [custom volume migration](storage_move_volume.md#howto-storage-move-volume-cluster) is interrupted mid-transfer (for example, due to a network failure or a killed LXD process), the target member may be left with a volume record in the global database that has no corresponding storage on disk.
These orphaned entries block future migrations for the affected instance or custom volume with an error like:

```none
Volume "myinstance" exists in database on member "member2" but not on storage
```

## Recover instance volumes

### Identify orphaned entries

List all volume entries for the affected instance across cluster members:

```none
lxd sql global "SELECT storage_volumes.id, storage_volumes.name, nodes.name AS member FROM storage_volumes JOIN nodes ON storage_volumes.node_id = nodes.id WHERE storage_volumes.name = '<instance-name>'"
```

Replace `<instance-name>` with the name of the affected instance.

Orphaned entries appear as rows on a member where the instance does not actually reside and no storage exists on disk.

### Remove orphaned entries

Once you have identified the orphaned entry, remove it with:

```none
lxd sql global "DELETE FROM storage_volumes WHERE name='<instance-name>' AND node_id=(SELECT id FROM nodes WHERE name='<member-name>')"
```

Replace `<instance-name>`, as well as `<member-name>` with the cluster member that holds the orphaned entry.

After removing the orphaned entry, retry the [instance migration](cluster_manage_instance.md#howto-cluster-manage-instance-migrate).

## Recover custom volumes

The same issue can occur with custom storage volumes during migration.

### Identify orphaned entries

List all volume entries for the affected custom volume across cluster members:

```none
lxd sql global "SELECT storage_volumes.id, storage_volumes.name, nodes.name AS member FROM storage_volumes JOIN nodes ON storage_volumes.node_id = nodes.id WHERE storage_volumes.name = '<volume-name>'"
```

Replace `<volume-name>` with the name of the custom volume.

Orphaned entries appear as rows on a member where the volume does not actually reside and no storage exists on disk.

### Remove orphaned entries

Once you have identified the orphaned entry, remove it with:

```none
lxd sql global "DELETE FROM storage_volumes WHERE name='<volume-name>' AND node_id=(SELECT id FROM nodes WHERE name='<member-name>')"
```

Replace `<volume-name>`, as well as `<member-name>` with the cluster member that holds the orphaned entry.

After removing the orphaned entry, retry the [volume migration](storage_move_volume.md#howto-storage-move-volume-cluster).


# index.html.md

<a id="network-ipam"></a>

# How to display IPAM information of a LXD deployment

 is a method used to plan, track, and manage the information associated with a computer network’s IP address space. In essence, it’s a way of organizing, monitoring, and manipulating the IP space in a network.

Checking the IPAM information for your LXD setup can help you debug networking issues. You can see which IP addresses are used for instances, network interfaces, forwards, and load balancers and use this information to track down where traffic is lost.

CLI

To display IPAM information, enter the following command:

```bash
lxc network list-allocations
```

By default, this command shows the IPAM information for the `default` project. You can select a different project with the `--project` flag, or specify `--all-projects` to display the information for all projects.

The resulting output will look something like this:

```default
+----------------------+-----------------+----------+------+-------------------+
|       USED BY        |      ADDRESS    |   TYPE   | NAT  | HARDWARE ADDRESS  |
+----------------------+-----------------+----------+------+-------------------+
| /1.0/networks/lxdbr0 | 192.0.2.0/24    | network  | true |                   |
+----------------------+-----------------+----------+------+-------------------+
| /1.0/networks/lxdbr0 | 2001:db8::/32   | network  | true |                   |
+----------------------+-----------------+----------+------+-------------------+
| /1.0/instances/u1    | 2001:db8::2/128 | instance | true | 00:16:3e:04:f0:95 |
+----------------------+-----------------+----------+------+-------------------+
| /1.0/instances/u1    | 192.0.2.2/32    | instance | true | 00:16:3e:04:f0:95 |
+----------------------+-----------------+----------+------+-------------------+
```

Each listed entry lists the IP address (in CIDR notation) of one of the following LXD entities: `network`, `network-forward`, `network-load-balancer`, and `instance`.
An entry contains an IP address using the CIDR notation.
It also contains a LXD resource URI, the type of the entity, whether it is in NAT mode, and the hardware address (only for the `instance` entity).

UI

View IPAM information from the Networking section of the main navigation.

## View DHCP leases for fully controlled networks

LXD can provide the currently held DHCP leases for [fully controlled networks](../explanation/networks.md#managed-networks):

CLI

To view DHCP lease information, run:

```bash
lxc network list-leases <network_name>
```

For example, using `lxdbr0` from above:

```default
+-----------+-------------------+-------------+---------+
| HOSTNAME  |    MAC ADDRESS    | IP ADDRESS  |   TYPE  |
+-----------+-------------------+-------------+---------+
| lxdbr0.gw |                   | 192.0.2.1   | GATEWAY |
+-----------+-------------------+-------------+---------+
| lxdbr0.gw |                   | 2001:db8::1 | GATEWAY |
+-----------+----------+--------+-------------+---------+
| u1        | 00:16:3e:04:f0:95 | 192.0.2.2   | DYNAMIC |
+-----------+-------------------+-------------+---------+
| u1        | 00:16:3e:04:f0:95 | 2001:db8::2 | DYNAMIC |
+-----------+-------------------+-------------+---------+
```

UI

To view DHCP leases, select your fully managed network from the Networks page, then open the Leases tab.

![View the network IPAM list in LXD](images/networks/network_view_leases.png)


# index.html.md

<a id="projects-confine"></a>

# How to confine users to specific projects

You restrict users or clients to specific projects.
Projects can be configured with features, limits, and restrictions to prevent misuse.
See [Instances grouping with projects](../explanation/projects.md#exp-projects) for more information.

How to confine users to specific projects depends on whether LXD is accessible via the [HTTPS API](#projects-confine-https), or via the [Unix socket](#projects-confine-users).

<a id="projects-confine-https"></a>

## Confine users to specific projects on the HTTPS API

You can confine access to specific projects by restricting the TLS client certificate that is used to connect to the LXD server.
See [Restricted TLS certificates](../explanation/authorization.md#restricted-tls-certs) for more information.
Only certificates returned by `lxc config trust list` can be managed in this way.


            <p class="youtube_link">
              <a href="https://www.youtube.com/watch?v=4iNpiL-lrXU&t=525s" target="_blank">
                <span title="LXD token based remote authentication" class="play_icon">▶</span>
                <span title="LXD token based remote authentication">Watch on YouTube</span>
              </a>
            </p>
        
#### NOTE
The UI does not currently support configuring project confinement for certificates of this type.
Use the CLI or API to set up confinement.

You can also confine access to specific projects via group membership and [Fine-grained authorization](../explanation/authorization.md#fine-grained-authorization).
The permissions of OIDC clients and fine-grained TLS identities must be managed with `lxc auth` subcommands and the `/1.0/auth` API.

To create a TLS client and restrict the client to a single project, follow these instructions:

CLI

### Create a restricted trust store entry with access to a project

If you’re using token authentication:

```none
lxc config trust add --projects <project_name> --restricted
```

To add the client certificate directly:

```none
lxc config trust add <certificate_file> --projects <project_name> --restricted
```

#### IMPORTANT
The `--projects` flag requires `--restricted` to be set. Projects can only be used to restrict certificate access when the certificate is marked as restricted.

The client can then add the server as a remote in the usual way ([`lxc remote add <server_name> <token>`](../reference/manpages/lxc/remote/add.md#lxc-remote-add-md) or [`lxc remote add <server_name> <server_address>`](../reference/manpages/lxc/remote/add.md#lxc-remote-add-md)) and can only access the project or projects that have been specified.

#### NOTE
You can specify the `--project` flag when adding a remote.
This configuration pre-selects the specified project.
However, it does not confine the client to this project.

### Create a fine-grained TLS identity with access to a project

First create a group and grant the group the `operator` entitlement on the project.

```none
lxc auth group create <group_name>
lxc auth group permission add <group_name> project <project_name> operator
```

The `operator` entitlement grants members of the group permission to create and edit resources belonging to that project, but does not grant permission to delete the project or edit its configuration.
See [Fine-grained authorization](../explanation/authorization.md#fine-grained-authorization) for more details.

Next create a TLS identity and add the identity to the group:

```none
lxc auth identity create tls/<client_name> [<certificate_file>] --group <group_name>
```

If `<certificate_file>` is provided the identity will be created directly.
Otherwise, a token will be returned that the client can use to add the LXD server as a remote:

```none
# Client machine
lxc remote add <remote_name> <token>
```

The client will be prompted with a list of projects to use as their default project.
Only the configured project will be presented to the client.

API

### Create a restricted trust store entry with access to a project

If you’re using token authentication, create the token first:

```none
lxc query --request POST /1.0/certificates --data '{
  "name": "<client_name>",
  "projects": ["<project_name>"]
  "restricted": true,
  "token": true,
  "type": "client"
}'
```

<!-- Include content from [/howto/server_expose.md](/howto/server_expose.md) -->

See [`POST /1.0/certificates`](/api/#/certificates/certificates_post) for more information.

The return value of this query contains an operation that has the information that is required to generate the trust token:

```none
   {
    "class": "token",
    ...
    "metadata": {
       "addresses": [
          "<server_address>"
       ],
       "fingerprint": "<fingerprint>",
       ...
       "secret": "<secret>"
    },
    ...
   }
```

Use this information to generate the trust token:

```none
   echo -n '{"client_name":"<client_name>","fingerprint":"<fingerprint>",'\
   '"addresses":["<server_address>"],'\
   '"secret":"<secret>","expires_at":"0001-01-01T00:00:00Z"}' | base64 -w0
```

To instead add the client certificate directly, send the following request:

```none
lxc query --request POST /1.0/certificates --data '{
  "certificate": "<certificate>",
  "name": "<client_name>",
  "projects": ["<project_name>"]
  "restricted": true,
  "token": false,
  "type": "client"
}'
```

The client can then authenticate using this trust token or client certificate and can only access the project or projects that have been specified.

<!-- Include content from [/howto/server_expose.md](/howto/server_expose.md) -->

On the client, generate a certificate to use for the connection:

```none
   openssl req -x509 -newkey rsa:2048 -keyout "<keyfile_name>" -nodes \
   -out "<crtfile_name>" -subj "/CN=<client_name>"
```

<!-- Include content from [/howto/server_expose.md](/howto/server_expose.md) -->

Then send a POST request to the `/1.0/certificates?public` endpoint to authenticate:

```none
   curl -k -s --key "<keyfile_name>" --cert "<crtfile_name>" \
   -X POST https://<server_address>/1.0/certificates \
   --data '{ "trust_token": "<trust_token>" }'
```

See [`POST /1.0/certificates?public`](/api/#/certificates/certificates_post_untrusted) for more information.

**Create a fine-grained TLS identity with access to a project**

First create a group and grant the group the `operator` entitlement on the project.

```none
lxc query --request POST /1.0/auth/groups --data '{
  "name": "<group_name>",
}'

lxc query --request PUT /1.0/auth/groups/<group_name> --data '{
  "permissions": [
    {
      "entity_type": "project",
      "url": "/1.0/projects/<project_name>",
      "entitlement": "operator"
    }
  ]
}'
```

The `operator` entitlement grants members of the group permission to create and edit resources belonging to that project, but does not grant permission to delete the project or edit its configuration.
See [Fine-grained authorization](../explanation/authorization.md#fine-grained-authorization) for more details.

Next create a TLS identity and add the identity to the group:

```none
lxc query --request POST /1.0/auth/identities/tls --data '{
  "name": "<client_name>",
  "groups": ["<group_name>"],
  "token": true
}'
```

<!-- Include content from [/howto/server_expose.md](/howto/server_expose.md) -->

See [`POST /1.0/auth/identities/tls`](/api/#/auth/identitites/identities_post_tls) for more information.

The return value of this query contains the information that is required to generate the trust token:

```none
   {
       "client_name": "<client_name>",
       "addresses": [
          "<server_address>"
       ],
       "expires_at": "<expiry_date>"
       "fingerprint": "<fingerprint>",
       "type": "<type>",
       "secret": "<secret>"
   }
```

Use this information to generate the trust token:

```none
   echo -n '{"client_name":"<client_name>","fingerprint":"<fingerprint>",'\
   '"addresses":["<server_address>"],'\
   '"secret":"<secret>","expires_at":"0001-01-01T00:00:00Z","type":"<type>"}' | base64 -w0
```

To instead add the client certificate directly, send the following request:

```none
lxc query --request POST /1.0/certificates --data '{
  "certificate": "<base64 encoded x509 certificate>",
  "name": "<client_name>",
  "groups": ["<group_name>"]
}'
```

If the certificate was added directly, the client is now authenticated with LXD.
If a token was used, the client must use it to add their certificate.

<!-- Include content from [/howto/server_expose.md](/howto/server_expose.md) -->

On the client, generate a certificate to use for the connection:

```none
   openssl req -x509 -newkey rsa:2048 -keyout "<keyfile_name>" -nodes \
   -out "<crtfile_name>" -subj "/CN=<client_name>"
```

<!-- Include content from [/howto/server_expose.md](/howto/server_expose.md) -->

Send a POST request to the `/1.0/auth/identities/tls?public` endpoint to authenticate:

```none
   curl --insecure --key "<keyfile_name>" --cert "<crtfile_name>" \
   -X POST https://<server_address>/1.0/auth/identities/tls \
   --data '{ "trust_token": "<trust_token>" }'
```

See [`POST /1.0/auth/identities/tls?public`](/api/#/auth/identities/identities_post_tls_untrusted) for more information.

To confine access for an existing certificate:

CLI

**Trust store entry**

Use the following command:

```none
lxc config trust edit <fingerprint>
```

Make sure that `restricted` is set to `true` and specify the projects that the certificate should give access to under `projects`.

**Fine-grained TLS or OIDC identity**

Create a group with the `operator` entitlement on the project:

```none
lxc auth group create <group_name>
lxc auth group permission add <group_name> project <project_name> operator
```

Then add the group to the identity. For TLS identities run:

```none
lxc auth identity group add tls/<client_name> <group_name>
```

The `<client_name>` must be unique. If it is not, the certificate fingerprint of the client can be used.

For OIDC identities, run:

```none
lxc auth identity group add oidc/<client_name> <group_name>
```

The `<client_name>` must be unique. If it is not, the email address of the client can be used.

API

**Trust store entry**

Send the following request:

```none
lxc query --request PATCH /1.0/certificates/<fingerprint> --data '{
  "projects": ["<project_name>"],
  "restricted": true
}'
```

Make sure that `restricted` is set to `true` and specify the projects that the certificate should give access to under `projects`.

**Fine-grained TLS or OIDC identity**

Create a group with the `operator` entitlement on the project:

```none
lxc query --request POST /1.0/auth/groups --data '{
  "name": "<group_name>",
}'

lxc query --request PUT /1.0/auth/groups/<group_name> --data '{
  "permissions": [
    {
      "entity_type": "project",
      "url": "/1.0/projects/<project_name>",
      "entitlement": "operator"
    }
  ]
}'
```

Then add the group to the identity. For TLS identities run:

```none
lxc query --request PATCH /1.0/auth/identities/tls/<client_name> --data '{
  "groups": ["<group_name>"]
}'
```

The `<client_name>` must be unique. If it is not, the certificate fingerprint of the client can be used.

For OIDC identities, run:

```none
lxc query --request PATCH /1.0/auth/identities/oidc/<client_name> --data '{
  "groups": ["<group_name>"]
}'
```

The `<client_name>` must be unique. If it is not, the email address of the client can be used.

<a id="projects-confine-users"></a>

## Confine users to specific LXD projects via Unix socket


            <p class="youtube_link">
              <a href="https://www.youtube.com/watch?v=6O0q3rSWr8A" target="_blank">
                <span title="LXD for multi-user systems" class="play_icon">▶</span>
                <span title="LXD for multi-user systems">Watch on YouTube</span>
              </a>
            </p>
        
If you use the [LXD snap](https://snapcraft.io/lxd), you can configure the multi-user LXD daemon contained in the snap to dynamically create projects for all users in a specific user group.

To do so, set the `daemon.user.group` configuration option to the corresponding user group:

```none
sudo snap set lxd daemon.user.group=<user_group>
```

Make sure that all user accounts that you want to be able to use LXD are a member of this group.

Once a member of the group issues a LXD command, LXD creates a confined project for this user and switches to this project.
If LXD has not been [initialized](initialize.md#initialize) at this point, it is automatically initialized (with the default settings).

If you want to customize the project settings, for example, to impose limits or restrictions, you can do so after the project has been created.
To modify the project configuration, you must have full access to LXD, which means you must be part of the `lxd` group and not only the group that you configured as the LXD user group.


# index.html.md

<a id="network-load-balancers"></a>

# How to configure network load balancers

#### NOTE
Network load balancers are currently available for the [OVN network](../reference/network_ovn.md#network-ovn).

Network load balancers are similar to forwards in that they allow specific ports on an IP address (external or internal) to be forwarded to specific ports on internal IP addresses in the same network as the load balancer.

The difference between load balancers and forwards is that load balancers can be used to share ingress traffic between multiple internal backend addresses. This feature can be useful if you have limited external IP addresses or want to share a single external address and ports over multiple instances.

A load balancer is made up of:

- A single listen IP address (external or internal).
- One or more named backends consisting of an internal IP and optional port ranges.
- One or more listen ports or port ranges that are configured to forward to one or more named backends.
- One or more listen ports that are configured to forward to one or more pools of instances.

A pool of instances allows a more simplified definition of backends as it doesn’t require additional configuration of the internal IP.

## Create a network load balancer

Use the following command to create a network load balancer:

```bash
lxc network load-balancer create <network_name> [<listen_address>] [--allocate=ipv{4,6}] [configuration_options...]
```

Example with a specified listen address:

```bash
lxc network load-balancer create my-ovn-network 192.0.2.178
```

Example with an allocated listen address:

```bash
lxc network load-balancer create my-ovn-network --allocate=ipv4
```

Each load balancer is assigned to a network.

Listen addresses are subject to restrictions. If a listen address is not specified, the `--allocate` flag must be provided. See [Requirements for listen addresses](#network-load-balancers-listen-addresses) for more information about which addresses can be load-balanced, as well as how to use the `--allocate` flag.

### Load balancer properties

Network load balancers have the following properties:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="network-load-balancer-load-balancer-properties:backends"></a>
`backends`

List of backend specifications

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-load-balancer-load-balancer-properties:backends)

| **Key:**      | `backends`   |
|---------------|--------------|
| **Type:**     | backend list |
| **Required:** | no           |

See [Configure backends](#network-load-balancers-backend-specifications).

<a id="network-load-balancer-load-balancer-properties:config"></a>
`config`

User-provided free-form key/value pairs

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-load-balancer-load-balancer-properties:config)

| **Key:**      | `config`   |
|---------------|------------|
| **Type:**     | string set |
| **Required:** | no         |

The only supported keys are `user.*` custom keys.

<a id="network-load-balancer-load-balancer-properties:description"></a>
`description`

Description of the network load balancer

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-load-balancer-load-balancer-properties:description)

| **Key:**      | `description`   |
|---------------|-----------------|
| **Type:**     | string          |
| **Required:** | no              |

<a id="network-load-balancer-load-balancer-properties:listen_address"></a>
`listen_address`

IP address to listen on

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-load-balancer-load-balancer-properties:listen_address)

| **Key:**      | `listen_address`   |
|---------------|--------------------|
| **Type:**     | string             |
| **Required:** | no                 |

<a id="network-load-balancer-load-balancer-properties:ports"></a>
`ports`

List of port specifications

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-load-balancer-load-balancer-properties:ports)

| **Key:**      | `ports`   |
|---------------|-----------|
| **Type:**     | port list |
| **Required:** | no        |

See [Configure ports](#network-load-balancers-port-specifications).

<a id="network-load-balancers-listen-addresses"></a>

### Requirements for listen addresses

The following requirements must be met for valid listen addresses:

For external listen IP addresses:

- Allowed listen addresses must be defined in the uplink network’s `ipv{n}.routes` settings or the project’s [`restricted.networks.subnets`](../reference/projects.md#project-restricted:restricted.networks.subnets) setting.
  - If you specify a listen address when creating a load balancer, it must be within the range of allowed addresses.
  - If you do not specify a listen address, you must use either `--allocate ipv4` or `--allocate ipv6`. This will allocate a listen address from the range of allowed addresses.
- The listen address must not overlap with a subnet that is in use with another network or entity in that network.

For internal listen IP addresses:

- Allowed listen addresses must not be used by the associated network’s gateway, other existing load balancers and network forwards, or instance NICs.

<a id="network-load-balancers-backend-specifications"></a>

## Configure backends

You can add backend specifications to the network load balancer to define target addresses (and optionally ports).
The backend target address must be within the same subnet as the network associated with the load balancer.

Use the following command to add a backend specification:

```bash
lxc network load-balancer backend add <network_name> <listen_address> <backend_name> <target_address> [<target_ports>]
```

Example:

```bash
lxc network load-balancer backend add my-ovn-network 192.0.2.178 test-backend 10.41.211.5
```

If no target ports are specified when adding the backend:

- The load balancer uses the listen ports defined in the [port specification]() associated with that backend, if any.
- If no such listen ports are defined, the backend has no target ports and is inactive. You must either [add a port specification]() or [edit the load balancer configuration]() to include a `target_port` value in the backend specification or a `listen_port` value in the ports specification.

If you want to forward the traffic to different ports, you have two options:

- Specify a single target port to forward traffic from all listen ports to this target port.
- Specify a set of target ports with the same number of ports as the listen ports to forward traffic from the first listen port to the first target port, the second listen port to the second target port, and so on.

### Backend properties

Network load balancer backends have the following properties:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="network-load-balancer-load-balancer-backend-properties:description"></a>
`description`

Description of the backend

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-load-balancer-load-balancer-backend-properties:description)

| **Key:**      | `description`   |
|---------------|-----------------|
| **Type:**     | string          |
| **Required:** | no              |

<a id="network-load-balancer-load-balancer-backend-properties:name"></a>
`name`

Name of the backend

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-load-balancer-load-balancer-backend-properties:name)

| **Key:**      | `name`   |
|---------------|----------|
| **Type:**     | string   |
| **Required:** | yes      |

<a id="network-load-balancer-load-balancer-backend-properties:target_address"></a>
`target_address`

IP address to forward to

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-load-balancer-load-balancer-backend-properties:target_address)

| **Key:**      | `target_address`   |
|---------------|--------------------|
| **Type:**     | string             |
| **Required:** | yes                |

<a id="network-load-balancer-load-balancer-backend-properties:target_port"></a>
`target_port`

Target port or ports

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-load-balancer-load-balancer-backend-properties:target_port)

| **Key:**      | `target_port`                                                                             |
|---------------|-------------------------------------------------------------------------------------------|
| **Type:**     | string                                                                                    |
| **Default:**  | same as [`listen_port`](#network-load-balancer-load-balancer-port-properties:listen_port) |
| **Required:** | no                                                                                        |

For example: `70,80-90` or `90`

<a id="network-load-balancers-pool-specifications"></a>

## Configure pools

Pools are not directly attached to a load balancer. Instead they are configured on the network and can therefore be referenced by one or many load balancers inside this network.

Use the following command to add a pool:

```bash
lxc network load-balancer pool create <network_name> <pool_name> <key>=<value>...
```

Example:

```bash
lxc network load-balancer pool create my-ovn-network https target_port=443
```

This creates a new pool and sets `443` as the target port for all instances inside the pool.
If necessary the port can be overwritten for each instance.

### Pool properties

Network load balancer pools have the following properties:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="network-load-balancer-pool-properties:protocol"></a>
`protocol`

Protocol used for ingress pool traffic.

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-load-balancer-pool-properties:protocol)

| **Key:**      | `protocol`   |
|---------------|--------------|
| **Type:**     | string       |
| **Default:**  | `tcp`        |
| **Required:** | no           |

Can be either `tcp` or `udp`.

<a id="network-load-balancer-pool-properties:target_port"></a>
`target_port`

Port used on instances for ingress pool traffic

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-load-balancer-pool-properties:target_port)

| **Key:**      | `target_port`   |
|---------------|-----------------|
| **Type:**     | string          |
| **Required:** | yes             |

<a id="network-load-balancers-pool-instances-specifications"></a>

### Configure pool instances

When a load balancer port references a pool, traffic can only be forwarded to the pool if it contains one or more instances.
Use the following command to add instances to the pool:

```bash
lxc network load-balancer pool instance add <network> <pool_name> <instance_name> [<target_port>]
```

Example:

```bash
lxc network load-balancer pool instance add my-ovn-network http i1
```

The target port is optional and allows you to use a custom port for the instance.
If you do not provide a target port for the instance, the instance will use the pool’s target port.

<a id="network-load-balancers-port-specifications"></a>

## Configure ports

You can add port specifications to the network load balancer to forward traffic from specific ports on the listen address:

- To specific ports on one or more target backends.
- To specific ports on all instances inside a target pool

Use the following command to add a port specification for explicit target backends:

```bash
lxc network load-balancer port add <network_name> <listen_address> <protocol> <listen_ports> target_backend=<backend_name>[,<backend_name>...]
```

Example:

```bash
lxc network load-balancer port add my-ovn-network 192.0.2.178 tcp 80 target_backend=test-backend
```

You can specify a single listen port or a set of ports.
The backend(s) specified must have target port(s) settings compatible with the port’s listen port(s) setting.

Use the following command to add a port specification for all instances inside a target pool:

```bash
lxc network load-balancer port add <network_name> <listen_address> <protocol> <listen_port> target_pool=<pool_name>
```

Example:

```bash
lxc network load-balancer port add my-ovn-network 192.0.2.178 tcp 443 target_pool=https
```

### Port properties

Network load balancer ports have the following properties:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="network-load-balancer-load-balancer-port-properties:description"></a>
`description`

Description of the port or ports

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-load-balancer-load-balancer-port-properties:description)

| **Key:**      | `description`   |
|---------------|-----------------|
| **Type:**     | string          |
| **Required:** | no              |

<a id="network-load-balancer-load-balancer-port-properties:listen_port"></a>
`listen_port`

Listen port or ports

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-load-balancer-load-balancer-port-properties:listen_port)

| **Key:**      | `listen_port`   |
|---------------|-----------------|
| **Type:**     | string          |
| **Required:** | yes             |

For example: `80,90-100`

<a id="network-load-balancer-load-balancer-port-properties:protocol"></a>
`protocol`

Protocol for the port or ports

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-load-balancer-load-balancer-port-properties:protocol)

| **Key:**      | `protocol`   |
|---------------|--------------|
| **Type:**     | string       |
| **Required:** | yes          |

Possible values are `tcp` and `udp`.

<a id="network-load-balancer-load-balancer-port-properties:target_backend"></a>
`target_backend`

Backend name(s) to forward to

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-load-balancer-load-balancer-port-properties:target_backend)

| **Key:**      | `target_backend`   |
|---------------|--------------------|
| **Type:**     | backend list       |
| **Required:** | no                 |

If you do not provide a list of backends, then you must provide a pool to `target_pool`.

<a id="network-load-balancer-load-balancer-port-properties:target_pool"></a>
`target_pool`

Pool of instances to forward to

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-load-balancer-load-balancer-port-properties:target_pool)

| **Key:**      | `target_pool`   |
|---------------|-----------------|
| **Type:**     | string          |
| **Required:** | no              |

If you do not provide a pool, then you must provide a list of backends to `target_backend`.

## Edit a network load balancer

Use the following command to edit a network load balancer:

```bash
lxc network load-balancer edit <network_name> <listen_address>
```

This command opens the network load balancer in YAML format for editing.
You can edit the general configuration, as well as the backend and port specifications.

Example load balancer configuration YAML file:

```yaml
listen_address: 192.0.2.178
location: ""
description: ""
config: {}
backends:
- name: test-backend
  description: ""
  target_port: ""
  target_address: 10.41.211.5
ports:
- description: ""
  protocol: tcp
  listen_port: 70,80-90
  target_backend:
  - test-backend
- description: ""
  protocol: tcp
  listen_port: 443
  target_pool: https
```

## Edit a network load balancer pool

Use the following command to edit a network load balancer pool:

```bash
lxc network load-balancer pool edit <network_name> <pool_name>
```

This command opens the network load balancer pool in YAML format for editing.
You can edit the general configuration, as well as the instances and their target port.

Example load balancer pool configuration YAML file:

```yaml
name: https
description: ""
config:
  protocol: tcp
  target_port: "443"
instances:
- name: i1
- name: i2
- name: i3
  target_port: "8443"
used_by:
- /1.0/networks/default/load-balancers/192.0.2.178
```

## Delete a network load balancer

Use the following command to delete a network load balancer:

```bash
lxc network load-balancer delete <network_name> <listen_address>
```

## Delete a network load balancer pool

Use the following command to delete a network load balancer pool:

```bash
lxc network load-balancer pool delete <network_name> <pool_name>
```

## Remove a network load balancer pool instance

Use the following command to remove a network load balancer pool instance:

```bash
lxc network load-balancer pool instance remove <network_name> <pool_name> <instance_name>
```

## Remove a network load balancer port

Use the following command to remove a network load balancer port:

```bash
lxc network load-balancer port remove <network_name> <listen_address> <protocol> <listen_ports>
```


# index.html.md

<a id="network-create"></a>

# How to create a network

To create a managed network, use the [`lxc network`](../reference/manpages/lxc/network.md#lxc-network-md) command and its subcommands.
Append `--help` to any command to see more information about its usage and available flags.

<a id="network-types"></a>

## Network types

The following network types are available:

| Network type   | Documentation                                                         | Configuration options                                                              |
|----------------|-----------------------------------------------------------------------|------------------------------------------------------------------------------------|
| `bridge`       | [Bridge network](../reference/network_bridge.md#network-bridge)       | [Configuration options](../reference/network_bridge.md#network-bridge-options)     |
| `ovn`          | [OVN network](../reference/network_ovn.md#network-ovn)                | [Configuration options](../reference/network_ovn.md#network-ovn-options)           |
| `macvlan`      | [Macvlan network](../reference/network_macvlan.md#network-macvlan)    | [Configuration options](../reference/network_macvlan.md#network-macvlan-options)   |
| `sriov`        | [SR-IOV network](../reference/network_sriov.md#network-sriov)         | [Configuration options](../reference/network_sriov.md#network-sriov-options)       |
| `physical`     | [Physical network](../reference/network_physical.md#network-physical) | [Configuration options](../reference/network_physical.md#network-physical-options) |

## Create a network

CLI

Use the following command to create a network:

```bash
lxc network create <name> --type=<network_type> [configuration_options...]
```

See [Network types](#network-types) for a list of available network types and links to their configuration options.

If you do not specify a `--type` argument, the default type of `bridge` is used.

<a id="id2"></a>

### Create a network in a cluster

If you are running a LXD cluster and want to create a network, you must create the network for each cluster member separately.
The reason for this is that the network configuration, for example, the name of the parent network interface, might be different between cluster members.

Therefore, you must first create a pending network on each member with the `--target=<cluster_member>` flag and the appropriate configuration for the member.
Make sure to use the same network name for all members.
Then create the network without specifying the `--target` flag to actually set it up.

For example, the following series of commands sets up a physical network with the name `UPLINK` on three cluster members:

`user@host:~$ ``lxc network create UPLINK --type=physical parent=br0 --target=vm01
`
```text
Network UPLINK pending on member vm01
```

`user@host:~$ ``lxc network create UPLINK --type=physical parent=br0 --target=vm02
`
```text
Network UPLINK pending on member vm02
```

`user@host:~$ ``lxc network create UPLINK --type=physical parent=br0 --target=vm03
`
```text
Network UPLINK pending on member vm03
```

`user@host:~$ ``lxc network create UPLINK --type=physical
`
```text
Network UPLINK created
```

Also see [How to configure networks for a cluster](cluster_config_networks.md#cluster-config-networks).

UI

From the main navigation, select Networks.

On the resulting page, click Create network in the upper-right corner.

You can then configure the network name and type, as well as other attributes. Optional additional attributes are split into the categories Bridge, IPv4, IPv6 and DNS, which can be seen in the submenu on the right.

Click Create to create the network.

![Create a network in LXD](images/networks/network_create.png)

<a id="network-attach"></a>

## Attach a network to an instance

CLI

After creating a managed network, you can attach it to an instance as a [NIC device](../reference/devices_nic.md#devices-nic).

To do so, use the following command:

```none
lxc network attach <network_name> <instance_name> [<device_name>] [<interface_name>]
```

The device name and the interface name are optional, but we recommend specifying at least the device name.
If not specified, LXD uses the network name as the device name, which might be confusing and cause problems.
For example, LXD images perform IP auto-configuration on the `eth0` interface, which does not work if the interface is called differently.

For example, to attach the network `my-network` to the instance `my-instance` as `eth0` device, enter the following command:

```none
lxc network attach my-network my-instance eth0
```

UI

When [creating](instances_create.md#instances-create) or [configuring an instance](instances_configure.md#instances-configure), go to the Devices section in the left-hand submenu, then select Network to view and edit the networks linked to the instance.

![Add a network to an instance in LXD](images/networks/network_add_to_instance.png)

Click the Attach network button to add a new network. From here, you can select an existing network from the Network dropdown and assign it a device name.

![Attach a network to an instance in LXD](images/networks/network_attach_instance.png)

If configuring an instance, select Save changes to save your changes. If creating an instance, select Create to create your instance.

### Attach the network as a device

The [`lxc network attach`](../reference/manpages/lxc/network/attach.md#lxc-network-attach-md) command is a shortcut for adding a NIC device to an instance.
Alternatively, you can add a NIC device based on the network configuration in the usual way:

```none
lxc config device add <instance_name> <device_name> nic network=<network_name>
```

When using this way, you can add further configuration to the command to override the default settings for the network if needed.
See [NIC device](../reference/devices_nic.md#devices-nic) for all available device options.


# index.html.md

<a id="howto-storage-volumes"></a>

# How to manage storage volumes


            <p class="youtube_link">
              <a href="https://www.youtube.com/watch?v=dvQ111pbqtk" target="_blank">
                <span title="Custom storage volumes in LXD" class="play_icon">▶</span>
                <span title="Custom storage volumes in LXD">Watch on YouTube</span>
              </a>
            </p>
        
See the following sections for instructions on how to create, configure, view and resize [Storage volumes](../explanation/storage.md#storage-volumes).

## View storage volumes

You can display a list of all available storage volumes and check their configuration.

CLI

To list all available storage volumes, use the following command:

```none
lxc storage volume list
```

To display the storage volumes for all projects (not only the default project), add the `--all-projects` flag.

You can also display the storage volumes in a specific storage pool:

```none
lxc storage volume list my-pool
```

The resulting table contains, among other information, the [storage volume type](../explanation/storage.md#storage-volume-types) and the [content type](../explanation/storage.md#storage-content-types) for each storage volume.

#### NOTE
Custom storage volumes can use the same name as instance volumes. For example, you might have a container named `c1` with a container storage volume named `c1` and a custom storage volume named `c1`.
Therefore, to distinguish between instance storage volumes and custom storage volumes, all instance storage volumes must be referred to as `<volume_type>/<volume_name>` (for example, `container/c1` or `virtual-machine/vm`) in commands.

To show detailed configuration information about a specific volume, use the following command:

```none
lxc storage volume show my-pool custom/my-volume
```

To show state information about a specific volume, use the following command:

```none
lxc storage volume info my-pool virtual-machine/my-vm
```

In both commands, the default [storage volume type](../explanation/storage.md#storage-volume-types) is `custom`, so you can leave out the `custom/` when displaying information about a custom storage volume.

UI

From the main navigation, select Storage > Volumes.
The resulting page displays a table of available volumes. You can sort volumes by their pool by clicking the Pool column header of the table.

## Create a custom storage volume

When you create an instance, LXD automatically creates a storage volume that is used as the root disk for the instance.

You can add custom storage volumes to your instances.
Such custom storage volumes are independent of the instance, which means that they can be backed up separately and are retained until you delete them.
Custom storage volumes with content type `filesystem` can also be shared between different instances.

See [Storage volumes](../explanation/storage.md#storage-volumes) for detailed information.

### Create the volume

CLI

Use the following command to create a custom storage volume `vol1` of type `filesystem` in storage pool `my-pool`:

```none
lxc storage volume create my-pool vol1
```

By default, custom storage volumes use the `filesystem` [content type](../explanation/storage.md#storage-content-types).
To create a custom volume with content type `block`, add the `--type` flag:

```none
lxc storage volume create my-pool vol2 --type=block
```

UI

From the main navigation, select Storage > Volumes.

On the resulting page, click Create volume in the upper-right corner.

You can then configure the name and size of your storage volume.

You can select a content type from the Content type dropdown. Additional settings might appear, depending on the content type selected.

Click Create to create the storage pool.

![Create a storage volume in LXD](images/storage/storage_volumes_create.png)

<a id="storage-attach-volume"></a>

### Attach the volume to an instance

After creating a custom storage volume, you can add it to one or more instances as a [disk device](../reference/devices_disk.md#devices-disk).

The following restrictions apply:

- Storage volumes of [content type](../explanation/storage.md#storage-content-types) `block` or `iso` cannot be attached to containers, only to virtual machines.
- Storage volumes of [content type](../explanation/storage.md#storage-content-types) `block` that don’t have `security.shared` enabled cannot be attached to more than one instance at the same time.
  Attaching a `block` volume to more than one instance at a time risks data corruption.
- Storage volumes of [content type](../explanation/storage.md#storage-content-types) `iso` are always read-only, and can therefore be attached to more than one virtual machine at a time without corrupting data.
- Storage volumes of [content type](../explanation/storage.md#storage-content-types) `filesystem` can’t be attached to virtual machines while they’re running.
- You cannot attach a storage volume from a local storage pool (a pool that uses the [Directory](../reference/storage_dir.md#storage-dir), [Btrfs](../reference/storage_btrfs.md#storage-btrfs), [ZFS](../reference/storage_zfs.md#storage-zfs), or [LVM](../reference/storage_lvm.md#storage-lvm) driver) to an instance that has [`migration.stateful`](../reference/instance_options.md#instance-migration:migration.stateful) set to `true`. You must set [`migration.stateful`](../reference/instance_options.md#instance-migration:migration.stateful) to `false` on the instance. Note that doing so makes the instance ineligible for [live migration](instances_migrate.md#live-migration).

CLI

Use the following command to attach a custom storage volume `fs-vol` with content type `filesystem` to instance `c1`.
`/data` is the mount point for the storage volume inside the instance:

```none
lxc storage volume attach my-pool fs-vol c1 /data
```

Custom storage volumes with the content type `block` do not take a mount point:

```none
lxc storage volume attach my-pool bl-vol vm1
```

By default, custom storage volumes are added to the instance with the volume name as the [device](../reference/devices.md#devices) name.
If you want to use a different device name, you can add it to the command:

```none
lxc storage volume attach my-pool fs-vol c1 filesystem-volume /data
lxc storage volume attach my-pool bl-vol vm1 block-volume
```

### Attach the volume as a device

The [`lxc storage volume attach`](../reference/manpages/lxc/storage/volume/attach.md#lxc-storage-volume-attach-md) command is a shortcut for adding a disk device to an instance.
The following commands have the same effect as the corresponding commands above:

```none
lxc config device add c1 filesystem-volume disk pool=my-pool source=fs-vol path=/data
lxc config device add vm1 block-volume disk pool=my-pool source=bl-vol
```

This allows adding further configuration for the device.
See [disk device](../reference/devices_disk.md#devices-disk) for all available device options.

<a id="id2"></a>

### Configure I/O options

When you attach a storage volume to an instance as a [disk device](../reference/devices_disk.md#devices-disk), you can configure I/O limits for it.
To do so, set the [`limits.read`](../reference/devices_disk.md#device-disk-device-conf:limits.read), [`limits.write`](../reference/devices_disk.md#device-disk-device-conf:limits.write) or [`limits.max`](../reference/devices_disk.md#device-disk-device-conf:limits.max) options to the corresponding limits.
See the [Type: disk](../reference/devices_disk.md#devices-disk) reference for more information.

The limits are applied through the Linux `blkio` cgroup controller, which makes it possible to restrict I/O at the disk level (but nothing finer grained than that).

#### NOTE
Because the limits apply to a whole physical disk rather than a partition or path, the following restrictions apply:

- Limits will not apply to file systems that are backed by virtual devices (for example, device mapper).
- If a file system is backed by multiple block devices, each device will get the same limit.
- If two disk devices that are backed by the same disk are attached to the same instance, the limits of the two devices will be averaged.

All I/O limits only apply to actual block device access.
Therefore, consider the file system’s own overhead when setting limits.
Access to cached data is not affected by the limit.

For VMs the way the disk is exposed to the guest and its behavior can be configured.
To do so, set the [`io.bus`](../reference/devices_disk.md#device-disk-device-conf:io.bus), [`io.cache`](../reference/devices_disk.md#device-disk-device-conf:io.cache) or [`io.threads`](../reference/devices_disk.md#device-disk-device-conf:io.threads) options.
See the [Type: disk](../reference/devices_disk.md#devices-disk) reference for more information.

UI

You can attach a storage volume to an existing instance, or when creating a new instance:

- For an existing instance, select Instances from the main navigation, then select the target instance to view its details page. Open its Configuration tab.
- For a new instance, you must first select a base image during the instance creation process.

In either scenario, then select Disk from the Devices section of the secondary menu.

Click Attach disk device.

![Attach a storage volume to an instance - Disk configuration page](images/storage/storage_volumes_attach_to_instance_1.png)

The resulting modal allows you to choose your disk type. Select Attach custom volume:

![Attach a storage volume to an instance - Attach disk device modal](images/storage/storage_volumes_attach_to_instance_2.png)

Next, you can either select a pre-existing volume to attach to the instance by clicking its corresponding Select button, or create a new custom volume by clicking Create volume:

![Attach a storage volume to an instance - Attach custom volume modal](images/storage/storage_volumes_attach_to_instance_3.png)

Once the modal closes, you might be required to add a mount point file path in the Mount point field.
Finally, you can save your instance changes. If you are in the instance creation process, create your instance by clicking Create.

<a id="storage-volume-special"></a>

### Use the volume for backups or images

Instead of attaching a custom volume to an instance as a disk device, you can also use it as a special kind of volume to store [backups](../backup.md#backups) or [images](../image-handling.md#about-images).

CLI

To do so, you must set the corresponding [server configuration](../server.md#server-options-misc):

- To use a custom volume `my-backups-volume` to store the backup tarballs:
  ```none
  lxc config set storage.backups_volume=my-pool/my-backups-volume
  ```
- To use a custom volume `my-images-volume` to store the image tarballs:
  ```none
  lxc config set storage.images_volume=my-pool/my-images-volume
  ```

UI

To use a volume to store backups or images, select Settings from the main navigation. From this page, set the value of the storage.backups_volume key or the storage.images_volume key to the name of the target storage volume, then select Save.

<a id="storage-configure-volume"></a>

## Configure storage volume settings

See the [Storage drivers](../reference/storage_drivers.md#storage-drivers) documentation for a list of available storage volume configuration options for each driver.

CLI

To set the maximum size of custom storage volume `my-volume` to 1 GiB, use the following command:

```none
lxc storage volume set my-pool my-volume size=1GiB
```

The default [storage volume type](../explanation/storage.md#storage-volume-types) is `custom`, but other volume types can be configured by using the `<volume_type>/<volume_name>` syntax.

To set the snapshot expiry time for virtual machine `my-vm` to one month, use the following command:

```none
lxc storage volume set my-pool virtual-machine/my-vm snapshots.expiry=1M
```

You can also edit the storage volume configuration as YAML in a text editor:

```none
lxc storage volume edit my-pool virtual-machine/my-vm
```

<a id="id4"></a>

### Configure default values for storage volumes

You can define default volume configurations for a storage pool.
To do so, set a storage pool configuration with a `volume` prefix: `volume.<KEY>=<VALUE>`.

This value is used for all new storage volumes in the pool, unless it is explicitly overridden.
In general, the defaults set at the storage pool level can be overridden through a volume’s configuration.
For storage volumes of [type](../explanation/storage.md#storage-volume-types) `container` or `virtual-machine`, the pool’s volume configuration can be overridden via the instance configuration.

For example, to set the default volume size for `my-pool`, use the following command:

```none
lxc storage set my-pool volume.size=15GiB
```

### Attach instance root volumes to other instances

Virtual-machine root volumes can be attached as disk devices to other virtual machines.
In order to prevent concurrent access, `security.protection.start` must be set on
an instance before its root volume can be attached to another virtual-machine.

Assuming `vm1` is stopped and `vm2` is running, attach the `virtual-machine/vm1` storage
volume to `vm2`:

```none
lxc config set vm1 security.protection.start=true
lxc storage volume attach my-pool virtual-machine/vm1 vm2
```

`virtual-machine/vm1` must be detached from `vm2` before `security.protection.start`
can be unset from `vm1`:

```none
lxc storage volume detach my-pool virtual-machine/vm1 vm2
lxc config unset vm1 security.protection.start
```

`security.shared` can also be used on `virtual-machine` volumes to enable concurrent
access. Note that concurrent access to block volumes may result in data loss.

### Attaching virtual machine snapshots to other instances

Virtual-machine snapshots can also be attached to instances with the
[`source.snapshot`](../reference/devices_disk.md#device-disk-device-conf:source.snapshot) disk device
configuration key.

```none
lxc config device add v1 v2-root-snap0 disk pool=my-pool source=vm2 source.type=virtual-machine source.snapshot=snap0
```

### Resize a storage volume

If you need more storage in a volume, you can increase the size of your storage volume.
In some cases, it is also possible to reduce the size of a storage volume.

To adjust a storage volume’s quota, set its `size` configuration.
For example, to resize `my-volume` in storage pool `my-pool` to `15GiB`, use the following command:

```none
lxc storage volume set my-pool my-volume size=15GiB
```

#### IMPORTANT
- Growing a volume is possible if the storage pool has sufficient storage.
- Shrinking a storage volume is only possible for storage volumes with content type `filesystem`.
  It is not guaranteed to work though, because you cannot shrink storage below its current used size.
- Shrinking a storage volume with content type `block` is not possible.

UI

To configure a custom storage volume, select Storage > Volumes from the main navigation. Next, click the name of your target storage volume to view its details page.

#### NOTE
Volume details pages are only available for volumes of type Custom. Volumes of other types—such as Instance root disks—can also be accessed from the Volumes page and redirect to their respective entity overview or list page.

To sort the Volumes table by type, you can click the Content type column header.

On the volume’s overview page, go to the Configuration tab. Here, you can configure settings such as the storage volume size. Further configuration options can be found in the secondary menu.
After making changes, click the Save changes button. This button also displays the number of changes you have made.

## Create a storage volume in a cluster

For most storage drivers, custom storage volumes are not replicated across the cluster and exist only on the member for which they were created.
This behavior differs for remote storage pools (`ceph`, `cephfs` and `powerflex`), where volumes are available from any cluster member.

CLI

To add a custom storage volume on a cluster member, add the `--target` flag:

```bash
lxc storage volume create <pool-name> <volume-name> --target=<member-name>
```

Example:

```bash
lxc storage volume create my-pool my-volume --target=my-member
```

To create a custom storage volume of type `iso`, use `import` instead of `create`:

```bash
lxc storage volume import <pool-name> <path-to-iso> <volume-name> --type=iso
```

UI

To create a storage volume in a clustered environment, select Storage > Volumes from the main navigation. On the Volumes page, click Create volume in the upper-right corner.

On the volume creation page, select the cluster member on which to base the storage volume from the Cluster member dropdown. This dropdown is only available if the storage pool selected for this volume is cluster-member specific, rather than shared across the cluster.

![Create a custom storage volume in a clustered environment](images/storage/storage_volumes_create_clustered.png)

To find out more about clusters in LXD, see:

- [Clustering how-to guides](../clustering.md#clustering)
- [An explanation about clusters](../explanation/clusters.md#exp-clusters)


# index.html.md

<a id="howto-cluster-storage"></a>

# How to configure storage for a cluster

All members of a cluster must have identical storage pools.
The only configuration keys that may differ between pools on different members are [`source`](../reference/storage_drivers.md#storage-drivers), [`size`](../reference/storage_drivers.md#storage-drivers), [`zfs.pool_name`](../reference/storage_zfs.md#storage-zfs-pool-conf:zfs.pool_name), [`lvm.thinpool_name`](../reference/storage_lvm.md#storage-lvm-pool-conf:lvm.thinpool_name) and [`lvm.vg_name`](../reference/storage_lvm.md#storage-lvm-pool-conf:lvm.vg_name).
See [Member configuration](../explanation/clusters.md#clustering-member-config) for more information.

LXD creates a default `local` storage pool for each cluster member during initialization.

Creating additional storage pools is a two-step process:

1. Define and configure the new storage pool across all cluster members.
   For example, for a cluster that has three members:
   ```none
   lxc storage create --target server1 data zfs source=/dev/vdb1
   lxc storage create --target server2 data zfs source=/dev/vdc1
   lxc storage create --target server3 data zfs source=/dev/vdb1 size=10GiB
   ```

   #### NOTE
   You can pass only the member-specific configuration keys `source`, `size`, `zfs.pool_name`, `lvm.thinpool_name` and `lvm.vg_name`.
   Passing other configuration keys results in an error.

   These commands define the storage pool, but they don’t create it.
   If you run [`lxc storage list`](../reference/manpages/lxc/storage/list.md#lxc-storage-list-md), you can see that the pool is marked as “pending”.
2. Run the following command to instantiate the storage pool on all cluster members:
   ```none
   lxc storage create data zfs
   ```

   #### NOTE
   You can add configuration keys that are not member-specific to this command.

   If you missed a cluster member when defining the storage pool, or if a cluster member is down, you get an error.

Also see [Create a storage pool in a cluster](storage_pools.md#howto-storage-pools-create-cluster).

<a id="howto-cluster-storage-view"></a>

## View member-specific pool configuration

Running [`lxc storage show <pool_name>`](../reference/manpages/lxc/storage/show.md#lxc-storage-show-md) shows the cluster-wide configuration of the storage pool.

To view the member-specific configuration, use the `--target` flag.
For example:

```none
lxc storage show data --target server2
```

## Create storage volumes

For most storage drivers (all except for Ceph-based storage drivers), storage volumes are not replicated across the cluster and exist only on the member for which they were created.
Run [`lxc storage volume list <pool_name>`](../reference/manpages/lxc/storage/volume/list.md#lxc-storage-volume-list-md) to see on which member a certain volume is located.

When creating a storage volume, use the `--target` flag to create a storage volume on a specific cluster member.
Without the flag, the volume is created on the cluster member on which you run the command.
For example, to create a volume on the current cluster member `server1`:

```none
lxc storage volume create local vol1
```

To create a volume with the same name on another cluster member:

```none
lxc storage volume create local vol1 --target server2
```

Different volumes can have the same name as long as they live on different cluster members.
Typical examples for this are image volumes.

You can manage storage volumes in a cluster in the same way as you do in non-clustered deployments, except that you must pass the `--target` flag to your commands if more than one cluster member has a volume with the given name.
For example, to show information about the storage volumes:

```none
lxc storage volume show local vol1 --target server1
lxc storage volume show local vol1 --target server2
```


# index.html.md

<a id="howto-storage-pools"></a>

# How to manage storage pools

See the following sections for instructions on how to create, configure, view, and resize [Storage pools](../explanation/storage.md#storage-pools).

<a id="howto-storage-pools-view"></a>

## View storage pools

You can display a list of all available storage pools and check their configuration.

CLI

To list all available storage pools, run:

```none
lxc storage list
```

The storage pool created during initialization is usually called `default` or `local`.

To show detailed information about a specific pool, run:

```none
lxc storage show <pool_name>
```

To see usage information for a specific pool, run:

```none
lxc storage info <pool_name>
```

UI

To view storage pools in the UI, select Pools from the Storage section of the main navigation. Select a pool from the list for detailed information.

<a id="howto-storage-pools-create"></a>

## Create a storage pool

LXD creates a storage pool during initialization. You can add more storage pools later, using the same or different driver. See the [Storage drivers](../reference/storage_drivers.md#storage-drivers) documentation to learn about available configuration options for each driver.

By default, LXD sets up loop-based storage with a sensible default size/quota: 20% of the free disk space, with a minimum of 5 GiB and a maximum of 30 GiB.

When using a Ceph storage driver, first see the [Requirements for Ceph-based storage pools](#howto-storage-pools-ceph-requirements) section below.

CLI

To create a storage pool, run:

```none
lxc storage create <pool_name> <driver> [configuration_options...]
```

See the [Storage drivers](../reference/storage_drivers.md#storage-drivers) documentation for a list of available configuration options for each driver.

UI

To create a storage pool, select Pools from the Storage section of the main navigation, then click Create pool. On the resulting screen, the Name and Driver fields are required.

Once you select a driver, the fields below the driver selection dropdown might change. Furthermore, some drivers also offer a secondary settings page, as shown in the example below for the ZFS driver:

![Storage pool options for driver ZFS in LXD-UI](images/storage/storage_pools_create_ZFS_driver.png)

After creating a storage pool, [back up its configuration](#howto-storage-pools-config-backup) for future recovery.

<a id="howto-storage-pools-create-examples"></a>

### Examples

The following CLI syntax examples show how to create a storage pool using different storage drivers.

dir

Create a directory pool named `pool1`:

```none
lxc storage create pool1 dir
```

Use the existing directory `/data/lxd` for `pool2`:

```none
lxc storage create pool2 dir source=/data/lxd
```

btrfs

Create a loop-backed pool named `pool1`:

```none
lxc storage create pool1 btrfs
```

You can specify `source` as either an existing filesystem path or a block device.

Reuse the existing Btrfs filesystem at `/some/path` for `pool2`:

```none
lxc storage create pool2 btrfs source=/some/path
```

Use a block device at `/dev/sdX` to create `pool3`:

```none
lxc storage create pool3 btrfs source=/dev/sdX
```

lvm

Create a loop-backed pool named `pool1` (the LVM volume group will also be called `pool1`):

```none
lxc storage create pool1 lvm
```

Use an existing LVM volume group called `my-pool` for `pool2`:

```none
lxc storage create pool2 lvm source=my-pool
```

Use an existing LVM thin pool called `my-pool` in volume group `my-vg` for `pool3`:

```none
lxc storage create pool3 lvm source=my-vg lvm.thinpool_name=my-pool
```

Create a pool named `pool4` on `/dev/sdX` (the LVM volume group will also be called `pool4`):

```none
lxc storage create pool4 lvm source=/dev/sdX
```

Create a pool named `pool5` on `/dev/sdX` with the LVM volume group name `my-pool`:

```none
lxc storage create pool5 lvm source=/dev/sdX lvm.vg_name=my-pool
```

zfs

Create a loop-backed pool named `pool1` (the ZFS zpool will also be called `pool1`):

```none
lxc storage create pool1 zfs
```

Create a loop-backed pool named `pool2` with the ZFS zpool name `my-tank`:

```none
lxc storage create pool2 zfs zfs.pool_name=my-tank
```

Use the existing ZFS zpool `my-tank` for `pool3`:

```none
lxc storage create pool3 zfs source=my-tank
```

Use the existing ZFS dataset `my-tank/slice` for `pool4`:

```none
lxc storage create pool4 zfs source=my-tank/slice
```

Use the existing ZFS dataset `my-tank/zvol` for `pool5` and configure it to use ZFS block mode:

```none
lxc storage create pool5 zfs source=my-tank/zvol volume.zfs.block_mode=yes
```

Create a pool named `pool6` on `/dev/sdX` (the ZFS zpool will also be called `pool6`):

```none
lxc storage create pool6 zfs source=/dev/sdX
```

Create a pool named `pool7` on `/dev/sdX` with the ZFS zpool name `my-tank`:

```none
lxc storage create pool7 zfs source=/dev/sdX zfs.pool_name=my-tank
```

ceph\*

For Ceph-based storage pools, first see the [Requirements for Ceph-based storage pools](#howto-storage-pools-ceph-requirements).

### Ceph RBD

Create an OSD storage pool named `pool1` in the default Ceph cluster (named `ceph`):

```none
lxc storage create pool1 ceph
```

Create an OSD storage pool named `pool2` in the Ceph cluster `my-cluster`:

```none
lxc storage create pool2 ceph ceph.cluster_name=my-cluster
```

Create an OSD storage pool named `pool3` with the on-disk name `my-osd` in the default Ceph cluster:

```none
lxc storage create pool3 ceph ceph.osd.pool_name=my-osd
```

Use the existing OSD storage pool `my-already-existing-osd` for `pool4`:

```none
lxc storage create pool4 ceph ceph.osd.pool_name=my-already-existing-osd
```

Use the existing OSD erasure-coded pool `ecpool` and the OSD replicated pool `rpl-pool` for `pool5`:

```none
lxc storage create pool5 ceph ceph.osd.pool_name=rpl-pool ceph.osd.data_pool_name=ecpool
```

### Create a CephFS pool

#### NOTE
Each CephFS file system consists of two OSD storage pools, one for the actual data and one for the file metadata.

Use the existing CephFS file system `my-filesystem` for `pool1`:

```none
lxc storage create pool1 cephfs cephfs.path=my-filesystem
```

Use the sub-directory `my-directory` from `my-filesystem` for `pool2`:

```none
lxc storage create pool2 cephfs cephfs.path=my-filesystem/my-directory
```

Create a CephFS file system `my-filesystem` with a data pool called `my-data` and a metadata pool called `my-metadata` for `pool3`:

```none
lxc storage create pool3 cephfs cephfs.path=my-filesystem cephfs.create_missing=true cephfs.data_pool=my-data cephfs.meta_pool=my-metadata
```

### Ceph Object

A RADOS Gateway endpoint is required for a [Ceph Object](../reference/storage_cephobject.md#storage-cephobject) storage pool. See: [Ceph Object and radosgw](#howto-storage-pools-ceph-requirements-radosgw).

For a non-clustered LXD server, create `pool1` by passing in a Ceph Object Gateway endpoint (the endpoint shown below is only an example; you must use your own):

```none
lxc storage create pool1 cephobject cephobject.radosgw.endpoint=http://192.0.2.10:8080
```

If your LXD server is clustered, such as in a [MicroCloud](https://canonical.com/microcloud) deployment, see: [Create a storage pool in a cluster](#howto-storage-pools-create-cluster).

powerflex

Create a storage pool named `pool1` using the PowerFlex pool `sp1` in the protection domain `pd1`:

```none
lxc storage create pool1 powerflex powerflex.pool=sp1 powerflex.domain=pd1 powerflex.gateway=https://powerflex powerflex.user.name=lxd powerflex.user.password=foo
```

Create a storage pool named `pool2` using the ID of PowerFlex pool `sp1`:

```none
lxc storage create pool2 powerflex powerflex.pool=<ID of sp1> powerflex.gateway=https://powerflex powerflex.user.name=lxd powerflex.user.password=foo
```

Create a storage pool named `pool3` that uses PowerFlex volume snapshots (see [Limitations](../reference/storage_powerflex.md#storage-powerflex-limitations)) when creating volume copies:

```none
lxc storage create pool3 powerflex powerflex.snapshot_copy=true powerflex.pool=<id of sp1> powerflex.gateway=https://powerflex powerflex.user.name=lxd powerflex.user.password=foo
```

Create a storage pool named `pool4` that uses a PowerFlex gateway with a certificate that is not trusted:

```none
lxc storage create pool4 powerflex powerflex.gateway.verify=false powerflex.pool=<id of sp1> powerflex.gateway=https://powerflex powerflex.user.name=lxd powerflex.user.password=foo
```

Create a storage pool named `pool5` that explicitly uses the PowerFlex SDC:

```none
lxc storage create pool5 powerflex powerflex.mode=sdc powerflex.pool=<id of sp1> powerflex.gateway=https://powerflex powerflex.user.name=lxd powerflex.user.password=foo
```

powerstore

Create a storage pool named `pool1` that uses iSCSI to connect to PowerStore array:

```none
lxc storage create pool1 powerstore powerstore.mode=iscsi powerstore.gateway=https://powerstore powerstore.user.name=lxd powerstore.user.password=foo
```

Create a storage pool named `pool2` that uses SCSI/FC to connect to PowerStore array:

```none
lxc storage create pool2 powerstore powerstore.mode=scsi/fc powerstore.gateway=https://powerstore powerstore.user.name=lxd powerstore.user.password=foo
```

Create a storage pool named `pool3` that uses a PowerStore gateway with a certificate that is not trusted:

```none
lxc storage create pool3 powerstore powerstore.mode=iscsi powerstore.gateway=https://powerstore powerstore.gateway.verify=false powerstore.user.name=lxd powerstore.user.password=foo
```

pure

Create a storage pool named `pool1` that uses NVMe/TCP by default:

```none
lxc storage create pool1 pure pure.gateway=https://<pure-storage-address> pure.api.token=<pure-storage-api-token>
```

Create a storage pool named `pool2` that uses a Pure Storage gateway with a certificate that is not trusted:

```none
lxc storage create pool2 pure pure.gateway=https://<pure-storage-address> pure.gateway.verify=false pure.api.token=<pure-storage-api-token>
```

Create a storage pool named `pool3` that uses iSCSI to connect to Pure Storage array:

```none
lxc storage create pool3 pure pure.gateway=https://<pure-storage-address> pure.api.token=<pure-storage-api-token> pure.mode=iscsi
```

Create a storage pool named `pool4` that uses NVMe/TCP to connect to Pure Storage array via specific target addresses:

```none
lxc storage create pool4 pure pure.gateway=https://<pure-storage-address> pure.api.token=<pure-storage-api-token> pure.mode=nvme/tcp pure.target=<target_address_1>,<target_address_2>
```

alletra

Create a storage pool named `pool1` that uses NVMe/TCP by default:

```none
lxc storage create pool1 alletra alletra.wsapi=https://<alletra-storage-address> alletra.user.name=<alletra-storage-username> alletra.user.password=<alletra-storage-password>
```

Create a storage pool named `pool2` that uses a HPE Alletra gateway with a certificate that is not trusted:

```none
lxc storage create pool2 alletra alletra.wsapi=https://<alletra-storage-address> alletra.wsapi.verify=false alletra.user.name=<alletra-storage-username> alletra.user.password=<alletra-storage-password>
```

Create a storage pool named `pool3` that uses NVMe/TCP to connect to HPE Alletra array via specific target addresses:

```none
lxc storage create pool3 alletra alletra.wsapi=https://<alletra-storage-address> alletra.user.name=<alletra-storage-username> alletra.user.password=<alletra-storage-password> alletra.mode=nvme/tcp alletra.target=<target_address_1>,<target_address_2>
```

<a id="howto-storage-pools-create-cluster"></a>

## Create a storage pool in a cluster

If you want to add a storage pool to a LXD cluster, you must create the storage pool for each cluster member separately. This is because the configuration might differ among cluster members (for example, the storage location or the size of the pool).

If any cluster members use disks that already contain a LXD storage pool, or you want to recover an existing remote storage pool, refer to the [Recover a storage pool](#howto-storage-pools-recover) section.

CLI

To create a storage pool via the CLI, start by creating a pending storage pool on each member with the `--target=<cluster_member>` flag and the appropriate configuration for the member.

Make sure to use the same storage pool name for all members. Then create the storage pool *without* specifying the `--target` flag to actually set it up.

For further details, see [How to configure storage for a cluster](cluster_config_storage.md#howto-cluster-storage).

UI

Follow the same method to [create a storage pool](#howto-storage-pools-create) as for a non-clustered LXD server.

Depending on the selected driver, some settings can be configured per cluster member or applied globally to the cluster, as shown in the example below for the ZFS driver:

![Create a storage pool in a clustered LXD environment](images/storage/storage_pools_create_clustered_pool.png)

After creating a storage pool, [back up its configuration](#howto-storage-pools-config-backup) for future recovery.

<a id="howto-storage-pools-create-cluster-examples"></a>

### Examples

The following CLI syntax examples show how to create a storage pool in a cluster using different storage drivers.

zfs

Create a storage pool named `my-pool` using the ZFS driver at different locations and with different sizes on three cluster members:

`user@host:~$ ``lxc storage create my-pool zfs source=/dev/sdX size=10GiB --target=vm01
`
```text
Storage pool my-pool pending on member vm01
```

`user@host:~$ ``lxc storage create my-pool zfs source=/dev/sdX size=15GiB --target=vm02
`
```text
Storage pool my-pool pending on member vm02
```

`user@host:~$ ``lxc storage create my-pool zfs source=/dev/sdY size=10GiB --target=vm03
`
```text
Storage pool my-pool pending on member vm03
```

`user@host:~$ ``lxc storage create my-pool zfs
`
```text
Storage pool my-pool created
```

ceph\*

For Ceph-based storage pools, first see the [Requirements for Ceph-based storage pools](#howto-storage-pools-ceph-requirements).

### Ceph RBD

Create a storage pool named `my-ceph-pool` using the [Ceph RBD driver](../reference/storage_ceph.md#storage-ceph) and the on-disk name `my-osd` on three cluster members.
Because the [`ceph.osd.pool_name`](../reference/storage_ceph.md#storage-ceph-pool-conf:ceph.osd.pool_name) configuration setting isn’t member-specific, it must be set when creating the actual storage pool:

`user@host:~$ ``lxc storage create my-ceph-pool ceph --target=vm01
`
```text
Storage pool my-ceph-pool pending on member vm01
```

`user@host:~$ ``lxc storage create my-ceph-pool ceph --target=vm02
`
```text
Storage pool my-ceph-pool pending on member vm02
```

`user@host:~$ ``lxc storage create my-ceph-pool ceph --target=vm03
`
```text
Storage pool my-ceph-pool pending on member vm03
```

`user@host:~$ ``lxc storage create my-ceph-pool ceph ceph.osd.pool_name=my-osd
`
```text
Storage pool my-ceph-pool created
```

### Ceph Object

Create a storage pool named `my-cephobject-pool` using the [Ceph Object driver](../reference/storage_cephobject.md#storage-cephobject) and a preconfigured [RADOS Gateway endpoint](#howto-storage-pools-ceph-requirements-radosgw) (the endpoint shown below is only an example):

`user@host:~$ ``lxc storage create my-cephobject-pool cephobject --target=vm01
`
```text
Storage pool my-cephobject-pool pending on member vm01
```

`user@host:~$ ``lxc storage create my-cephobject-pool cephobject --target=vm02
`
```text
Storage pool my-cephobject-pool pending on member vm02
```

`user@host:~$ ``lxc storage create my-cephobject-pool cephobject --target=vm03
`
```text
Storage pool my-cephobject-pool pending on member vm03
```

`user@host:~$ ``lxc storage create my-cephobject-pool cephobject cephobject.radosgw.endpoint=http://192.0.2.10:8080
`
```text
Storage pool my-cephobject-pool created
```

powerflex

Create a storage pool named `my-powerflex-pool` using the [Dell PowerFlex driver](../reference/storage_powerflex.md#storage-powerflex) in SDC mode and the pool `sp1` in protection domain `pd1`:

`user@host:~$ ``lxc storage create my-powerflex-pool powerflex --target=vm01
`
```text
Storage pool my-powerflex-pool pending on member vm01
```

`user@host:~$ ``lxc storage create my-powerflex-pool powerflex --target=vm02
`
```text
Storage pool my-powerflex-pool pending on member vm02
```

`user@host:~$ ``lxc storage create my-powerflex-pool powerflex --target=vm03
`
```text
Storage pool my-powerflex-pool pending on member vm03
```

`user@host:~$ ``lxc storage create my-powerflex-pool powerflex powerflex.mode=sdc powerflex.pool=sp1 powerflex.domain=pd1 powerflex.gateway=https://powerflex powerflex.user.name=lxd powerflex.user.password=foo
`
```text
Storage pool my-powerflex-pool created
```

powerstore

Create a storage pool named `my-powerstore-pool` using the [Dell PowerStore driver](../reference/storage_powerstore.md#storage-powerstore):

`user@host:~$ ``lxc storage create my-powerstore-pool powerstore --target=vm01
`
```text
Storage pool my-powerstore-pool pending on member vm01
```

`user@host:~$ ``lxc storage create my-powerstore-pool powerstore --target=vm02
`
```text
Storage pool my-powerstore-pool pending on member vm02
```

`user@host:~$ ``lxc storage create my-powerstore-pool powerstore --target=vm03
`
```text
Storage pool my-powerstore-pool pending on member vm03
```

`user@host:~$ ``lxc storage create my-powerstore-pool powerstore powerstore.mode=scsi/fc powerstore.gateway=https://<powerstore-storage-address> powerstore.user.name=<admin-username> powerstore.user.password=<admin-password>
`
```text
Storage pool my-powerstore-pool created
```

pure

Create a storage pool named `my-purestorage-pool` using the [Pure Storage driver](../reference/storage_pure.md#storage-pure):

`user@host:~$ ``lxc storage create my-purestorage-pool pure --target=vm01
`
```text
Storage pool my-purestorage-pool pending on member vm01
```

`user@host:~$ ``lxc storage create my-purestorage-pool pure --target=vm02
`
```text
Storage pool my-purestorage-pool pending on member vm02
```

`user@host:~$ ``lxc storage create my-purestorage-pool pure --target=vm03
`
```text
Storage pool my-purestorage-pool pending on member vm03
```

`user@host:~$ ``lxc storage create my-purestorage-pool pure pure.gateway=https://<pure-storage-address> pure.api.token=<pure-storage-api-token>
`
```text
Storage pool my-purestorage-pool created
```

alletra

Create a storage pool named `my-alletrastorage-pool` using the [HPE Alletra driver](../reference/storage_alletra.md#storage-alletra):

`user@host:~$ ``lxc storage create my-alletrastorage-pool alletra --target=vm01
`
```text
Storage pool my-alletrastorage-pool pending on member vm01
```

`user@host:~$ ``lxc storage create my-alletrastorage-pool alletra --target=vm02
`
```text
Storage pool my-alletrastorage-pool pending on member vm02
```

`user@host:~$ ``lxc storage create my-alletrastorage-pool alletra --target=vm03
`
```text
Storage pool my-alletrastorage-pool pending on member vm03
```

`user@host:~$ ``lxc storage create my-alletrastorage-pool alletra alletra.wsapi=https://<alletra-storage-address> alletra.user.name=<alletra-storage-username> alletra.user.password=<alletra-storage-password>
`
```text
Storage pool my-alletrastorage-pool created
```

<a id="howto-storage-pools-config-backup"></a>

## Back up storage pool configuration

To assist future [recovery](#howto-storage-pools-recover) in case a storage pool malfunctions, maintain a record of storage pools as a backup. For each pool, record the `driver` type and its `config` options shown by running:

```none
lxc storage show <pool_name>
```

The `config` options vary by driver type. Keep this record in a safe place, and update it if you [update a storage pool’s configuration](#howto-storage-pools-configure).

### For pools in a cluster

For [local storage pools](../reference/storage_drivers.md#storage-drivers-features-local) in a cluster, the `source` value is member-specific and must be obtained from each cluster member. For [non-local storage pools](../reference/storage_drivers.md#storage-drivers-features-nonlocal) with the `source` config option, its value is shared across all cluster members.

<a id="howto-storage-pools-recover"></a>

## Recover a storage pool

You might need to recover a storage pool when setting up a new LXD server or cluster with non-pristine storage disks, or when trying to access remote storage that was previously used by another LXD deployment.

Using recovery, you can restore instances, custom volumes, and buckets that are still located on those storage pools.

### Get storage pool configuration

Before recovering a storage pool, you need to know its original configuration: the driver type and any `config` options that differ from the default. Ideally, you have access to a record of the configuration as described in [Back up storage pool configuration](#howto-storage-pools-config-backup).

If you do not have access to this information, try alternate ways to retrieve it. If the pool is still available in the LXD database, you can use [`lxc storage show`](../reference/manpages/lxc/storage/show.md#lxc-storage-show-md):

```none
lxc storage show <pool_name>
```

You can also try this command, which provides hints about missing storage pools and their original configuration, if such information can be discovered:

```none
lxd recover
```

See the [Storage drivers](../reference/storage_drivers.md#storage-drivers) documentation for a list of available configuration options for each driver.

### Recover a pool

To recover a storage pool, use the [`lxc storage create`](../reference/manpages/lxc/storage/create.md#lxc-storage-create-md) command with the `source.recover=true` flag and the pool’s original, non-default configuration options:

```none
lxc storage create <pool_name> <driver> source.recover=true [original_pool_configuration_options...]
```

<a id="howto-storage-pools-recover-examples"></a>

### Examples

The following CLI syntax examples show how to recover different types of storage pools.

dir

Recover a pool named `pool1`:

```none
lxc storage create pool1 dir source.recover=true source=/data/lxd
```

btrfs

Recover a pool named `pool1` on the existing Btrfs filesystem at `/some/path`:

```none
lxc storage create pool1 btrfs source.recover=true source=/some/path
```

Recover a pool named `pool2` on `/dev/sdX`:

```none
lxc storage create pool2 btrfs source.recover=true source=/dev/sdX
```

lvm

Recover a pool named `pool1` using the existing LVM volume group called `my-pool`:

```none
lxc storage create pool1 lvm source.recover=true source=my-pool
```

Recover a pool named `pool2` using the existing LVM thin pool called `my-pool` in volume group `my-vg`:

```none
lxc storage create pool2 lvm source.recover=true source=my-vg lvm.thinpool_name=my-pool
```

Recover a pool named `pool3` on `/dev/sdX`:

```none
lxc storage create pool3 lvm source.recover=true source=/dev/sdX
```

Recover a pool named `pool4` on `/dev/sdX` with the LVM volume group name `my-pool`:

```none
lxc storage create pool4 lvm source.recover=true source=/dev/sdX lvm.vg_name=my-pool
```

zfs

Recover a pool named `pool1` using the existing ZFS pool `my-tank`:

```none
lxc storage create pool1 zfs source.recover=true source=my-tank
```

Recover a pool named `pool2` using the existing ZFS dataset `my-tank/slice`:

```none
lxc storage create pool2 zfs source.recover=true source=my-tank/slice
```

ceph\*

For Ceph-based storage pools, first see the [Requirements for Ceph-based storage pools](#howto-storage-pools-ceph-requirements).

### Ceph RBD

Recover a pool named `pool1` using the existing OSD storage pool `my-osd`:

```none
lxc storage create pool1 ceph source.recover=true ceph.osd.pool_name=my-osd
```

Recover a pool named `pool2` using the existing OSD storage pool `my-osd` in the Ceph cluster `my-cluster`:

```none
lxc storage create pool2 ceph source.recover=true ceph.osd.pool_name=my-osd ceph.cluster_name=my-cluster
```

### CephFS

Recover a pool named `pool1` using the existing CephFS file system `my-filesystem`:

```none
lxc storage create pool1 cephfs source.recover=true cephfs.path=my-filesystem
```

Recover a pool named `pool2` using the existing sub-directory `my-directory` on the Ceph FS file system `my-filesystem`:

```none
lxc storage create pool2 cephfs source.recover=true cephfs.path=my-filesystem/my-directory
```

### Ceph Object

The Ceph Object storage driver doesn’t require providing any additional configuration for recovery.
Use the regular Ceph object pool creation command for recovery.

Ceph Object does not yet support recovery of existing buckets already present on the `radosgw`.

powerflex

You do not need to provide any additional configuration for recovery with the PowerFlex storage driver. Use the regular PowerFlex pool creation command for recovery.

This is because when creating a PowerFlex pool, LXD does not create any entities on the storage array. Instead, it uses an existing pool inside the respective protection domain.

pure

Recover a pool named `pool1` using the existing pod `pool1`:

```none
lxc storage create pool1 pure source.recover=true pure.gateway=https://<pure-storage-address> pure.api.token=<pure-storage-api-token>
```

Recover a pool named `pool2` using the existing pod `pool2` and iSCSI to connect to Pure Storage array:

```none
lxc storage create pool2 pure source.recover=true pure.gateway=https://<pure-storage-address> pure.api.token=<pure-storage-api-token> pure.mode=iscsi
```

Recover a pool named `pool3` using the existing pod `pool3` and NVMe/TCP to connect to Pure Storage array via specific target address:

```none
lxc storage create pool3 pure source.recover=true pure.gateway=https://<pure-storage-address> pure.api.token=<pure-storage-api-token> pure.mode=nvme/tcp pure.target=<target_address_1>,<target_address_2>
```

alletra

Recover a pool named `pool1` using the existing volume set `pool1`:

```none
lxc storage create pool1 alletra source.recover=true alletra.wsapi=https://<alletra-storage-address> alletra.user.name=<alletra-storage-username> alletra.user.password=<alletra-storage-password>
```

Recover a pool named `pool2` using the existing volume set `pool2` and accept a not trusted certificate of the HPE Alletra gateway:

```none
lxc storage create pool2 alletra source.recover=true alletra.wsapi=https://<alletra-storage-address> alletra.wsapi.verify=false alletra.user.name=<alletra-storage-username> alletra.user.password=<alletra-storage-password>
```

Recover a pool named `pool3` using the existing volume set `pool3` and NVMe/TCP to connect to HPE Alletra array via specific target address:

```none
lxc storage create pool3 alletra source.recover=true alletra.wsapi=https://<alletra-storage-address> alletra.user.name=<alletra-storage-username> alletra.user.password=<alletra-storage-password> alletra.mode=nvme/tcp alletra.target=<target_address_1>,<target_address_2>
```

<a id="howto-storage-pools-configure"></a>

## Configure a storage pool

See the [Storage drivers](../reference/storage_drivers.md#storage-drivers) page for the available configuration options for each storage driver.

General keys for a storage pool (like `source`) are top-level. Driver-specific keys are namespaced by the driver name.

CLI

Use the following command to set configuration options for a storage pool:

```none
lxc storage set <pool_name> <key> <value>
```

For example, to turn off compression during storage pool migration for a `dir` storage pool, use the following command:

```none
lxc storage set my-dir-pool rsync.compression false
```

You can also edit the storage pool configuration by using the following command:

```none
lxc storage edit <pool_name>
```

UI

To configure a storage pool, select Pools from the Storage section of the main navigation.

The resulting screen shows a list of existing storage pools. Click a pool’s name to access its details.

Go to the Configuration tab. Here, you can configure settings such as the storage pool description.

After making changes, click the Save changes button. This button also displays the number of changes you have made.

We recommend that you [maintain a backup](#howto-storage-pools-config-backup) of the configuration of your storage pools for future recovery. Make sure to update this backup after your edited configuration.

<a id="howto-storage-pools-resize"></a>

## Resize a storage pool

If you need more storage, you can increase the size (quota) of your storage pool. You can only grow the pool (increase its size), not shrink it.

You can only resize loop-backed storage pools that are managed by LXD, meaning they must use the Btrfs, LVM, or ZFS storage drivers.

CLI

In the CLI, resize a storage pool by changing the `size` configuration key:

```none
lxc storage set <pool_name> size=<new_size>
```

UI

To resize a storage pool in the UI, select Pools from the Storage section of the main navigation.

Click the name of a storage pool to open its details page, then go to its Configuration tab. Edit the Size field.

After making changes, click the Save changes button. This button also displays the number of changes you have made before you save.

In clustered environments, the Size field appears as a per-member selector, allowing you to configure the size for each cluster member.

![Configuring storage pools sizes within a clustered environment.](images/storage/storage_pools_create_clustered_pool_size_config.png)

If you later need to [recover a storage pool](#howto-storage-pools-recover) and the pool has a non-default `size` configuration option, that option must be included for recovery. If needed, update the `size` in your [backup of the storage pool configuration](#howto-storage-pools-config-backup).

<a id="howto-storage-pools-ceph-requirements"></a>

## Requirements for Ceph-based storage pools

For Ceph-based storage pools, the requirements below must be met before you can [Create a storage pool](#howto-storage-pools-create) or [Create a storage pool in a cluster](#howto-storage-pools-create-cluster).

<a id="howto-storage-pools-ceph-requirements-cluster"></a>

### Ceph cluster

Before you can create a storage pool that uses the [Ceph RBD](../reference/storage_ceph.md#storage-ceph), [CephFS](../reference/storage_cephfs.md#storage-cephfs), or [Ceph Object](../reference/storage_cephobject.md#storage-cephobject) driver, you must have access to a [Ceph](https://ceph.io) cluster.

To deploy a Ceph cluster, we recommend using [MicroCloud](https://snapcraft.io/microcloud). If you have completed the default MicroCloud setup, you already have a Ceph cluster deployed through MicroCeph, so this requirement is met. MicroCeph is a lightweight way of deploying and managing a Ceph cluster.

If you do not use MicroCloud, set up a standalone deployment of [MicroCeph](https://snapcraft.io/microceph) before you continue.

<a id="howto-storage-pools-ceph-requirements-radosgw"></a>

### Ceph Object and `radosgw`

Storage pools that use the [Ceph Object driver](../reference/storage_cephobject.md#storage-cephobject) require a Ceph cluster with the RADOS Gateway (also known as RGW or `radosgw`) enabled.

<a id="howto-storage-pools-ceph-requirements-radosgw-check"></a>

#### Check if `radosgw` is already enabled

To check if the RADOS Gateway is already enabled in MicroCeph, run this command from one of its cluster members:

```none
microceph status
```

In the output, look for a cluster member with `rgw` in its `Services` list.

Example:

`root@micro1:~# ``microceph status
`
```text
MicroCeph deployment summary:
- micro1 (192.0.2.10)
  Services: mds, mgr, mon, rgw, osd
  Disks: 1
- micro2 (192.0.2.20)
  Services: mds, mgr, mon, osd
  Disks: 1
```

In the output above, notice `rgw` in the list of `Services` for `micro1`. This means that this cluster member is running the RADOS Gateway.

Look for `rgw` in your output. If you do not see it, you must [Enable radosgw](#howto-storage-pools-ceph-requirements-radosgw-enable).

If you do see it, you’ll need the corresponding port number. On the cluster member with the `rgw` service, run:

```none
sudo ss -ltnp | grep radosgw
```

Example:

`root@micro1:~# ``sudo ss -ltnp | grep radosgw
`
```text
LISTEN 0      4096         0.0.0.0:8080      0.0.0.0:*    users:(("radosgw",pid=11345,fd=60))
LISTEN 0      4096            [::]:8080         [::]:*    users:(("radosgw",pid=11345,fd=61))
```

The output above shows that the `radosgw` port number is `8080`.

<a id="howto-storage-pools-ceph-requirements-radosgw-enable"></a>

#### Enable `radosgw`

If you did not find `rgw` in the `Services` list for any of your cluster members in the output from `microceph status`, then you must enable the RADOS Gateway. On one of the Ceph cluster members, run:

```none
sudo microceph enable rgw --port 8080
```

We include the `--port 8080` flag because if unspecified, the default port is `80`. This default is a commonly used port number that can often cause conflicts with other services. You are not required to use `8080` — if needed, use a different port number.

<a id="howto-storage-pools-ceph-requirements-radosgw-endpoint"></a>

#### The RADOS Gateway endpoint

The full RADOS Gateway endpoint includes the HTTP protocol, the IP address of the Ceph cluster member where the `rgw` service is enabled, and the port number specified. Example: `http://192.0.2.10:8080`.


# index.html.md

<a id="images-create"></a>

# How to create images

If you want to create and share your own images, you can do this either based on an existing instance or snapshot or by building your own image from scratch.

<a id="images-create-publish"></a>

## Publish an image from an instance or snapshot

If you want to be able to use an instance or an instance snapshot as the base for new instances, you should create and publish an image from it.

When publishing an image from an instance, make sure that the instance is stopped.

CLI

To publish an image from an instance, enter the following command:

```none
lxc publish <instance_name> [<remote>:]
```

To publish an image from a snapshot, enter the following command:

```none
lxc publish <instance_name>/<snapshot_name> [<remote>:]
```

In both cases, you can specify an alias for the new image with the `--alias` flag, set an expiration date with `--expire` and make the image publicly available with `--public`.
If an image with the same name already exists, add the `--reuse` flag to overwrite it.
See [`lxc publish --help`](../reference/manpages/lxc/publish.md#lxc-publish-md) for a full list of available flags.

API

To publish an image from an instance or a snapshot, send a POST request with the suitable source type to the `/1.0/images` endpoint.

To publish an image from an instance:

```none
lxc query --request POST /1.0/images --data '{
  "source": {
    "name": "<instance_name>",
    "type": "instance"
  }
}'
```

To publish an image from a snapshot:

```none
lxc query --request POST /1.0/images --data '{
  "source": {
    "name": "<instance_name>/<snapshot_name>",
    "type": "snapshot"
  }
}'
```

In both cases, you can include additional configuration (for example, you can include aliases, set a custom expiration date, or make the image publicly available).
For example:

```none
lxc query --request POST /1.0/images --data '{
  "aliases": [ { "name": "<alias>" } ],
  "expires_at": "2025-03-23T20:00:00-04:00",
  "public": true,
  "source": {
    "name": "<instance_name>",
    "type": "instance"
  }
}'
```

See [`POST /1.0/images`](/api/#/images/images_post) for more information.

UI

The UI does not currently support publishing an image from an instance, but you can publish from a snapshot.

To do so, go to the instance detail page and switch to the Snapshots tab.
Then click the Create image button (<svg width='16' height='16' xmlns='http://www.w3.org/2000/svg'><path d='M2.5 6v7.5h11V6H15v7.5a1.5 1.5 0 01-1.5 1.5h-11A1.5 1.5 0 011 13.5V6h1.5zM8 .22l3.309 3.308-.884.884-1.676-1.677.001 6.258h-1.5V2.735L5.574 4.412l-.884-.884L8 .219z' fill='%23000'  fill-rule='evenodd'/></svg>) and optionally enter an alias for the new image.
You can also choose whether the image should be publicly available.

Publishing the image might take a few minutes.
You can check the status under Operations.

The publishing process can take quite a while because it generates a tarball from the instance or snapshot and then compresses it.
As this can be particularly I/O and CPU intensive, publish operations are serialized by LXD.

### Prepare the instance for publishing

Before you publish an image from an instance, clean up all data that should not be included in the image.
Usually, this includes the following data:

- Instance metadata (use [`lxc config metadata`](../reference/manpages/lxc/config/metadata.md#lxc-config-metadata-md) or [`PATCH /1.0/instances/{name}/metadata`](/api/#/instances/instance_metadata_patch)/[`PUT /1.0/instances/{name}/metadata`](/api/#/instances/instance_metadata_put) to edit)
- File templates (use [`lxc config template`](../reference/manpages/lxc/config/template.md#lxc-config-template-md) or [`POST /1.0/instances/{name}/metadata/templates`](/api/#/instances/instance_metadata_templates_post) to edit)
- Instance-specific data inside the instance itself (for example, host SSH keys and `dbus/systemd machine-id`)

<a id="images-create-build"></a>

## Build an image

For building your own images, you can use [LXD image builder](https://github.com/canonical/lxd-imagebuilder).

See the [LXD image builder documentation](https://canonical-lxd-imagebuilder.readthedocs-hosted.com/en/latest/) for instructions for installing and using the tool.

<a id="images-repack-windows"></a>

### Repack a Windows image

You can run Windows VMs in LXD.
To do so, you must repack the Windows ISO with LXD image builder.

See the [LXD image builder tutorial](https://canonical-lxd-imagebuilder.readthedocs-hosted.com/en/latest/tutorials/use/) for instructions, or [How to install a Windows 11 VM using LXD](https://ubuntu.com/tutorials/how-to-install-a-windows-11-vm-using-lxd) for a full walk-through.


# index.html.md

<a id="instances-create"></a>

# How to create instances

When creating an instance, you must specify the [image](../image-handling.md#about-images) on which the instance should be based.

Images contain a basic operating system (for example, a Linux distribution) and some LXD-related information.
Images for various operating systems are available on the built-in remote image servers.
See [Images](../images.md#images) for more information.

If you don’t specify a name for the instance, LXD will automatically generate one.
Instance names must be unique within a LXD deployment (also within a cluster).
See [Instance name requirements](../reference/instance_properties.md#instance-name-requirements) for additional requirements.

CLI

To create an instance, you can use either the [`lxc init`](../reference/manpages/lxc/init.md#lxc-init-md) or the [`lxc launch`](../reference/manpages/lxc/launch.md#lxc-launch-md) command.
The [`lxc init`](../reference/manpages/lxc/init.md#lxc-init-md) command only creates the instance, while the [`lxc launch`](../reference/manpages/lxc/launch.md#lxc-launch-md) command creates and starts it.

Enter the following command to create a container:

```none
lxc launch|init <image_server>:<image_name> <instance_name> [flags]
```

Unless the image is available locally, you must specify the name of the image server and the name of the image (for example, `ubuntu:24.04` for the official Ubuntu 24.04 LTS image).

See [`lxc launch --help`](../reference/manpages/lxc/launch.md#lxc-launch-md) or [`lxc init --help`](../reference/manpages/lxc/init.md#lxc-init-md) for a full list of flags.
The most common flags are:

- `--config` to specify a configuration option for the new instance
- `--device` to override [device options](../reference/devices.md#devices) for a device provided through a profile, or to specify an [initial configuration for the root disk device](../reference/devices_disk.md#devices-disk-initial-config) (syntax: `--device <device_name>,<device_option>=<value>`)
- `--profile` to specify a [profile](../profiles.md#profiles) to use for the new instance
- `--network` or `--storage` to make the new instance use a specific network or storage pool
- `--target` to create the instance on a specific cluster member
- `--vm` to create a virtual machine instead of a container

Instead of specifying the instance configuration as flags, you can pass it to the command as a YAML file.

For example, to launch a container with the configuration from `config.yaml`, enter the following command:

```none
lxc launch ubuntu:24.04 ubuntu-config < config.yaml
```

API

To create an instance, send a POST request to the `/1.0/instances` endpoint:

```none
lxc query --request POST /1.0/instances --data '{
  "name": "<instance_name>",
  "source": {
    "alias": "<image_alias>",
    "protocol": "simplestreams",
    "server": "<server_URL>",
    "type": "image"
  }
}'
```

The return value of this query contains an operation ID, which you can use to query the status of the operation:

```none
lxc query --request GET /1.0/operations/<operation_ID>
```

Use the following query to monitor the state of the instance:

```none
lxc query --request GET /1.0/instances/<instance_name>/state
```

See [`POST /1.0/instances`](/api/#/instances/instances_post) and [`GET /1.0/instances/{name}/state`](/api/#/instances/instance_state_get) for more information.

The request creates the instance, but does not start it.
To start an instance, send a PUT request to change the instance state:

```none
lxc query --request PUT /1.0/instances/<instance_name>/state --data '{"action": "start"}'
```

See [Start an instance](instances_manage.md#instances-manage-start) for more information.

If you would like to start the instance upon creation, set the `start` property to true. The following example will create the container, then start it:

```none
lxc query --request POST /1.0/instances --data '{
  "name": "<instance_name>",
  "source": {
    "alias": "<image_alias>",
    "protocol": "simplestreams",
    "server": "<server_URL>",
    "type": "image"
  },
  "start": true
}'
```

UI

To create an instance, go to the Instances section and click Create instance.

On the resulting screen, optionally enter a name and description for the instance.
Then click Browse images to select the image to be used for the instance.
Depending on the selected image, you might be able to select the [instance type](../explanation/instances.md#expl-instances) (container or virtual machine).
You can also specify one or more profiles to use for the instance.

To further tweak the instance configuration or add devices to the instance, go to any of the tabs under Advanced.
You can also edit the full instance configuration on the YAML configuration tab.

Finally, click Create or Create and start to create the instance.

## Examples

The following CLI and API examples create the instances, but don’t start them.
If you are using the CLI client, you can use [`lxc launch`](../reference/manpages/lxc/launch.md#lxc-launch-md) instead of [`lxc init`](../reference/manpages/lxc/init.md#lxc-init-md) to automatically start them after creation.

In the UI, you can choose between Create and Create and start when you are ready to create the instance.

### Create a container

To create a container with an Ubuntu 24.04 LTS image from the `ubuntu` server using the instance name `ubuntu-container`:

CLI

```none
lxc init ubuntu:24.04 ubuntu-container
```

API

```none
lxc query --request POST /1.0/instances --data '{
  "name": "ubuntu-container",
  "source": {
    "alias": "24.04",
    "protocol": "simplestreams",
    "server": "https://cloud-images.ubuntu.com/releases/",
    "type": "image"
  }
}'
```

UI

![Create an Ubuntu 24.04 LTS container](images/UI/create_instance_ex1.png)

### Create a virtual machine

To create a virtual machine with an Ubuntu 24.04 LTS image from the `ubuntu` server using the instance name `ubuntu-vm`:

CLI

```none
lxc init ubuntu:24.04 ubuntu-vm --vm
```

API

```none
lxc query --request POST /1.0/instances --data '{
  "name": "ubuntu-vm",
  "source": {
    "alias": "24.04",
    "protocol": "simplestreams",
    "server": "https://cloud-images.ubuntu.com/releases/",
    "type": "image"
  },
  "type": "virtual-machine"
}'
```

UI

![Create an Ubuntu 24.04 LTS VM](images/UI/create_instance_ex2.png)

Or with a bigger disk:

CLI

```none
lxc init ubuntu:24.04 ubuntu-vm-big --vm --device root,size=30GiB
```

API

```none
lxc query --request POST /1.0/instances --data '{
  "devices": {
    "root": {
      "path": "/",
      "pool": "default",
      "size": "30GiB",
      "type": "disk"
    }
  },
  "name": "ubuntu-vm-big",
  "source": {
    "alias": "24.04",
    "protocol": "simplestreams",
    "server": "https://cloud-images.ubuntu.com/releases/",
    "type": "image"
  },
  "type": "virtual-machine"
}'
```

UI

![Configure the size of the root disk](images/UI/create_instance_ex2-2.png)

### Create a container with specific configuration options

To create a container and limit its resources to one vCPU and 8 GiB of RAM:

CLI

```none
lxc init ubuntu:24.04 ubuntu-limited --config limits.cpu=1 --config limits.memory=8GiB
```

API

```none
lxc query --request POST /1.0/instances --data '{
  "config": {
    "limits.cpu": "1",
    "limits.memory": "8GiB"
  },
  "name": "ubuntu-limited",
  "source": {
    "alias": "24.04",
    "protocol": "simplestreams",
    "server": "https://cloud-images.ubuntu.com/releases/",
    "type": "image"
  }
}'
```

UI

![Configure resource limits](images/UI/create_instance_ex3.png)

### Create a VM on a specific cluster member

To create a virtual machine on the cluster member `micro2`, enter the following command:

CLI

```none
lxc init ubuntu:24.04 ubuntu-vm-server2 --vm --target micro2
```

API

```none
lxc query --request POST /1.0/instances?target=micro2 --data '{
  "name": "ubuntu-vm-server2",
  "source": {
    "alias": "24.04",
    "protocol": "simplestreams",
    "server": "https://cloud-images.ubuntu.com/releases/",
    "type": "image"
  },
  "type": "virtual-machine"
}'
```

UI

![Specify which cluster member to create an instance on](images/UI/create_instance_ex4.png)

### Create a container with a specific instance type

LXD supports simple instance types for clouds.
Those are represented as a string that can be passed at instance creation time.

The list of supported clouds and instance types can be found at [`images.lxd.canonical.com/meta/instance-types/all.yaml`](https://images.lxd.canonical.com/meta/instance-types/all.yaml).

The syntax allows the three following forms:

- `<instance type>`
- `<cloud>:<instance type>`
- `c<CPU>-m<RAM in GiB>`

For example, the following three instance types are equivalent:

- `t2.micro`
- `aws:t2.micro`
- `c1-m1`

To create a container with this instance type:

CLI

```none
lxc init ubuntu:24.04 my-instance --type t2.micro
```

API

```none
lxc query --request POST /1.0/instances --data '{
  "instance_type": "t2.micro",
  "name": "my-instance",
  "source": {
    "alias": "24.04",
    "protocol": "simplestreams",
    "server": "https://cloud-images.ubuntu.com/releases/",
    "type": "image"
  }
}'
```

UI

Creating an instance with a specific cloud instance type is currently not possible through the UI.
Configure the corresponding options manually or through a profile.

<a id="instances-create-iso"></a>

### Create a VM that boots from an ISO

To create a VM that boots from an ISO:

CLI

<!-- iso_vm_step1 start -->

First, create an empty VM that we can later install from the ISO image:

<!-- iso_vm_step1 end -->
```none
lxc init iso-vm --empty --vm --config limits.cpu=2 --config limits.memory=4GiB --device root,size=30GiB
```

#### NOTE
Adapt the `limits.cpu`, `limits.memory`, and root size based on the hardware recommendations for the ISO image used.

<!-- iso_vm_step2 start -->

The second step is to import an ISO image that can later be attached to the VM as a storage volume:

<!-- iso_vm_step2 end -->
```none
lxc storage volume import <pool> <path-to-image.iso> iso-volume --type=iso
```

<!-- iso_vm_step3 start -->

Lastly, attach the custom ISO volume to the VM using the following command:

<!-- iso_vm_step3 end -->
```none
lxc config device add iso-vm iso-volume disk pool=<pool> source=iso-volume boot.priority=10
```

<!-- iso_vm_step4 start -->

The [`boot.priority`](../reference/devices_disk.md#device-disk-device-conf:boot.priority) configuration key ensures that the VM will boot from the ISO first.
Start the VM and [connect to the console](instances_console.md#instances-console) as there might be a menu you need to interact with:

<!-- iso_vm_step4 end -->
```none
lxc start iso-vm --console
```

<!-- iso_vm_step5 start -->

Once you’re done in the serial console, disconnect from the console using `Ctrl`+`a` `q` and [connect to the VGA console](instances_console.md#instances-console) using the following command:

<!-- iso_vm_step5 end -->
```none
lxc console iso-vm --type=vga
```

<!-- iso_vm_step6 start -->

You should now see the installer. After the installation is done, detach the custom ISO volume:

<!-- iso_vm_step6 end -->
```none
lxc storage volume detach <pool> iso-volume iso-vm
```

<!-- iso_vm_step7 start -->

Now the VM can be rebooted, and it will boot from disk.

<!-- iso_vm_step7 end -->

#### NOTE
On Linux virtual machines, the [LXD agent can be manually installed](#lxd-agent-manual-install).

API

First, create an empty VM that we can later install from the ISO image:

```none
lxc query --request POST /1.0/instances --data '{
  "name": "iso-vm",
  "config": {
    "limits.cpu": "2",
    "limits.memory": "4GiB"
  },
  "devices": {
    "root": {
      "path": "/",
      "pool": "default",
      "size": "30GiB",
      "type": "disk"
    }
  },
  "source": {
    "type": "none"
  },
  "type": "virtual-machine"
}'
```

#### NOTE
Adapt the values for `limits.cpu`, `limits.memory`, and `root: size` based on the hardware recommendations for the ISO image used.

The second step is to import an ISO image that can later be attached to the VM as a storage volume:

```none
curl -X POST -H "Content-Type: application/octet-stream" -H "X-LXD-name: iso-volume" \
-H "X-LXD-type: iso" --data-binary @<path-to-image.iso> --unix-socket /var/snap/lxd/common/lxd/unix.socket \
lxd/1.0/storage-pools/<pool>/volumes/custom
```

#### NOTE
When importing an ISO image, you must send both binary data from a file and additional headers.
The [`lxc query`](../reference/manpages/lxc/query.md#lxc-query-md) command cannot do this, so you need to use `curl` or another tool instead.

Lastly, attach the custom ISO volume to the VM using the following command:

```none
lxc query --request PATCH /1.0/instances/iso-vm --data '{
  "devices": {
    "iso-volume": {
      "boot.priority": "10",
      "pool": "<pool>",
      "source": "iso-volume",
      "type": "disk"
    }
  }
}'
```

The [`boot.priority`](../reference/devices_disk.md#device-disk-device-conf:boot.priority) configuration key ensures that the VM will boot from the ISO first.
Start the VM and [connect to the console](instances_console.md#instances-console) as there might be a menu you need to interact with:

```none
lxc query --request PUT /1.0/instances/iso-vm/state --data '{"action": "start"}'
lxc query --request POST /1.0/instances/iso-vm/console --data '{
  "height": 24,
  "type": "console",
  "width": 80
}'
```

Once you’re done in the serial console, disconnect from the console using `Ctrl`+`a` `q` and [connect to the VGA console](instances_console.md#instances-console) using the following command:

```none
lxc query --request POST /1.0/instances/iso-vm/console --data '{
  "height": 24,
  "type": "vga",
  "width": 80
}'
```

You should now see the installer. After the installation is done, detach the custom ISO volume:

```none
lxc query --request GET /1.0/instances/iso-vm
lxc query --request PUT /1.0/instances/iso-vm --data '{
  [...]
  "devices": {}
  [...]
}'
```

#### NOTE
You cannot remove the device through a PATCH request, but you must use a PUT request.
Therefore, get the current configuration first and then provide the relevant configuration with an empty devices list through the PUT request.

Now the VM can be rebooted, and it will boot from disk.

```none
   :end-before: 
```

UI

In the Create instance dialog, click Use custom ISO instead of Browse images.
You can then upload your ISO file and install a VM from it.

<a id="lxd-agent-manual-install"></a>

### Install the LXD agent into virtual machine instances

In order for features like direct command execution (`lxc exec` & `lxc shell`), file transfers (`lxc file`) and detailed usage metrics (`lxc info`)
to work properly with virtual machines, an agent software is provided by LXD.

The virtual machine images from the official [remote image servers](../reference/remote_image_servers.md#remote-image-servers) are pre-configured to load that agent on startup.

For other virtual machines, you may want to manually install the agent.

#### NOTE
The LXD agent is currently available only on Linux virtual machines using `systemd`.

LXD provides the agent through a remote `9p` file system and a `virtiofs` one that are both available under the mount name `config`.
To install the agent, you’ll need to get access to the virtual machine and run the following commands as root:

```none
modprobe 9pnet_virtio
mount -t 9p config /mnt -o access=0,transport=virtio || mount -t virtiofs config /mnt
cd /mnt
./install.sh
cd /
umount /mnt
reboot
```

You need to perform this task once.

### Create a Windows VM

To create a Windows VM, you must first prepare a Windows image.
See [Repack a Windows image](images_create.md#images-repack-windows).

The [How to install a Windows 11 VM using LXD](https://ubuntu.com/tutorials/how-to-install-a-windows-11-vm-using-lxd) tutorial shows how to prepare the image and create a Windows VM from it.


# index.html.md

<a id="images-remote"></a>

# How to use remote images

The [`lxc`](../reference/manpages/lxc.md#lxc-md) CLI command is pre-configured with several remote image servers.
See [Remote image servers](../reference/remote_image_servers.md#remote-image-servers) for an overview.

#### NOTE
- If you are using the API, you can interact with different LXD servers by using their exposed API addresses.
  See [Authenticate with the LXD server](server_expose.md#server-authenticate) for instructions on how to authenticate with the servers.

  [How to manage images](images_manage.md#images-manage) describes how to interact with images on any LXD server through the API.
- The UI is pre-configured with several remote image servers, but does not currently support adding other servers or managing remote images.

  You can see the available remote images (and which server they are hosted on) when you select the base image for a new instance.

## List configured remotes

<!-- Include start list remotes -->

To see all configured remote servers, enter the following command:

```none
lxc remote list
```

Remote servers that use the [simple streams format](https://git.launchpad.net/simplestreams/tree/) are pure image servers.
Servers that use the `lxd` format are LXD servers, which either serve solely as image servers or might provide some images in addition to serving as regular LXD servers.
See [Remote server types](../reference/remote_image_servers.md#remote-image-server-types) for more information.

<!-- Include end list remotes -->

## List available images on a remote

To list all remote images on a server, enter the following command:

```none
lxc image list <remote>:
```

You can filter the results.
See [Filter available images](images_manage.md#images-manage-filter) for instructions.

## Add a remote server

How to add a remote depends on the protocol that the server uses.

### Add a simple streams server

To add a simple streams server as a remote, enter the following command:

```none
lxc remote add <remote_name> <URL> --protocol=simplestreams
```

The URL must use HTTPS.

### Add a remote LXD server

<!-- Include start add remotes -->

To add a LXD server as a remote, enter the following command:

```none
lxc remote add <remote_name> <IP|FQDN|URL|token> [flags]
```

Some authentication methods require specific flags (for example, use [`lxc remote add <remote_name> <IP|FQDN|URL> --auth-type=oidc`](../reference/manpages/lxc/remote/add.md#lxc-remote-add-md) for OIDC authentication).
See [Authenticate with the LXD server](server_expose.md#server-authenticate) and [Remote API authentication](../authentication.md#authentication) for more information.

For example, enter the following command to add a remote through an IP address:

```none
lxc remote add my-remote 192.0.2.10
```

You are prompted to confirm the remote server fingerprint and then asked for the token.

<!-- Include end add remotes -->

## Reference an image

To reference an image, specify its remote and its alias or fingerprint, separated with a colon.
For example:

```none
ubuntu:24.04
ubuntu-minimal:24.04
images:alpine/edge
local:ed7509d7e83f
```

<a id="images-remote-default"></a>

## Select a default remote

If you specify an image name without the name of the remote, the default image server is used.

To see which server is configured as the default image server, enter the following command:

```none
lxc remote get-default
```

To select a different remote as the default image server, enter the following command:

```none
lxc remote switch <remote_name>
```


# index.html.md

<a id="projects-work"></a>

# How to work with different projects

If you have more projects than just the `default` project, you must make sure to use or address the correct project when working with LXD.

#### NOTE
If you have projects that are [confined to specific users](../explanation/projects.md#projects-confined), only users with full access to LXD can see all projects.

Users without full access can only see information for the projects to which they have access.

## List projects

CLI

To list all projects (that you have permission to see), enter the following command:

```none
lxc project list
```

By default, the output is presented as a list:

`user@host:~$ ``lxc project list
`
```text
+----------------------+--------+----------+-----------------+-----------------+----------+---------------+---------------------+---------+
|      NAME            | IMAGES | PROFILES | STORAGE VOLUMES | STORAGE BUCKETS | NETWORKS | NETWORK ZONES |     DESCRIPTION     | USED BY |
+----------------------+--------+----------+-----------------+-----------------+----------+---------------+---------------------+---------+
| default              | YES    | YES      | YES             | YES             | YES      | YES           | Default LXD project | 19      |
+----------------------+--------+----------+-----------------+-----------------+----------+---------------+---------------------+---------+
| my-project (current) | YES    | NO       | NO              | NO              | YES      | YES           |                     | 0       |
+----------------------+--------+----------+-----------------+-----------------+----------+---------------+---------------------+---------+
```

You can request a different output format by adding the `--format` flag.
See [`lxc project list --help`](../reference/manpages/lxc/project/list.md#lxc-project-list-md) for more information.

API

To list all projects (that you have permission to see), send the following request:

```none
lxc query --request GET /1.0/projects
```

To display information about each project, use [Recursion](../rest-api.md#rest-api-recursion):

```none
lxc query --request GET /1.0/projects?recursion=1
```

See [`GET /1.0/projects`](/api/#/projects/projects_get) and  [`GET /1.0/projects?recursion=1`](/api/#/projects/projects_get_recursion1) for more information.

UI

To list all projects (that you have permission to see), expand the Project drop-down.

<a id="projects-switch"></a>

## Switch projects

CLI

By default, all commands that you issue in LXD affect the project that you are currently using.
To see which project you are in, use either the [`lxc project list`](../reference/manpages/lxc/project/list.md#lxc-project-list-md) or [`lxc project get-current`](../reference/manpages/lxc/project/get-current.md#lxc-project-get-current-md) command.

To switch to a different project, enter the following command:

```none
lxc project switch <project_name>
```

API

The API does not have the concept of switching projects.
All requests target the default project unless a different project is specified (see [Target a project](#projects-target)).

UI

To switch to another project, select a different project from the Project drop-down.

<a id="projects-target"></a>

## Target a project

When using the CLI or the API, you can target a specific project when running a command.
Many LXD commands support the `--project` flag or the `project` parameter to run an action in a different project.

#### NOTE
You can target only projects that you have permission for.

An example for targeting another project instead of switching to it is listing the instances in a specific project:

CLI

To list the instances in a specific project, add the `--project` flag to the [`lxc list`](../reference/manpages/lxc/list.md#lxc-list-md) command.
For example:

```none
lxc list --project my-project
```

API

To list the instances in a specific project, add the `project` parameter to the request.
For example:

```none
lxc query --request GET /1.0/instances?project=my-project
```

Or with [Recursion](../rest-api.md#rest-api-recursion):

```none
lxc query --request GET /1.0/instances?recursion=2\&project=my-project
```

UI

The UI does not currently support targeting another project.
Instead, [switch to the other project](#projects-switch).

<a id="howto-projects-work-move-instance"></a>

## Move an instance to another project

CLI

To move an instance from one project to another, enter the following command:

```none
lxc move <instance_name> <new_instance_name> --project <source_project> --target-project <target_project>
```

You can keep the same instance name if no instance with that name exists in the target project.

For example, to move the instance `my-instance` from the `default` project to `my-project` and keep the instance name, enter the following command:

```none
lxc move my-instance my-instance --project default --target-project my-project
```

API

To move an instance from one project to another, send a POST request to the instance:

```none
lxc query --request POST /1.0/instances/<instance_name>?project=<source_project> --data '{
  "name": "<new_instance_name>",
  "project": "<target_project>",
  "migration": true
}'
```

If no instance with that name exists in the target project, you can leave out the name for the new instance to keep the existing name.

For example, to move the instance `my-instance` from the `default` project to `my-project` and keep the instance name, enter the following command:

```none
lxc query --request POST /1.0/instances/my-instance?project=default --data '{
  "project": "my-project",
  "migration": true
}'
```

Depending on your projects, you might need to change other configuration options when moving the instance.
For example, you might need to change the root disk device if one of the projects uses isolated storage volumes.

See [`POST /1.0/instances/{name}`](/api/#/instances/instance_post) for more information.

UI

The UI does not currently support moving instances between projects.

## Copy a profile to another project

If you create a project with the default settings, profiles are isolated in the project ([`features.profiles`](../reference/projects.md#project-features:features.profiles) is set to `true`).
Therefore, the project does not have access to the default profile (which is part of the `default` project), and you will see an error similar to the following when trying to create an instance:

```none
Error: Failed instance creation: Failed creating instance record: Failed initialising instance: Failed getting root disk: No root device could be found
```

To fix this, you can copy the contents of the `default` project’s default profile into the current project’s default profile.
To do so:

CLI

Enter the following command:

```none
lxc profile show default --project default | lxc profile edit default
```

API

Send the following request, replacing `<project>` with the new project that has an empty default profile:

```none
lxc query --request PUT /1.0/profiles/default?projects=<project> --data \
  "$(lxc query --request GET /1.0/profiles/default)"
```

UI

1. Select the `default` project from the Project drop-down.
2. Go to Profiles and select the default profile.
3. In the profile view, switch to the Configuration tab.
4. Select YAML configuration and copy the YAML representation of the profile.
5. Select the project with the empty default profile from the Project drop-down.
6. Go to Profiles and select the empty default profile for the project.
7. In the profile view, switch to the Configuration tab.
8. Select YAML configuration and click Edit profile.
9. Paste the YAML representation that you copied and save the changes.


# index.html.md

<a id="howto-cluster-links-manage"></a>

# How to manage cluster links

<a id="howto-cluster-links-view"></a>

## View cluster links

CLI

To list all cluster links (that you have permission to see), run:

```none
lxc cluster link list
```

The `list` view shows each link’s addresses, identity status, and type.

To view the full configuration of a specific cluster link, run:

```none
lxc cluster link show <cluster-link-name>
```

To view detailed information about the state of a specific cluster link, run:

```none
lxc cluster link info <cluster-link-name>
```

The `info` view shows the link type and the status of each linked cluster member.

API

To list all cluster links (that you have permission to see), send the following request:

```none
lxc query --request GET /1.0/cluster/links
```

To display detailed information about each cluster link, use [Recursion](../rest-api.md#rest-api-recursion):

```none
lxc query --request GET /1.0/cluster/links?recursion=1
```

See [`GET /1.0/cluster/links`](/api/#/cluster-links/cluster_links_get) and [`GET /1.0/cluster/links?recursion=1`](/api/#/cluster-links/cluster_links_get_recursion1) for more information.

To view the full configuration of a specific cluster link, run:

```none
lxc query --request GET /1.0/cluster/links/<name>
```

See [`GET /1.0/cluster/links/{name}`](/api/#/cluster-links/%7Bname%7D/cluster_link_get) for more information.

To view detailed information about the state of a specific cluster link, run:

```none
lxc query --request GET /1.0/cluster/links/<name>/state
```

See [`GET /1.0/cluster/links/{name}/state`](/api/#/cluster-links/%7Bname%7D/state/cluster_link_state_get) for more information.

<a id="howto-cluster-links-permissions"></a>

## Manage cluster link permissions

To modify the permissions of a cluster link, add its identity to authentication groups. See [Manage permissions](../explanation/authorization.md#manage-permissions) for more information.

For example, you can create an authentication group with server viewer permissions and add the cluster link identity to it:

```bash
lxc auth group create viewers
lxc auth group permission add viewers server viewer
lxc auth identity group add tls/<cluster-link-name> viewers
```

Alternatively, you can specify an authentication group when creating a cluster link, which will automatically assign the cluster link identity to that group:

```bash
lxc cluster link create <cluster-link-name> --auth-group <group name>
```

<a id="howto-cluster-links-configure"></a>

## Configure a cluster link

See [Cluster link configuration](../reference/cluster_link_config.md#ref-cluster-link-config) for more details on cluster link configuration options.

There are multiple ways to update the configuration for a cluster link.

You can edit the entire configuration at once:

CLI

To edit a cluster link in your default text editor, enter the following command:

```none
lxc cluster link edit <cluster-link-name>
```

API

To edit a cluster link, send the following request:

```none
lxc query --request PUT /1.0/cluster/links/<name> --data "<link_configuration>"
```

See [`PUT /1.0/cluster/links/{name}`](/api/#/cluster-links/%7Bname%7D/cluster_link_put) for more information.

You can update a single property for a cluster link:

CLI

Use the `set` command with the `--property` flag:

```none
lxc cluster link set <cluster-link-name> --property <key>=<value>
```

For example, to update the `description` property:

```none
lxc cluster link set cluster_b --property description="Backup cluster in data center 2"
```

API

To modify a specific property, send the following request:

```none
lxc query --request PATCH /1.0/cluster/links/<name> --data '{"<key>": "<value>"}'
```

Example:

```none
lxc query --request PATCH /1.0/cluster/links/cluster_b --data '{"description": "Backup cluster in data center B"}'
```

See [`PATCH /1.0/cluster/links/{name}`](/api/#/cluster-links/%7Bname%7D/cluster_link_patch) for more information.

Cluster links have the following properties:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="cluster-link-properties:config"></a>
`config`

Cluster link configuration map

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#cluster-link-properties:config)

| **Key:**      | `config`   |
|---------------|------------|
| **Type:**     | string set |
| **Required:** | no         |

<a id="cluster-link-properties:description"></a>
`description`

Description of the cluster link

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#cluster-link-properties:description)

| **Key:**      | `description`   |
|---------------|-----------------|
| **Type:**     | string          |
| **Required:** | no              |

<a id="cluster-link-properties:name"></a>
`name`

Name of the cluster link

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#cluster-link-properties:name)

| **Key:**      | `name`   |
|---------------|----------|
| **Type:**     | string   |
| **Required:** | yes      |

<a id="cluster-link-properties:type"></a>
`type`

Type of the cluster link

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#cluster-link-properties:type)

| **Key:**      | `type`   |
|---------------|----------|
| **Type:**     | string   |
| **Required:** | yes      |

You can also update a single configuration option for a cluster link. Run:

CLI

```none
lxc cluster link set <cluster-link-name> <key>=<value>
```

API

```none
lxc query --request PATCH /1.0/cluster/links/<name> --data '{"config": <config>}'
```

See [`PATCH /1.0/cluster/links/{name}`](/api/#/cluster-links/%7Bname%7D/cluster_link_patch) for more information.

<a id="howto-cluster-links-delete"></a>

## Delete a cluster link

To delete a cluster link, run:

CLI

```none
lxc cluster link delete <cluster-link-name>
```

API

```none
lxc query --request DELETE /1.0/cluster/links/<name>
```

See [`DELETE /1.0/cluster/links/{name}`](/api/#/cluster-links/%7Bname%7D/cluster_link_delete) for more information.


# index.html.md

<a id="howto-oidc"></a>

# Configure single sign-on with OIDC

LXD uses [OpenID Connect (OIDC)](https://openid.net/developers/how-connect-works/) to authenticate users to the web UI and the CLI without storing local passwords. Instead, users are redirected to an external identity provider’s login page. For details about this process, refer to [OpenID Connect authentication](../authentication.md#authentication-openid).

The following how-to guides provide detailed instructions for the SSO-based identity providers supported by LXD:

* [Configure Auth0](oidc_auth0.md)
* [Configure Ory Hydra](oidc_ory.md)
* [Configure Keycloak](oidc_keycloak.md)
* [Configure Entra ID](oidc_entra_id.md)
* [Configure Pocket ID](oidc_pocket_id.md)

## Related topics

How-to guides:

- [How to add remote servers](../remotes.md#remotes)
- [How to expose LXD to the network](server_expose.md#server-expose)

Explanation:

- [Remote API authentication](../authentication.md#authentication)


# index.html.md

<a id="howto-security-events"></a>

# How to monitor security events

LXD emits security events that track authentication attempts, authorization
decisions, and administrative changes. You can access these events through
the CLI, the REST API, or by forwarding them to Loki for centralized log
retention and analysis.

For the full list of event types and field definitions, see [Security events](../events.md#events-security).

## View security events with the CLI

Use the `lxc monitor` command to stream security events in real time:

```bash
lxc monitor --type=security --format=yaml
```

You will see output like:

```yaml
type: security
timestamp: 2026-05-08T14:32:15Z
location: lxd1
metadata:
  name: authn_login_fail:tls
  level: warning
  description: "Authentication failure: untrusted client certificate"
  requestor:
    username: ""
    protocol: tls
    address: "192.168.1.100:45632"
    user_agent: "curl/7.68.0"
  request_path: /1.0/projects
  request_method: GET
```

## View security events with the REST API

Connect to the `/1.0/events` WebSocket endpoint with `type=security`.
Access requires appropriate permissions on the server.

For general event stream usage, see [Events](../events.md#events).

<a id="howto-security-events-loki"></a>

## Monitor security events with Loki

In a production environment, forward security events to
[Loki](https://grafana.com/oss/loki/) for centralized audit log
aggregation and analysis.

For general Loki setup, see [How to send logs to Loki](logs_loki.md#logs-loki). The steps below cover
security-event-specific configuration and queries.

### Configure security event forwarding

Ensure `security` is included in `loki.types`:

```bash
lxc config set loki.types=logging,lifecycle,security
```

LXD will forward security events to Loki in [OWASP (Open Worldwide Application Security Project)](https://owasp.org/) audit log format. See [Security event fields in Loki](../events.md#events-security-loki-fields) for the full field mapping.

### Query security events

Use the LogCLI utility to query security events:

```bash
logcli query -t '{type="security"}'
```

Filter by a specific event type:

```bash
logcli query -t '{type="security"}' | grep 'authn_login_fail'
```

Filter by requestor identity (requires adding `user_id` to `loki.labels`):

```bash
logcli query -t '{type="security", user_id="tls/alice"}'
```

Alternatively, use a JSON parsing pipeline to filter without modifying labels:

```bash
logcli query -t '{type="security"} | json | user_id="tls/alice"'
```


# index.html.md

<a id="network-increase-bandwidth"></a>

# How to increase the network bandwidth

You can increase the network bandwidth of your LXD setup by configuring the transmit queue length (`txqueuelen`).
This change makes sense in the following scenarios:

- You have a NIC with 1 GbE or higher on a LXD host with a lot of local activity (instance-instance connections or host-instance connections).
- You have an internet connection with 1 GbE or higher on your LXD host.

The more instances you use, the more you can benefit from this tweak.

#### NOTE
The following instructions use a `txqueuelen` value of 10000, which is commonly used with 10GbE NICs, and a `net.core.netdev_max_backlog` value of 182757.
Depending on your network, you might need to use different values.

In general, you should use small `txqueuelen` values with slow devices with a high latency, and high `txqueuelen` values with devices with a low latency.
For the `net.core.netdev_max_backlog` value, a good guideline is to use the minimum value of the `net.ipv4.tcp_mem` configuration.

## Increase the network bandwidth on the LXD host

Ubuntu >= 18.04

Complete the following steps to increase the network bandwidth on the LXD host:

1. Increase the transmit queue length (`txqueuelen`) of both the real NIC (for example, `enp5s0f1`) and the LXD NIC (for example, `lxdbr0`).
   To make the change permanent, create a file named `/etc/udev/rules.d/60-custom-txqueuelen.rules` with the following content:
   ```none
   KERNEL=="enp5s0f1", RUN+="/sbin/ip link set %k txqueuelen 10000"
   KERNEL=="lxdbr0", RUN+="/sbin/ip link set %k txqueuelen 10000"
   ```

   Apply the above `udev` rules via:
   ```none
    udevadm trigger
   ```
2. Increase the receive queue length (`net.core.netdev_max_backlog`).
   To make the change permanent, add the following configuration to `/etc/sysctl.conf`:
   ```none
   net.core.netdev_max_backlog = 182757
   ```

   Apply the above `sysctl.conf` change via:
   ```none
    sysctl -p
   ```

Ubuntu <= 17.04

Complete the following steps to increase the network bandwidth on the LXD host:

1. Increase the transmit queue length (`txqueuelen`) of both the real NIC and the LXD NIC (for example, `lxdbr0`).
   You can do this temporarily for testing with the following command:
   ```none
   ifconfig <interface> txqueuelen 10000
   ```

   To make the change permanent, add the following command to your interface configuration in `/etc/network/interfaces`:
   ```none
   up ip link set eth0 txqueuelen 10000
   ```
2. Increase the receive queue length (`net.core.netdev_max_backlog`).
   You can do this temporarily for testing with the following command:
   ```none
   echo 182757 > /proc/sys/net/core/netdev_max_backlog
   ```

   To make the change permanent, add the following configuration to `/etc/sysctl.conf`:
   ```none
   net.core.netdev_max_backlog = 182757
   ```

## Increase the transmit queue length on the instances

You must also change the `txqueuelen` value for all Ethernet interfaces in your instances.
To do this, use one of the following methods:

- Apply the same changes as described above for the LXD host.
- Set the `queue.tx.length` device option on the instance profile or configuration.
  For example, to do this for the LXD default profile:
  ```none
   lxc profile device set default eth0 queue.tx.length "10000"
  ```


# index.html.md

<a id="howto-cluster-links-create"></a>

# How to create cluster links

[Cluster links](../explanation/clusters.md#exp-cluster-links) can connect separate LXD clusters by establishing a trust relationship using mutual TLS with certificates, ensuring secure communication.

<a id="howto-cluster-links-auth"></a>

## Prepare authentication

Before creating cluster links, set up proper authentication groups and [Manage permissions](../explanation/authorization.md#manage-permissions):

```bash
lxc auth group create <group-name>
lxc auth group permission add <group-name> <entity-type> <entitlement>
```

The example below shows how to create an authentication group for each cluster called `link` with the `admin` entitlement on the `server` entity type:

```bash
lxc auth group create link
lxc auth group permission add link server admin
```

```bash
lxc auth group create link
lxc auth group permission add link server admin
```

Adjust the permissions according to your security requirements. [Fine-grained permissions](../explanation/authorization.md#fine-grained-authorization) can be applied to control what operations each cluster can perform on the other.

For example, you can create a more restricted group for backup operations only:

```bash
lxc auth group create backup
lxc auth group permission add backup instance can_manage_backups
```

## Create a cluster link

To create a new cluster link between two clusters (Cluster A and Cluster B), you must create the link on both sides. Follow these steps:

1. On Cluster A, create a new cluster link to Cluster B and receive a trust token:
   ```bash
   lxc cluster link create <name-of-link-to-cluster-b> --auth-group <auth-group-name>
   ```

   This command:
   - Creates a pending identity for Cluster B under the link name you provided.
   - Assigns this identity to the specified authentication group.
   - Returns a trust token.

   Copy the trust token. You’ll need it for the next step.

   Example:
   ```bash
   lxc cluster link create cluster_b --auth-group clusters
   ```
2. On Cluster B, create the corresponding cluster link using the trust token from Cluster A:
   ```bash
   lxc cluster link create <name-of-link-to-cluster-a> --token <token-from-A> --auth-group <auth-group-name>
   ```

   This command:
   - Verifies the token’s fingerprint against Cluster A’s certificate.
   - Creates an identity for Cluster A under the name you provided and assigns it to the specified authentication group.
   - Activates the pending link with Cluster A by sending Cluster B’s certificate.
   - Establishes bidirectional trust between the clusters.

   Example:
   ```bash
   lxc cluster link create cluster_a --token <token-from-A> --auth-group clusters
   ```

<a id="howto-cluster-links-identities"></a>

## View the underlying identities

When you create a cluster link, LXD automatically creates an identity for authentication. You can view this identity with:

```bash
lxc auth identity show tls/<cluster-link-name>
```

The output shows the identity of your cluster link, with the type `Cluster link certificate`.


# index.html.md

<a id="howto-replicators-dr"></a>

# How to perform disaster recovery with replicators

Once you have [set up replicators](replicators_create.md#howto-replicators-setup) for active-passive replication, you can use them to fail over to the standby cluster if the leader cluster becomes unavailable, and to restore the original replication direction when the leader comes back online.

## Failover process

If the leader cluster becomes unavailable, you can manually fail over to the standby cluster.

On the standby cluster, promote the replica project to become the leader:

```bash
lxc project promote-replica <project_name>
```

If the leader cluster is unreachable, promotion proceeds automatically without requiring validation. Use `--force` to skip validation when the leader cluster is still reachable but you want to promote anyway (for example, during a planned takeover before demoting the leader):

```bash
lxc project promote-replica <project_name> --force
```

After this command, the project on the standby cluster becomes writable. Start the instances to resume your workloads:

```bash
lxc start --all --project <project_name>
```

## Recovering the original leader cluster

When the original leader cluster comes back online, it will be out of sync with the new leader (the former standby). Scheduled replicator runs on the original leader cluster will fail because both projects are in leader mode.

A replicator run requires the source project to be in leader mode and the target project to be in standby mode.

To restore the original leader cluster and resume the original replication direction:

### 1. Sync from the new leader back to the original leader

On the original leader cluster, stop all running instances in the project before running restore.
The `--restore` action is rejected if any local instance is running, to prevent partial restores:

```bash
lxc stop <instance_name> [<instance_name>...] --force
```

Demote the project on the original leader cluster to standby mode:

```bash
lxc project demote-replica <project_name>
```

If the new leader cluster is unreachable, use `--force` to skip the validation:

```bash
lxc project demote-replica <project_name> --force
```

On the original leader cluster, run the replicator in restore mode to pull data from the new leader:

```bash
lxc replicator run <replicator_name> --restore
```

Restore mode uses the new leader’s instance list as the authoritative source. Any instances created on the new leader during the failover period are also created on the recovering cluster automatically.

The original leader cluster is now a standby replica of the new leader cluster.

### 2. Resume original replication direction

To return to the original setup where the original leader cluster replicates to the standby, stop any running instances in the project on the new leader cluster (former standby). Next, demote the project on the new leader cluster back to standby mode:

```bash
lxc project demote-replica <project_name>
```

Finally, promote the project on the original leader cluster back to leader mode:

```bash
lxc project promote-replica <project_name>
```

Your original active-passive disaster recovery setup is now restored. You can restart your instances on the leader cluster and resume your scheduled replicator runs.

## Related topics

How-to guides:

* [How to set up replicators](replicators_create.md#howto-replicators-setup)
* [How to manage replicators](replicators_manage.md#howto-replicators-manage)
* [How to perform disaster recovery with storage replication](disaster_recovery_replication.md#disaster-recovery-replication)


# index.html.md

<a id="network-bridge-firewall"></a>

# How to configure your firewall

#### IMPORTANT
This guide applies to managed bridge networks only.

Linux firewalls are based on `netfilter`.
LXD uses the same subsystem, which can lead to connectivity issues.

If you run a firewall on your system, you might need to configure it to allow network traffic between the managed LXD bridge and the host.
Otherwise, some network functionality (DHCP, DNS and external network access) might not work as expected.

You might also see conflicts between the rules defined by your firewall (or another application) and the firewall rules that LXD adds.
For example, your firewall might erase LXD rules if it is started after the LXD daemon, which might interrupt network connectivity to the instance.

## `xtables` vs. `nftables`

There are different userspace commands to add rules to `netfilter`: `xtables` (`iptables` for IPv4 and `ip6tables` for IPv6) and `nftables`.

`xtables` provides an ordered list of rules, which might cause issues if multiple systems add and remove entries from the list.
`nftables` adds the ability to separate rules into namespaces, which helps to separate rules from different applications.
However, if a packet is blocked in one namespace, it is not possible for another namespace to allow it.
Therefore, rules in one namespace can still affect rules in another namespace, and firewall applications can still impact LXD network functionality.

If your system supports and uses `nftables`, LXD detects this and switches to `nftables` mode.
In this mode, LXD adds its rules into the `nftables`, using its own `nftables` namespace.

## Use LXD’s firewall

By default, managed LXD bridges add firewall rules to ensure full functionality.
If you do not run another firewall on your system, you can let LXD manage its firewall rules.

To enable or disable this behavior, use the `ipv4.firewall` or `ipv6.firewall` [configuration options](../reference/network_bridge.md#network-bridge-options).

## Use another firewall

Firewall rules added by other applications might interfere with the firewall rules that LXD adds.
Therefore, if you use another firewall, you should disable LXD’s firewall rules.
You must also configure your firewall to allow network traffic between the instances and the LXD bridge, so that the LXD instances can access the DHCP and DNS server that LXD runs on the host.

See the following sections for instructions on how to disable LXD’s firewall rules and how to properly configure `firewalld` and UFW, respectively.

### Disable LXD’s firewall rules

Run the following commands to prevent LXD from setting firewall rules for a specific network bridge (for example, `lxdbr0`):

```none
lxc network set <network_bridge> ipv6.firewall false
lxc network set <network_bridge> ipv4.firewall false
```

### `firewalld`: Add the bridge to the trusted zone

To allow traffic to and from the LXD bridge in `firewalld`, add the bridge interface to the `trusted` zone.
To do this permanently (so that it persists after a reboot), run the following commands:

```none
sudo firewall-cmd --zone=trusted --change-interface=<network_bridge> --permanent
sudo firewall-cmd --reload
```

For example:

```none
sudo firewall-cmd --zone=trusted --change-interface=lxdbr0 --permanent
sudo firewall-cmd --reload
```

#### WARNING
<!-- Include start warning -->

The commands given above show a simple example configuration.
Depending on your use case, you might need more advanced rules and the example configuration might inadvertently introduce a security risk.

<!-- Include end warning -->

### UFW: Add rules for the bridge

If UFW has a rule to drop all unrecognized traffic, it blocks the traffic to and from the LXD bridge.
In this case, you must add rules to allow traffic to and from the bridge, as well as allowing traffic forwarded to it.

To do so, run the following commands:

```none
sudo ufw allow in on <network_bridge>
sudo ufw route allow in on <network_bridge>
sudo ufw route allow out on <network_bridge>
```

For example:

```none
sudo ufw allow in on lxdbr0
sudo ufw route allow in on lxdbr0
sudo ufw route allow out on lxdbr0
```

#### WARNING
<!-- Repeat warning from above -->

The commands given above show a simple example configuration.
Depending on your use case, you might need more advanced rules and the example configuration might inadvertently introduce a security risk.

Here’s an example for more restrictive firewall rules that limit access from the guests to the host to only DHCP and DNS and allow all outbound connections:

```default
# allow the guest to get an IP from the LXD host
sudo ufw allow in on lxdbr0 to any port 67 proto udp
sudo ufw allow in on lxdbr0 to any port 547 proto udp

# allow the guest to resolve host names from the LXD host
sudo ufw allow in on lxdbr0 to any port 53

# allow the guest to have access to outbound connections
CIDR4="$(lxc network get lxdbr0 ipv4.address | sed 's|\.[0-9]\+/|.0/|')"
CIDR6="$(lxc network get lxdbr0 ipv6.address | sed 's|:[0-9]\+/|:/|')"
sudo ufw route allow in on lxdbr0 from "${CIDR4}"
sudo ufw route allow in on lxdbr0 from "${CIDR6}"
```

<a id="network-lxd-docker"></a>

## Prevent connectivity issues with LXD and Docker

Running LXD and Docker on the same host can cause connectivity issues.
A common reason for these issues is that Docker sets the global FORWARD policy to `drop`, which prevents LXD from forwarding traffic and thus causes the instances to lose network connectivity.
See [Docker on a router](https://docs.docker.com/engine/network/packet-filtering-firewalls/#docker-on-a-router) for detailed information.

There are multiple ways to work around this problem:

Enable IPv4 forwarding
: To prevent Docker from modifying the global FORWARD policy, you can enable IPv4 forwarding *before* the Docker service starts. LXD bridge networks normally enable this setting, but if LXD starts after Docker, then Docker will already have modified the global FORWARD policy.
  <br/>
  #### WARNING
  For Docker versions prior to 28.0, enabling IPv4 forwarding can cause Docker container ports to be reachable from any machine on your local network. This is no longer the case since Docker 28.0. For details, see the [announcement from Docker](https://www.docker.com/blog/docker-engine-28-hardening-container-networking-by-default/).
  <br/>
  Enable IPv4 forwarding with the following `sysctl` setting:
  <br/>
  ```none
  net.ipv4.conf.all.forwarding=1
  ```
  <br/>
  #### IMPORTANT
  You must make this setting persistent across host reboots.
  <br/>
  One way to ensure this is to add a file in the `/etc/sysctl.d/` directory by running the following commands:
  <br/>
  ```none
  echo "net.ipv4.conf.all.forwarding=1" > /etc/sysctl.d/99-forwarding.conf
  systemctl restart systemd-sysctl
  ```

Allow egress network traffic flows
: If you do not want the Docker container ports to be potentially reachable from any machine on your local network, you can apply a more complex solution provided by Docker.
  <br/>
  Use the following commands to explicitly allow egress network traffic flows from your LXD managed bridge interface:
  <br/>
  ```none
  iptables  -I DOCKER-USER -i <network_bridge> -j ACCEPT
  ip6tables -I DOCKER-USER -i <network_bridge> -j ACCEPT
  iptables  -I DOCKER-USER -o <network_bridge> -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
  ip6tables -I DOCKER-USER -o <network_bridge> -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
  ```
  <br/>
  For example, if your LXD managed bridge is called `lxdbr0`, you can allow egress traffic to flow using the following commands:
  <br/>
  ```none
  iptables  -I DOCKER-USER -i lxdbr0 -j ACCEPT
  ip6tables -I DOCKER-USER -i lxdbr0 -j ACCEPT
  iptables  -I DOCKER-USER -o lxdbr0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
  ip6tables -I DOCKER-USER -o lxdbr0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
  ```
  <br/>
  #### IMPORTANT
  You  must make these firewall rules persistent across host reboots.
  How to do this depends on your Linux distribution.

Uninstall Docker
: To avoid issues with Docker entirely, uninstall Docker from the system that runs LXD and restart the system.
  You can run Docker inside a LXD container or virtual machine instead.
  <br/>
  See [Running Docker inside of a LXD container](https://www.youtube.com/watch?v=_fCSSEyiGro) for detailed information.


# index.html.md

<a id="disaster-recovery-replication"></a>

# How to perform disaster recovery with storage replication

To enable disaster recovery, set up a secondary LXD deployment in a different location that can take over running workloads if a non-clustered LXD server or an entire cluster goes offline or becomes unreachable.

If such an incident occurs, you can rely on the storage layer that replicates all instances and custom volumes to the secondary location. You can then consolidate the storage layer and recover the resources to make them available to
your secondary deployment (see [How to recover instances in case of disaster](disaster_recovery.md#disaster-recovery)).

This requires not only two separate LXD deployments, but also storage replication configuration for the respective storage array.

In this guide, we assume two LXD deployments: a primary and a secondary. Each deployment is configured to use only its own co-located storage array, and both operate independently.

<a id="disaster-recovery-replication-entities"></a>

## Set up entities at each location

Before you can set up storage replication, you must set up the required [entities](../explanation/index.md#explanation-entities) at each location.

<a id="disaster-recovery-replication-entities-pool"></a>

### Storage pool

Ensure that both the primary and secondary LXD deployments have a storage pool on their respective storage arrays that can later be used for replication.

If you need to create a storage pool at either location, see: [Create a storage pool](storage_pools.md#howto-storage-pools-create).

<a id="disaster-recovery-replication-entities-other"></a>

### Networks and profiles

You might also want to set up other entities, such as [networks](../explanation/networks.md#networks) and [profiles](../profiles.md#profiles), in advance on the secondary location. This way, in the event of a disaster, you can focus on recovering the volumes.

When performing [How to recover instances in case of disaster](disaster_recovery.md#disaster-recovery), LXD checks if the required entities are present and notifies you if anything is missing. The recovery does not create these entities.

<a id="disaster-recovery-replication-setup"></a>

## Set up storage replication

Replication must be configured outside of LXD, according to the concepts and constructs by the storage vendor.

The following links lead to replication setup guides published by various storage vendors:

* Ceph RBD: [RBD mirroring](https://docs.ceph.com/en/reef/rbd/rbd-mirroring/)
* Dell PowerFlex: [Introduction to Replication](https://infohub.delltechnologies.com/en-us/t/dell-powerflex-introduction-to-replication/)

Once you have configured the connection between the primary and secondary storage arrays, follow the relevant storage vendor’s steps to set up the actual replication of volumes.

Some vendors (such as Dell) use a concept called replication consistency group (RCG), which allows consistent replication of a group of volumes. An RCG can contain an instance’s volume along with all of its attached custom volumes. Other vendors might use different concepts.

<a id="disaster-recovery-replication-limitations"></a>

### Known storage array limitations

When setting up replication, consider the following limitations:

<a id="disaster-recovery-replication-limitations-powerflex"></a>

#### PowerFlex

Cannot replicate and recover volumes with snapshots
: In [PowerFlex](../reference/storage_powerflex.md#storage-powerflex), a volume’s snapshot appears as its own volume but is still logically connected to its parent volume (vTree).
  When replicating a volume inside a RCG, its snapshots are not replicated; this causes inconsistencies on the secondary location.
  A volume’s snapshot can be replicated but will be placed inside a new vTree, losing the logical relation to its parent volume.
  During recovery, LXD notices this inconsistency and raises an error.

<a id="disaster-recovery-replication-cephrdb"></a>

#### Ceph RBD

Cannot use journaling mode
: On [Ceph RBD](../reference/storage_ceph.md#storage-ceph) storage arrays, it’s possible to configure mirroring using either journaling or snapshot mode.
  However, with LXD, only snapshot mode is supported. This is because the volumes need to be mapped to the host for read access during recovery, which might not be possible due to missing kernel features.

<a id="disaster-recovery-replication-verify"></a>

## Verify replication

After setting up storage replication, confirm that the primary location’s volumes are successfully replicated to the secondary location.

<a id="disaster-recovery-replication-promote"></a>

## Promote secondary location after disaster

If the primary location becomes unreachable, the secondary location can be promoted to become the new source of truth. The method to promote the secondary storage array depends on the storage vendor. For links to vendor guides, see: [Set up storage replication](#disaster-recovery-replication-setup).

<a id="disaster-recovery-replication-recover"></a>

## Recover resources

After the secondary storage array has been promoted, you can start recovering the workload. Run the steps in [How to recover instances in case of disaster](disaster_recovery.md#disaster-recovery) on the secondary LXD deployment.

When prompted to choose the pools to scan for unknown volumes, select the storage pool that was configured during the replication setup.

The instances and custom storage volumes are then recovered on the secondary LXD deployment. Use `lxc start` to bring up the instances that were originally running on the primary deployment.

<a id="disaster-recovery-replication-add-pool"></a>

### Add missing pool

If the LXD storage pool at the secondary location exists only in the storage array and has not yet been created in LXD (as described in [Storage pool](#disaster-recovery-replication-entities-pool)), you must recover it first.

Use the `lxc storage create` command to add the storage pool. This works for both single and clustered LXD deployments. For more information, see: [Create a storage pool](storage_pools.md#howto-storage-pools-create).

<a id="disaster-recovery-replication-add-pool-cephrbd"></a>

#### Recover Ceph RBD pool

LXD’s [Ceph RBD driver](../reference/storage_ceph.md#storage-ceph) uses a *placeholder* volume to reserve the storage pool and ensure it isn’t used more than once. For replication, this behavior can be ignored because the replicated pool must be recovered at the secondary location. To allow this, set [`source.recover`](../reference/storage_ceph.md#storage-ceph-pool-conf:source.recover) to ignore the placeholder volume if it was also replicated to the secondary location.

When creating the storage pool in a LXD cluster, make sure to add the `source.recover=true` setting when creating the pending storage pools per cluster member as this setting is cluster member specific.

<a id="disaster-recovery-replication-failback"></a>

## Demote secondary and fail back to primary location

Once the primary location is back online, the storage layer ensures data consistency because the secondary storage array
now acts as the source of truth and no longer receives updates from the primary array. As long as this replication flow is not reversed, the running instances and custom volumes on the secondary location are protected.

Service failback to the primary location can be performed in two ways. In both cases, the operations on the storage layer are identical, but the correct approach depends on the state of the instances and custom volumes on the secondary location:

1. Shut down the resources on the secondary location and bring them back up on the primary
   This approach requires that the configuration of the recovered instances and volumes on the secondary location has not been modified in any way. Any modifications would not be reflected in the database of the primary LXD deployment and might cause unexpected side effects.
2. Set up a fresh deployment of LXD on the primary location and repeat the steps outlined in [How to recover instances in case of disaster](disaster_recovery.md#disaster-recovery).
   This approach repeats the same process performed for the initial disaster recovery, but in reverse.

After choosing an approach, demote the storage array at the secondary location and promote the array at the primary location. Refer to [Set up storage replication](#disaster-recovery-replication-setup) for details on how to perform these actions.

Finally, either bring up the instances on the primary deployment using `lxc start`, or recover them first to make them known again to the primary deployment before starting them.

## Related topics

How-to guides:

* [How to recover instances in case of disaster](disaster_recovery.md#disaster-recovery)
* [How to recover a cluster](cluster_recover.md#cluster-recover)
* [Storage](../storage.md#storage)

Explanation:

* [Storage pools, volumes, and buckets](../explanation/storage.md#exp-storage)

Reference:

* [Storage drivers](../reference/storage_drivers.md#storage-drivers)


# index.html.md

<a id="images-manage"></a>

# How to manage images

When working with images, you can inspect various information about the available images, view and edit their properties and configure aliases to refer to specific images.
You can also export an image to a file, which can be useful to [copy or import it](images_copy.md#images-copy) on another machine.

## List available images

CLI

To list all images on a server, enter the following command:

```none
lxc image list [<remote>:]
```

If you do not specify a remote, the [default remote](images_remote.md#images-remote-default) is used.

API

Query the `/1.0/images` endpoint to list all images on the server:

```none
lxc query --request GET /1.0/images
```

To include information about each image, add `recursion=1`:

```none
lxc query --request GET /1.0/images?recursion=1
```

See [`GET /1.0/images`](/api/#/images/images_get) and [`GET /1.0/images?recursion=1`](/api/#/images/images_get_recursion1) for more information.

#### NOTE
The `/1.0/images` endpoint is available on LXD servers, but not on simple streams servers (see [Remote server types](../reference/remote_image_servers.md#remote-image-server-types)).
Public image servers, like the [official Ubuntu image server](https://cloud-images.ubuntu.com/releases/), use the [simple streams format](https://git.launchpad.net/simplestreams/tree/).

To retrieve the list of images from a simple streams server, start at the `streams/v1/index.sjson` index (for example, [`https://cloud-images.ubuntu.com/releases/streams/v1/index.sjson`](https://cloud-images.ubuntu.com/releases/streams/v1/index.sjson)).

UI

Go to Images to view all images on the local server.

<a id="images-manage-filter"></a>

### Filter available images

CLI

To filter the results that are displayed, specify a part of the alias or fingerprint after the command.
For example, to show all Ubuntu 24.04 LTS images, enter the following command:

```none
lxc image list ubuntu: 24.04
```

You can specify several filters as well.
For example, to show all Arm 64-bit Ubuntu 24.04 LTS images, enter the following command:

```none
lxc image list ubuntu: 24.04 arm64
```

To filter for properties other than alias or fingerprint, specify the filter in `<key>=<value>` format.
For example:

```none
lxc image list ubuntu: 24.04 architecture=x86_64
```

API

You can [filter](../rest-api.md#rest-api-filtering) the images that are displayed by any of their fields.

For example, to show all Ubuntu images, or all images for Ubuntu 24.04 LTS:

```none
lxc query --request GET /1.0/images?filter=properties.os+eq+ubuntu
lxc query --request GET /1.0/images?filter=properties.version+eq+24.04
```

You can specify several filters as well.
For example, to show all Arm 64-bit images for virtual machines, enter the following command:

```none
lxc query --request GET /1.0/images?filter=architecture+eq+arm64+and+type+eq+virtual-machine
```

You can also use a regular expression:

```none
lxc query --request GET "/1.0/images?filter=fingerprint+eq+be25.*"
```

See [`GET /1.0/images`](/api/#/images/images_get) and [Filtering](../rest-api.md#rest-api-filtering) for more information.

UI

To filter the images that are displayed, use the search box.

For example, to show all Ubuntu images, search for `ubuntu`.
To display only images for version 24.04, search for `24.04`.

## View image information

CLI

To view information about an image, enter the following command:

```none
lxc image info <image_ID>
```

As the image ID, you can specify either the image’s alias or its fingerprint.
For a remote image, remember to include the remote server (for example, `ubuntu:24.04`).

To display only the image properties, enter the following command:

```none
lxc image show <image_ID>
```

You can also display a specific image property (located under the `properties` key) with the following command:

```none
lxc image get-property <image_ID> <key>
```

For example, to show the release name of the official Ubuntu 24.04 LTS image, enter the following command:

```none
lxc image get-property ubuntu:24.04 release
```

API

To view all information about an image, query it using its fingerprint:

```none
lxc query --request GET /1.0/images/<fingerprint>
```

See [`GET /1.0/images/{fingerprint}`](/api/#/images/image_get) for more information.

If you don’t know the fingerprint but the alias, you can retrieve the fingerprint by querying the `/1.0/images/aliases/{alias}` endpoint:

```none
lxc query --request GET /1.0/images/aliases/<alias>
```

See [`GET /1.0/images/aliases/{name}`](/api/#/images/image_alias_get) for more information.

UI

The UI does not currently support viewing detailed image information.

<a id="images-manage-edit"></a>

## Edit image properties

CLI

To set a specific image property that is located under the `properties` key, enter the following command:

```none
lxc image set-property <image_ID> <key> <value>
```

#### NOTE
These properties can be used to convey information about the image.
They do not configure LXD’s behavior in any way.

To edit the full image properties, including the top-level properties, enter the following command:

```none
lxc image edit <image_ID>
```

API

To set a specific image property that is located under the `properties` key, send a PATCH request to the image:

```none
lxc query --request PATCH /1.0/images/<fingerprint> --data '{
  "properties": {
    "<key>": "<value>"
  }
}'
```

See [`PATCH /1.0/images/{fingerprint}`](/api/#/images/image_patch) for more information.

#### NOTE
These properties can be used to convey information about the image.
They do not configure LXD’s behavior in any way.

To update the full image properties, including the top-level properties, send a PUT request with the full image data:

```none
lxc query --request PUT /1.0/images/<fingerprint> --data '<image_configuration>'
```

See [`PUT /1.0/images/{fingerprint}`](/api/#/images/image_put) for more information.

UI

The UI does not currently support editing image properties.

## Delete an image

CLI

To delete a local copy of an image, enter the following command:

```none
lxc image delete <image_ID>
```

API

To delete a local copy of an image, send a DELETE request:

```none
lxc query --request DELETE /1.0/images/<fingerprint>
```

See [`DELETE /1.0/images/{fingerprint}`](/api/#/images/image_delete) for more information.

UI

In the images list, click the Delete button (<svg width='16' height='16' xmlns='http://www.w3.org/2000/svg'><path d='M4.5 6v6a1.5 1.5 0 001.356 1.493L6 13.5h4a1.5 1.5 0 001.493-1.356L11.5 12V6H13v6a3 3 0 01-3 3H6a3 3 0 01-3-3V6h1.5zm3 0v5.994H6V6h1.5zm2.498 0v5.994h-1.5V6h1.5zM8.5 0A2.5 2.5 0 0111 2.5V3h3v1.5H2V3h3v-.5A2.5 2.5 0 017.5 0h1zm0 1.5h-1a1 1 0 00-.993.883L6.5 2.5V3h3v-.5a1 1 0 00-.883-.993L8.5 1.5z' fill='%23000' fill-rule='evenodd'/></svg>) next to an image to delete it.

You can also select several images and click the Delete images button at the top to delete all selected images.

Deleting an image won’t affect running instances that are already using it, but it will remove the image locally.

After deletion, if the image was downloaded from a remote server, it will be removed from local cache and downloaded again on next use.
However, if the image was manually created (not cached), the image will be deleted.

## Configure image aliases

Configuring an alias for an image can be useful to make it easier to refer to an image, since remembering an alias is usually easier than remembering a fingerprint.
Most importantly, however, you can change an alias to point to a different image, which allows creating an alias that always provides a current image (for example, the latest version of a release).

CLI

You can see some of the existing aliases in the image list.
To see the full list, enter the following command:

```none
lxc image alias list
```

You can directly assign an alias to an image when you [copy or import](images_copy.md#images-copy) or [publish](images_create.md#images-create-publish) it.
Alternatively, enter the following command:

```none
lxc image alias create <alias_name> <image_fingerprint>
```

You can also delete an alias:

```none
lxc image alias delete <alias_name>
```

To rename an alias, enter the following command:

```none
lxc image alias rename <alias_name> <new_alias_name>
```

If you want to keep the alias name, but point the alias to a different image (for example, a newer version), you must delete the existing alias and then create a new one.

API

To retrieve a list of all defined aliases, query the `/1.0/images/aliases` endpoint:

```none
lxc query --request GET /1.0/images/aliases
```

To include information about each alias, add `recursion=1`:

```none
lxc query --request GET /1.0/images/aliases?recursion=1
```

See [`GET /1.0/images/aliases`](/api/#/images/images_aliases_get) and [`GET /1.0/images/aliases?recursion=1`](/api/#/images/images_aliases_get_recursion1) for more information.

You can directly assign an alias to an image when you [copy or import](images_copy.md#images-copy) or [publish](images_create.md#images-create-publish) it.
Alternatively, send a POST request to the `/1.0/images/aliases` endpoint to create an alias:

```none
lxc query --request POST /1.0/images/aliases --data '{
  "name": "<alias_name>",
  "target": "<image_fingerprint>"
}'
```

See [`POST /1.0/images/aliases`](/api/#/images/images_aliases_post) for more information.

You can also delete an alias:

```none
lxc query --request DELETE /1.0/images/aliases/<alias_name>
```

To rename an alias, send a POST request to the alias:

```none
lxc query --request POST /1.0/images/aliases/<alias_name> --data '{
  "name": "<new_alias_name>"
}'
```

If you want to keep the alias name, but point the alias to a different image (for example, a newer version), send a PATCH request to the alias:

```none
lxc query --request PATCH /1.0/images/aliases/<alias_name> --data '{
  "target": "<new_fingerprint>"
}'
```

See [`DELETE /1.0/images/aliases/{name}`](/api/#/images/image_alias_delete), [`POST /1.0/images/aliases/{name}`](/api/#/images/images_alias_post), and [`PATCH /1.0/images/aliases/{name}`](/api/#/images/images_alias_patch) for more information.

UI

The UI displays configured aliases in the images list, but it does not currently support configuring image aliases.

<a id="images-manage-export"></a>

## Export an image to a set of files

Images are located in the image store of your local server or a remote LXD server.
You can export them to a file or a set of files though (see [Image tarballs](../reference/image_format.md#image-format-tarballs)).
This method can be useful to back up image files or to transfer them to an air-gapped environment.

CLI

To export a container image to a set of files, enter the following command:

```none
lxc image export [<remote>:]<image> [<output_directory_path>]
```

To export a virtual machine image to a set of files, add the `--vm` flag:

```none
lxc image export [<remote>:]<image> [<output_directory_path>] --vm
```

API

Send a query to the `export` endpoint of the image to retrieve it:

```none
curl -X GET --unix-socket /var/snap/lxd/common/lxd/unix.socket lxd/1.0/images/<fingerprint>/export \
--output <output-file>
```

If the image is a [split image](../reference/image_format.md#image-format-split), the output file contains two separate tarballs in multipart format.

See [`GET /1.0/images/{fingerprint}/export`](/api/#/images/image_export_get) for more information.

UI

The UI does not currently support exporting images.

See [Image format](../reference/image_format.md#image-format) for a description of the file structure used for the image.


# index.html.md

<a id="instances-manage"></a>

# How to manage instances

When listing the existing instances, you can see their type, status, and location (if applicable).
You can filter the instances and display only the ones that you are interested in.

CLI

Enter the following command to list all instances:

```none
lxc list
```

You can filter the instances that are displayed, for example, by type, status or the cluster member where the instance is located:

```none
lxc list type=container
lxc list status=running
lxc list location=server1
```

You can also filter by name.
To list several instances, use a regular expression for the name.
For example:

```none
lxc list ubuntu.*
```

Enter [`lxc list --help`](../reference/manpages/lxc/list.md#lxc-list-md) to see all filter options.

API

Query the `/1.0/instances` endpoint to list all instances.
You can use [Recursion](../rest-api.md#rest-api-recursion) to display more information about the instances:

```none
lxc query --request GET /1.0/instances?recursion=2
```

You can [filter](../rest-api.md#rest-api-filtering) the instances that are displayed, by name, type, status or the cluster member where the instance is located:

```none
lxc query --request GET /1.0/instances?filter=name+eq+ubuntu
lxc query --request GET /1.0/instances?filter=type+eq+container
lxc query --request GET /1.0/instances?filter=status+eq+running
lxc query --request GET /1.0/instances?filter=location+eq+server1
```

To list several instances, use a regular expression for the name.
For example:

```none
lxc query --request GET /1.0/instances?filter=name+eq+ubuntu.*
```

See [`GET /1.0/instances`](/api/#/instances/instances_get) for more information.

### Optimize queries with selective recursion

To improve performance when querying many instances, you can use semicolon-separated syntax in the `recursion` parameter to selectively fetch only the state fields you need.
This avoids expensive disk and network queries when they are not required.

Fetch only disk usage information:

```none
lxc query --request GET '/1.0/instances?recursion=2%3Bfields%3Dstate.disk'
```

Fetch only network information:

```none
lxc query --request GET '/1.0/instances?recursion=2%3Bfields%3Dstate.network'
```

Fetch both disk and network information:

```none
lxc query --request GET '/1.0/instances?recursion=2%3Bfields%3Dstate.disk%2Cstate.network'
```

Skip all expensive state fields (fastest option):

```none
lxc query --request GET '/1.0/instances?recursion=2%3Bfields%3D'
```

Note: The semicolon (`;`), equals (`=`), and comma (`,`) must be URL-encoded as `%3B`, `%3D`, and `%2C` respectively.

This selective recursion syntax works with both `/1.0/instances` (list) and `/1.0/instances/{name}` (single instance) endpoints.

See [instances_state_selective_recursion](../api-extensions.md#extension-instances-state-selective-recursion) for more information.

UI

Go to Instances to see a list of all instances.

You can filter the instances that are displayed by status, instance type, or the profile they use by selecting the corresponding filter.

In addition, you can search for instances by entering a search text.
The text you enter is matched against the name, the description, and the name of the base image.

## Show information about an instance

CLI

Enter the following command to show detailed information about an instance:

```none
lxc info <instance_name>
```

Add `--show-log` to the command to show the latest log lines for the instance:

```none
lxc info <instance_name> --show-log
```

API

Query the following endpoint to show detailed information about an instance:

```none
lxc query --request GET /1.0/instances/<instance_name>
```

See [`GET /1.0/instances/{name}`](/api/#/instances/instance_get) for more information.

UI

Clicking an instance line in the overview will show a summary of the instance information right next to the instance list.

Click the instance name to go to the instance detail page, which contains detailed information about the instance.

<a id="instances-manage-start"></a>

## Start an instance

CLI

Enter the following command to start an instance:

```none
lxc start <instance_name>
```

You will get an error if the instance does not exist or if it is running already.

To immediately attach to the console when starting, pass the `--console` flag.
For example:

```none
lxc start <instance_name> --console
```

See [How to access the console](instances_console.md#instances-console) for more information.

API

To start an instance, send a PUT request to change the instance state:

```none
lxc query --request PUT /1.0/instances/<instance_name>/state --data '{"action": "start"}'
```

<!-- Include start monitor status -->

The return value of this query contains an operation ID, which you can use to query the status of the operation:

```none
lxc query --request GET /1.0/operations/<operation_ID>
```

Use the following query to monitor the state of the instance:

```none
lxc query --request GET /1.0/instances/<instance_name>/state
```

See [`GET /1.0/instances/{name}/state`](/api/#/instances/instance_state_get) and [`PUT /1.0/instances/{name}/state`](/api/#/instances/instance_state_put)for more information.

<!-- Include end monitor status -->

UI

To start an instance, go to the instance list or the respective instance and click the Start button (▷).

You can also start several instances at the same time by selecting them in the instance list and clicking the Start button at the top.

On the instance detail page, select the Console tab to see the boot log with information about the instance starting up.
Once it is running, you can select the Terminal tab to access the instance.

### Prevent accidental start of instances

To protect a specific instance from being started, set [`security.protection.start`](../reference/instance_options.md#instance-security:security.protection.start) to `true` for the instance.
See [How to configure instances](instances_configure.md#instances-configure) for instructions.

<a id="instances-manage-stop"></a>

## Stop an instance

CLI

Enter the following command to stop an instance:

```none
lxc stop <instance_name>
```

You will get an error if the instance does not exist or if it is not running.

API

To stop an instance, send a PUT request to change the instance state:

```none
lxc query --request PUT /1.0/instances/<instance_name>/state --data '{"action": "stop"}'
```

<!-- Include content from above -->

The return value of this query contains an operation ID, which you can use to query the status of the operation:

```none
lxc query --request GET /1.0/operations/<operation_ID>
```

Use the following query to monitor the state of the instance:

```none
lxc query --request GET /1.0/instances/<instance_name>/state
```

See [`GET /1.0/instances/{name}/state`](/api/#/instances/instance_state_get) and [`PUT /1.0/instances/{name}/state`](/api/#/instances/instance_state_put)for more information.

UI

To stop an instance, go to the instance list or the respective instance and click the Stop button (□).
You are then prompted to confirm.

<!-- Include start skip confirmation -->
<!-- Include end skip confirmation -->

You can choose to force-stop the instance.
If stopping the instance takes a long time or the instance is not responding to the stop request, click the spinning stop button to go back to the confirmation prompt, where you can select to force-stop the instance.

You can also stop several instances at the same time by selecting them in the instance list and clicking the Stop button at the top.

<a id="instances-manage-delete"></a>

## Delete an instance

If you don’t need an instance anymore, you can remove it.
The instance must be stopped before you can delete it.

CLI

Enter the following command to delete an instance:

```none
lxc delete <instance_name>
```

API

To delete an instance, send a DELETE request to the instance:

```none
lxc query --request DELETE /1.0/instances/<instance_name>
```

See [`DELETE /1.0/instances/{name}`](/api/#/instances/instance_delete) for more information.

UI

To delete an instance, go to its instance detail page and click Delete instance.
You are then prompted to confirm.

<!-- Include content from above -->

You can also delete several instances at the same time by selecting them in the instance list and clicking the Delete button at the top.

### Prevent accidental deletion of instances

There are different ways to prevent accidental deletion of instances:

- To protect a specific instance from being deleted, set [`security.protection.delete`](../reference/instance_options.md#instance-security:security.protection.delete) to `true` for the instance.
  See [How to configure instances](instances_configure.md#instances-configure) for instructions.
- In the CLI client, you can create an alias to be prompted for approval every time you use the [`lxc delete`](../reference/manpages/lxc/delete.md#lxc-delete-md) command:
  ```none
   lxc alias add delete "delete -i"
  ```

<a id="instances-manage-rebuild"></a>

## Rebuild an instance

If you want to wipe and re-initialize the root disk of your instance but keep the instance configuration, you can rebuild the instance.

Rebuilding is only possible for instances that do not have any snapshots.

Stop your instance before rebuilding it.

CLI

Enter the following command to rebuild the instance with a different image:

```none
lxc rebuild <image_name> <instance_name>
```

Enter the following command to rebuild the instance with an empty root disk:

```none
lxc rebuild <instance_name> --empty
```

For more information about the `rebuild` command, see [`lxc rebuild --help`](../reference/manpages/lxc/rebuild.md#lxc-rebuild-md).

API

To rebuild the instance with a different image, send a POST request to the instance’s `rebuild` endpoint.
For example:

```none
lxc query --request POST /1.0/instances/<instance_name>/rebuild --data '{
  "source": {
    "alias": "<image_alias>",
    "protocol": "simplestreams",
    "server": "<server_URL>"
  }
}'
```

To rebuild the instance with an empty root disk, specify the source type as `none`:

```none
lxc query --request POST /1.0/instances/<instance_name>/rebuild --data '{
  "source": {
    "type": "none"
  }
}'
```

See [`POST /1.0/instances/{name}/rebuild`](/api/#/instances/instance_rebuild_post) for more information.

UI

Rebuilding an instance is not yet supported in the UI.


# index.html.md

<a id="instances-routed-nic-vm"></a>

# How to add a routed NIC device to a virtual machine

When adding a [routed NIC device](../reference/devices_nic.md#nic-routed) to an instance, you must configure the instance to use the link-local gateway IPs as default routes.
For containers, this is configured for you automatically.
For virtual machines, the gateways must be configured manually or via a mechanism like `cloud-init`.

To configure the gateways with `cloud-init`, firstly initialize an instance:

CLI

```none
lxc init ubuntu:24.04 my-vm --vm
```

API

```none
lxc query --request POST /1.0/instances --data '{
  "name": "my-vm",
  "source": {
    "alias": "24.04",
    "protocol": "simplestreams",
    "server": "https://cloud-images.ubuntu.com/releases/",
    "type": "image"
  },
  "type": "virtual-machine"
}'
```

UI

![Create an Ubuntu 24.04 LTS VM](images/UI/routed_nic_create_instance.png)

Then add the routed NIC device:

CLI

```none
lxc config device add my-vm eth0 nic nictype=routed parent=my-parent ipv4.address=192.0.2.2 ipv6.address=2001:db8::2
```

API

```none
lxc query --request PATCH /1.0/instances/my-vm --data '{
  "devices": {
    "eth0": {
      "ipv4.address": "192.0.2.2",
      "ipv6.address": "2001:db8::2",
      "nictype": "routed",
      "parent": "my-parent",
      "type": "nic"
    }
  }
}'
```

UI

You cannot add a routed NIC device through the UI directly.
Therefore, go to the instance detail page, switch to the Configuration tab and select YAML configuration.
Then click Edit instance and add the routed NIC device to the `devices` section.
For example:

```none
devices:
  eth0:
    ipv4.address: 192.0.2.2
    ipv6.address: 2001:db8::2
    nictype: routed
    parent: my-parent
    type: nic
```

In this configuration, `my-parent` is your parent network, and the IPv4 and IPv6 addresses are within the subnet of the parent.

Next we will add some `netplan` configuration to the instance using the `cloud-init.network-config` configuration key:

CLI

```none
cat <<EOF | lxc config set my-vm cloud-init.network-config -
network:
  version: 2
  ethernets:
    enp5s0:
      routes:
      - to: default
        via: 169.254.0.1
        on-link: true
      - to: default
        via: fe80::1
        on-link: true
      addresses:
      - 192.0.2.2/32
      - 2001:db8::2/128
EOF
```

API

```none
cat > cloud-init.txt <<EOF
network:
  version: 2
  ethernets:
    enp5s0:
      routes:
      - to: default
        via: 169.254.0.1
        on-link: true
      - to: default
        via: fe80::1
        on-link: true
      addresses:
      - 192.0.2.2/32
      - 2001:db8::2/128
EOF

lxc query --request PATCH /1.0/instances/my-vm --data '{
  "config": {
    "cloud-init.network-config": "'"$(awk -v ORS='\\n' '1' cloud-init.txt)"'"
  }
}'
```

UI

On the instance detail page, switch to the Advanced > Cloud-init tab and click Edit instance.

Click the Create override icon for the Network config and enter the following configuration:

```none
network:
  version: 2
  ethernets:
    enp5s0:
      routes:
      - to: default
        via: 169.254.0.1
        on-link: true
      - to: default
        via: fe80::1
        on-link: true
      addresses:
      - 192.0.2.2/32
      - 2001:db8::2/128
```

This `netplan` configuration adds the [static link-local next-hop addresses](../reference/devices_nic.md#nic-routed) (`169.254.0.1` and `fe80::1`) that are required.
For each of these routes we set `on-link` to `true`, which specifies that the route is directly connected to the interface.
We also add the addresses that we configured in our routed NIC device.
For more information on `netplan`, see [their documentation](https://netplan.readthedocs.io/en/latest/).

#### NOTE
This `netplan` configuration does not include a name server.
To enable DNS within the instance, you must set a valid DNS IP address.
If there is a `lxdbr0` network on the host, the name server can be set to that IP instead.

Before you start your instance, make sure that you have [configured the parent network](../reference/devices_nic.md#nic-routed-parent) to enable proxy ARP/NDP.

Then start your instance:

CLI

```none
lxc start my-vm
```

API

```none
lxc query --request PUT /1.0/instances/my-vm/state --data '{"action": "start"}'
```

UI

Go to the instance list or the respective instance and click the Start button (▷).


# index.html.md

<a id="howto-storage-create-instance"></a>

# How to create an instance in a specific storage pool

Instance storage volumes are created in the storage pool that is specified by the instance’s root disk device.
This configuration is normally provided by the profile or profiles applied to the instance.
See [Default storage pool](../explanation/storage.md#storage-default-pool) for detailed information.

CLI

To use a different storage pool when creating or launching an instance, add the `--storage` flag.
This flag overrides the root disk device from the profile.
For example:

```none
lxc launch <image> <instance_name> --storage <storage_pool>
```

UI

To create an instance in a specific storage pool, override the root storage during instance creation.

To do this, begin the [instance creation wizard](instances_create.md#instances-create). Once the Base Image is selected, the Devices section of the left-hand sub-menu becomes available. From this section, select Devices > Disk.

![LXD Create instance form](images/instances/create_instance_form_disk_devices.png)

In this page, in the Override column, click the Edit button to create an override.

![LXD Create instance disk devices form](images/instances/create_instance_form.png)

From here, you can override the pool and size of the root storage by editing their respective fields.

<!-- Include content from [storage_move_volume.md](storage_move_volume.md) -->

## Move instance storage volumes to another pool

To move an instance storage volume to another storage pool, [stop the instance](instances_manage.md#instances-manage-stop) that contains the storage volume you want to move.

CLI

Use the following command to move the instance to a different pool:

```none
lxc move <instance_name> --storage <target_pool_name>
```

UI

Navigate to the overview page of the selected instance, and click on the Migrate button in the top right corner.

![LXD Instance overview page](images/instances/instance_overview_page.png)

Within the move modal, click Move instance root storage to a different pool to view available storage pools to move to.

![LXD Instance root storage move method modal](images/instances/move_instance_modal.png)

Click Select in the row of the target storage pool for the move.

![LXD Instance root storage move pool selection modal](images/instances/move_instance_modal_2.png)

On the resulting confirmation modal, click Move to finalize the process.

![LXD Instance root storage confirmation modal](images/instances/move_confirmation_modal.png)


# index.html.md

<a id="import-machines-to-instances"></a>

# How to import physical or virtual machines to LXD instances


            <p class="youtube_link">
              <a href="https://www.youtube.com/watch?v=F9GALjHtnUU" target="_blank">
                <span title="Importing systems into LXD" class="play_icon">▶</span>
                <span title="Importing systems into LXD">Watch on YouTube</span>
              </a>
            </p>
        
If you have an existing machine, either physical or virtual (VM or container), you can use the `lxd-convert` tool to create a LXD instance based on your existing disk or image.

The tool copies the provided partition, disk or image to the LXD storage pool of the provided LXD server, sets up an instance using that storage and allows you to configure additional settings for the new instance.

#### NOTE
If you want to configure your new instance during the conversion process, set up the entities that you want your instance to use before starting the conversion process.

By default, the new instance will use the entities specified in the `default` profile.
You can specify a different profile (or a profile list) to customize the configuration.
See [How to use profiles](../profiles.md#profiles) for more information.
You can also override [Instance options](../reference/instance_options.md#instance-options), the [storage pool](../explanation/storage.md#storage-pools) to be used and the size for the [storage volume](../explanation/storage.md#storage-volumes), and the [network](../networks.md#networking) to be used.

Alternatively, you can update the instance configuration after the conversion is complete.

The tool can create both containers and virtual machines:

* When creating a container, you must provide a disk or partition that contains the root file system for the container.
  For example, this could be the `/` root disk of the machine or container where you are running the tool.
* When creating a virtual machine, you must provide a bootable disk, partition, or an image in raw, QCOW, QCOW2, VDI, VHDX, or VMDK format.
  This means that just providing a file system is not sufficient, and you cannot create a virtual machine from a container that you are running.
  It is also not possible to create a virtual machine from the physical machine that you are using to do the conversion, because the conversion tool would be using the disk that it is copying.
  Instead, you could provide a bootable image, or a bootable partition or disk that is currently not in use.

The tool can also inject the required VIRTIO drivers into the image:

* To convert the image into raw format and inject the VIRTIO drivers during the conversion, use the following command:
  ```none
  lxd-convert --options=format,virtio
  ```

  #### NOTE
  The conversion option `virtio` requires `virt-v2v-in-place` to be installed on the host where the LXD server runs.
* For converting Windows images from a foreign hypervisor (not from QEMU/KVM with Q35/`virtio-scsi`), you must install additional drivers on the host:
  * `/usr/share/virtio-win/virtio-win.iso`

    Download [`virtio-win.iso`](https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso).
  * `/usr/share/virt-tools/rhsrvany.exe`
  * `/usr/share/virt-tools/pnp_wait.exe`

    `rhsrvany.exe` and `pnp_wait.exe` are provided in Ubuntu 24.04 and later in
    the [`rhsrvany`](https://launchpad.net/ubuntu/+source/rhsrvany) package.
    For other OS versions, download [`rhsrvany.exe` and `pnp_wait.exe`](https://github.com/rwmjones/rhsrvany?tab=readme-ov-file#binary-releases).

## Interactive instance import

Complete the following steps to convert an existing machine to a LXD instance:

1. Download the `bin.linux.lxd-convert` tool ([`bin.linux.lxd-convert.aarch64`](https://github.com/canonical/lxd/releases/latest/download/bin.linux.lxd-convert.aarch64) or [`bin.linux.lxd-convert.x86_64`](https://github.com/canonical/lxd/releases/latest/download/bin.linux.lxd-convert.x86_64)) from the **Assets** section of the latest [LXD release](https://github.com/canonical/lxd/releases).
2. Place the tool on the machine that you want to use to create the instance.
   Make it executable (usually by running `chmod u+x bin.linux.lxd-convert`).
3. Make sure that the machine has `rsync` and `file` installed.
   If they are missing, install them (for example, with `sudo apt install rsync file`).
4. Run the tool:
   ```none
   sudo ./bin.linux.lxd-convert
   ```

   The tool then asks you to provide the information required for the conversion.
   1. Specify the LXD server URL, either as an IP address or as a DNS name.

      #### NOTE
      The LXD server must be [exposed to the network](server_expose.md#server-expose).
      If you want to import to a local LXD server, you must still expose it to the network.
      You can then specify `127.0.0.1` as the IP address to access the local server.
   2. Check and confirm the certificate fingerprint.
   3. Choose a method for authentication (see [Remote API authentication](../authentication.md#authentication)).

      For example, if you choose using a certificate token, log on to the LXD server and create a token for the machine on which you are running the conversion tool with [`lxc config trust add`](../reference/manpages/lxc/config/trust/add.md#lxc-config-trust-add-md).
      Then use the generated token to authenticate the tool.
   4. Choose whether to create a container or a virtual machine.
      See [Containers and VMs](../explanation/instances.md#containers-and-vms).
   5. Specify a name for the instance that you are creating.
   6. Provide the path to a root file system (for containers) or a bootable disk, partition or image file (for virtual machines).
   7. For containers, optionally add additional file system mounts.
   8. For virtual machines, specify whether secure boot is supported.
   9. Optionally, configure the new instance.
      You can do so by specifying [profiles](../profiles.md#profiles), directly setting [configuration options](../reference/instance_options.md#instance-options) or changing [storage](../storage.md#storage) or [network](../networks.md#networking) settings.

      Alternatively, you can configure the new instance after the conversion.
   10. When you are done with the configuration, start the conversion process.

   <details>
   <summary>Expand to see an example output for importing to a container</summary>
   `user@host:~$ ``sudo ./bin.linux.lxd-convert
   `
   ```text
   Please provide LXD server URL: https://192.0.2.7:8443
   Certificate fingerprint: xxxxxxxxxxxxxxxxx
   ok (y/n)? y

   1) Use a certificate token
   2) Use an existing TLS authentication certificate
   3) Generate a temporary TLS authentication certificate
   Please pick an authentication mechanism above: 1
   Please provide the certificate token: xxxxxxxxxxxxxxxx

   Remote LXD server:
     Hostname: bar
     Version: 5.4

   Would you like to create a container (1) or virtual-machine (2)?: 1
   Name of the new instance: foo
   Please provide the path to a root filesystem: /
   Do you want to add additional filesystem mounts? [default=no]:

   Instance to be created:
     Name: foo
     Project: default
     Type: container
     Source: /

   Additional overrides can be applied at this stage:
   1) Begin the conversion with the above configuration
   2) Override profile list
   3) Set additional configuration options
   4) Change instance storage pool or volume size
   5) Change instance network

   Please pick one of the options above [default=1]: 3
   Please specify config keys and values (key=value ...): limits.cpu=2

   Instance to be created:
     Name: foo
     Project: default
     Type: container
     Source: /
     Config:
       limits.cpu: "2"

   Additional overrides can be applied at this stage:
   1) Begin the conversion with the above configuration
   2) Override profile list
   3) Set additional configuration options
   4) Change instance storage pool or volume size
   5) Change instance network

   Please pick one of the options above [default=1]: 4
   Please provide the storage pool to use: default
   Do you want to change the storage volume size? [default=no]: yes
   Please specify the storage volume size: 20GiB

   Instance to be created:
     Name: foo
     Project: default
     Type: container
     Source: /
     Storage pool: default
     Storage volume size: 20GiB
     Config:
       limits.cpu: "2"

   Additional overrides can be applied at this stage:
   1) Begin the conversion with the above configuration
   2) Override profile list
   3) Set additional configuration options
   4) Change instance storage pool or volume size
   5) Change instance network

   Please pick one of the options above [default=1]: 5
   Please specify the network to use for the instance: lxdbr0

   Instance to be created:
     Name: foo
     Project: default
     Type: container
     Source: /
     Storage pool: default
     Storage volume size: 20GiB
     Network name: lxdbr0
     Config:
       limits.cpu: "2"

   Additional overrides can be applied at this stage:
   1) Begin the conversion with the above configuration
   2) Override profile list
   3) Set additional configuration options
   4) Change instance storage pool or volume size
   5) Change instance network

   Please pick one of the options above [default=1]: 1
   Instance foo successfully created
   ```

   </details>
   <details>
   <summary>Expand to see an example output for importing to a VM</summary>
   `user@host:~$ ``sudo ./bin.linux.lxd-convert
   `
   ```text
   Please provide LXD server URL: https://192.0.2.7:8443
   Certificate fingerprint: xxxxxxxxxxxxxxxxx
   ok (y/n)? y

   1) Use a certificate token
   2) Use an existing TLS authentication certificate
   3) Generate a temporary TLS authentication certificate
   Please pick an authentication mechanism above: 1
   Please provide the certificate token: xxxxxxxxxxxxxxxx

   Remote LXD server:
     Hostname: bar
     Version: 5.4

   Would you like to create a container (1) or virtual-machine (2)?: 2
   Name of the new instance: foo
   Please provide the path to a root filesystem: ./virtual-machine.img
   Does the VM support UEFI Secure Boot? [default=no]: no

   Instance to be created:
     Name: foo
     Project: default
     Type: virtual-machine
     Source: ./virtual-machine.img
     Config:
       boot.mode: "uefi-nosecureboot"

   Additional overrides can be applied at this stage:
   1) Begin the conversion with the above configuration
   2) Override profile list
   3) Set additional configuration options
   4) Change instance storage pool or volume size
   5) Change instance network

   Please pick one of the options above [default=1]: 3
   Please specify config keys and values (key=value ...): limits.cpu=2

   Instance to be created:
     Name: foo
     Project: default
     Type: virtual-machine
     Source: ./virtual-machine.img
     Config:
       boot.mode: "uefi-nosecureboot"
       limits.cpu: "2"

   Additional overrides can be applied at this stage:
   1) Begin the conversion with the above configuration
   2) Override profile list
   3) Set additional configuration options
   4) Change instance storage pool or volume size
   5) Change instance network

   Please pick one of the options above [default=1]: 4
   Please provide the storage pool to use: default
   Do you want to change the storage volume size? [default=no]: yes
   Please specify the storage volume size: 20GiB

   Instance to be created:
     Name: foo
     Project: default
     Type: virtual-machine
     Source: ./virtual-machine.img
     Storage pool: default
     Storage volume size: 20GiB
     Config:
       boot.mode: "uefi-nosecureboot"
       limits.cpu: "2"

   Additional overrides can be applied at this stage:
   1) Begin the conversion with the above configuration
   2) Override profile list
   3) Set additional configuration options
   4) Change instance storage pool or volume size
   5) Change instance network

   Please pick one of the options above [default=1]: 5
   Please specify the network to use for the instance: lxdbr0

   Instance to be created:
     Name: foo
     Project: default
     Type: virtual-machine
     Source: ./virtual-machine.img
     Storage pool: default
     Storage volume size: 20GiB
     Network name: lxdbr0
     Config:
       boot.mode: "uefi-nosecureboot"
       limits.cpu: "2"

   Additional overrides can be applied at this stage:
   1) Begin the conversion with the above configuration
   2) Override profile list
   3) Set additional configuration options
   4) Change instance storage pool or volume size
   5) Change instance network

   Please pick one of the options above [default=1]: 1
   Instance foo successfully created
   ```

   </details>
5. When the conversion is complete, check the new instance and update its configuration to the new environment.
   Typically, you must update at least the storage configuration (`/etc/fstab`) and the network configuration.

## Non-interactive instance import

Alternatively, the entire instance import configuration can be provided using `lxd-convert` flags.
If any required flag is missing, `lxd-convert` will interactively prompt for the missing value.
However, when the `--non-interactive` flag is used, an error is returned instead.

Note that if any flag contains an invalid value, an error is returned regardless of the mode (interactive or non-interactive).

The `lxd-convert` command supports the following flags that can be used in non-interactive conversion:

```default
Instance configuration:
  -c, --config               Config key/value to apply to the new instance
      --mount-path           Additional container mount paths
      --name                 Name of the new instance
      --network              Network name
      --no-profiles          Create the instance with no profiles applied
      --profiles             Profiles to apply on the new instance (default [default])
      --project              Project name
      --source               Path to the root filesystem for containers, or to the block device or disk image file for virtual machines
      --storage              Storage pool name
      --storage-size         Size of the instance's storage volume
      --type                 Type of the instance to create (container or vm)

Target server:
      --server               Unix or HTTPS URL of the target server
      --token                Authentication token for HTTPS remote
      --cert-path            Trusted certificate path
      --key-path             Trusted certificate path

Other:
      --options strings      Comma-separated list of conversion options to apply. Allowed values are: [format, virtio] (default [format])
      --non-interactive      Prevent further interaction if conversion questions are incomplete
      --rsync-args           Extra arguments to pass to rsync
```

Example VM import to local LXD server:

```sh
lxd-convert \
  --name v1 \
  --type vm \
  --source "${sourcePath}" \
  --non-interactive
```

Example VM import to remote HTTPS server:

```sh
# Token from remote server.
token=$(lxc config trust add --name lxd-convert --quiet)

lxd-convert \
  --server https://example.com:8443 \
  --token "$token" \
  --name v1 \
  --type vm \
  --source "${sourcePath}" \
  --non-interactive
```

Example VM import with secure boot disabled and custom resource limits:

```sh
lxd-convert \
  --name v1 \
  --type vm \
  --source "${sourcePath}" \
  --config boot.mode=uefi-nosecureboot \
  --config limits.cpu=4 \
  --config limits.memory=4GiB \
  --non-interactive
```


# index.html.md

<a id="projects-create"></a>

# How to create and configure projects

You can configure projects at creation time or later.
However, note that it is not possible to modify the features that are enabled for a project when the project contains instances.

## Create a project

CLI

To create a project, use the [`lxc project create`](../reference/manpages/lxc/project/create.md#lxc-project-create-md) command.

You can specify configuration options by using the `--config` flag.
See [Project configuration](../reference/projects.md#ref-projects) for the available configuration options.

For example, to create a project called `my-project` that isolates instances, but allows access to the default project’s images and profiles, enter the following command:

```none
lxc project create my-project --config features.images=false --config features.profiles=false
```

To create a project called `my-restricted-project` that blocks access to security-sensitive features (for example, container nesting) but allows snapshots, enter the following command:

```none
lxc project create my-restricted-project --config restricted=true --config restricted.snapshots=allow
```

API

To create a project, send a POST request to the `/1.0/projects` endpoint.

You can specify configuration options under the `"config"` field.
See [Project configuration](../reference/projects.md#ref-projects) for the available configuration options.

For example, to create a project called `my-project` that isolates instances, but allows access to the default project’s images and profiles, send the following request:

```none
lxc query --request POST /1.0/projects --data '{
  "config": {
    "features.images": "false",
    "features.profiles": "false"
  },
  "name": "my-project"
}'
```

To create a project called `my-restricted-project` that blocks access to security-sensitive features (for example, container nesting) but allows snapshots, send the following request:

```none
lxc query --request POST /1.0/projects --data '{
  "config": {
    "restricted": "true",
    "restricted.snapshots": "allow"
  },
  "name": "my-restricted-project"
}'
```

See [`POST /1.0/projects`](/api/#/projects/projects_post) for more information.

UI

To create a project, expand the Project drop-down and select + Create project at the bottom.

Enter a name and optionally a description for the new project.
You can create the project using the default set of features or select Customised to add or remove specific features.
See [Project features](../reference/projects.md#project-features) for more information about the available features.

For example, to create a project called `my-project` that isolates instances, but allows access to the default project’s images and profiles:

![Create a project](images/UI/create_project.png)

To configure resource limits for the project, select Resource limits.

To restrict a project from accessing security-sensitive features, check Allow custom restrictions on a project level.
You can then configure the restrictions under Restrictions.
See [Project restrictions](../reference/projects.md#project-restrictions) for more information.

For example, to create a project called `my-restricted-project` that blocks access to security-sensitive features (for example, container nesting) but allows snapshots:

1. Check Allow custom restrictions on a project level:
   ![Create a restricted project](images/UI/create_restr_project1.png)
2. Configure the restrictions:
   ![Allow snapshots in a restricted project](images/UI/create_restr_project2.png)

<a id="projects-configure"></a>

## Configure a project

To configure a project, you can either set a specific configuration option or edit the full project.

Some configuration options can only be set for projects that do not contain any instances.

### Set specific configuration options

CLI

To set a specific configuration option, use the [`lxc project set`](../reference/manpages/lxc/project/set.md#lxc-project-set-md) command.

For example, to limit the number of containers that can be created in `my-project` to five, enter the following command:

```none
lxc project set my-project limits.containers=5
```

To unset a specific configuration option, use the [`lxc project unset`](../reference/manpages/lxc/project/unset.md#lxc-project-unset-md) command.

#### NOTE
If you unset a configuration option, it is set to its default value.
This default value might differ from the initial value that is set when the project is created.

API

To set a specific configuration option, send a PATCH request to the project.

For example, to limit the number of containers that can be created in `my-project` to five, send the following request:

```none
lxc query --request PATCH /1.0/projects/my-project --data '{
  "config": {
    "limits.containers": "5"
  }
}'
```

See [`PATCH /1.0/projects/{name}`](/api/#/projects/project_patch) for more information.

UI

To update the project configuration, select the respective project from the Project drop-down.
Then go to Configuration and click Edit configuration to set or unset any configuration options.

### Edit the project

CLI

To edit the full project configuration, use the [`lxc project edit`](../reference/manpages/lxc/project/edit.md#lxc-project-edit-md) command.
For example:

```none
lxc project edit my-project
```

API

To update the entire project configuration, send a PUT request to the project.
For example:

```none
lxc query --request PUT /1.0/projects/my-project --data '{
  "config": { ... },
  "description": "<description>"
}'
```

See [`PUT /1.0/projects/{name}`](/api/#/projects/project_put) for more information.

UI

The UI does not currently support editing the full YAML configuration for a project.
However, you can update several or all configuration options at the same time through the UI.


# index.html.md

<a id="oidc-entra-id"></a>

# How to configure authentication with Entra ID

[Entra ID](https://www.microsoft.com/en-gb/security/business/identity-access/microsoft-entra-id) is an Identity and Access Management offering from Microsoft.
It is commonly used as a central location for managing users, groups, roles, and their privileges across many applications and deployments.

LXD supports authentication Entra ID via [OpenID Connect (OIDC)](https://openid.net/) (see [OpenID Connect authentication](../authentication.md#authentication-openid)).
To configure authentication with Entra ID, follow the steps below.

We assumed that LXD is initialized and accessible over HTTPS on port 8443 (see [How to expose LXD to the network](server_expose.md#server-expose) for instructions).
It is also assumed that you have access to an Entra ID tenant.

1. In your Entra ID tenant, go to `Identity > Applications > App registrations` in the left panel.
   ![image](images/auth/entra-id/1-app-registrations.png)
2. Click `+ New registration`. Then choose a name for the application (for example `LXD`).
   ![image](images/auth/entra-id/2-app-name.png)
3. Under `Redirect URI (optional)`, select `Public client/native (mobile & desktop)` and type:
   ```none
   https://<your-LXD-hostname>/oidc/callback
   ```

   ![image](images/auth/entra-id/3-redirect-uri.png)
4. Click `Register`.
5. In the configuration page for your new application, go to `Authentication` in the `Manage` menu.
   ![image](images/auth/entra-id/4-authentication.png)
6. Scroll down to `Advanced settings`. Under `Allow public client flows`, toggle `Yes` and click `Save`.
   ![image](images/auth/entra-id/5-public-client-flows.png)
7. In the configuration page for your new application, go to `API permissions` in the `Manage` menu.
   ![image](images/auth/entra-id/6-api-permissions.png)
8. Go to `Configured permissions` and click `+ Add a permission`.
   ![image](images/auth/entra-id/7-add-a-permission.png)
9. Click `Microsoft Graph` in the right panel.
   ![image](images/auth/entra-id/8-graph-api.png)
10. Click `Delegated permissions`.
    ![image](images/auth/entra-id/9-delegated-permissions.png)
11. Select all `OpenId permissions`, then click `Add permissions`.
    ![image](images/auth/entra-id/10-openid-permissions.png)
12. Above the `Manage` menu, go to `Overview` and copy the `Application (client) ID`.
    ![image](images/auth/entra-id/11-client-id.png)
13. Set this as the client ID in LXD:
    ```none
    lxc config set oidc.client.id <your-client-id>
    ```
14. While still in `Overview`, click `Endpoints` and copy the URL under `OpenID Connect metadata document`.
    ![image](images/auth/entra-id/12-discovery-url.png)
15. Navigate to the URL that you copied. This URL will display some output in JSON format.
16. Copy the URL from the `issuer` field. Then set this as the `oidc.issuer` in LXD:
    ```none
    lxc config set oidc.issuer <your-issuer>
    ```

    Alternatively, execute this command:
    ```none
    lxc config set oidc.issuer "$(curl <URL that you copied> | jq -r .issuer)"
    ```

You can now navigate to the LXD UI in your browser.
When you click `Login with SSO`, you will be redirected to Entra ID to authenticate.

In the terminal, add this LXD server as a remote by running:

```none
lxc remote add <remote-name> <remote-url> --auth-type oidc
```

This prompts you to accept the public certificate fingerprint of the remote server, which should match the value for `certificate` shown in `lxc info`.
If you accept, the CLI then displays a unique login code and opens your browser.
In the browser, log in to your Entra ID tenant and enter the code.
Once the CLI process has completed, you can connect to the remote server.


# index.html.md

<a id="network-forwards"></a>

# How to configure network forwards

#### NOTE
Network forwards are available for the [OVN network](../reference/network_ovn.md#network-ovn) and the [Bridge network](../reference/network_bridge.md#network-bridge).


            <p class="youtube_link">
              <a href="https://www.youtube.com/watch?v=B-Uzo9WldMs" target="_blank">
                <span title="LXD network forwards" class="play_icon">▶</span>
                <span title="LXD network forwards">Watch on YouTube</span>
              </a>
            </p>
        
Network forwards allow an external IP address (or specific ports on it) to be forwarded to an internal IP address (or specific ports on it) in the network that the forward belongs to.

This feature can be useful if you have limited external IP addresses and want to share a single external address between multiple instances. In this case, you have two options:

- Forward all traffic from the external address to the internal address of one instance.
  This method makes it easy to move the traffic destined for the external address to another instance by simply reconfiguring the network forward.
- Forward traffic from different port numbers of the external address to different instances (and optionally different ports on those instances).
  This method allows to “share” your external IP address and expose more than one instance at a time.

For [OVN networks](../reference/network_ovn.md#network-ovn), network forwards also allow an internal IP address (or specific ports on it) to be forwarded to another internal IP address (or specific ports).

## List network forwards

View a list of all forwards configured on a network:

CLI

```default
lxc network forward list <network_name>
```

Example:

```default
lxc network forward list lxdbr0
```

#### NOTE
This list displays the listen address of the network forward and its default target address, if set. To view the target addresses for a network forward’s ports [set in its port specifications](#network-forwards-port-specifications), you can [show details about the network forward](#network-forward-show) or [edit the network forward](#network-forward-edit).

API

Query the `/1.0/networks/{networkName}` endpoint to list all forwards for a network.

```default
lxc query --request GET /1.0/networks/{networkName}/forwards
```

Example:

```default
lxc query --request GET /1.0/networks/lxdbr0/forwards
```

See [the API reference](/api/#/network-forwards/network_forwards_get) for more information.

You can also use [recursion](../rest-api.md#rest-api-recursion) to list the forwards with a higher level of detail:

```default
lxc query --request GET /1.0/networks/{networkName}/forwards?recursion=1
```

UI

In [the web UI](access_ui.md#access-ui), select Networks in the left sidebar, then select the desired network. On the resulting screen, view the Forwards tab:

![View a list of forwards on a network](images/UI/forwards_view.png)

<a id="network-forward-show"></a>

## Show a network forward

Show details about a specific network forward:

CLI

```default
lxc network forward show <network_name> <listen_address>
```

Example:

```default
lxc network forward show lxdbr0 192.0.2.1
```

API

Query the following endpoint for details about a specific forward:

```default
lxc query --request GET /1.0/networks/{networkName}/forwards/{listenAddress}
```

See [the API reference](/api/#/network-forwards/network_forward_get) for more information.

Example:

```default
lxc query --request GET /1.0/networks/ovn1/forwards/10.152.119.200
```

UI

In [the web UI](access_ui.md#access-ui), select Networks in the left sidebar, then select the desired network. On the resulting screen, view the Forwards tab. This tab shows you information about all forwards on the network. You can click the Edit icon to view details for a specific forward:

![View details about a specific forward on a network through its edit screen](images/UI/forward_edit_ex1.png)

<a id="network-forward-create"></a>

## Create a network forward

<a id="network-forwards-listen-addresses"></a>

### Requirements for listen addresses

Before you can create a network forward, you must understand the requirements for listen addresses.

For both OVN and bridge networks, the listen addresses must not overlap with any subnet in use by other networks on the host. Otherwise, the listen address requirements differ by network type.

OVN network

For an OVN network, the allowed listen addresses that are external IPs must be defined in at least one of the following configuration options, using [CIDR notation](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing):

- [`ipv4.routes`](../reference/network_bridge.md#network-bridge-network-conf:ipv4.routes) or [`ipv6.routes`](../reference/network_bridge.md#network-bridge-network-conf:ipv6.routes) in the OVN network’s uplink network configuration
- [`restricted.networks.subnets`](../reference/projects.md#project-restricted:restricted.networks.subnets) in the OVN network’s project configuration

The allowed internal IPs do not need to be defined. Use any non-conflicting internal IP address available on the OVN network.

Bridge network

A bridge network does not require you to define allowed listen addresses. Use any non-conflicting IP address available on the host.

### Create a forward in an OVN network

#### NOTE
You must configure the [allowed listen addresses](#network-forwards-listen-addresses) before you can create a forward in an OVN network.

The IP addresses and ports shown in the examples below are only examples. It is up to you to choose the allowed and available addresses and ports for your setup.

CLI

Use the following command to create a forward in an OVN network:

```default
lxc network forward create <ovn_network_name> <listen_address>|--allocate=ipv{4,6} [target_address=<target_address>] [user.<key>=<value>]
```

- For `<ovn_network_name>`, specify the name of the OVN network on which to create the forward.
- Immediately following the network name, provide only one of the following for the listen address:
  - A listen IP address allowed by the [Requirements for listen addresses](#network-forwards-listen-addresses) (no port number)
  - The `--allocate=` flag with a value of either `ipv4` or `ipv6` for automatic allocation of an allowed external IP address
- Optionally provide a default `target_address` (no port number). Any traffic that does not match a port specification is forwarded to this address. This must be an IP address within the OVN network’s subnet; typically, the static IP address of an instance is used.
- Optionally provide custom user.\* keys to be stored in the network forward’s configuration.

### Examples

This example shows how to create a network forward on a network named `ovn1` with an allocated listen address and no default target address:

```default
lxc network forward create ovn1 --allocate=ipv4
```

This example shows how to create a network forward on a network named `ovn1` with a specific listen address and a default target address:

```default
lxc network forward create ovn1 192.0.2.1 target_address=10.41.211.2
```

API

To create a network forward in an OVN network, send a POST request to the `/1.0/networks/{networkName}/forwards` endpoint:

```default
lxc query --request POST /1.0/networks/{networkName}/forwards --data '{
  "listen_address": "<listen_address>",            # required
  "description": "<description of the forward>",   # optional
  "config": {
     "target_address": "<default_target_address>",  # optional
     "user.<key>": "<value>"                        # optional
  },
  "ports": [                                        # optional
    {
      "description": "<description of the forward to this port>",
      "listen_port": "<listen_port>",
      "protocol": "<tcp|udp>",
      "target_address": "<target address>",
      "target_port": "<target port or ports>"
    }
  ]
}'
```

- For `{networkName}`, specify the name of the OVN network on which to create the forward.
- For `<listen_address>`, provide only one of the following:
  - A listen IP address allowed by the [Requirements for listen addresses](#network-forwards-listen-addresses) (no port number)
  - For automatic allocation of an allowed IP address, use `"0.0.0.0"` for IPv4 and `"::"` for IPv6.
- Optionally provide a description of the forward.
- Optionally provide a default `target_address` as part of the `config` object (no port number). Any traffic that does not match a port specification is forwarded to this address. This must be an IP address within the OVN network’s subnet; typically, the static IP address of an instance is used.
- Optionally provide custom `user.*` keys, also as part of the `config` object.
- Optionally set up port specifications during forward creation. These specifications allow forwarding traffic from specific ports on the listen address to ports on a target address. For details on how to configure ports, see: [Configure ports](#network-forwards-port-specifications).

See [the API reference](/api/#/network-forwards/network_forward_post) for more information.

### Examples

This example shows how to create a network forward on a network named `ovn1` with an allocated listen address and no default target address:

```default
lxc query --request POST /1.0/networks/ovn1/forwards --data '{
  "listen_address": "0.0.0.0"
}'
```

This example shows how to create a network forward on a network named `ovn1` with a specific listen address and a default target address:

```default
lxc query --request POST /1.0/networks/ovn1/forwards --data '{
  "listen_address": "192.0.2.1",
  "config": {
    "target_address": "10.41.211.2"
  }
}'
```

UI

In [the web UI](access_ui.md#access-ui), select Networks in the left sidebar, then select the desired OVN network. On the resulting screen, view the Forwards tab. Click the Create forward button.

In the Create a new forward panel, only the Listen address field is required.

![Create an OVN network forward](images/UI/forward_create_ovn.png)
- For the Listen address, provide an IP address allowed by the [Requirements for listen addresses](#network-forwards-listen-addresses) (no port number).
- Optionally provide a Default target address (no port number). Any traffic that does not match a port specification is forwarded to this address. This must be an IP address within the OVN network’s subnet; typically, the static IP address of an instance is used.

You can optionally set up port specifications for the network forward by clicking the Add port button. These specifications allow forwarding traffic from specific ports on the listen address to ports on a target address. For details on how to configure this section, see: [Configure ports](#network-forwards-port-specifications).

Once you have finished setting up the network forward, click the Create button.

### Create a forward in a bridge network

#### NOTE
The IP addresses and ports shown in the examples below are only examples. It is up to you to choose the allowed and available addresses and ports for your setup.

CLI

Use the following command to create a forward in a bridge network:

```default
lxc network forward create <bridge_network_name> <listen_address> [target_address=<target_address>] [user.<key>=<value>]
```

- For `<bridge_network_name>`, specify the name of the bridge network on which to create the forward.
- Immediately following the network name, provide an IP address allowed by the [Requirements for listen addresses](#network-forwards-listen-addresses) (no port number).
- Optionally provide a default `target_address` (no port number). Any traffic that does not match a port specification is forwarded to this address. This must be an IP address within the bridge network’s subnet; typically, the static IP address of an instance is used.
- Optionally provide custom user.\* keys to be stored in the network forward’s configuration.
- You cannot use the `--allocate` flag with bridge networks.

### Example

This example shows how to create a forward on a network named `bridge1`. The listen address is required, and the default target address is optional:

```default
lxc network forward create bridge1 192.0.2.1 target_address=10.41.211.2
```

API

To create a network forward in a bridge network, send a POST request to the `/1.0/networks/{networkName}/forwards` endpoint:

```default
lxc query --request POST /1.0/networks/{networkName}/forwards --data '{
  "listen_address": "<listen_address>",            # required
  "description": "<description of the forward>",   # optional
  "config": {
     "target_address": "<default_target_address>",  # optional
     "user.<key>": "<value>"                        # optional
  },
  "ports": [                                        # optional
    {
      "description": "<description of the forward to this port>",
      "listen_port": "<listen_port>",
      "protocol": "<tcp|udp>",
      "target_address": "<target address>",
      "target_port": "<target port or ports>"
    }
  ]
}'
```

- For `{networkName}`, specify the name of the bridge network on which to create the forward.
- For `<listen_address>`, provide an IP address allowed by the [Requirements for listen addresses](#network-forwards-listen-addresses) (no port number).
  - With bridge networks, you cannot dynamically allocate the listen address. You must input a specific address.
- Optionally provide a description of the forward.
- Optionally provide a default `target_address` as part of the `config` object (no port number). Any traffic that does not match a port specification is forwarded to this address. This must be an IP address within the OVN network’s subnet; typically, the static IP address of an instance is used.
- Optionally provide custom `user.*` keys, also as part of the `config` object.
- Optionally set up port specifications during forward creation. These specifications allow forwarding traffic from specific ports on the listen address to ports on a target address. For details on how to configure ports, see: [Configure ports](#network-forwards-port-specifications).

See [the API reference](/api/#/network-forwards/network_forward_post) for more information.

### Example

This example shows how to create a forward on a network named `bridge1`. The listen address is required, and the default target address is optional:

```default
lxc query --request POST /1.0/networks/bridge1/forwards --data '{
  "listen_address": "192.0.2.1",
  "config": {
    "target_address": "10.41.211.2"
  }
}'
```

UI

In [the web UI](access_ui.md#access-ui), select Networks in the left sidebar, then select the desired bridge network. On the resulting screen, view the Forwards tab. Click the Create forward button.

In the Create a new forward panel, only the Listen address field is required.

![Create a bridge network forward](images/UI/forward_create_bridge.png)
- For the Listen address, provide a listen IP address allowed by the [Requirements for listen addresses](#network-forwards-listen-addresses) (no port number).
- Optionally provide a Default target address (no port number). Any traffic that does not match a port specification is forwarded to this address. This must be an IP address within the bridge network’s subnet; typically, the static IP address of an instance is used.

You can optionally set up port specifications for the network forward by clicking the Add port button. These specifications allow forwarding traffic from specific ports on the listen address to ports on a target address. For details on how to configure this section, see: [Configure ports](#network-forwards-port-specifications).

Once you have finished setting up the network forward, click the Create button.

### Forward properties

Network forwards have the following properties:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="network-forward-forward-properties:config"></a>
`config`

User-provided free-form key/value pairs

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-forward-forward-properties:config)

| **Key:**      | `config`   |
|---------------|------------|
| **Type:**     | string set |
| **Required:** | no         |

The only supported keys are `target_address` and `user.*` custom keys.

The `target_address` key is for the default target address of the network forward.
It must be an IP address within the subnet of the network the forward belongs to.

<a id="network-forward-forward-properties:description"></a>
`description`

Description of the network forward

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-forward-forward-properties:description)

| **Key:**      | `description`   |
|---------------|-----------------|
| **Type:**     | string          |
| **Required:** | yes             |

<a id="network-forward-forward-properties:listen_address"></a>
`listen_address`

IP address to listen on

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-forward-forward-properties:listen_address)

| **Key:**      | `listen_address`   |
|---------------|--------------------|
| **Type:**     | string             |
| **Required:** | no                 |

See [Requirements for listen addresses](#network-forwards-listen-addresses).

<a id="network-forward-forward-properties:ports"></a>
`ports`

List of port specifications

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-forward-forward-properties:ports)

| **Key:**      | `ports`   |
|---------------|-----------|
| **Type:**     | port list |
| **Required:** | no        |

See [Configure ports](#network-forwards-port-specifications).

<a id="network-forwards-port-specifications"></a>

## Configure ports

Once a forward is created on a network (whether bridge or OVN), it can be configured with port specifications. These specifications allow forwarding traffic from ports on the listen address to ports on a target address.

CLI

When using the CLI, you must first [create a network forward](#network-forward-create) before you can add port specifications to it.

Use the following command to add port specifications on a forward:

```default
lxc network forward port add <network_name> <listen_address> <protocol> <listen_ports> <target_address> [<target_ports>]
```

- Use the network name and listen address of the forward for which you want to add port specifications.
- Use either `tcp` or `udp` as the protocol.
- For the listen ports, you can specify a single listen port, a port range, or a comma-separated set of ports/port ranges.
- Specify a target address. This address must be within the network’s subnet, and it must be different from the forward’s default target address. Typically, the static IP address of an instance is used.
- Optionally specify a target port or ports. You can:
  - Specify a single target port to forward traffic from all listen ports to this target port.
  - Specify a set of target ports with the same number of set items as the listen ports. This forwards traffic from the first listen port to the first target port, the second listen port to the second target port, and so on.
- If no target port is specified, the listen port value is used for the target port.
- You can add multiple port configurations to the same network forward.

### Examples

The example below shows how to configure a forward with a single listen port. Since no target port is specified, the target port defaults to the value of the listen port:

```default
lxc network forward port add network1 192.0.2.1 tcp 22 10.41.211.2
```

The example below shows how to configure a forward with a set of listen ports mapped to a single target port. Traffic to the listen address at ports 80 and 90 through 100 is forwarded to port 443 of the target address:

```default
lxc network forward port add network1 192.0.2.1 tcp 80,90-100 10.41.211.2 443
```

The example below shows how to configure a forward with a set of listen ports mapped to a set of target ports. Traffic to the listen address at port 22 is forwarded to port 22 of the target address, whereas traffic to port 80 is forwarded to port 443:

```default
lxc network forward port add network1 192.0.2.1 tcp 22,80 10.41.211.2 22,443
```

API

Using the API, you can configure port specifications on a network forward at the time you [create the forward](#network-forward-create), or by [editing the forward](#network-forward-edit) after creation.

In either case, you must configure the `ports` object shown below:

```default
{
  "listen_address": "<listen_address>",
  "description": "<description of the forward>",
  "config": {
     "target_address": "<default_target_address>",
     "user.<key>": "<value>"
  },
  "ports": [
    {
      "description": "<description of the forward to this port>",
      "listen_port": "<listen_port>",
      "protocol": "<tcp|udp>",
      "target_address": "<target address>",
      "target_port": "<target port or ports>"
    }
  ]
}
```

- For `"listen_port"`, you can specify a single listen port, a port range, or a comma-separated set of ports/port ranges.
- Use either `"tcp"` or `"udp"` as the `"protocol"`.
- Specify a `"target_address"`. This address must be within the network’s subnet, and it must be different from the forward’s default target address that is configured in the `config` object. Typically, the static IP address of an instance is used.
- Optionally specify a target port or ports. You can:
  - Specify a single target port to forward traffic from all listen ports to this target port.
  - Specify a set of target ports with the same number of set items as the listen ports. This forwards traffic from the first listen port to the first target port, the second listen port to the second target port, and so on.
- If no target port is specified, the listen port value is used for the target port.
- The `"ports"` JSON property is configured as an array (list) of objects. You can set multiple port configurations on the same network forward, each as a separate JSON object in the array.

### Examples

```default
"ports": [
   {
      "description": "My web server forward",
      "listen_port": "80,81,8080-8090",
      "protocol": "tcp",
      "target_address": "198.51.100.2",
      "target_port": "80,81,8080-8090"
   },
   {
      "description": "My API server forward",
      "listen_port": "3000",
      "protocol": "tcp",
      "target_address": "198.51.100.3",
      "target_port": "8080"
   }
]
```

In the example above, traffic to the network forward’s listen ports of 80, 81, or 8080-8090 is explicitly forwarded to the same ports on the target address. Traffic to the forward’s listen port of 3000 is explicitly forwarded to port 8080 on the target address.

More examples;

- If the `"listen_port"` is set to `"22"` and no `"target_port`” is specified, the target port value defaults to `"22"`.
- If the `"listen_port"` is set to `"80,90-100"` and the `"target_port`” is set to `"442"`, all traffic to the listen address at ports 80 and 90 through 100 is forwarded to port 443 of the target address.
- If the `"listen_port"` is set to `"22,80"` and the `"target_port`” is set to `"22,443"`, all traffic to the listen address at port 22 is forwarded to port 22 of the target address, whereas traffic to port 80 is forwarded to port 443.

UI

In the web UI, you can configure port specifications on a network forward at the time you [create the forward](#network-forward-create), or by [editing the forward](#network-forward-edit) after creation.

![Configure a network forward's port specifications](images/UI/forward_create_port.png)
- For the Listen port, you can specify a single port, a port range, or a comma-separated set of ports/port ranges.
- Select either TCP or UDP as the protocol.
- Specify a Target address. This address must be within the network’s subnet, and it must be different from the forward’s Default target address. Typically, the static IP address of an instance is used.
- Optionally specify a target port or ports. You can:
  - Specify a single target port to forward traffic from all listen ports to this target port.
  - Specify a set of target ports with the same number of set items as the listen ports. This forwards traffic from the first listen port to the first target port, the second listen port to the second target port, and so on.
- If no target port is specified, the listen port value is used for the target port.

### Examples

- If the Listen port is set to `22` and no Target port is specified, the target port value defaults to 22.
- If the Listen port is set to `80,90-100` and the Target port is set to 442, all traffic to the listen address at ports 80 and 90 through 100 is forwarded to port 443 of the target address.
- If the Listen port is set to `22,80` and the Target port is set to `22,443`, all traffic to the listen address at port 22 is forwarded to port 22 of the target address, whereas traffic to port 80 is forwarded to port 443.

### Port properties

Network forward ports have the following properties:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="network-forward-port-properties:description"></a>
`description`

Description of the port or ports

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-forward-port-properties:description)

| **Key:**      | `description`   |
|---------------|-----------------|
| **Type:**     | string          |
| **Required:** | no              |

<a id="network-forward-port-properties:listen_port"></a>
`listen_port`

Listen port or ports

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-forward-port-properties:listen_port)

| **Key:**      | `listen_port`   |
|---------------|-----------------|
| **Type:**     | string          |
| **Required:** | yes             |

For example: `80,90-100`

<a id="network-forward-port-properties:protocol"></a>
`protocol`

Protocol for the port or ports

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-forward-port-properties:protocol)

| **Key:**      | `protocol`   |
|---------------|--------------|
| **Type:**     | string       |
| **Required:** | yes          |

Possible values are `tcp` and `udp`.

<a id="network-forward-port-properties:target_address"></a>
`target_address`

IP address to forward to

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-forward-port-properties:target_address)

| **Key:**      | `target_address`   |
|---------------|--------------------|
| **Type:**     | string             |
| **Required:** | yes                |

This `target_address` must be within the subnet of the network the forward belongs to.
Also, it must be different from the forward’s default target address.

<a id="network-forward-port-properties:target_port"></a>
`target_port`

Target port or ports

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-forward-port-properties:target_port)

| **Key:**      | `target_port`         |
|---------------|-----------------------|
| **Type:**     | string                |
| **Default:**  | same as `listen_port` |
| **Required:** | no                    |

For example: `70,80-90` or `90`

<a id="network-forward-edit"></a>

## Edit a network forward

CLI

Use the following command to edit a network forward:

```bash
lxc network forward edit <network_name> <listen_address>
```

This command opens the network forward in YAML format for editing.
You can edit both the general configuration and the port specifications.

API

### Partial update

To update a subset of the network forward configuration, send a PATCH request to the `/1.0/networks/{networkName}/forwards/{listenAddress}` endpoint:

```default
lxc query --request PATCH /1.0/networks/{networkName}/forwards/{listenAddress} --data '{
  "config": {
     "target_address": "<default_target_address>",
     "user.<key>": "<value>"
  },
  "description": "<description of the forward>",
  "ports": [
    {
      "description": "<description of the forward to this port>",
      "listen_port": "<listen_port>",
      "protocol": "<tcp|udp>",
      "target_address": "<target address>",
      "target_port": "<target port or ports>"
    }
  ]
}'
```

See [the API reference](/api/#/network-forwards/network_forward_patch) for more information.

### Example

Update only the default target address of a forward:

```default
lxc query --request PATCH /1.0/networks/ovn1/forwards/10.152.119.200 --data '{
  "config": {
    "target_address": "10.41.211.3"
  }
}'
```

### Full update

To replace the entire configuration of an existing network forward, send a PUT request to the `/1.0/networks/{networkName}/forwards/{listenAddress}` endpoint:

```default
lxc query --request PUT /1.0/networks/{networkName}/forwards/{listenAddress} --data '{
  "config": {
     "target_address": "<default_target_address>",
     "user.<key>": "<value>"
  },
  "description": "<description of the forward>",
  "ports": [
    {
      "description": "<description of the forward to this port>",
      "listen_port": "<listen_port>",
      "protocol": "<tcp|udp>",
      "target_address": "<target address>",
      "target_port": "<target port or ports>"
    }
  ]
}'
```

Unlike a `PATCH` request, the `PUT` request replaces the entire configuration.

See [the API reference](/api/#/network-forwards/network_forward_put) for more information.

### Example

When using PUT, take care to send any data should be kept in the configuration. Consider the following configuration for a network forward:

```default
{
  "listen_address": "10.152.119.200",
  "config": {
     "target_address": "10.41.211.3",
  },
  "ports": [
    {
      "listen_port": "80",
      "protocol": "tcp",
      "target_address": "10.41.211.4",
      "target_port": "443"
    }
  ]
}'
```

The following PUT request updates the entire configuration:

```default
lxc query --request PUT /1.0/networks/ovntest/forwards/10.152.119.200 --data '{
  "ports": [
    {
      "listen_port": "80",
      "protocol": "tcp",
      "target_address": "10.41.211.5",
      "target_port": "443"
    }
  ]
}'
```

The forward’s configuration after the PUT update:

```default
{
  "listen_address": "10.152.119.200",
  "config": {},
  "ports": [
    {
      "listen_port": "80",
      "protocol": "tcp",
      "target_address": "10.41.211.5",
      "target_port": "443"
    }
  ]
}
```

Notice that the `config` object no longer contains any values. This is because none were sent as part of the PUT update.

UI

In [the web UI](access_ui.md#access-ui), select Networks in the left sidebar, then select the desired network. On the resulting screen, view the Forwards tab. This tab shows you information about all forwards on the network. Click the Edit icon next to a forward to edit it:

![Choose to edit a forward on a network](images/UI/forward_edit_ex1.png)

In the resulting screen, you can edit the forward’s general configuration as well as its port specifications:

![Edit a forward on a network](images/UI/forward_edit_ex2.png)

## Delete a network forward

CLI

Use the following command to delete a network forward:

```bash
lxc network forward delete <network_name> <listen_address>
```

API

To delete a network forward, send a DELETE request to the `/1.0/networks/{networkName}/forwards/{listenAddress}` endpoint:

```default
lxc query --request DELETE /1.0/networks/{networkName}/forwards/{listenAddress}
```

Example:

```default
lxc query --request DELETE /1.0/networks/ovn1/forwards/192.0.2.21
```

See [the API reference](/api/#/network-forwards/network_forward_delete) for more information.

UI

In [the web UI](access_ui.md#access-ui), select Networks in the left sidebar, then select the desired network. On the resulting screen, view the Forwards tab. This tab shows you information about all forwards on the network. Click the Delete icon next to a forward to delete it:

![Delete a forward on a network](images/UI/forward_delete.png)


# index.html.md

<a id="oidc-ory"></a>

# How to configure Ory Hydra as login method for the LXD UI

Ory Hydra is an easy solution to authenticate users for the LXD UI. It supports local users and social sign in through Google, Facebook, Microsoft, GitHub, Apple or others. It does not yet work for the LXD command line. This guide shows you how to set up Ory Hydra as the login method for the LXD UI.

## Using Ory Hydra to access LXD UI

1. Open a free account on [Ory.sh/Hydra](https://www.ory.com/hydra).
2. Once logged into the Ory Console, navigate to OAuth 2 > OAuth2 Clients > Create OAuth2 Client.
3. Select the type Mobile / SPA and click Create. Enter the details for the client:
   - **Client Name**: Choose a name, such as `lxd-ory-client`.
   - **Scope**: Enter `email` and click Add, then add `profile` as well.
   - **Redirect URIs**: Enter your LXD UI address, followed by `/oidc/callback`, then click Add.
     - Example: `https://example.com:8443/oidc/callback`
     - An IP address can be used instead of a domain name.
     - Note: `:8443` is the default listening port for the LXD server. It might differ for your setup. Use `lxc config get core.https_address` to find the correct port for your LXD server.
4. Select Create Client on the bottom of the page.
5. On the OAuth2 Clients list, find the ID for the client you created. Copy the value and set it in your LXD server configuration with the command:
   ```none
   lxc config set oidc.client.id=<your OAuth2 Client ID>
   ```
6. In the Ory Console, navigate to OAuth 2 > Overview. Find the Issuer URL and copy the value. Set this value in your LXD server configuration as issuer with the commands:
   ```none
   lxc config set oidc.issuer=https://<ory-id>.projects.oryapis.com
   ```

Now you can access the LXD UI with any browser and use  login.

No users exist within ORY by default. New users can use the sign-up link during login. Alternatively, configure Google, Facebook, Microsoft, GitHub, Apple, or another social sign-in provider as described in the [ORY documentation](https://www.ory.com/docs/kratos/social-signin/overview).

Users authenticated through ORY have no default permissions in the LXD UI. Set up [LXD authorization groups](../explanation/authorization.md#manage-permissions) to grant access to projects and instances and map a LXD authorization group to the user. Note that the user object in LXD is only created on the first login of that user to LXD.


# index.html.md

<a id="howto-replicators-setup"></a>

# How to set up replicators

Replicators sync instances across LXD cluster links. This is useful for active-passive disaster recovery, where a leader (active) cluster handles all workloads while a standby cluster remains ready to take over if the leader fails.

LXD supports this strategy using project replicators over a [cluster link](../explanation/clusters.md#exp-cluster-links).

<a id="howto-replicators-prereqs"></a>

## Prerequisites

Before setting up replicators:

1. Two LXD clusters must be initialized. We will call them “leader” and “standby”.
2. You need sufficient permissions on both clusters to establish links and manage projects.
3. A [cluster link must be established](cluster_links_create.md#howto-cluster-links-create) between the two clusters.
4. Network connectivity must exist between the clusters.

<a id="howto-replicators-auth"></a>

## Prepare authentication

Replicators communicate over cluster links, so the linked cluster identities must be granted the permissions they need on the replicated project. Configure these permissions using authentication groups and [Manage permissions](../explanation/authorization.md#manage-permissions).

For project replication, the cluster-link identity on each cluster typically needs at least these permissions:

- `operator` on the replicated project, so it can perform instance replication work in that project
- `can_edit` on the replicated project, so replica project configuration can be validated and updated as part of the workflow

For example, if the replicated project is called `myproject`, you can prepare an authentication group on each cluster before creating the cluster links:

```bash
lxc auth group create replicators
lxc auth group permission add replicators project myproject operator
lxc auth group permission add replicators project myproject can_edit
```

Then create the cluster links with that authentication group, as described in [How to create cluster links](cluster_links_create.md#howto-cluster-links-create).

<a id="howto-replicators-project-setup"></a>

## Configure projects for replication

Both clusters need a project with the same name. Only the standby project requires the [`replica.cluster`](../reference/projects.md#project-replica:replica.cluster) configuration key; the leader project does not need it because the replicator defines the target cluster.

1. On the leader cluster, create a project:
   ```bash
   lxc project create <project_name>
   ```
2. On the standby cluster, create a project with the same name and configure it to accept replication from the leader cluster:
   ```bash
   lxc project create <project_name> -c replica.cluster=<leader_cluster_link_name>
   ```
3. On the standby cluster, demote the project to standby mode. This prevents new instances from being created in the project and existing instances from being started. The project must be promoted to `leader` during a failover before instances can be started.
   ```bash
   lxc project demote-replica <project_name>
   ```
4. On the leader cluster, promote the project to leader mode:
   ```bash
   lxc project promote-replica <project_name>
   ```

<a id="howto-replicators-create"></a>

## Create a replicator

After configuring the projects on both clusters, create a replicator on the leader cluster. The `cluster` configuration key is required and must be set to the name of an existing cluster link.

Each cluster link can be targeted by at most one replicator per project. Creating or updating a replicator to target a cluster link already used by another replicator in the same project fails with a conflict error.

```bash
lxc replicator create <replicator_name> cluster=<standby_cluster_link_name> --project <project_name>
```

For example:

```bash
lxc replicator create my-replicator cluster=lxd-standby --project myproject
```

You can also create a replicator with a schedule and snapshot options:

```bash
lxc replicator create my-replicator cluster=lxd-standby schedule="@daily" snapshot=true --project myproject
```

See [Replicator configuration](../reference/replicator_config.md#ref-replicator-config) for all available configuration options.

<a id="howto-replicators-run"></a>

## Run a replicator

To manually trigger a replicator run, use the following command on the leader cluster:

```bash
lxc replicator run <replicator_name>
```

This syncs all instances in the source project to the standby cluster.

To schedule replication automatically, set the `schedule` configuration key with a cron expression:

```bash
lxc replicator set <replicator_name> schedule="0 0 * * *"
```

<a id="howto-replicators-snapshot"></a>

## Snapshot before replication

Each replicator run performs an incremental instance sync to the standby cluster using
the equivalent of `lxc copy --refresh`. This transfers only the data that has changed since the last sync,
using any existing snapshots as a reference point to minimize the amount of data transferred.

When you set `snapshot=true` on a replicator, LXD creates a point-in-time snapshot of each
source instance before performing the incremental copy. This gives the copy operation a
consistent reference point, which reduces the amount of data transferred on each sync and
provides a rollback point on the source in case anything goes wrong during replication.

Snapshot naming and expiry are controlled entirely by the instance’s own configuration (for
example [`snapshots.pattern`](../reference/instance_options.md#instance-snapshots:snapshots.pattern) and
[`snapshots.expiry`](../reference/instance_options.md#instance-snapshots:snapshots.expiry)), or by the profile applied to the
instance. The replicator does not impose its own naming scheme.

If an instance already has a [`snapshots.schedule`](../reference/instance_options.md#instance-snapshots:snapshots.schedule) set at
the instance or profile level, the replicator skips creating a new snapshot and reuses the
most recent existing snapshot as the reference point for the incremental copy instead.

When `snapshot` is not set (or set to `false`), no new snapshot is created before the
incremental copy runs. If existing snapshots are present on the instance, the copy operation
uses them to transfer only the delta; if no snapshots exist, the full instance is transferred.

#### NOTE
Snapshots created by replication accumulate over time. Use `snapshots.expiry` on the instance or
profile to automatically prune them, or delete them manually with `lxc snapshot delete`.

## Next steps

Once replicators are running, see [How to manage replicators](replicators_manage.md#howto-replicators-manage) to view, configure, or delete replicators, and [How to perform disaster recovery with replicators](replicators_dr.md#howto-replicators-dr) to fail over to the standby cluster if the leader becomes unavailable.


# index.html.md

<a id="network-ovn-setup"></a>

# How to set up OVN with LXD

See the following sections for how to set up a basic OVN network, either as a standalone network or to host a small LXD cluster.

## Set up a standalone OVN network

Complete the following steps to create a standalone OVN network that is connected to a managed LXD parent bridge network (for example, `lxdbr0`) for outbound connectivity.

1. Install the OVN tools on the local server:
   ```none
   sudo apt install ovn-host ovn-central
   ```
2. Configure the OVN integration bridge:
   ```none
   sudo ovs-vsctl set open_vswitch . \
      external_ids:ovn-remote=unix:/var/run/ovn/ovnsb_db.sock \
      external_ids:ovn-encap-type=geneve \
      external_ids:ovn-encap-ip=127.0.0.1
   ```
3. Create an OVN network:
   ```none
   lxc network set <parent_network> ipv4.dhcp.ranges=<IP_range> ipv4.ovn.ranges=<IP_range>
   lxc network create ovntest --type=ovn network=<parent_network>
   ```
4. Create an instance that uses the `ovntest` network:
   ```none
   lxc init ubuntu:24.04 c1
   lxc config device override c1 eth0 network=ovntest
   lxc start c1
   ```
5. Run [`lxc list`](../reference/manpages/lxc/list.md#lxc-list-md) to show the instance information:
   `user@host:~$ ``lxc list
   `
   ```text
   +------+---------+---------------------+----------------------------------------------+-----------+-----------+
   | NAME |  STATE  |        IPV4         |                     IPV6                     |   TYPE    | SNAPSHOTS |
   +------+---------+---------------------+----------------------------------------------+-----------+-----------+
   | c1   | RUNNING | 192.0.2.2 (eth0)    | 2001:db8:cff3:5089:216:3eff:fef0:549f (eth0) | CONTAINER | 0         |
   +------+---------+---------------------+----------------------------------------------+-----------+-----------+
   ```

## Set up a LXD cluster on OVN


            <p class="youtube_link">
              <a href="https://www.youtube.com/watch?v=1M_\_Rm9iZb8" target="_blank">
                <span title="OVN and a LXD cluster" class="play_icon">▶</span>
                <span title="OVN and a LXD cluster">Watch on YouTube</span>
              </a>
            </p>
        
Complete the following steps to set up a LXD cluster that uses an OVN network.

Just like LXD, the distributed database for OVN must be run on a cluster that consists of an odd number of members.
The following instructions use the minimum of three servers, which run both the distributed database for OVN and the OVN controller.
In addition, you can add any number of servers to the LXD cluster that run only the OVN controller.
See the linked YouTube video for the complete tutorial using four machines.

1. Complete the following steps on the three machines that you want to run the distributed database for OVN:
   1. Install the OVN tools:
      ```none
      sudo apt install ovn-central ovn-host
      ```
   2. Mark the OVN services as enabled to ensure that they are started when the machine boots:
      ```none
       systemctl enable ovn-central
       systemctl enable ovn-host
      ```
   3. Stop OVN for now:
      ```none
      systemctl stop ovn-central
      ```
   4. Note down the IP address of the machine:
      ```none
      ip -4 a
      ```
   5. Open `/etc/default/ovn-central` for editing.
   6. Paste in one of the following configurations (replace `<server_1>`, `<server_2>` and `<server_3>` with the IP addresses of the respective machines, and `<local>` with the IP address of the machine that you are on).
      - For the first machine:
        ```default
        OVN_CTL_OPTS=" \
             --db-nb-addr=<local> \
             --db-nb-create-insecure-remote=yes \
             --db-sb-addr=<local> \
             --db-sb-create-insecure-remote=yes \
             --db-nb-cluster-local-addr=<local> \
             --db-sb-cluster-local-addr=<local> \
             --ovn-northd-nb-db=tcp:<server_1>:6641,tcp:<server_2>:6641,tcp:<server_3>:6641 \
             --ovn-northd-sb-db=tcp:<server_1>:6642,tcp:<server_2>:6642,tcp:<server_3>:6642"
        ```
      - For the second and third machine:
        ```default
        OVN_CTL_OPTS=" \
              --db-nb-addr=<local> \
             --db-nb-cluster-remote-addr=<server_1> \
             --db-nb-create-insecure-remote=yes \
             --db-sb-addr=<local> \
             --db-sb-cluster-remote-addr=<server_1> \
             --db-sb-create-insecure-remote=yes \
             --db-nb-cluster-local-addr=<local> \
             --db-sb-cluster-local-addr=<local> \
             --ovn-northd-nb-db=tcp:<server_1>:6641,tcp:<server_2>:6641,tcp:<server_3>:6641 \
             --ovn-northd-sb-db=tcp:<server_1>:6642,tcp:<server_2>:6642,tcp:<server_3>:6642"
        ```
   7. Start OVN:
      ```none
      systemctl start ovn-central
      ```
2. On the remaining machines, install only `ovn-host` and make sure it is enabled:
   ```none
   sudo apt install ovn-host
   systemctl enable ovn-host
   ```
3. On all machines, configure Open vSwitch (replace the variables as described above):
   ```none
   sudo ovs-vsctl set open_vswitch . \
      external_ids:ovn-remote=tcp:<server_1>:6642,tcp:<server_2>:6642,tcp:<server_3>:6642 \
      external_ids:ovn-encap-type=geneve \
      external_ids:ovn-encap-ip=<local>
   ```
4. Create a LXD cluster by running `lxd init` on all machines.
   On the first machine, create the cluster.
   Then join the other machines with tokens by running [`lxc cluster add <machine_name>`](../reference/manpages/lxc/cluster/add.md#lxc-cluster-add-md) on the first machine and specifying the token when initializing LXD on the other machine.
5. On the first machine, create and configure the uplink network:
   ```none
   lxc network create UPLINK --type=physical parent=<uplink_interface> --target=<machine_name_1>
   lxc network create UPLINK --type=physical parent=<uplink_interface> --target=<machine_name_2>
   lxc network create UPLINK --type=physical parent=<uplink_interface> --target=<machine_name_3>
   lxc network create UPLINK --type=physical parent=<uplink_interface> --target=<machine_name_4>
   lxc network create UPLINK --type=physical \
      ipv4.ovn.ranges=<IP_range> \
      ipv6.ovn.ranges=<IP_range> \
      ipv4.gateway=<gateway> \
      ipv6.gateway=<gateway> \
      dns.nameservers=<name_server>
   ```

   To determine the required values:

   Uplink interface
   : A high availability OVN cluster requires a shared layer 2 network, so that the active OVN chassis can move between cluster members (which effectively allows the OVN router’s external IP to be reachable from a different host).
     <br/>
     Therefore, you must specify either an unmanaged bridge interface or an unused physical interface as the parent for the physical network that is used for OVN uplink.
     The instructions assume that you are using a manually created unmanaged bridge.
     See [How to configure network bridges](https://netplan.readthedocs.io/en/stable/examples/#how-to-configure-network-bridges) for instructions on how to set up this bridge.

   Gateway
   : Run `ip -4 route show default` and `ip -6 route show default`.

   Name server
   : Run `resolvectl`.

   IP ranges
   : Use suitable IP ranges based on the assigned IPs.
6. Still on the first machine, configure LXD to be able to communicate with the OVN DB cluster.
   To do so, find the value for `ovn-northd-nb-db` in `/etc/default/ovn-central` and provide it to LXD with the following command:
   ```none
   lxc config set network.ovn.northbound_connection <ovn-northd-nb-db>
   ```

   #### NOTE
   If you are using a MicroOVN deployment, pass the value of the MicroOVN node IP address you want to target. Prefix the IP address with `ssl:`, and suffix it with the `:6641` port number that corresponds to the OVN central service within MicroOVN.
7. Finally, create the actual OVN network (on the first machine):
   ```none
   lxc network create my-ovn --type=ovn
   ```
8. To test the OVN network, create some instances and check the network connectivity:
   ```none
   lxc launch ubuntu:24.04 c1 --network my-ovn
   lxc launch ubuntu:24.04 c2 --network my-ovn
   lxc launch ubuntu:24.04 c3 --network my-ovn
   lxc launch ubuntu:24.04 c4 --network my-ovn
   lxc list
   lxc exec c4 -- bash
   ping <IP of c1>
   ping <nameserver>
   ping6 -n www.example.com
   ```

## Send OVN logs to LXD

Complete the following steps to have the OVN controller send its logs to LXD.

1. Enable the syslog socket:
   ```none
   lxc config set core.syslog_socket=true
   ```
2. Open `/etc/default/ovn-host` for editing.
3. Paste the following configuration:
   ```none
   OVN_CTL_OPTS=" \
          --ovn-controller-log='-vsyslog:info --syslog-method=unix:/var/snap/lxd/common/lxd/syslog.socket'"
   ```
4. Restart the OVN controller:
   ```none
   systemctl restart ovn-controller.service
   ```

You can now use [`lxc monitor`](../reference/manpages/lxc/monitor.md#lxc-monitor-md) to see logs from the OVN controller:

```none
lxc monitor --type=ovn
```

You can also send the logs to Loki.
To do so, add the `ovn` value to the [`loki.types`](../server.md#server-loki:loki.types) configuration key, for example:

```none
lxc config set loki.types=ovn
```


# index.html.md

<a id="howto-replicators-manage"></a>

# How to manage replicators

<a id="howto-replicators-view"></a>

## View replicators

CLI

To list all replicators in the current project, run:

```none
lxc replicator list
```

To view the configuration for a specific replicator, run:

```none
lxc replicator show <replicator_name>
```

To view the current state and job information for a specific replicator, run:

```none
lxc replicator info <replicator_name>
```

API

To list all replicators in the current project, send the following request:

```none
lxc query --request GET /1.0/replicators?project=<project_name>
```

To display detailed information about each replicator, use [Recursion](../rest-api.md#rest-api-recursion):

```none
lxc query --request GET /1.0/replicators?project=<project_name>&recursion=1
```

See [`GET /1.0/replicators`](/api/#/replicators/replicators_get) and [`GET /1.0/replicators?recursion=1`](/api/#/replicators/replicators_get_recursion1) for more information.

To view the configuration of a specific replicator, send the following request:

```none
lxc query --request GET /1.0/replicators/<name>?project=<project_name>
```

See [`GET /1.0/replicators/{name}`](/api/#/replicators/replicator_get) for more information.

To view the current state and job information for a specific replicator, send the following request:

```none
lxc query --request GET /1.0/replicators/<name>/state?project=<project_name>
```

See [`GET /1.0/replicators/{name}/state`](/api/#/replicators/%7Bname%7D/state/replicator_state_get) for more information.

<a id="howto-replicators-modify"></a>

## Configure a replicator

See [Replicator configuration](../reference/replicator_config.md#ref-replicator-config) for all available configuration options.

You can edit the entire configuration at once:

CLI

To edit a replicator in your default text editor, run:

```none
lxc replicator edit <replicator_name>
```

API

To edit a replicator, send the following request:

```none
lxc query --request PUT /1.0/replicators/<name>?project=<project_name> --data "<replicator_configuration>"
```

See [`PUT /1.0/replicators/{name}`](/api/#/replicators/replicator_put) for more information.

You can update a single configuration option for a replicator:

CLI

```none
lxc replicator set <replicator_name> <key>=<value>
```

To unset a configuration key, run:

```none
lxc replicator unset <replicator_name> <key>
```

API

```none
lxc query --request PATCH /1.0/replicators/<name>?project=<project_name> --data '{"config": {"<key>": "<value>"}}'
```

See [`PATCH /1.0/replicators/{name}`](/api/#/replicators/replicator_patch) for more information.

<a id="howto-replicators-rename"></a>

## Rename a replicator

CLI

```none
lxc replicator rename <replicator_name> <new_name>
```

API

```none
lxc query --request POST /1.0/replicators/<name>?project=<project_name> --data '{"name": "<new_name>"}'
```

See [`POST /1.0/replicators/{name}`](/api/#/replicators/replicator_post) for more information.

<a id="howto-replicators-delete"></a>

## Delete a replicator

CLI

```none
lxc replicator delete <replicator_name>
```

API

```none
lxc query --request DELETE /1.0/replicators/<name>?project=<project_name>
```

See [`DELETE /1.0/replicators/{name}`](/api/#/replicators/replicator_delete) for more information.

## Related topics

How-to guides:

* [How to set up replicators](replicators_create.md#howto-replicators-setup)
* [How to perform disaster recovery with replicators](replicators_dr.md#howto-replicators-dr)

Reference:

* [Replicator configuration](../reference/replicator_config.md#ref-replicator-config)


# index.html.md

<a id="instances-console"></a>

# How to access the console

You can access the instance console to log in to the instance and see log messages.
The console is available at boot time already, so you can use it to see boot messages and, if necessary, debug startup issues of a container or VM.

CLI

Use the [`lxc console`](../reference/manpages/lxc/console.md#lxc-console-md) command to attach to instance consoles.
To get an interactive console, enter the following command:

```none
lxc console <instance_name>
```

To show new log messages (only for containers), pass the `--show-log` flag:

```none
lxc console <instance_name> --show-log
```

You can also immediately attach to the console when you start your instance:

```none
lxc start <instance_name> --console
lxc start <instance_name> --console=vga # VM only
```

API

To start an interactive console, send a POST request to the `console` endpoint:

```none
lxc query --request POST /1.0/instances/<instance_name>/console --data '{
  "height": 24,
  "type": "console",
  "width": 80
}'
```

This query sets up two WebSockets that you can use for connection.
One WebSocket is used for control, and the other transmits the actual console data.

See [`POST /1.0/instances/{name}/console`](/api/#/instances/instance_console_post) for more information.

To access the WebSockets, you need the operation ID and the secrets for each socket.
This information is available in the operation started by the query, for example:

```none
{
  "class": "websocket",
  "created_at": "2024-01-31T10:11:48.135150288Z",
  "description": "Showing console",
  "err": "",
  "id": "<operation_ID>",
  "location": "none",
  "may_cancel": false,
  "metadata": {
    "fds": {
      "0": "<data_socket_secret>",
      "control": "<control_socket_secret>"
    }
  }
[...]
}
```

How to connect to the WebSockets depends on the tooling that you use (see [`GET /1.0/operations/{id}/websocket`](/api/#/operations/operation_websocket_get) for general information).
To quickly check whether the connection is successful and you can read from the socket, you can use a tool like [`websocat`](https://github.com/vi/websocat):

```none
websocat --text \
--ws-c-uri=ws://unix.socket/1.0/operations/<operation_ID>/websocket?secret=<data_socket_secret> \
- ws-c:unix:/var/snap/lxd/common/lxd/unix.socket
```

Alternatively, if you just want to retrieve new log messages from the console instead of connecting through a WebSocket, you can send a GET request to the `console` endpoint:

```none
lxc query --request GET /1.0/instances/<instance_name>/console
```

See [`GET /1.0/instances/{name}/console`](/api/#/instances/instance_console_get) for more information.
Note that this operation is supported only for containers, not for VMs.

UI

Navigate to the instance detail page and switch to the Console tab to view the console.

## Access the graphical console (for virtual machines)


            <p class="youtube_link">
              <a href="https://www.youtube.com/watch?v=pEUsTMiq4B4" target="_blank">
                <span title="Arch Linux and Ubuntu Desktop in LXD VMs" class="play_icon">▶</span>
                <span title="Arch Linux and Ubuntu Desktop in LXD VMs">Watch on YouTube</span>
              </a>
            </p>
        
On virtual machines, log on to the console to get graphical output.
Using the console you can, for example, install an operating system using a graphical interface or run a desktop environment.

An additional advantage is that the console is available even if the `lxd-agent` process is not running.
This means that you can access the VM through the console before the `lxd-agent` starts up, and also if the `lxd-agent` is not available at all.

CLI

To start the VGA console with graphical output for your VM, you must install a SPICE client (for example, `virt-viewer` or `spice-client-gtk`).
Then enter the following command:

```none
lxc console <vm_name> --type vga
```

API

To start the VGA console with graphical output for your VM, send a POST request to the `console` endpoint:

```none
lxc query --request POST /1.0/instances/<instance_name>/console --data '{
  "height": 0,
  "type": "vga",
  "width": 0
}'
```

See [`POST /1.0/instances/{name}/console`](/api/#/instances/instance_console_post) for more information.

UI

Navigate to the instance detail page and switch to the Console tab to view the console.

For virtual machines, you can switch between the graphic console and the text console.


# index.html.md

<a id="howto-auth-bearer"></a>

# How to authenticate to the LXD API using bearer tokens

To authenticate to the LXD API using a bearer token, first create an identity of type `bearer`:

CLI

```none
lxc auth identity create bearer/<name> [[--group <group> ]]
```

API

```none
lxc query --request POST /1.0/auth/identities/bearer --data '{
  "name": "<name>",
  "type": "bearer",
  "groups": [
    "<group>"
  ]
}'
```

Next, issue a token for the identity:

CLI

```none
lxc auth identity token issue bearer/<name> [--expiry <expiry> ]
```

API

```none
lxc query --request POST /1.0/auth/identities/bearer/<name>/token --data '{
  "expiry": "<expiry>"
}'
```

The returned token can be used to authenticate with LXD.
It must be set as a bearer token in the `Authorization` header.

You can verify trust by checking the `auth` field in the response metadata of `GET /1.0`:

```default
$ curl -k -H "Authorization: Bearer ${TOKEN}" https://<lxd_address>/1.0
{
  ...
  "metadata": {
    "auth":"trusted"
  }
}
```


# index.html.md

<a id="snap-track-bugfix"></a>

# Track a bugfix in the LXD snap

Given a bug report that has been fixed in LXD, we can determine which snap channels have the fix and which ones don’t.

The strategy used to track the fix will depend on both the snap’s [risk level](../reference/releases-snap.md#ref-snap-risk) (`edge` vs `candidate`/`stable`) and its [release type](../reference/releases-snap.md#ref-releases).

The LXD snap packaging is maintained in a separate git repository ([canonical/lxd-pkg-snap](https://github.com/canonical/lxd-pkg-snap)) from LXD itself ([canonical/lxd](https://github.com/canonical/lxd)); tracking fixes for `candidate` and `stable` risk levels requires information from both repositories.

As an example, consider the issue [canonical/lxd#18023](https://github.com/canonical/lxd/issues/18023); this bug was [introduced in LXD 3.0](https://github.com/canonical/lxd/commit/d840004886b702b3bea15d4a1d6e4f32717a6b62). The linked pull request points to commit [`c1e8ab4`](https://github.com/canonical/lxd/commit/c1e8ab4c33c217a200e59f27916fd8e1d49241e2) as the fix.

Use `snap info` to show the currently available versions of LXD:

`ubuntu@ubuntu:~$ ``snap info lxd
`
```text
channels:
  5.21/stable:      5.21.4-aee7e08 2026-04-09 (38767)  123MB -
  5.21/candidate:   5.21.4-4189d16 2026-05-05 (39296)  123MB -
  5.21/beta:        ↑
  5.21/edge:        git-658877c    2026-05-07 (39329)  120MB -
  latest/stable:    6.7-d814d89    2026-04-03 (38768)  121MB -
  latest/candidate: 6.8-5a1a287    2026-05-06 (39313)  121MB -
  latest/beta:      ↑
  latest/edge:      git-3c2c6c6    2026-05-08 (39363)  119MB -
  6/stable:         6.7-d814d89    2026-04-03 (38768)  121MB -
  6/candidate:      6.8-5a1a287    2026-05-06 (39313)  121MB -
  6/beta:           ↑
  6/edge:           git-3c2c6c6    2026-05-08 (39363)  119MB -
```

#### NOTE
The `latest/*` and `6/*` channels are equivalent in the above snap output; they point to the same snap revision. The strategies shown below for `latest/*` can be used unmodified for the current [feature release](../reference/releases-snap.md#ref-releases-feature) channels (`6/*` in this case).

## Feature releases

### `latest/edge` channel

The snap version numbers for all `edge` [risk levels](../reference/releases-snap.md#ref-snap-risk) include the commit hash from [canonical/lxd](https://github.com/canonical/lxd) that was used to build that snap revision. To check if `latest/edge` contains the bug fix, clone [canonical/lxd](https://github.com/canonical/lxd) and check if the fix commit (`c1e8ab4`) is an ancestor of the commit used to build the snap (`3c2c6c6`):

`ubuntu@ubuntu:~$ ``git merge-base --is-ancestor c1e8ab4 3c2c6c6 && echo "c1e8ab4 reachable from 3c2c6c6"
`
```text
c1e8ab4 reachable from 3c2c6c6
```

This means that the fix is present in the `latest/edge` channel.

<a id="ref-troubleshoot-snap-track-stable"></a>

### `latest/candidate` and `latest/stable` channels

The commit hash shown for all `candidate` and `stable` risk levels comes from [canonical/lxd-pkg-snap](https://github.com/canonical/lxd-pkg-snap), so they can’t be compared with the original fix commit.

Clone [canonical/lxd-pkg-snap](https://github.com/canonical/lxd-pkg-snap) and switch to the commit in the `latest/candidate` version string (`6.8-5a1a287`):

`ubuntu@ubuntu:~$ ``git switch --detach 5a1a287
`

The `source-commit` field of the `lxd` [part](https://documentation.ubuntu.com/snapcraft/stable/explanation/parts/) in `snapcraft.yaml` gives the commit in [canonical/lxd](https://github.com/canonical/lxd) that corresponds to the snap revision (you may need to `sudo apt install yq`):

`ubuntu@ubuntu:~$ ``yq '.parts["lxd"]["source-commit"]' snapcraft.yaml
`
```text
"84705553d17aeb8e15032611c321127a06c2f2ff"
```

Then in [canonical/lxd](https://github.com/canonical/lxd), use `git merge-base` to check if the fix is reachable:

`ubuntu@ubuntu:~$ ``git merge-base --is-ancestor c1e8ab4 8470555 && echo "c1e8ab4 reachable from 8470555"
`
```text
c1e8ab4 reachable from 8470555
```

This means that the fix is present in the `latest/candidate` channel. To check if the fix is present in `latest/stable`, follow the same procedure as above using the corresponding version string (`6.7-d814d89`).

#### IMPORTANT
Critical fixes may be cherry-picked at build time by `git` commands executed during the snap build process. Use `yq '.parts["lxd"]["override-build"]' snapcraft.yaml` in [canonical/lxd-pkg-snap](https://github.com/canonical/lxd-pkg-snap) to check if the fix was cherry-picked.

## LTS releases

Bugfixes are frequently backported to [LTS releases](../reference/releases-snap.md#ref-releases-snap); backports do not use the same commit hash and may not even have exactly the same code. Use `git log` to determine if the fix is present in the `5.21/edge` channel by checking the `stable-5.21` branch in [canonical/lxd](https://github.com/canonical/lxd) for commits containing the issue number (`#18023`) or the original commit hash (`c1e8ab4`):

`ubuntu@ubuntu:~$ ``git log --grep="#18023" origin/stable-5.21
`
```text
commit cce42965ad1e3b6a20995dc2c7a6a73ac2246944
Author: Thomas Parrott <thomas.parrott@canonical.com>
Date:   Wed Apr 15 16:04:40 2026 +0100

    lxd/networks: Only take networkCreateLock for external API requests

    This avoids deadlocks with the operation notification when multiple concurrent network creation requests arrive at different cluster members.

    Fixes #18023

    Signed-off-by: Thomas Parrott <thomas.parrott@canonical.com>
```

[`c1e8ab4`](https://github.com/canonical/lxd/commit/c1e8ab4c33c217a200e59f27916fd8e1d49241e2) was backported as [`cce4296`](https://github.com/canonical/lxd/commit/cce42965ad1e3b6a20995dc2c7a6a73ac2246944).

Follow the same strategy used for `stable` and `candidate` [feature releases](#ref-troubleshoot-snap-track-stable) to determine if [`cce4296`](https://github.com/canonical/lxd/commit/cce42965ad1e3b6a20995dc2c7a6a73ac2246944) is available in the `5.21/candidate` and `5.21/stable` channels.


# index.html.md

<a id="howto-storage-buckets"></a>

# How to manage storage buckets

[Storage buckets](../explanation/storage.md#storage-buckets) store object-based data using non-local `cephobject` storage pools. When used in LXD or MicroCloud clusters, they are available from any cluster member.

Unlike custom storage volumes, storage buckets cannot be attached to instances. Instead, applications access them directly via a URL using the S3 protocol. A [Ceph RADOS Gateway endpoint](storage_pools.md#howto-storage-pools-ceph-requirements-radosgw-endpoint) provides the S3-compatible URL.

<a id="howto-storage-buckets-view"></a>

## View storage buckets

CLI

To list all available storage buckets in a storage pool, run:

```bash
lxc storage bucket list <pool-name>
```

To show detailed information about a specific bucket, run:

```bash
lxc storage bucket show <pool-name> <bucket-name>
```

UI

Select Buckets from the Storage section of the main navigation.

<a id="howto-storage-buckets-requirements"></a>

## Requirements

To use storage buckets, your LXD server must have access to a storage pool that uses the [Ceph Object](../reference/storage_cephobject.md#storage-cephobject) driver. You can confirm this by [viewing your available storage pools](storage_pools.md#howto-storage-pools-view).

If no listed pool uses the `cephobject` storage driver, you must create one. This requires a [Ceph](https://ceph.io) cluster with a RADOS Gateway (`radosgw`) enabled. Refer to our how-to guide for storage pools: [Requirements for Ceph-based storage pools](storage_pools.md#howto-storage-pools-ceph-requirements).

<a id="howto-storage-buckets-create"></a>

## Create a storage bucket

CLI

To create a storage bucket, run:

```bash
lxc storage bucket create <pool-name> <bucket-name> [configuration_options...]
```

Refer to the [Ceph Object](../reference/storage_cephobject.md#storage-cephobject) documentation for a list of available storage bucket configuration options for the driver.

UI

To create a storage bucket, select Buckets from the Storage section of the main navigation.

On the resulting screen, click Create bucket in the upper-right corner.

In the form that appears, set a unique name for the storage bucket and select a storage pool. You can optionally configure the bucket’s size and description.

<a id="howto-storage-buckets-configure"></a>

## Configure storage bucket settings

CLI

Use the following command to set configuration options for a storage bucket:

```bash
lxc storage bucket set <pool-name> <bucket-name> <key> <value>
```

For example, to set the size (quota) of a bucket, use the following command:

```bash
lxc storage bucket set my-pool my-bucket size 1MiB
```

You can also edit the storage bucket configuration by using the following command:

```bash
lxc storage bucket edit <pool-name> <bucket-name>
```

Use the following command to delete a storage bucket and its keys:

```bash
lxc storage bucket delete <pool-name> <bucket-name>
```

Refer to the [Ceph Object](../reference/storage_cephobject.md#storage-cephobject) documentation for a list of available storage bucket configuration options for the driver.

UI

To configure a storage bucket, select Buckets from the Storage section of the main navigation.

The resulting screen shows a list of existing storage buckets. Click the Edit button on the row of the desired bucket to access its details.

After making changes, click the Save changes button. This button also displays the number of changes you have made.

<a id="howto-storage-buckets-resize"></a>

## Resize a storage bucket

By default, storage buckets do not have a quota applied.

CLI

To set or change a quota for a storage bucket, set its size configuration:

```bash
lxc storage bucket set <pool-name> <bucket-name> size <new-size>
```

UI

To configure a storage bucket, select Buckets from the Storage section of the main navigation.

The resulting screen shows a list of existing storage buckets. Change the quota of the bucket by changing the values in the Size fields.

After making changes, click the Save changes button. This button also displays the number of changes you have made.

<a id="howto-storage-buckets-keys"></a>

## Manage storage bucket keys

To access a storage bucket, applications must use a set of S3 credentials made up of an *access key* and a *secret key*. You can create multiple sets of credentials for a specific bucket.

Each set of credentials is given a key name. The key name is used only for reference and does not need to be provided to the application that uses the credentials.

Each set of credentials has a *role* that specifies what operations they can perform on the bucket. The available roles are:

`admin`
: Provides full access to the bucket.

`read-only`
: Default. Provides read-only (view) access to the bucket.

<a id="howto-storage-buckets-keys-view"></a>

### View storage bucket keys

CLI

Use the following command to list the keys defined for an existing bucket:

```default
lxc storage bucket key list <pool-name> <bucket-name>
```

Use the following command to show a specific bucket key:

```default
lxc storage bucket key show <pool-name> <bucket-name> <key-name>
```

UI

To view storage bucket keys, select Buckets from the Storage section of the main navigation.

Click the name of a storage bucket to display its key management page, where you can view and manage a list of keys for that bucket.

<a id="howto-storage-buckets-keys-create"></a>

### Create keys

CLI

Use the following command to generate and display a set of keys for a storage bucket. The default role is `read-only`. To create credentials with the `admin` role, include the `--role=admin` flag:

```bash
lxc storage bucket key create <pool-name> <bucket-name> <key-name> [--role=admin] [configuration_options...]
```

Refer to [`lxc storage bucket key create`](../reference/manpages/lxc/storage/bucket/key/create.md#lxc-storage-bucket-key-create-md) for configuration options.

UI

To create a storage bucket key, go to the [key management page](#howto-storage-buckets-keys-view) of the desired bucket.

On the resulting screen, click Create key in the upper-right corner. In the form that appears, set a unique name for the key. You can optionally configure its role and description.

While you can enter values for the Access and Secret Key fields, this is not necessary. You can leave them blank, and LXD will generate random values for those credential keys.

<a id="howto-storage-buckets-keys-edit"></a>

### Edit or delete storage bucket keys

CLI

To edit an existing bucket key, run:

```bash
lxc storage bucket key edit <pool-name> <bucket-name> <key-name>
```

To delete an existing bucket key, run:

```bash
lxc storage bucket key delete <pool-name> <bucket-name> <key-name>
```

UI

You can edit or delete storage bucket keys from the [key management page](#howto-storage-buckets-keys-view) of the desired bucket.

## Related topics

How-to guides:

- [Requirements for Ceph-based storage pools](storage_pools.md#howto-storage-pools-ceph-requirements)

Explanation:

- [Storage buckets](../explanation/storage.md#storage-buckets)

Reference:

- [Ceph Object - cephobject](../reference/storage_cephobject.md#storage-cephobject)
- [Object storage backend](../reference/storage_drivers.md#storage-drivers-object)


# index.html.md

<a id="access-documentation"></a>

# How to access the local LXD documentation

The latest version of the LXD documentation is available at [`documentation.ubuntu.com/lxd`](https://documentation.ubuntu.com/lxd/).

Alternatively, you can access a local version of the LXD documentation that is embedded in the LXD snap.
This version of the documentation exactly matches the version of your LXD deployment, but might be missing additions, fixes, or clarifications that were added after the release of the snap.

Complete the following steps to access the local LXD documentation:

1. Make sure that your LXD server is [exposed to the network](server_expose.md#server-expose).
   You can expose the server during [initialization](initialize.md#initialize), or afterwards by setting the [`core.https_address`](../server.md#server-core:core.https_address) server configuration option.
2. Access the documentation in your browser by entering the server address followed by `/documentation/` (for example, `https://192.0.2.10:8443/documentation/`).

   If you have not set up a secure [TLS server certificate](../authentication.md#authentication-server-certificate), LXD uses a self-signed certificate, which will cause a security warning in your browser.
   Use your browser’s mechanism to continue despite the security warning.


# index.html.md

<a id="instances-backup"></a>

# How to back up instances

There are different ways of backing up your instances:

- [Use snapshots for instance backup](#instances-snapshots)
- [Use export files for instance backup](#instances-backup-export)
- [Copy an instance to a backup server](#instances-backup-copy)

<!-- Include content from [storage_backup_volume.md](storage_backup_volume.md) -->

Which method to choose depends both on your use case and on the storage driver you use.

In general, snapshots are quick and space efficient (depending on the storage driver), but they are stored in the same storage pool as the instance and therefore not too reliable.
Export files can be stored on different disks and are therefore more reliable.
They can also be used to restore the instance into a different storage pool.
If you have a separate, network-connected LXD server available, regularly copying instances to this other server gives high reliability as well, and this method can also be used to back up snapshots of the instance.

#### NOTE
Custom storage volumes might be attached to an instance, but they are not part of the instance.
Therefore, the content of a custom storage volume is not stored when you back up your instance.
You must back up the data of your storage volume separately.
See [How to back up custom storage volumes](storage_backup_volume.md#howto-storage-backup-volume) for instructions.

<a id="instances-snapshots"></a>

## Use snapshots for instance backup

You can save your instance at a point in time by creating an instance snapshot, which makes it easy to restore the instance to a previous state.

Instance snapshots are stored in the same storage pool as the instance volume itself.

<!-- Include content from [storage_backup_volume.md](storage_backup_volume.md) -->

Most storage drivers support optimized snapshot creation (see [Feature comparison](../reference/storage_drivers.md#storage-drivers-features)).
For these drivers, creating snapshots is both quick and space-efficient.
For the `dir` driver, snapshot functionality is available but not very efficient.
For the `lvm` driver, snapshot creation is quick, but restoring snapshots is efficient only when using thin-pool mode.

### Create a snapshot

CLI

Use the following command to create a snapshot of an instance:

```none
lxc snapshot <instance_name> [<snapshot name>]
```

<!-- Include content from [storage_backup_volume.md](storage_backup_volume.md) -->

The snapshot name is optional.
If you don’t specify one, the name follows the naming pattern defined in `snapshots.pattern`.

Add the `--reuse` flag in combination with a snapshot name to replace an existing snapshot.

By default, snapshots are kept forever, unless the `snapshots.expiry` configuration option is set.
To retain a specific snapshot even if a general expiry time is set, use the `--no-expiry` flag.

For virtual machines, you can add the `--stateful` flag to capture not only the data included in the instance volume but also the running state of the instance.
Stateful snapshots are not supported for containers.

By default, instance snapshots include a snapshot of the instance’s root disk volume only. To include snapshots of attached storage volumes, set the `--disk-volumes` flag to “all-exclusive”.

API

To create a snapshot of an instance, send a POST request to the `snapshots` endpoint:

```none
lxc query --request POST /1.0/instances/<instance_name>/snapshots --data '{"name": "<snapshot_name>"}'
```

The snapshot name is optional.
If you set it to an empty string, the name follows the naming pattern defined in [`snapshots.pattern`](../reference/instance_options.md#instance-snapshots:snapshots.pattern).

By default, snapshots are kept forever, unless the [`snapshots.expiry`](../reference/instance_options.md#instance-snapshots:snapshots.expiry) configuration option is set.
To set an expiration date, add the`expires_at` field to the request data.
To retain a specific snapshot even if a general expiry time is set, set the `expires_at` field to `"0001-01-01T00:00:00Z"`.

If you want to replace an existing snapshot, [delete it](#instances-snapshots-delete) first and then create another snapshot with the same name.

For virtual machines, you can add `"stateful": true` to the request data to capture not only the data included in the instance volume but also the running state of the instance.
Stateful snapshots are not supported for containers.

By default, instance snapshots include a snapshot of the instance’s root disk volume only. To include snapshots of attached storage volumes, set the `disk_volumes_mode` flag to “all-exclusive” in the request data.

See [`POST /1.0/instances/{name}/snapshots`](/api/#/instances/instance_snapshots_post) for more information.

UI

To create a snapshot of an instance, go to the instance detail page and switch to the Snapshots tab.
Click Create snapshot to open the dialog to create a snapshot.

The snapshot name is optional.
If you don’t specify one, the name follows the naming pattern defined in [`snapshots.pattern`](../reference/instance_options.md#instance-snapshots:snapshots.pattern).
You can check and update this option by switching to the Configuration tab and selecting Advanced > Snapshots, or simply by clicking See configuration.

By default, snapshots are kept forever, unless you specify an expiry date and time, or the [`snapshots.expiry`](../reference/instance_options.md#instance-snapshots:snapshots.expiry) configuration option is set for the instance.

For virtual machines, you can choose to create a stateful snapshot to capture not only the data included in the instance volume but also the running state of the instance.
Note that this feature requires [`migration.stateful`](../reference/instance_options.md#instance-migration:migration.stateful) to be enabled.

<a id="instances-snapshots-delete"></a>

### View, edit or delete snapshots

CLI

Use the following command to display the snapshots for an instance:

```none
lxc info <instance_name>
```

You can view or modify snapshots in a similar way to instances, by referring to the snapshot with `<instance_name>/<snapshot_name>`.

To show configuration information about a snapshot, use the following command:

```none
lxc config show <instance_name>/<snapshot_name>
```

To change the expiry date of a snapshot, use the following command:

```none
lxc config edit <instance_name>/<snapshot_name>
```

#### NOTE
In general, snapshots cannot be edited, because they preserve the state of the instance.
The only exception is the expiry date.
Other changes to the configuration are silently ignored.

To delete a snapshot, use the following command:

```none
lxc delete <instance_name>/<snapshot_name>
```

By default, only the instance’s root disk volume snapshot is deleted. To also delete snapshots of attached storage volumes, set the `--disk-volumes` flag to “all-exclusive”.

API

To retrieve the snapshots for an instance, send a GET request to the `snapshots` endpoint:

```none
lxc query --request GET /1.0/instances/<instance_name>/snapshots
```

To show configuration information about a snapshot, send the following request:

```none
lxc query --request GET /1.0/instances/<instance_name>/snapshots/<snapshot_name>
```

To change the expiry date of a snapshot, send a PATCH request:

```none
lxc query --request PATCH /1.0/instances/<instance_name>/snapshots/<snapshot_name> --data '{
  "expires_at": "2029-03-23T17:38:37.753398689-04:00"
}'
```

#### NOTE
In general, snapshots cannot be modified, because they preserve the state of the instance.
The only exception is the expiry date.
Other changes to the configuration are silently ignored.

To delete a snapshot, send a DELETE request:

```none
lxc query --request DELETE /1.0/instances/<instance_name>/snapshots/<snapshot_name>
```

By default, only the instance’s root disk volume snapshot is deleted. To also delete snapshots of attached storage volumes, set the `disk-volumes` query parameter to “all-exclusive” in the request.

See [`GET /1.0/instances/{name}/snapshots`](/api/#/instances/instance_snapshots_get), [`GET /1.0/instances/{name}/snapshots/{snapshot}`](/api/#/instances/instance_snapshot_get), [`PATCH /1.0/instances/{name}/snapshots/{snapshot}`](/api/#/instances/instance_snapshot_patch), and [`DELETE /1.0/instances/{name}/snapshots/{snapshot}`](/api/#/instances/instance_snapshot_delete) for more information.

UI

To see all snapshots for an instance, go to the instance detail page and switch to the Snapshots tab.

From the snapshot list, you can choose to edit the name or expiry date of a specific snapshot, create an image based on the snapshot, restore it to the instance, or delete it.

### Schedule instance snapshots

You can configure an instance to automatically create snapshots at specific times (at most once every minute).
To do so, set the [`snapshots.schedule`](../reference/instance_options.md#instance-snapshots:snapshots.schedule) instance option.

For example, to configure daily snapshots:

CLI

```none
lxc config set <instance_name> snapshots.schedule @daily
```

API

```none
lxc query --request PATCH /1.0/instances/<instance_name> --data '{
  "config": {
    "snapshots.schedule": "@daily"
  }
}'
```

UI

![Configure daily snapshots](images/UI/snapshots_daily.png)

To configure taking a snapshot every day at 6 am:

CLI

```none
lxc config set <instance_name> snapshots.schedule "0 6 * * *"
```

API

```none
lxc query --request PATCH /1.0/instances/<instance_name> --data '{
  "config": {
    "snapshots.schedule": "0 6 * * *"
  }
}'
```

UI

![Configure snapshots daily at 6am](images/UI/snapshots_cron.png)

When scheduling regular snapshots, consider setting an automatic expiry ([`snapshots.expiry`](../reference/instance_options.md#instance-snapshots:snapshots.expiry)) and a naming pattern for snapshots ([`snapshots.pattern`](../reference/instance_options.md#instance-snapshots:snapshots.pattern)).
You should also configure whether you want to take snapshots of instances that are not running ([`snapshots.schedule.stopped`](../reference/instance_options.md#instance-snapshots:snapshots.schedule.stopped)).

### Restore an instance snapshot

You can restore an instance to any of its snapshots.

CLI

To restore an instance to a snapshot, use the following command:

```none
lxc restore <instance_name> <snapshot_name>
```

If the snapshot is stateful (which means that it contains information about the running state of the instance), you can add the `--stateful` flag to restore the state.

By default, instance snapshot restores include a snapshot of the instance’s root disk volume only. To also restore snapshots of attached storage volumes, set the `--disk-volumes` flag to “all-exclusive”.

API

To restore an instance to a snapshot, send a PUT request to the instance:

```none
lxc query --request PUT /1.0/instances/<instance_name> --data '{
  "restore": "<instance_name>/<snapshot_name>"
}'
```

If the snapshot is stateful (which means that it contains information about the running state of the instance), you can add `"stateful": true` to the request data:

```none
lxc query --request PUT /1.0/instances/<instance_name> --data '{
  "restore": "<instance_name>/<snapshot_name>",
  "stateful": true
}'
```

By default, instance snapshot restores include a snapshot of the instance’s root disk volume only. To also restore snapshots of attached storage volumes, set the `restore_disk_volumes_mode` flag to “all-exclusive” in the request data.

See [`PUT /1.0/instances/{name}`](/api/#/instances/instance_put) for more information.

UI

To restore an instance to a snapshot, click the Restore snapshot button (<svg width='16' height='16' xmlns='http://www.w3.org/2000/svg'><path d='M5.948 9.012v1.5l-2.458.001A5.163 5.163 0 0012.76 10h1.596a6.665 6.665 0 01-11.839 1.785v2.158h-1.5v-4.93h4.93zM8 1.338a6.655 6.655 0 015.516 2.925V2.11h1.5v4.93h-4.93v-1.5h2.453A5.163 5.163 0 003.24 6H1.643A6.665 6.665 0 018 1.338z' fill='%23000'  fill-rule='evenodd'/></svg>) next to the snapshot that you want to restore.

If the snapshot is stateful (which means that it contains information about the running state of the instance), select Restore the instance state if you want to restore the state.

<a id="instances-backup-export"></a>

## Use export files for instance backup

You can export the full content of your instance to a standalone file that can be stored at any location.
For highest reliability, store the backup file on a different file system to ensure that it does not get lost or corrupted.

<a id="instances-backup-export-instance"></a>

### Export an instance

CLI

Use the following command to export an instance to a compressed file (for example, `/path/to/my-instance.tgz`):

```none
lxc export <instance_name> [<file_path>]
```

If you do not specify a file path, the export file is saved as `<instance_name>.<extension>` in the working directory (for example, `my-container.tar.gz`).

#### WARNING
If the output file (`<instance_name>.<extension>` or the specified file path) already exists, the command overwrites the existing file without warning.

<!-- Include content from [storage_backup_volume.md](storage_backup_volume.md) -->

You can add any of the following flags to the command:

`--compression`
: By default, the output file uses `gzip` compression.
  You can specify a different compression algorithm (for example, `bzip2`) or turn off compression with `--compression=none`.

`--optimized-storage`
: If your storage pool uses the `btrfs` or the `zfs` driver, add the `--optimized-storage` flag to store the data as a driver-specific binary blob instead of an archive of individual files.
  In this case, the export file can only be used with pools that use the same storage driver.
  <br/>
  Exporting a volume in optimized mode is usually quicker than exporting the individual files.
  Snapshots are exported as differences from the main volume, which decreases their size (quota) and makes them easily accessible.

`--export-version`
: If you intend to import the backup to an older version of LXD, set the version to `1` which will use the original (old) backup metadata format.
  Backups using the old format can always be imported on newer versions of LXD.
  If the flag is not specified and the server has support for the `backup_metadata_version` API extension, version `2` is used by default.

`--instance-only`
: By default, the export file contains all snapshots of the instance.
  Add this flag to export the instance without its snapshots.

API

To create a backup of an instance, send a POST request to the `backups` endpoint:

```none
lxc query --request POST /1.0/instances/<instance_name>/backups --data '{"name": ""}'
```

You can specify a name for the backup, or use the default (`backup0`, `backup1` and so on).

You can add any of the following fields to the request data:

`"compression_algorithm": "bzip2"`
: By default, the output file uses `gzip` compression.
  You can specify a different compression algorithm (for example, `bzip2`) or turn off compression with `none`.

`"optimized-storage": true`
: If your storage pool uses the `btrfs` or the `zfs` driver, set the `"optimized-storage"` field to `true` to store the data as a driver-specific binary blob instead of an archive of individual files.
  In this case, the backup can only be used with pools that use the same storage driver.
  <br/>
  Exporting a volume in optimized mode is usually quicker than exporting the individual files.
  Snapshots are exported as differences from the main volume, which decreases their size (quota) and makes them easily accessible.

`"instance-only": true`
: By default, the backup contains all snapshots of the instance.
  Set this field to `true` to back up the instance without its snapshots.

After creating the backup, you can download it with the following request:

```none
lxc query --request GET /1.0/instances/<instance_name>/backups/<backup_name>/export > <file_name>
```

Remember to delete the backup when you don’t need it anymore:

```none
lxc query --request DELETE /1.0/instances/<instance_name>/backups/<backup_name>
```

See [`POST /1.0/instances/{name}/backups`](/api/#/instances/instance_backups_post), [`GET /1.0/instances/{name}/backups/{backup}/export`](/api/#/instances/instance_backup_export), and [`DELETE /1.0/instances/{name}/backups/{backup}`](/api/#/instances/instance_backup_delete) for more information.

UI

From the instance detail page, click Export.

Modify the default settings if necessary, then export the instance.

Download will start automatically once the export is ready.

<a id="instances-backup-import-instance"></a>

### Restore an instance from an export file

You can import an export file (for example, `/path/to/my-backup.tgz`) as a new instance.

CLI

To import an export file, use the following command:

```none
lxc import <file_path> [<instance_name>]
```

If you do not specify an instance name, the original name of the exported instance is used for the new instance.
If an instance with that name already (or still) exists in the specified storage pool, the command returns an error.
In that case, either delete the existing instance before importing the backup or specify a different instance name for the import.

Add the `--storage` flag to specify which storage pool to use, or the `--device` flag to override the device configuration (syntax: `--device <device_name>,<device_option>=<value>`).

API

To import an export file, post it to the `/1.0/instances` endpoint:

```none
curl -X POST -H "Content-Type: application/octet-stream" --data-binary @<file_path> \
--unix-socket /var/snap/lxd/common/lxd/unix.socket lxd/1.0/instances
```

If an instance with that name already (or still) exists in the specified storage pool, the command returns an error.
In this case, delete the existing instance before importing the backup.

See [`POST /1.0/instances`](/api/#/instances/instances_post) for more information.

UI

To import an export file, go to the instance list and click Create instance.

From the resulting modal, upload the instance file.
The instance name and description fields are optional. If you don’t specify the instance name, the name of the export file is used, appended with `-tar-import`.

Click Choose file.
Select the export file, then click Upload and create.

The newly created instance will appear in the instance list.

<a id="instances-backup-copy"></a>

## Copy an instance to a backup server

You can copy an instance to a secondary backup server to back it up.

See [Secondary backup LXD server](../backup.md#secondary-backup-server) for more information, and [How to migrate LXD instances between servers](instances_migrate.md#howto-instances-migrate) for instructions.


# index.html.md

<a id="benchmark-performance"></a>

# How to benchmark performance


            <p class="youtube_link">
              <a href="https://www.youtube.com/watch?v=z_OKwO5TskA" target="_blank">
                <span title="Benchmarking LXD storage drivers" class="play_icon">▶</span>
                <span title="Benchmarking LXD storage drivers">Watch on YouTube</span>
              </a>
            </p>
        
The performance of your LXD server or cluster depends on a lot of different factors, ranging from the hardware, the server configuration, the selected storage driver and the network bandwidth to the overall usage patterns.

To find the optimal configuration, you should run benchmark tests to evaluate different setups.

LXD provides a benchmarking tool for this purpose.
This tool allows you to initialize or launch a number of containers and measure the time it takes for the system to create the containers.
If you run this tool repeatedly with different configurations, you can compare the performance and evaluate which is the ideal configuration.

## Get the tool

To get the `lxd-benchmark` tool, you can download a pre-built binary:

1. Download the `bin.linux.lxd-benchmark` tool ([`bin.linux.lxd-benchmark.aarch64`](https://github.com/canonical/lxd/releases/latest/download/bin.linux.lxd-benchmark.aarch64) or [`bin.linux.lxd-benchmark.x86_64`](https://github.com/canonical/lxd/releases/latest/download/bin.linux.lxd-benchmark.x86_64)) from the **Assets** section of the latest [LXD release](https://github.com/canonical/lxd/releases).
2. Save the binary as `lxd-benchmark` and make it executable (usually by running `chmod u+x lxd-benchmark`).

If you have `go` ([Go](../requirements.md#requirements-go)) installed, you can build the tool with the following command:

```none
go install github.com/canonical/lxd/lxd-benchmark@latest
```

## Run the tool

Run `lxd-benchmark [action]` to measure the performance of your LXD setup.

The benchmarking tool uses the current LXD configuration, but users of the snap must export the `LXD_DIR` variable for the configuration to be found:

```none
  export LXD_DIR=/var/snap/lxd/common/lxd
```

If you want to use a different project, specify it with `--project`.

For all actions, you can specify the number of parallel threads to use (default is to use a dynamic batch size).
You can also choose to append the results to a CSV report file and label them in a certain way.

See `lxd-benchmark help` for all available actions and flags.

### Select an image

Before you run the benchmark, select what kind of image you want to use.

Local image
: If you want to measure the time it takes to create a container and ignore the time it takes to download the image, you should copy the image to your local image store before you run the benchmarking tool.
  <br/>
  To do so, run a command similar to the following and specify the fingerprint (for example, `2d21da400963`) of the image when you run `lxd-benchmark`:
  <br/>
  ```none
  lxc image copy ubuntu:24.04 local:
  ```
  <br/>
  You can also assign an alias to the image and specify that alias (for example, `ubuntu`) when you run `lxd-benchmark`:
  <br/>
  ```none
  lxc image copy ubuntu:24.04 local: --alias ubuntu
  ```

Remote image
: If you want to include the download time in the overall result, specify a remote image (for example, `ubuntu:24.04`).
  The default image that `lxd-benchmark` uses is the latest Ubuntu image (`ubuntu:`), so if you want to use this image, you can leave out the image name when running the tool.

### Create and launch containers

Run the following command to create a number of containers:

```none
lxd-benchmark init --count <number> <image>
```

Add `--privileged` to the command to create privileged containers.

For example:

| Command                                                           | Description                                                                                    |
|-------------------------------------------------------------------|------------------------------------------------------------------------------------------------|
| `lxd-benchmark init --count 10 --privileged`                      | Create ten privileged containers that use the latest Ubuntu image.                             |
| `lxd-benchmark init --count 20 --parallel 4 ubuntu-minimal:24.04` | Create 20 containers that use the Ubuntu Minimal 24.04 LTS image, using four parallel threads. |
| `lxd-benchmark init 2d21da400963`                                 | Create one container that uses the local image with the fingerprint `2d21da400963`.            |
| `lxd-benchmark init --count 10 ubuntu`                            | Create ten containers that use the image with the alias `ubuntu`.                              |

If you use the `init` action, the benchmarking containers are created but not started.
To start the containers that you created, run the following command:

```none
lxd-benchmark start
```

Alternatively, use the `launch` action to both create and start the containers:

```none
lxd-benchmark launch --count 10 <image>
```

For this action, you can add the `--freeze` flag to freeze each container right after it starts.
Freezing a container pauses its processes, so this flag allows you to measure the pure launch times without interference of the processes that run in each container after startup.

### Delete containers

To delete the benchmarking containers that you created, run the following command:

```none
lxd-benchmark delete
```

#### NOTE
You must delete all existing benchmarking containers before you can run a new benchmark.


# index.html.md

<a id="first-steps"></a>

<a id="tutorial-first-steps"></a>

# First steps with LXD

This tutorial guides you through your first steps with LXD. You’ll begin by installing and initializing LXD. Then you’ll use its CLI or graphical web UI to work with instances, including both containers and virtual machines. You’ll learn how to create and configure instances, create snapshots, and more.

<a id="tutorial-requirements"></a>

## Requirements

- At least 20 GiB free disk space
- A Linux distribution installed

<a id="tutorial-install"></a>

## Install LXD using snap

This section of the tutorial assumes that you have the `snap` packaging system available on your system, which is the recommended way to install and update LXD.

To install LXD using `snap`, run:

```bash
sudo snap install lxd
```

### If the LXD snap is already installed

This tutorial is designed for LXD version 5.21 and higher. If you see an error message that the LXD snap is already installed, run the following command to find the channel the snap is tracking:

```bash
snap list lxd
```

The `Tracking` column lists the installed [snap channel](../reference/releases-snap.md#ref-snap-channels). If the number shown is 5.21 or higher, run the following command to update the snap to the most recent release in its channel:

```bash
sudo snap refresh lxd
```

Otherwise, if the number shown is lower, an older version is installed. In this case, upgrade to the 5.21/stable channel by following the instructions in this guide: [Change the snap channel](../howto/snap.md#howto-snap-change).

<a id="tutorial-adduser"></a>

## Add the current user to the `lxd` group

Installing LXD through its snap should automatically create a `lxd` group on your system. The user you are logged in as must be in this group to interact with LXD.

Enter the following commands. The first command adds your user to the `lxd` group.
The second command starts a new shell where the group membership takes effect immediately.

```bash
sudo usermod -aG lxd "$USER"
newgrp lxd
```

<a id="tutorial-initialize"></a>

## Initialize LXD

Next, initialize LXD using a minimal setup with default options.

Run:

```bash
lxd init --minimal
```

If this command results in an error message, your group membership might not have taken effect. In this case, close and re-open your terminal, then try again.

If you do not see any message when running this command, that means it has succeeded. Congratulations! You have successfully installed and initialized LXD. Continue on to learn how to use some of LXD’s core features.

<a id="tutorial-enable-ui"></a>

## Enable the LXD UI

While the installation and initialization steps must be performed via the command line interface, a graphical interface (the LXD UI) is available for use after these setup steps. The LXD UI is accessed through your web browser.

If you prefer to use the LXD UI, expand and follow the steps below.

### View steps to enable the LXD UI

### Expose the LXD server to the local network

By default, LXD is exposed through a Unix socket only and is not accessible over HTTPS. To access and manage LXD through a web browser using HTTPS, we must set the [`core.https_address`](../server.md#server-core:core.https_address) server configuration option. We will use the local network by configuring this to the IPv4 loopback address `127.0.0.1` and port 8443. Run:

```bash
lxc config set core.https_address 127.0.0.1:8443
```

Confirm that the `core.https_address` option has been set:

`user@host:~$ ``lxc config get core.https_address
`
```text
127.0.0.1:8443
```

### Set up UI access

Go to this URL in your browser: [`https://localhost:8443`](https://localhost:8443)

If you have not set up a secure [TLS server certificate](../authentication.md#authentication-server-certificate), LXD uses a self-signed certificate, which will cause a security warning in your browser. Use your browser’s mechanism to continue this time despite the security warning.

For example, in Chrome, click **Advanced**, then follow the link to **Proceed** at the bottom as shown below:

![Example for a security warning in Chrome](images/ui_security_warning.png)

In Firefox, click **Advanced**, then follow the link to **Accept the risk and continue**.

### Set up the browser certificate

Follow the instructions in the LXD UI browser page to install and select the browser certificate, also called a client certificate.

If you have previously installed a certificate for the LXD UI, your browser will offer you the option to use it. Confirm that the installed certificate’s issuer is listed in the LXD UI, then select it.

After you have selected your certificate, follow the LXD UI’s on-page instructions to set up the trust token.

Finally, click Connect in the UI to complete gaining access. You should then see the Instances page.

As you continue on with this tutorial, notice that many of the following sections include sets of tabs. When the `UI` tab is available, you can now use the instructions in that tab.

<a id="tutorial-create-instances"></a>

## Create instances

LXD uses images to create instances from either [local or remote image servers](../image-handling.md#about-images). We will fetch our container images from the remote [`ubuntu:`](https://cloud-images.ubuntu.com/releases/) server, which hosts official Ubuntu images.

<a id="tutorial-create-containers"></a>

### Create and start containers

CLI

For managing instances, we use the [`lxc` command instead of `lxd`](../explanation/lxd_lxc.md#lxd-lxc).

The `lxc launch` command creates an instance, then immediately starts it. By default, it creates a container instead of a virtual machine. Use this command to launch a container named `first`, based on the Ubuntu 24.04 LTS image:

```bash
lxc launch ubuntu:24.04 first
```

This downloads and unpacks the image, then uses it to create and start a container. Since this command does not specify a remote server, the default [`ubuntu:`](https://cloud-images.ubuntu.com/releases/) server is used. Once downloaded, this image is cached temporarily in the local image server.

We can also create an instance without starting it, using the `lxc init` command. Note that this differs from the `lxd init` command you used to initialize LXD.

Create a container called `second` but do not start it, using the same image as the first:

```bash
lxc init ubuntu:24.04 second
```

Since the image is now cached locally, this container is created much more quickly than the first.

To confirm that the containers have been created, run:

```bash
lxc list
```

You should see both containers you created in the output, with the `first` container in a `RUNNING` state and the `second` container in a `STOPPED` state.

<!-- End group-tab CLI -->

UI

To create a container, select Instances from the main navigation, then click Create instance.

In the form that opens, name this instance `first`. Click Browse images and select the `Ubuntu 24.04 LTS` image. Note that the Source for this image is `Ubuntu`, which is the remote [`ubuntu:`](https://cloud-images.ubuntu.com/releases/) server.

Launch the container by clicking the Create and start button.

This downloads and unpacks the image, then uses it to create and start a container. The image is cached temporarily in the local image server.

Create another container named `second`, using the same image. This time, click Create instead of Create and start. This container will be created but not started.

Since the image is now cached locally, this container is created much more quickly than the first.

<a id="tutorial-create-vm"></a>

## Create and start a VM

Next, let’s launch a VM using the Ubuntu 24.04 LTS image.

Although we will use the same image name as we used when creating a container, LXD will download a variant of the image built specifically for VMs. This image is not yet cached, and it is larger than the container VM, so it will take longer to download.

CLI

We will use the same `lxc launch` command, this time to create an instance named `ubuntu-vm`. To create it as a VM instead of a container, we must add the `--vm` flag. Run:

```bash
lxc launch ubuntu:24.04 ubuntu-vm --vm
```

<!-- End group-tab CLI -->

UI

Open the form to create an instance, and set its name to `ubuntu-vm`. Browse for an image. Do not select the the cached Ubuntu 24.04 image at the top, which has a Type set to `container`. Instead, select the Ubuntu 24.04 LTS image with the Type of `all`, which can be used for VMs.

After you select this image and return to the main creation form, set the Instance type to `VM`. Create and start the VM.

![Create an Ubuntu 24.04 LTS VM](images/tutorial/create_vm.png)

<a id="tutorial-create-vm-desktop"></a>

## Configure, create, and start a desktop VM

A desktop Ubuntu VM is available from the remote [`images:`](https://images.lxd.canonical.com/) server. This server is provided by Canonical for unofficial images of not only Ubuntu variants but other Linux distributions, for testing and development purposes.

The [`limits.memory`](../reference/instance_options.md#instance-resource-limits:limits.memory) option defaults to 1 GiB for VMs. For the desktop VM to run smoothly, we must allocate a higher memory limit.

CLI

You can configure instance options during [creation](../howto/instances_create.md#instances-create) or [afterward](../howto/instances_configure.md#instances-configure). We will configure the desktop VM during creation, using the `--config` flag to set [`limits.memory`](../reference/instance_options.md#instance-resource-limits:limits.memory) to `4GiB`.

Run:

```bash
lxc launch images:ubuntu/24.04/desktop ubuntu-desktop --vm --config limits.memory=4GiB
```

Once the VM has launched, confirm that its memory limit is set to `4 GiB`:

```bash
lxc config get ubuntu-desktop limits.memory
```

<!-- End group-tab CLI -->

UI

Open the form to create a new instance. Name it `ubuntu-desktop`.

Browse for its image, and filter by variant `desktop` to find the Ubuntu 24.04 LTS desktop image. Note that its Source is `LXD Images`, meaning that it uses the remote [`images:`](https://images.lxd.canonical.com/) server. Select this image.

In the submenu, go to Resource limits and override the Memory limit to 4 GiB.

Finally, click Create and start to start the VM.

<a id="tutorial-inspect"></a>

## Inspect instances

CLI

List all the instances that you created:

```bash
lxc list
```

The output tells you the name, state, IP addresses, instance type, and number of snapshots for each instance.

You can retrieve further information about each instance with `lxc info`, including its architecture, process ID, usage data, and more. Run:

```bash
lxc info first
```

<!-- End group-tab CLI -->

UI

View the list of instances that you created:

![List of instances](images/tutorial/instances.png)

This list tells you the name, instance type, description, IPv4 address, and status for each instance. When you hover over an instance row, icons appear to start, restart, freeze (pause), or stop the instance.

Click one of the rows (but not on the instance name) to view the instance summary panel:

![Information about an instance in the instance summary](images/tutorial/instance_summary.png)

This panel provides more information, including the instance’s architecture and process ID.

In either the list of instances or the instance summary panel, click the name of the instance to view its detail page. The Overview tab displays general information about the instance, including its architecture, process ID, creation date, and usage data. You can also view the instance’s network, devices, and profiles here.

Click the Configuration tab. From here, you can both view and edit the instance configuration details. You can also click the YAML Configuration toggle at the bottom of this tab to view and edit the full YAML representation of the instance configuration:

![YAML configuration of an instance](images/tutorial/yaml_configuration.png)

The Console tab is mainly useful for viewing information from the startup process of an instance, and for viewing the graphic console of a desktop VM. Open this tab for the `ubuntu-desktop` VM to see that you can access the graphic console.

You can view and download log files from the Logs tab. Running instances log only limited information by default. More log files are added if an instance ends up in an error state.

We will explore the Terminal and Snapshots tabs later in this tutorial. For now, click the word Instances at the top of this page to return to the list of instances.

<a id="tutorial-start"></a>

### Start a stopped instance

CLI

When you ran `lxc list`, you saw that the `second` container’s state is `STOPPED`, because we used `lxc init` to create the container instead of `lxc launch`.

Start the `second` container:

```bash
lxc start second
```

Run `lxc list` again to confirm that it is now in a `RUNNING` state.

<!-- End group-tab CLI -->

UI

In the list of instances, you should see that the `second` container’s state is `Stopped`, because you created the container but did not start it.

Start the `second` container by clicking the Start button (▷) that appears when you hover over its row.

See [How to create instances](../howto/instances_create.md#instances-create) and [How to manage instances](../howto/instances_manage.md#instances-manage) for more information.

<a id="tutorial-configure"></a>

## Configure instances

Each instance created inherits a default set of configuration options. You can customize these options for each instance. See [Instance options](../reference/instance_options.md#instance-options) for a list of available options.

Earlier, we set the [`limits.memory`](../reference/instance_options.md#instance-resource-limits:limits.memory) option for the `ubuntu-desktop` VM during its creation. We can also update an instance’s configuration after creation.

As an example, let’s reduce the `second` container’s resource limits. Follow the instructions below to update its [`limits.cpu`](../reference/instance_options.md#instance-resource-limits:limits.cpu) to `1`, and its [`limits.memory`](../reference/instance_options.md#instance-resource-limits:limits.memory) to `192MiB`.

CLI

Run:

```bash
lxc config set second limits.cpu=1 limits.memory=192MiB
```

To confirm that the options have been set, use the `lxc config get` command for each option:

```bash
lxc config get second limits.cpu
lxc config get second limits.memory
```

You can also use the `lxc config show` command to view values for all the options. Run:

```bash
lxc config show second
```

<!-- End group-tab CLI -->

UI

Go to the detail page for the `second` container, then its Configuration tab.

From the Resource limits section, override the `Exposed CPU limit` to a `number` of `1`.

Override the `Memory limit` to an `absolute` value of 192. Change the dropdown value from `GiB` to `MiB`.

Save the updated configuration, then confirm that you see the updated values reflected in the Configuration tab.

<a id="tutorial-shell"></a>

## Open an interactive shell into instances

Thus far, we have only acted upon instances from outside of them, from the host system. It’s time to see what we can do inside an instance.

First, let’s run a couple of standard Linux commands on your host system. The first command below displays memory information in megabytes, and the second displays the number of available CPUs.

In a terminal, run:

```bash
free -m
nproc
```

Take note of the outputs. We will compare them to the outputs from the same commands run within your instances.

CLI

Use `lxc shell` to open an interactive shell into the `first` container:

```bash
lxc shell first
```

Notice that your command prompt has changed. You are now logged in as `root` inside the `first` instance.

In this shell session, run the same commands as you did on the host:

```bash
free -m
nproc
```

Note that the total memory returned by `free -m` and the value returned by `nproc` are identical for the host system and the `first` container. This is because by default, containers inherit the resources from their host environment.

Next, exit the `first` container:

```bash
exit
```

Enter an interactive shell into the `second` container:

```bash
lxc shell second
```

Then in the `second` container, run the same commands:

```bash
free -m
nproc
```

For the `second` container, notice that only `192 MiB` total memory and `1` CPU is available. These are the options that we configured for this container earlier.

You can try other commands to interact with your instance. For example, enter the following command to display information about the operating system:

```bash
cat /etc/*release
```

Or have some fun:

```bash
apt update
apt install fortune -y
/usr/games/fortune
```

When you’re done, exit the shell:

```bash
exit
```

Your command prompt should return to that of the host system. From here, try out one other way to run commands inside an instance: the `lxc exec` command. This command is used to execute a single command inside an instance from the host system, without opening a shell. Run:

```bash
lxc exec second -- free -m
```

Notice that the output is the same as if you had run `lxc shell second` then the `free -m` command from inside the `second` container.

See [How to run commands in an instance](../instance-exec.md#run-commands) for more information.

<!-- End group-tab CLI -->

UI

Go to the Terminal tab for the `first` container. This tab provides an interactive shell into an instance.

From there, run the same commands as you did on the host:

```bash
free -m
nproc
```

Note that the total memory returned by `free -m` and the value returned by `nproc` are identical for the host system and the `first` container. This is because by default, containers inherit the resources from their host environment.

Go to the Terminal tab for the `second` container and enter the same commands. Notice that only `192 MiB` total memory and `1` CPU is available. These are the options that we configured for this container earlier.

You can try other commands to interact with your instance. For example, enter the following command to display information about the operating system:

```bash
cat /etc/*release
```

Or have some fun:

```bash
apt update
apt install fortune
/usr/games/fortune
```

<a id="tutorial-files"></a>

## Access files

To access files inside an instance from your host system, use the CLI.

As an example, let’s create a file in the `first` container, pull it out to the host system, modify it, then push it back to the container.

From the host system, use `lxc exec` to create an empty `helloworld` file in the `first` container:

```bash
lxc exec first -- touch helloworld.txt
```

Confirm that the file is empty:

```bash
lxc exec first -- cat helloworld.txt
```

Since the `touch` command creates an empty file, the `cat` command should display no output.

Pull this file from the `first` container to the current directory of your host system:

```bash
lxc file pull first/root/helloworld.txt .
```

Add content to the file:

```bash
echo "Hello world" > helloworld.txt
```

Push the file back to the container:

```bash
lxc file push helloworld.txt first/root/helloworld.txt
```

Now again view the content of the file on the container:

```bash
lxc exec first -- cat helloworld.txt
```

You should see the line that you added:

`your-user@host-system:~$ ``lxc exec first -- cat helloworld.txt
`
```text
Hello world!
```

See [How to access files in an instance](../howto/instances_access_files.md#instances-access-files) for more information.

<a id="tutorial-snapshots"></a>

## Back up and restore instances by creating snapshots

You can back up your instance by creating a snapshot, then use it later to restore the instance to a saved state.

CLI

The following command creates a snapshot called “clean” that saves the current state of your instance. Run:

```bash
lxc snapshot first clean
```

Let’s see how many snapshots are available for the `first` container:

```bash
lxc list first
```

The `SNAPSHOTS` column shows the number of available snapshots.

Let’s find out more information about the available snapshots for the `first` container:

```bash
lxc info first
```

At the bottom of the output, a `Snapshots` table displays details about available snapshots.

If you accidentally do something to break an instance, or wish to revert recent changes to it, you can restore a previous state through a snapshot. To see how this works, let’s deliberately break the `first` container by deleting the `bash` command from it:

```bash
lxc exec first -- rm /usr/bin/bash
```

Confirm that you can no longer use the bash command on `first`:

```bash
lxc exec first -- bash
```

This results in an error because the `bash` command no longer exists. Luckily, we have a snapshot we can use to restore the container to a previous state. Run:

```bash
lxc restore first clean
```

Confirm that you can now enter the `bash` shell:

```bash
lxc exec first -- bash
```

Then exit the shell:

```bash
exit
```

When you no longer need a snapshot, you can delete it. Go ahead and delete the `clean` snapshot:

```bash
lxc delete first/clean
```

<!-- End group-tab CLI -->

UI

Go to the instance detail page of the `first` container and select the Snapshots tab.

Click Create snapshot and enter the snapshot name `clean`. Leave the other options unchanged and create the snapshot. Confirm that the snapshot is now available in the Snapshots tab.

If you accidentally do something to break an instance, or wish to revert recent changes to it, you can restore a previous state through a snapshot. To see how this works, let’s deliberately break the `first` container by deleting the `bash` command from it.

Go to the Terminal tab and break the container:

```bash
rm /usr/bin/bash
```

Refresh the page, and you’ll see the following error:

![Error when trying to load the terminal](images/tutorial/broken_terminal.png)

The UI cannot open a terminal for your container anymore, because you deleted the `bash` command. Luckily, we have a snapshot we can use to restore the container to a previous state.

Return to the Snapshots tab. From there, restore the container to the state of the `clean` snapshot by clicking the Restore snapshot button (<svg width='16' height='16' xmlns='http://www.w3.org/2000/svg'><path d='M5.948 9.012v1.5l-2.458.001A5.163 5.163 0 0012.76 10h1.596a6.665 6.665 0 01-11.839 1.785v2.158h-1.5v-4.93h4.93zM8 1.338a6.655 6.655 0 015.516 2.925V2.11h1.5v4.93h-4.93v-1.5h2.453A5.163 5.163 0 003.24 6H1.643A6.665 6.665 0 018 1.338z' fill='%23000'  fill-rule='evenodd'/></svg>) next to it.

Confirm that the container was reverted to its previous unbroken state by returning to the Terminal tab. The terminal should now load.

When you no longer need a snapshot, you can delete it. In the Snapshots tab, delete the snapshot by clicking the Delete snapshot button (<svg width='16' height='16' xmlns='http://www.w3.org/2000/svg'><path d='M4.5 6v6a1.5 1.5 0 001.356 1.493L6 13.5h4a1.5 1.5 0 001.493-1.356L11.5 12V6H13v6a3 3 0 01-3 3H6a3 3 0 01-3-3V6h1.5zm3 0v5.994H6V6h1.5zm2.498 0v5.994h-1.5V6h1.5zM8.5 0A2.5 2.5 0 0111 2.5V3h3v1.5H2V3h3v-.5A2.5 2.5 0 017.5 0h1zm0 1.5h-1a1 1 0 00-.993.883L6.5 2.5V3h3v-.5a1 1 0 00-.883-.993L8.5 1.5z' fill='%23000' fill-rule='evenodd'/></svg>) next to it.

To learn more about instance snapshots, see: [Use snapshots for instance backup](../howto/instances_backup.md#instances-snapshots).

<a id="tutorial-delete"></a>

## Optional: Stop and delete all instances

Congratulations! You have reached the end of this tutorial and acquired a greater understanding of LXD’s usage and capabilities along the way.

If you wish, you can clean up the instances you created.

CLI

You must first stop an instance before you can delete it:

```bash
lxc stop ubuntu-vm
lxc delete ubuntu-vm
```

You can also use the `--force` flag to delete an instance without stopping it:

```bash
lxc delete ubuntu-desktop --force
```

In the same way, you can delete the other instances that you created in this tutorial (`first` and `second`).

<!-- End group-tab CLI -->

UI

Click the checkbox to the left of each instance you want to delete. Use the buttons that appear at the top of the page to first stop then delete all checked instances.

<a id="tutorial-snap-updates"></a>

## Optional: Hold snap updates

By default, snaps update automatically when a new release is published to their channel. In production environments, we strongly recommend that you disable automatic updates for the LXD snap and apply them manually. This approach allows you to schedule maintenance windows and avoid unplanned downtime.

To hold updates for the LXD snap indefinitely, run on your host machine:

```bash
sudo snap refresh --hold lxd
```

Once updates are on hold, manually update LXD regularly to benefit from security and bug fixes.

If you do not intend to run a production deployment of LXD, you might not need this. To remove the hold and restore automatic updates, run:

```bash
sudo snap refresh --unhold lxd
```

For more information on managing the LXD snap and its updates, see: [How to manage the LXD snap](../howto/snap.md#howto-snap).

<a id="tutorial-next"></a>

## Next steps

Now that you’ve completed your first steps with LXD, you have a general idea of how LXD works. Next, read up on important concepts in the [Explanation](../explanation/index.md#explanation) section and check out more advanced use cases in our [How-to guides](../howto/index.md#howtos). You can also find a wealth of information in the [Reference](../reference/index.md#reference) section, including the [Main API specification](../api.md).


# index.html.md

<a id="exp-replicators"></a>

# Replicators

Replicators are LXD entities that periodically copy instances from one cluster to another across a [cluster link](clusters.md#exp-cluster-links). They are designed for active-passive disaster recovery, where a leader cluster runs all workloads and a standby cluster stays ready to take over if the leader fails.

<a id="exp-replicators-concepts"></a>

## Leader and standby projects

Replication is configured at the project level. Both clusters have a project with the same name, and each project has a replica mode:

- `leader`: The project is writable. Instances in this project are the source of replication. The replicator runs from this cluster.
- `standby`: Instances in this project are replicas, kept in sync by the replicator. New instances cannot be created directly in this project, and existing instances cannot be started. The project must be promoted to `leader` during a failover before instances can be started.

Replica mode is managed via `lxc project promote-replica` and `lxc project demote-replica`. It is not a configuration key and cannot be set with `lxc project set`.

Only the standby project needs the [`replica.cluster`](../reference/projects.md#project-replica:replica.cluster) configuration key, which identifies the cluster link that is allowed to push replication data into it. The leader project does not need this key because the replicator defines the target cluster.

The leader project pushes its instances to the standby project over the cluster link. The standby project mirrors the leader at the time of the last replicator run.

<a id="exp-replicators-how"></a>

## How replication works

When a replicator runs, LXD performs an incremental refresh of every instance in the leader project to the standby project. Instances that do not yet exist on the standby are created; existing instances are updated to match the leader’s current state.

If [`snapshot`](../reference/replicator_config.md#replicator-conf:snapshot) is set to `true` on the replicator, LXD creates a point-in-time snapshot of each instance on the leader before the refresh. This provides a consistent rollback point on the source cluster in case anything goes wrong during replication.

Replication can be triggered manually with `lxc replicator run`, or scheduled automatically using a cron expression in the [`schedule`](../reference/replicator_config.md#replicator-conf:schedule) configuration key.

<a id="exp-replicators-failover"></a>

## Failover and recovery

If the leader cluster fails, the standby project can be promoted with `lxc project promote-replica`. This makes the project writable and allows instances to be started. If the leader cluster is unreachable, validation against it is skipped automatically. Use `--force` to skip all validation without attempting to connect, which is useful when the leader is known to be down or during a planned takeover.

When the original leader comes back online, it can be re-synced from the new leader by running the replicator in restore mode (`lxc replicator run --restore`), then returning both projects to their original roles with `lxc project demote-replica` and `lxc project promote-replica`. In restore mode, the remote leader’s instance list is used as the authoritative source: instances that were created on the new leader after failover are also created on the recovering cluster, not just the instances that existed before the failure.

See [How to perform disaster recovery with replicators](../howto/replicators_dr.md#howto-replicators-dr) for step-by-step instructions.

<a id="exp-replicators-vs-storage-replication"></a>

## Replicators vs. storage replication

LXD supports two distinct approaches to cross-site disaster recovery:

|                           | Replicators                                                                                             | Storage replication                                                  |
|---------------------------|---------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------|
| **Level**                 | LXD instance layer                                                                                      | Storage array layer                                                  |
| **Mechanism**             | Incremental instance refresh over cluster links                                                         | Vendor storage replication (Ceph RBD mirroring, PowerFlex RCG, etc.) |
| **Scheduling**            | Controlled by LXD ([`schedule`](../reference/replicator_config.md#replicator-conf:schedule) config key) | Controlled by the storage vendor                                     |
| **Requires cluster link** | Yes                                                                                                     | No                                                                   |
| **Recovery method**       | Promote standby project with `lxc project promote-replica`                                              | Promote storage array, then run `lxd recover`                        |
| **Snapshot support**      | Optional pre-replication snapshots                                                                      | Depends on storage vendor                                            |

Use replicators when you want LXD to manage replication end-to-end across two clusters without dependency on a specific storage backend. Use [storage replication](../howto/disaster_recovery_replication.md#disaster-recovery-replication) when you need replication at the storage array level, or when you are not using cluster links.

## Related topics

How-to guides:

* [How to set up replicators](../howto/replicators_create.md#howto-replicators-setup)
* [How to manage replicators](../howto/replicators_manage.md#howto-replicators-manage)
* [How to perform disaster recovery with replicators](../howto/replicators_dr.md#howto-replicators-dr)
* [How to perform disaster recovery with storage replication](../howto/disaster_recovery_replication.md#disaster-recovery-replication)

Reference:

* [Replicator configuration](../reference/replicator_config.md#ref-replicator-config)
* [Cluster links](clusters.md#exp-cluster-links)


# index.html.md

<a id="exp-projects"></a>

# Instances grouping with projects


            <p class="youtube_link">
              <a href="https://www.youtube.com/watch?v=cUHkgg6TovM" target="_blank">
                <span title="Overview of LXD projects" class="play_icon">▶</span>
                <span title="Overview of LXD projects">Watch on YouTube</span>
              </a>
            </p>
        
You can use projects to keep your LXD server clean by grouping related instances together.
In addition to isolated instances, each project can also have specific images, profiles, networks, and storage.

For example, projects can be useful in the following scenarios:

- You run a huge number of instances for different purposes, for example, for different customer projects.
  You want to keep these instances separate to make it easier to locate and maintain them, and you might want to reuse the same instance names in each customer project for consistency reasons.
  Each instance in a customer project should use the same base configuration (for example, networks and storage), but the configuration might differ between customer projects.

  In this case, you can create a LXD project for each customer project (thus each group of instances) and use different profiles, networks, and storage for each LXD project.
- Your LXD server is shared between multiple users.
  Each user runs their own instances, and might want to configure their own profiles.
  You want to keep the user instances confined, so that each user can interact only with their own instances and cannot see the instances created by other users.
  In addition, you want to be able to limit resources for each user and make sure that the instances of different users cannot interfere with one another.

  In this case, you can set up a multi-user environment with confined projects.

LXD comes with a `default` project.
See [How to create and configure projects](../howto/projects_create.md#projects-create) for instructions on how to add projects.

<a id="projects-isolation"></a>

## Isolation of projects

Projects always encapsulate the instances they contain, which means that instances cannot be shared between projects and instance names can be duplicated in several projects.
When you are in a specific project, you can see only the instances that belong to this project.

Other entities (images, profiles, networks, and storage) can be either isolated in the project or inherited from the `default` project.
To configure which entities are isolated, you enable or disable the respective *feature* in the project.
If a feature is enabled, the corresponding entity is isolated in the project; if the feature is disabled, it is inherited from the `default` project.

For example, if you enable [`features.networks`](../reference/projects.md#project-features:features.networks) for a project, the project uses a separate set of networks and not the networks defined in the `default` project. If you disable [`features.images`](../reference/projects.md#project-features:features.images), the project has access to the images defined in the `default` project, and any images you add while you’re using the project are also added to the `default` project.

See the list of available [Project features](../reference/projects.md#project-features) for information about which features are enabled or disabled when you create a project.

#### NOTE
You must select the features that you want to enable before starting to use a new project.
When a project contains instances, the features are locked.
To edit them, you must remove all instances first.

New features that are added in an upgrade are disabled for existing projects.

#### IMPORTANT
In a multi-tenant environment, unless using [Fine-grained authorization](authorization.md#fine-grained-authorization), all projects should have all features enabled.
Otherwise, clients with [Restricted TLS certificates](authorization.md#restricted-tls-certs) are able to create, edit, and delete resources in the default project. This might affect other tenants.

For example, if project “foo” is created and `features.networks` is not set to true, then a restricted client certificate with access to “foo” can view, edit, and delete networks in the default project.

Conversely, if a client’s permissions are managed via [Fine-grained authorization](authorization.md#fine-grained-authorization), resources may be inherited from the default project but access to those resources is not automatically granted.

<a id="projects-confined"></a>

## Confined projects in a multi-user environment

If your LXD server is used by multiple users (for example, in a lab environment), you can use projects to confine the activities of each user.
This method isolates the instances and other entities (depending on the feature configuration), as described in [Isolation of projects](#projects-isolation).
It also confines users to their own user space and prevents them from gaining access to other users’ instances or data.
Any changes that affect the LXD server and its configuration, for example, adding or removing storage, are not permitted.

In addition, this method allows users to work with LXD without being a member of the `lxd` group (see [Access to the LXD daemon](security.md#security-daemon-access)).
Members of the `lxd` group have full access to LXD, including permission to attach file system paths and tweak the security features of an instance, which makes it possible to gain root access to the host system.
Using confined projects limits what users can do in LXD, but it also prevents users from gaining root access.

When LXD is accessible over the HTTPS API, both [TLS client certificates](../authentication.md#authentication-tls-certs) and [OIDC clients](../authentication.md#authentication-openid) can be restricted to allow access to specific projects only.
This is managed via [Fine-grained authorization](authorization.md#fine-grained-authorization).
See [Confine users to specific projects on the HTTPS API](../howto/projects_confine.md#projects-confine-https) for instructions.

### Multi-user LXD daemon

The LXD snap contains a multi-user LXD daemon that allows dynamic project creation on a per-user basis.
You can configure a specific user group other than the `lxd` group to give restricted LXD access to every user in the group.

When a user that is a member of this group starts using LXD, the multi-user daemon automatically creates a confined project for this user.

If you’re not using the snap, you can still use this feature if your distribution supports it.

See [Confine users to specific LXD projects via Unix socket](../howto/projects_confine.md#projects-confine-users) for instructions on configuring the multi-user daemon.

## Related topics

How-to guides:

- [Projects](../projects.md#projects)

Reference:

- [Project configuration](../reference/projects.md#ref-projects)


# index.html.md

<a id="explanation"></a>

# Explanation

The explanatory guides in this section discuss the concepts used in LXD and help you understand how things fit together.

<a id="explanation-concepts"></a>

## Important concepts

LXD’s core concepts include its relationship with LXC and the instance types it supports: system containers and virtual machines.

* [`lxd` and `lxc`](lxd_lxc.md)
* [Containers and VMs](instances.md)

<a id="explanation-entities"></a>

## Entities in LXD

LXD uses several distinct entity types, including images, storage pools, networks, and projects. To learn how to use them, refer to the [How-to guides](../howto/index.md#howtos).

* [Local and remote images](../image-handling.md)
* [Storage pools, volumes, and buckets](storage.md)
* [Networking setups](networks.md)
* [The LXD Dqlite database](../database.md)
* [`lxc` `show` and `info`](lxc_show_info.md)

<a id="explanation-iam"></a>

## Access management

LXD supports multiple methods for authenticating remote API clients and provides fine-grained authorization controls. Projects can also be used to scope and restrict access.

* [Remote API authentication](../authentication.md)
* [Remote API authorization](authorization.md)
* [Instances grouping with projects](projects.md)

<a id="explanation-production"></a>

## Production setup

For scalable, reliable, and secure LXD deployments, these guides help you understand the key concepts around clustering, performance tuning, and security.

* [Clusters](clusters.md)
* [Replicators](replicators.md)
* [Performance tuning](performance_tuning.md)
* [Security](security.md)
* [Privilege delegation using BPF Token](bpf.md)

<a id="explanation-csi"></a>

## The LXD CSI driver

The LXD CSI driver is an open source implementation of the Container Storage Interface (CSI) that integrates LXD storage backends with Kubernetes.

* [The LXD CSI driver](csi.md)


# index.html.md

<a id="lxc-show-info"></a>

# `lxc` `show` and `info`

For the entities managed by LXD, the `lxc` command provides a `list` sub-command, and might provide `show` and `info` sub-commands.
The purpose of the `info` sub-command is to show current state information, and the purpose of the `show` sub-command is to show configuration information and how the entity is used by other entities.

For example, the `lxc network info` command shows IP address and traffic statistics:

```none
Name: lxdbr0
MAC address: 00:16:3e:d3:ec:41
MTU: 1500
State: up

Ips:
  inet    192.0.2.1
  inet6   2001:db8:f4a1:53d2::1
  inet6   fe80::216:3eff:fed3:ec41

Network usage:
  Bytes received: 127.66kB
  Bytes sent: 15.54kB
  Packets received: 1433
  Packets sent: 175
```

The `lxc network show` command, on the other hand, shows how the network is configured, and which entities are using the network:

```none
config:
  ipv4.address: 192.0.2.1/24
  ipv4.nat: "true"
  ipv6.address: 2001:db8:f4a1:53d2::1/64
  ipv6.nat: "true"
description: ""
name: lxdbr0
type: bridge
used_by:
- /1.0/instances/ubuntu
- /1.0/profiles/default
managed: true
status: Created
locations:
- none
```

Refer to the manual pages for details of the commands for managing entities:

- Instances: [`lxc list`](../reference/manpages/lxc/list.md#lxc-list-md), [`lxc info`](../reference/manpages/lxc/info.md#lxc-info-md)
- Images: [`lxc image list`](../reference/manpages/lxc/image/list.md#lxc-image-list-md), [`lxc image info`](../reference/manpages/lxc/image/info.md#lxc-image-info-md), [`lxc image show`](../reference/manpages/lxc/image/show.md#lxc-image-show-md)
- Networks: [`lxc network list`](../reference/manpages/lxc/network/list.md#lxc-network-list-md), [`lxc network info`](../reference/manpages/lxc/network/info.md#lxc-network-info-md), [`lxc network show`](../reference/manpages/lxc/network/show.md#lxc-network-show-md)
- Profiles: [`lxc profile list`](../reference/manpages/lxc/profile/list.md#lxc-profile-list-md), [`lxc profile show`](../reference/manpages/lxc/profile/show.md#lxc-profile-show-md)
- Projects: [`lxc project list`](../reference/manpages/lxc/project/list.md#lxc-project-list-md), [`lxc project info`](../reference/manpages/lxc/project/info.md#lxc-project-info-md), [`lxc project show`](../reference/manpages/lxc/project/show.md#lxc-project-show-md)
- Storage: [`lxc storage list`](../reference/manpages/lxc/storage/list.md#lxc-storage-list-md), [`lxc storage info`](../reference/manpages/lxc/storage/info.md#lxc-storage-info-md), [`lxc storage show`](../reference/manpages/lxc/storage/show.md#lxc-storage-show-md)
- Cluster links: [`lxc cluster link list`](../reference/manpages/lxc/cluster/link/list.md#lxc-cluster-link-list-md), [`lxc cluster link info`](../reference/manpages/lxc/cluster/link/info.md#lxc-cluster-link-info-md), [`lxc cluster link show`](../reference/manpages/lxc/cluster/link/show.md#lxc-cluster-link-show-md)


# index.html.md

<a id="performance-tuning"></a>

# Performance tuning

When you are ready to move your LXD setup to production, you should take some time to optimize the performance of your system.
There are different aspects that impact performance.
The following steps help you to determine the choices and settings that you should tune to improve your LXD setup.

## Run benchmarks

LXD provides a benchmarking tool to evaluate the performance of your system.
You can use the tool to initialize or launch a number of containers and measure the time it takes for the system to create the containers.
By running the tool repeatedly with different LXD configurations, system settings or even hardware setups, you can compare the performance and evaluate which is the ideal configuration.

See [How to benchmark performance](../howto/benchmark_performance.md#benchmark-performance) for instructions on running the tool.

## Monitor instance metrics

<!-- Include content from [../metrics.md](../metrics.md) -->

LXD collects metrics for all running instances as well as some internal metrics.
These metrics cover the CPU, memory, network, disk and process usage.
They are meant to be consumed by Prometheus, and you can use Grafana to display the metrics as graphs.
See [Provided metrics](../reference/provided_metrics.md#provided-metrics) for lists of available metrics and [Set up a Grafana dashboard](../howto/grafana.md#grafana) for instructions on how to display the metrics in Grafana.

You should regularly monitor the metrics to evaluate the resources that your instances use.
The numbers help you to determine if there are any spikes or bottlenecks, or if usage patterns change and require updates to your configuration.

See [How to monitor metrics](../metrics.md#metrics) for more information about metrics collection.

## Tune server settings

The default kernel settings for most Linux distributions are not optimized for running a large number of containers or virtual machines.
Therefore, you should check and modify the relevant server settings to avoid hitting limits caused by the default settings.

Typical errors that you might see when you encounter those limits are:

- `Failed to allocate directory watch: Too many open files`
- `<Error> <Error>: Too many open files`
- `failed to open stream: Too many open files in...`
- `neighbour: ndisc_cache: neighbor table overflow!`

See [Server settings for a LXD production setup](../reference/server_settings.md#server-settings) for a list of relevant server settings and suggested values.

## Tune the network bandwidth

If you have a lot of local activity between instances or between the LXD host and the instances, or if you have a fast internet connection, you should consider increasing the network bandwidth of your LXD setup.
You can do this by increasing the transmit and receive queue lengths.

See [How to increase the network bandwidth](../howto/network_increase_bandwidth.md#network-increase-bandwidth) for instructions.

## Related topics

How-to guides:

- [How to benchmark performance](../howto/benchmark_performance.md#benchmark-performance)
- [How to increase the network bandwidth](../howto/network_increase_bandwidth.md#network-increase-bandwidth)
- [How to monitor metrics](../metrics.md#metrics)

Reference:

- [Provided metrics](../reference/provided_metrics.md#provided-metrics)
- [Server settings for a LXD production setup](../reference/server_settings.md#server-settings)


# index.html.md

<a id="containers-and-vms"></a>

# Containers and VMs

LXD provides support for two different types of [instances](#expl-instances): *system containers* and *virtual machines*.

When running a system container, LXD simulates a virtual version of a full operating system. To do this, it uses the functionality provided by the kernel running on the host system.

When running a virtual machine, LXD uses the hardware of the host system, but the kernel is provided by the virtual machine. Therefore, virtual machines can be used to run, for example, a different operating system.

## Application containers vs. system containers

Application containers (as provided by, for example, Docker) package a single process or application. System containers, on the other hand, simulate a full operating system and let you run multiple processes at the same time.

Therefore, application containers are suitable to provide separate components, while system containers provide a full solution of libraries, applications, databases, and so on. In addition, you can use system containers to create different user spaces and isolate all processes belonging to each user space, which is not what application containers are intended for.

![Application and system containers](images/application-vs-system-containers.svg)

## Virtual machines vs. system containers

Virtual machines emulate a physical machine, using the hardware of the host system from a full and completely isolated operating system. System containers, on the other hand, use the OS kernel of the host system instead of creating their own environment. If you run several system containers, they all share the same kernel, which makes them faster and more lightweight than virtual machines.

With LXD, you can create both system containers and virtual machines. You should use a system container to leverage the smaller size and increased performance if all functionality you require is compatible with the kernel of your host operating system. If you need functionality that is not supported by the OS kernel of your host system or you want to run a completely different OS, use a virtual machine.

![Virtual machines and system containers](images/virtual-machines-vs-system-containers.svg)

<a id="expl-instances"></a>

## Instance types in LXD

LXD supports the following types of instances:

Containers
: Containers are the default type for instances. They are implemented through the use of `liblxc` (LXC).

Virtual machines
:  are natively supported since version 4.0 of LXD.
  Thanks to a built-in agent, they can be used almost like containers, with a similar set of features.
  <br/>
  LXD uses `qemu` to provide the VM functionality.
  <br/>
  #### NOTE
  In the [Instance options](../reference/instance_options.md#instance-options) documentation, some instance options display a `condition` field in their details, with the value of either `container` or `virtual machine`. This indicates the type of instance for which that option is available. If no `condition` field exists in an option’s details, that option applies to both types.

## Related topics

How-to guides:

- [Instances](../instances.md#instances)

Reference:

- [Container runtime environment](../container-environment.md#container-runtime-environment)
- [Instance configuration](instance_config.md#instance-config)


# index.html.md

<a id="lxd-lxc"></a>

# `lxd` and `lxc`

LXD is frequently confused with LXC, and the fact that LXD provides both a `lxd` command and a `lxc` command doesn’t make things easier.

## LXD vs. LXC

LXD and LXC are two distinct implementations of Linux containers.

[LXC](https://linuxcontainers.org/lxc/introduction/) is a low-level user space interface for the Linux kernel containment features.
It consists of tools (`lxc-*` commands), templates, and library and language bindings.

[LXD](https://canonical.com/lxd) is a more intuitive and user-friendly tool aimed at making it easy to work with Linux containers.
It is an alternative to LXC’s tools and distribution template system, with the added features that come from being controllable over the network.
Under the hood, LXD uses LXC to create and manage the containers.

LXD provides a superset of the features that LXC supports, and it is easier to use.
Therefore, if you are unsure which of the tools to use, you should go for LXD.
LXC should be seen as an alternative for experienced users that want to run Linux containers on distributions that don’t support LXD.

<a id="lxd-daemon"></a>

## LXD daemon

The central part of LXD is its daemon.
It runs persistently in the background, manages the instances, and handles all requests.
The daemon provides a REST API that you can access directly or through a client (for example, the default command-line client that comes with LXD).

See [Daemon behavior](../daemon-behavior.md#daemon-behavior) for more information about the LXD daemon.

## `lxd` vs. `lxc`

To control LXD, you typically use two different commands: `lxd` and `lxc`.

LXD daemon
: The `lxd` command controls the LXD daemon.
  Since the daemon is typically started automatically, you hardly ever need to use the `lxd` command.
  An exception is the `lxd init` subcommand that you run to [initialize LXD](../howto/initialize.md#initialize).
  <br/>
  There are also some subcommands for debugging and administrating the daemon, but they are intended for advanced users only.
  See `lxd --help` for an overview of all available subcommands.

LXD client
: The `lxc` command is a command-line client for LXD, which you can use to interact with the LXD daemon.
  You use the `lxc` command to manage your instances, the server settings, and overall the entities you create in LXD.
  See [`lxc --help`](../reference/manpages/lxc.md#lxc-md) for an overview of all available subcommands.
  <br/>
  The `lxc` tool is not the only client you can use to interact with the LXD daemon.
  You can also use the API, the UI, or a custom LXD client.


# index.html.md

<a id="bpf-delegation-token"></a>

# Privilege delegation using BPF Token

## Overview

The [`security.delegate_bpf`](../reference/instance_options.md#instance-security:security.delegate_bpf) option enables the  functionality delegation mechanism, using a [BPF Token](https://docs.ebpf.io/linux/concepts/token). When enabled, LXD mounts a BPF File System (BPFFS) inside a container instance. This file system is configured with the `security.delegate_bpf.*` settings.
For example:

```default
none on /sys/fs/bpf type bpf (rw,relatime,uid=1000000,gid=1000000,
                            delegate_cmds=map_create:prog_load,
                            delegate_maps=ringbuf,
                            delegate_progs=socket_filter,
                            delegate_attachs=cgroup_inet_ingress)
```

Then, applications inside the container can create a BPF Token file descriptor using that BPFFS mount and the `bpf(BPF_TOKEN_CREATE)` syscall. Later, this File Descriptor can be passed to `bpf(BPF_PROG_LOAD)`, `bpf(BPF_MAP_CREATE)`, or another `bpf()`-command syscall, and the kernel will perform a permission check against the token instead of the current user credentials. To be more precise, current user caps are also checked for `CAP_BPF` but in a current user namespace when `bpf(BPF_TOKEN_CREATE)` is called.

It follows that user space applications inside the container must be aware of  the BPF Token kernel feature (which appeared in Linux kernel v6.9) and make use of it. In contrast to `security.syscalls.intercept.*` features, this one is not fully transparent and might require updates or modifications to the software inside the container. Fortunately, [the libbpf library](https://docs.kernel.org/bpf/libbpf/libbpf_overview.html) supports BPF tokens. Thus if an application uses libbpf, then to make use of this feature, you might only need to update libbpf.

#### NOTE
Configure the following instance options for the container, depending on its BPF workload:

- [`security.delegate_bpf.cmd_types`](../reference/instance_options.md#instance-security:security.delegate_bpf.cmd_types)
- [`security.delegate_bpf.map_types`](../reference/instance_options.md#instance-security:security.delegate_bpf.map_types)
- [`security.delegate_bpf.prog_types`](../reference/instance_options.md#instance-security:security.delegate_bpf.prog_types)
- [`security.delegate_bpf.attach_types`](../reference/instance_options.md#instance-security:security.delegate_bpf.attach_types)

See the [BPF Token documentation page](https://docs.ebpf.io/linux/concepts/token/) on `docs.ebpf.io` for details.

## Example (socket filter)

Let’s consider an example with a socket filter program from [libbpf-bootstrap](https://github.com/libbpf/libbpf-bootstrap).

The following creates an unprivileged container instance and sets all the necessary configuration options to enable BPF delegation:

```bash
lxc launch ubuntu:noble bpf-experiments
lxc config set bpf-experiments limits.kernel.memlock=unlimited
lxc config set bpf-experiments security.delegate_bpf=true
lxc config set bpf-experiments security.delegate_bpf.prog_types=socket_filter
lxc config set bpf-experiments security.delegate_bpf.attach_types=cgroup_inet_ingress
lxc config set bpf-experiments security.delegate_bpf.cmd_types=prog_load:map_create
lxc config set bpf-experiments security.delegate_bpf.map_types=ringbuf
```

The following set of commands clones and builds the libbpf-bootstrap.git repository within the example `bpf-experiments` container:

```bash
lxc shell bpf-experiments
apt install clang build-essential
git clone https://github.com/libbpf/libbpf-bootstrap.git
git submodule update --init --recursive
cd libbpf-bootstrap/examples/c
make
```

This experiment completes by running commands from two different shells into the `bpf-experiments` container.

From one terminal:

`user@host:~$ ``lxc shell bpf-experiments
``> ./sockfilter
`

From another terminal:

`user@host:~$ ``lxc shell bpf-experiments
``> ping -c 4 localhost
`

Sample output:

```default
ibbpf: loading object 'sockfilter_bpf' from buffer
libbpf: elf: section(2) .symtab, size 192, link 1, flags 0, type=2
libbpf: elf: section(3) socket, size 576, link 0, flags 6, type=1
libbpf: sec 'socket': found program 'socket_handler' at insn offset 0 (0 bytes), code size 72 insns (576 bytes)
...
libbpf: Kernel doesn't support BTF, skipping uploading it.
libbpf: map 'rb': created successfully, fd=3
interface: lo        protocol: ICMP        127.0.0.1:2048(src) -> 127.0.0.1:32429(dst)
interface: lo        protocol: ICMP        127.0.0.1:0(src) -> 127.0.0.1:34477(dst)
interface: lo        protocol: ICMP        127.0.0.1:2048(src) -> 127.0.0.1:46163(dst)
interface: lo        protocol: ICMP        127.0.0.1:0(src) -> 127.0.0.1:48211(dst)
```

We can see from this sample output that the ICMP packets were captured by the  program and logged.

## Finding the right configuration

To figure out the right values for the `security.delegate_bpf.cmd_types`, `security.delegate_bpf.map_types`, `security.delegate_bpf.prog_types`, `security.delegate_bpf.attach_types` options, you must know how your application inside the container uses eBPF, such as its program types and map types. You can consult the application’s source code, or use the [`strace`](https://github.com/strace/strace) tool to trace `bpf` syscall and see how it is being used.

Example using `strace`:

`user@host:~$ ``strace -e bpf ./sockfilter
`

Sample output:

```default
bpf(0x24 /* BPF_??? */, 0x7fffafdf5a40, 8) = 5
bpf(BPF_PROG_LOAD, {prog_type=BPF_PROG_TYPE_SOCKET_FILTER, insn_cnt=2, insns=0x7fffafdf59e0, license="GPL", log_level=0, log_size=0, log_buf=NULL, kern_version=KERNEL_VERSION(0, 0, 0), prog_flags=0, prog_name="", prog_ifindex=0, expected_attach_type=BPF_CGROUP_INET_INGRESS, prog_btf_fd=0, func_info_rec_size=0, func_info=NULL, func_info_cnt=0, line_info_rec_size=0, line_info=NULL, line_info_cnt=0, attach_btf_id=0, attach_prog_fd=0, fd_array=NULL}, 148) = -1 EPERM (Operation not permitted)
bpf(BPF_PROG_LOAD, {prog_type=BPF_PROG_TYPE_SOCKET_FILTER, insn_cnt=2, insns=0x7fffafdf5c10, license="GPL", log_level=0, log_size=0, log_buf=NULL, kern_version=KERNEL_VERSION(0, 0, 0), prog_flags=0x10000 /* BPF_F_??? */, prog_name="", prog_ifindex=0, expected_attach_type=BPF_CGROUP_INET_INGRESS, prog_btf_fd=0, func_info_rec_size=0, func_info=NULL, func_info_cnt=0, line_info_rec_size=0, line_info=NULL, line_info_cnt=0, attach_btf_id=0, attach_prog_fd=0, fd_array=NULL, ...}, 152) = 4
bpf(BPF_BTF_LOAD, {btf="\237\353\1\0\30\0\0\0\0\0\0\0000\0\0\0000\0\0\0\t\0\0\0\1\0\0\0\0\0\0\1"..., btf_log_buf=NULL, btf_size=81, btf_log_size=0, btf_log_level=0, ...}, 40) = -1 EPERM (Operation not permitted)
bpf(BPF_BTF_LOAD, {btf="\237\353\1\0\30\0\0\0\0\0\0\0000\0\0\0000\0\0\0\5\0\0\0\0\0\0\0\0\0\0\1"..., btf_log_buf=NULL, btf_size=77, btf_log_size=0, btf_log_level=0, ...}, 40) = -1 EPERM (Operation not permitted)
bpf(BPF_BTF_LOAD, {btf="\237\353\1\0\30\0\0\0\0\0\0\0\20\0\0\0\20\0\0\0\5\0\0\0\1\0\0\0\0\0\0\1"..., btf_log_buf=NULL, btf_size=45, btf_log_size=0, btf_log_level=0, ...}, 40) = -1 EPERM (Operation not permitted)
libbpf: Kernel doesn't support BTF, skipping uploading it.
bpf(BPF_PROG_LOAD, {prog_type=BPF_PROG_TYPE_SOCKET_FILTER, insn_cnt=2, insns=0x7fffafdf59c0, license="GPL", log_level=0, log_size=0, log_buf=NULL, kern_version=KERNEL_VERSION(0, 0, 0), prog_flags=0x10000 /* BPF_F_??? */, prog_name="libbpf_nametest", prog_ifindex=0, expected_attach_type=BPF_CGROUP_INET_INGRESS, prog_btf_fd=0, func_info_rec_size=0, func_info=NULL, func_info_cnt=0, line_info_rec_size=0, line_info=NULL, line_info_cnt=0, attach_btf_id=0, attach_prog_fd=0, fd_array=NULL, ...}, 148) = 4
bpf(BPF_PROG_LOAD, {prog_type=BPF_PROG_TYPE_SOCKET_FILTER, insn_cnt=2, insns=0x7fffafdf58e0, license="GPL", log_level=0, log_size=0, log_buf=NULL, kern_version=KERNEL_VERSION(0, 0, 0), prog_flags=0, prog_name="libbpf_nametest", prog_ifindex=0, expected_attach_type=BPF_CGROUP_INET_INGRESS, prog_btf_fd=0, func_info_rec_size=0, func_info=NULL, func_info_cnt=0, line_info_rec_size=0, line_info=NULL, line_info_cnt=0, attach_btf_id=0, attach_prog_fd=0, fd_array=NULL}, 148) = -1 EPERM (Operation not permitted)
bpf(BPF_MAP_CREATE, {map_type=BPF_MAP_TYPE_RINGBUF, key_size=0, value_size=0, max_entries=262144, map_flags=0x10000 /* BPF_F_??? */, inner_map_fd=0, map_name="", map_ifindex=0, btf_fd=0, btf_key_type_id=0, btf_value_type_id=0, btf_vmlinux_value_type_id=0, map_extra=0, ...}, 80) = 4
libbpf: map 'rb': created successfully, fd=3
bpf(BPF_PROG_LOAD, {prog_type=BPF_PROG_TYPE_SOCKET_FILTER, insn_cnt=72, insns=0x56198b83c180, license="Dual BSD/GPL", log_level=0, log_size=0, log_buf=NULL, kern_version=KERNEL_VERSION(6, 12, 14), prog_flags=0x10000 /* BPF_F_??? */, prog_name="", prog_ifindex=0, expected_attach_type=BPF_CGROUP_INET_INGRESS, prog_btf_fd=0, func_info_rec_size=0, func_info=NULL, func_info_cnt=0, line_info_rec_size=0, line_info=NULL, line_info_cnt=0, attach_btf_id=0, attach_prog_fd=0, fd_array=NULL, ...}, 152) = 4
bpf(BPF_OBJ_GET_INFO_BY_FD, {info={bpf_fd=3, info_len=88, info=0x7fffafdf5de0}}, 16) = 0
```

This log shows that `sockfilter` is using:

1. Program types: `BPF_PROG_TYPE_SOCKET_FILTER`
2. Map types: `BPF_MAP_TYPE_RINGBUF`
3. Attachment types: `BPF_CGROUP_INET_INGRESS`
4. BPF commands: `BPF_BTF_LOAD`, `BPF_PROG_LOAD`, `BPF_MAP_CREATE`


# index.html.md

<a id="exp-security"></a>

<a id="security"></a>

# Security


            <p class="youtube_link">
              <a href="https://www.youtube.com/watch?v=cOOzKdYHkus" target="_blank">
                <span title="LXD security" class="play_icon">▶</span>
                <span title="LXD security">Watch on YouTube</span>
              </a>
            </p>
        <!-- Include content from [../../README.md](../../README.md) -->

Consider the following aspects to ensure that your LXD installation is secure:

- Keep your operating system up-to-date and install all available security patches.
- Use only supported LXD versions (LTS releases or the latest feature release).
- Restrict access to the LXD daemon and the remote API.
- Configure your network interfaces to be secure.
- Do not use privileged containers unless required. If you use privileged containers, put appropriate security measures in place.

See the following sections for detailed information. Also see: [How to harden security for LXD](../howto/security_harden.md#howto-security-harden).

If you discover a security issue, see the [LXD security policy](https://github.com/canonical/lxd/blob/main/SECURITY.md) for information on how to report the issue.

## Supported versions

Never use unsupported LXD versions in a production environment.

<!-- Include content from [../../SECURITY.md](../../SECURITY.md) -->

LXD has two types of releases:

- Feature releases
- LTS releases

For feature releases, only the latest one is supported, and we usually
don’t do point releases. Instead, users are expected to wait until the
next feature release.

For LTS releases, we do periodic bugfix releases that include an
accumulation of bugfixes from the feature releases. Such bugfix releases
do not include new features.

<a id="security-daemon-access"></a>

## Access to the LXD daemon

LXD is a daemon that can be accessed locally over a Unix socket or, if configured, remotely over a  socket.
Anyone with access to the socket can fully control LXD, which includes the ability to attach host devices and file systems or to tweak the security features for all instances.

Therefore, make sure to restrict the access to the daemon to trusted users.

### Local access to the LXD daemon

The LXD daemon runs as root and provides a Unix socket for local communication.
Access control for LXD is based on group membership.
The root user and all members of the `lxd` group can interact with the local daemon.

#### IMPORTANT
<!-- Include content from [../../README.md](../../README.md) -->

Local access to LXD through the Unix socket always grants full access to LXD.
This includes the ability to attach file system paths or devices to any instance as well as tweak the security features on any instance.

Therefore, you should only give such access to users who you’d trust with root access to your system.

<a id="security-remote-access"></a>

### Access to the remote API

By default, access to the daemon is only possible locally, but you can also [expose LXD to the network](../howto/server_expose.md#server-expose) on a  (Transport Layer Security) socket.
Remote clients can then connect to LXD and access any image that is marked for public use.

There are several ways to authenticate remote clients as trusted clients to allow them to access the API.
See [Remote API authentication](../authentication.md#authentication) for details.
To increase your security posture in a production setup, you can also [harden remote API access](../howto/security_harden.md#howto-security-harden-remote) and [configure your firewall](../howto/network_bridge_firewalld.md#network-bridge-firewall).

<a id="container-security"></a>

## Container security

LXD containers can use a wide range of features for security.

Also see the [LXC security page](https://linuxcontainers.org/lxc/security/) on `linuxcontainers.org` for details on LXC container security and the applied kernel features.

### Unprivileged containers

By default, containers are *unprivileged*, meaning that they operate inside a user namespace, restricting the abilities of users in the container to that of regular users on the host with limited privileges on the devices that the container owns.

Unprivileged containers are safe by design: The container UID 0 is mapped to an unprivileged user outside of the container.
It has extra rights only on resources that it owns itself.

This mechanism ensures that most security issues (for example, container escape or resource abuse) that might occur in a container apply just as well to a random unprivileged user, which means they are a generic kernel security bug rather than a LXD issue.

### Privileged containers

LXD can also run *privileged* containers.
In privileged containers, the container UID 0 is mapped to the host’s UID 0.

Such privileged containers are not root-safe, and a user with root access in such a container will be able to DoS the host as well as find ways to escape confinement.

LXC applies some protection measures to privileged containers to prevent accidental damage of the host (where damage is defined as things like reconfiguring host hardware, reconfiguring the host kernel, or accessing the host file system).
This protection of the host and prevention of escape is achieved through mandatory access control (`apparmor`, `selinux`), Seccomp filters, dropping of capabilities, and namespaces.
These measures are valuable when running trusted workloads, but they do not make privileged containers root-safe.

Therefore, you should not use privileged containers unless required.
If you use them, make sure to put appropriate security measures in place.

## Network security

Make sure to configure your network interfaces to be secure.
Which aspects you should consider depends on the networking mode you decide to use.

<a id="exp-security-bridged"></a>

### Bridged NIC security

The default networking mode in LXD is to provide a “managed” private network bridge that each instance connects to.
In this mode, there is an interface on the host called `lxdbr0` that acts as the bridge for the instances.

The host runs an instance of `dnsmasq` for each managed bridge, which is responsible for allocating IP addresses and providing both authoritative and recursive DNS services.

Instances using DHCPv4 will be allocated an IPv4 address, and a DNS record will be created for their instance name.
This prevents instances from being able to spoof DNS records by providing false host name information in the DHCP request.

The `dnsmasq` service also provides IPv6 router advertisement capabilities.
This means that instances will auto-configure their own IPv6 address using SLAAC, so no allocation is made by `dnsmasq`.
However, instances that are also using DHCPv4 will also get an AAAA DNS record created for the equivalent SLAAC IPv6 address.
This assumes that the instances are not using any IPv6 privacy extensions when generating IPv6 addresses.

In this default configuration, whilst DNS names cannot not be spoofed, the instance is connected to an Ethernet bridge and can transmit any layer 2 traffic that it wishes, which means an instance that is not trusted can effectively do MAC or IP spoofing on the bridge.

In the default configuration, it is also possible for instances connected to the bridge to modify the LXD host’s IPv6 routing table by sending (potentially malicious) IPv6 router advertisements to the bridge.
This is because the `lxdbr0` interface is created with `/proc/sys/net/ipv6/conf/lxdbr0/accept_ra` set to `2`, meaning that the LXD host will accept router advertisements even though `forwarding` is enabled (see [`/proc/sys/net/ipv4/*` Variables](https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt) for more information).

However, LXD offers several bridged  security features that can be used to control the type of traffic that an instance is allowed to send onto the network.
These NIC settings should be added to the profile that the instance is using, or they can be added to individual instances, as shown below.

The following security features are available for bridged NICs:

| Key                       | Type   | Default   | Required   | Description                                                                                  |
|---------------------------|--------|-----------|------------|----------------------------------------------------------------------------------------------|
| `security.mac_filtering`  | bool   | `false`   | no         | Prevent the instance from spoofing another instance’s MAC address                            |
| `security.ipv4_filtering` | bool   | `false`   | no         | Prevent the instance from spoofing another instance’s IPv4 address (enables `mac_filtering`) |
| `security.ipv6_filtering` | bool   | `false`   | no         | Prevent the instance from spoofing another instance’s IPv6 address (enables `mac_filtering`) |

One can override the default bridged NIC settings from the profile on a per-instance basis using:

```default
lxc config device override <instance> <NIC> security.mac_filtering=true
```

Used together, these features can prevent an instance connected to a bridge from spoofing MAC and IP addresses.
These options are implemented using either `xtables` (`iptables`, `ip6tables` and `ebtables`) or `nftables`, depending on what is available on the host.

It’s worth noting that those options effectively prevent nested containers from using the parent network with a different MAC address (i.e using bridged or `macvlan` NICs).

The IP filtering features block ARP and NDP advertisements that contain a spoofed IP, as well as blocking any packets that contain a spoofed source address.

If `security.ipv4_filtering` or `security.ipv6_filtering` is enabled and the instance cannot be allocated an IP address (because `ipvX.address=none` or there is no DHCP service enabled on the bridge), then all IP traffic for that protocol is blocked from the instance.

When `security.ipv6_filtering` is enabled, IPv6 router advertisements are blocked from the instance.

When `security.ipv4_filtering` or `security.ipv6_filtering` is enabled, any Ethernet frames that are not ARP, IPv4 or IPv6 are dropped.
This prevents stacked VLAN Q-in-Q (802.1ad) frames from bypassing the IP filtering.

### Routed NIC security

An alternative networking mode is available called “routed”.
It provides a virtual Ethernet device pair between container and host.
In this networking mode, the LXD host functions as a router, and static routes are added to the host directing traffic for the container’s IPs towards the container’s `veth` interface.

By default, the `veth` interface created on the host has its `accept_ra` setting disabled to prevent router advertisements from the container modifying the IPv6 routing table on the LXD host.
In addition to that, the `rp_filter` on the host is set to `1` to prevent source address spoofing for IPs that the host does not know the container has.

<a id="security-audit-events"></a>

## Security events and audit logging

LXD emits [security events](../events.md#events-security) that track important security-related actions in your system. These events provide a comprehensive audit trail of authentication attempts, authorization decisions, and administrative changes. This is essential for compliance, intrusion detection, and security incident investigation.

Security events include:

- **Authentication events**: Track login attempts, token lifecycle changes, and certificate modifications
- **Authorization events**: Track permission denials and any changes to identities, groups, and their privileges.
- **Daemon lifecycle events**: Track daemon startup/shutdown and changes to monitoring configuration
- **User lifecycle events**: Track identity creation, modification, and deletion

In a production environment, you can [monitor security events with Loki](../howto/security_events.md#howto-security-events-loki) or another centralized logging system to maintain a persistent audit trail. To access security events with the CLI or REST API, consult [How to monitor security events](../howto/security_events.md#howto-security-events).

For additional logging methods, consult the [Logging](../howto/security_harden.md#howto-security-harden-logging) section in [How to harden security for LXD](../howto/security_harden.md#howto-security-harden). For details on metrics, including how to gather metrics with Prometheus, consult [How to monitor metrics](../metrics.md#metrics). You can also [set up Grafana](../howto/grafana.md#grafana) to visualize metrics and logging data.

<a id="security-cryptography"></a>

## Cryptography

LXD uses cryptographic technologies to authenticate, encrypt, and decrypt communication between servers, and to verify images copied from remote servers. For details, see [Remote API authentication](../authentication.md#authentication) and [Local and remote images](../image-handling.md#about-images), as well as the guides to common operations related to [LXD server and client](../operation.md#lxd-server) and [Images](../images.md#images).

## Related topics

How-to guides:

- [How to harden security for LXD](../howto/security_harden.md#howto-security-harden)
- [How to expose LXD to the network](../howto/server_expose.md#server-expose)
- [How to monitor security events](../howto/security_events.md#howto-security-events)

Explanation:

- [Remote API authentication](../authentication.md#authentication)
- [Local and remote images](../image-handling.md#about-images)


# index.html.md

<a id="networks"></a>

# Networking setups

There are different ways to connect your instances to the Internet. The easiest method is to have LXD create a network bridge during initialization and use this bridge for all instances, but LXD supports many different and advanced setups for networking.

## Network devices

To grant direct network access to an instance, you must assign it at least one network device, also called .
You can configure the network device in one of the following ways:

- Use the default network bridge that you set up during the LXD initialization.
  Check the default profile to see the default configuration:
  ```none
    lxc profile show default
  ```

  This method is used if you do not specify a network device for your instance.
- Use an existing network interface by adding it as a network device to your instance.
  This network interface is outside of LXD control.
  Therefore, you must specify all information that LXD needs to use the network interface.

  Use a command similar to the following:
  ```none
    lxc config device add <instance_name> <device_name> nic nictype=<nic_type> ...
  ```

  See [Type: `nic`](../reference/devices_nic.md#devices-nic) for a list of available NIC types and their configuration properties.

  For example, you could add a pre-existing Linux bridge (`br0`) with the following command:
  ```none
    lxc config device add <instance_name> eth0 nic nictype=bridged parent=br0
  ```
- [Create a managed network](../howto/network_create.md) and add it as a network device to your instance.
  With this method, LXD has all required information about the configured network, and you can directly attach it to your instance as a device:
  ```none
    lxc network attach <network_name> <instance_name> <device_name>
  ```

  See [Attach a network to an instance](../howto/network_create.md#network-attach) for more information.

<a id="managed-networks"></a>

## Managed networks

Managed networks in LXD are created and configured with the `lxc network [create|edit|set]` command.

Depending on the network type, LXD either fully controls the network or just manages an external network interface.

Note that not all [NIC types](../reference/devices_nic.md#devices-nic) are supported as network types.
LXD can only set up some of the types as managed networks.

### Fully controlled networks

<!-- Include content from [../reference/networks.md](../reference/networks.md) -->

Fully controlled networks create and manage their own network interfaces, supporting features like IP management and network ACLs, forwards, and zones.

LXD supports the following network types:

[Bridge network](../reference/network_bridge.md#network-bridge)
: <!-- Include content from [../reference/network_bridge.md](../reference/network_bridge.md) -->
  <br/>
  A network bridge creates a virtual L2 Ethernet switch that instance NICs can connect to, making it possible for them to communicate with each other and the host.
  LXD bridges can leverage underlying native Linux bridges and Open vSwitch.
  <br/>
  In LXD context, the `bridge` network type creates an L2 bridge that connects the instances that use it together into a single network L2 segment.
  This makes it possible to pass traffic between the instances.
  The bridge can also provide local DHCP and DNS.
  <br/>
  This is the default network type.

[OVN network](../reference/network_ovn.md#network-ovn)
: <!-- Include content from [../reference/network_ovn.md](../reference/network_ovn.md) -->
  <br/>
   is a software-defined networking system that supports virtual network abstraction.
  You can use it to build your own private cloud.
  See [`www.ovn.org`](https://www.ovn.org/) for more information.
  <br/>
  In LXD context, the `ovn` network type creates a logical network.
  To set it up, you must install and configure the OVN tools.
  In addition, you must create an uplink network that provides the network connection for OVN.
  As the uplink network, you should use one of the external network types or a managed LXD bridge.

### External networks

<!-- Include content from [../reference/networks.md](../reference/network_external.md) -->

External networks use interfaces that already exist. As a result, LXD has limited control over them, and LXD networking features like ACLs, forwards, and zones are not supported.

External networks mainly serve as uplink networks, providing a parent interface for connecting instances or other networks. They also specify the configuration presets applied when making those connections.

LXD supports the following external network types:

[Macvlan network](../reference/network_macvlan.md#network-macvlan)
: <!-- Include content from [../reference/network_macvlan.md](../reference/network_macvlan.md) -->
  <br/>
  Macvlan is a virtual  that you can use if you want to assign several IP addresses to the same network interface, basically splitting up the network interface into several sub-interfaces with their own IP addresses.
  You can then assign IP addresses based on the randomly generated MAC addresses.
  <br/>
  In LXD context, the `macvlan` network type provides a preset configuration to use when connecting instances to a parent macvlan interface.

[SR-IOV network](../reference/network_sriov.md#network-sriov)
: <!-- Include content from [../reference/network_sriov.md](../reference/network_sriov.md) -->
  <br/>
   is a hardware standard that allows a single network card port to appear as several virtual network interfaces in a virtualized environment.
  <br/>
  In LXD context, the `sriov` network type provides a preset configuration to use when connecting instances to a parent SR-IOV interface.

[Physical network](../reference/network_physical.md#network-physical)
: <!-- Include content from [../reference/network_physical.md](../reference/network_physical.md) -->
  <br/>
  The `physical` network type connects to an existing physical network, which can be a network interface or a bridge, and serves as an uplink network for OVN.
  <br/>
  It provides a preset configuration to use when connecting OVN networks to a parent interface.

## Recommendations

In general, if you can use a managed network, you should do so because networks are easy to configure and you can reuse the same network for several instances without repeating the configuration.

Which network type to choose depends on your specific use case.
If you choose a fully controlled network, it provides more functionality than using a network device.

As a general recommendation:

- If you are running LXD on a single system or in a public cloud, use a [Bridge network](../reference/network_bridge.md#network-bridge), possibly in connection with the [Ubuntu Fan](https://www.youtube.com/watch?v=5cwd0vZJ5bw).
- If you are running LXD in your own private cloud, use an [OVN network](../reference/network_ovn.md#network-ovn).

  #### NOTE
  OVN requires a shared L2 uplink network for proper operation.
  Therefore, using OVN is usually not possible if you run LXD in a public cloud.
- To connect an instance NIC to a managed network, use the `network` property rather than the `parent` property, if possible.
  This way, the NIC can inherit the settings from the network and you don’t need to specify the `nictype`.

## Related topics

How-to guides:

- [Networking](../networks.md#networking)

Reference:

- [Networks](../reference/networks.md#ref-networks)


# index.html.md

<a id="authorization"></a>

# Remote API authorization

When LXD is [exposed over the network](../howto/server_expose.md#server-expose) it is possible to restrict API access via two mechanisms:

- [Restricted TLS certificates](#restricted-tls-certs)
- [Fine-grained authorization](#fine-grained-authorization)

<a id="restricted-tls-certs"></a>

## Restricted TLS certificates

It is possible to restrict a [TLS client](../authentication.md#authentication-trusted-clients) to one or multiple projects.
In this case, the client will also be prevented from performing global configuration changes or altering the configuration (limits, restrictions) of the projects it’s allowed access to.

To restrict access, use [`lxc config trust edit <fingerprint>`](../reference/manpages/lxc/config/trust/edit.md#lxc-config-trust-edit-md).
Set the `restricted` key to `true` and specify a list of projects to restrict the client to.
If the list of projects is empty, the client will not be allowed access to any of them.

<a id="fine-grained-authorization"></a>

## Fine-grained authorization

It is possible to restrict [OIDC clients](../authentication.md#authentication-openid) and fine-grained TLS identities to granular actions on specific LXD resources.
For example, one could restrict a user to be able to view, but not edit, a single instance.

There are four key concepts that LXD uses to manage these fine-grained permissions:

- **Entitlements**: An entitlement encapsulates an action that can be taken against a LXD API resource type.
  Some entitlements might apply to many resource types, whereas other entitlements can only apply to a single resource type.
  For example, the entitlement `can_view` is available for all resource types, but the entitlement `can_exec` is only available for LXD resources of type `instance`.
- **Permissions**: A permission is the application of an entitlement to a particular LXD resource.
  For example, given the entitlement `can_exec` that is only defined for instances, a permission is the combination of `can_exec` and a single instance, as uniquely defined by its API URL (for example, `/1.0/instances/c1?project=foo`).
- **Identities (users)**: An identity is any authenticated party that makes requests to LXD, including TLS clients.
  When an OIDC client adds a LXD server as a remote, the OIDC client is saved in LXD as an identity.
  Permissions cannot be assigned to identities directly.
- **Groups**: A group is a collection of one or more identities.
  Identities can belong to one or more groups.
  Permissions can be assigned to groups.
  TLS clients cannot currently be assigned to groups.

<a id="permissions"></a>

### Explore permissions

To discover available permissions that can be assigned to a group, or view permissions that are currently assigned, run the following command:

```none
lxc auth permission list --max-entitlements 0
```

The entity type column displays the LXD API resource type, this value is required when adding a permission to a group.

The URL column displays the URL of the LXD API resource.

The entitlements column displays all available entitlements for that entity type.
If any groups are already assigned permissions on the API resource at the displayed URL, they are listed alongside the entitlements that they have been granted.

Some useful permissions at a glance:

- The `admin` entitlement on entity type `server` gives full access to LXD.
  This is equivalent to an unrestricted TLS client or Unix socket access.
- The `project_manager` entitlement on entity type `server` grants access to create, edit, and delete projects, and all resources belonging to those projects.
  However, this permission does not allow access to server configuration, storage pool configuration, or certificate/identity management.
- The `operator` entitlement on entity type `project` grants access to create, edit, and delete all resources belonging to the project against which the permission is granted.
  Members of a group with this permission will not be able to edit the project configuration itself.
  This is equivalent to a restricted TLS client with access to the same project.
- The `user` entitlement on entity type `instance` grants access to view an instance, pull/push files, get a console, and begin a terminal session.
  Members of a group with this entitlement cannot edit the instance configuration.

For a full list, see [Permissions](../reference/permissions.md#permissions-reference).

#### NOTE
Due to a limitation in the LXD client, if `can_exec` is granted to a group for a particular instance, members of the group will not be able to start a terminal session unless `can_view_events` is additionally granted for the parent project of the instance.
We are working to resolve this.

<a id="identities"></a>

### Explore identities

To discover available identities that can be assigned to a group, or view identities that are currently assigned, run the following command:

```none
lxc auth identity list
```

The authentication method column displays the method by which the client authenticates with LXD.

The type column displays the type of identity.
Identity types are a superset of TLS certificate types and additionally include OIDC clients.

The name column displays the name of the identity.
For TLS clients, this will be the name of the certificate.
For OIDC clients this will be the name of the client as given by the  (requested via the [profile scope](https://openid.net/specs/openid-connect-basic-1_0.html#Scopes)).

The identifier column displays a unique identifier for the identity within that authentication method.
For TLS clients, this will be the certificate fingerprint.
For OIDC clients, this will be the email address of the client.

The groups column displays any groups that are currently assigned to the identity.
Groups cannot currently be assigned to TLS clients.

#### NOTE
OIDC clients will only be displayed in the list of identities once they have authenticated with LXD.

<a id="manage-permissions"></a>

### Manage permissions

In LXD, identities cannot be granted permissions directly. Instead, identities are added to groups, and groups are granted permissions.
To create a group, run:

```none
lxc auth group create <group_name>
```

To add an identity to a group, run:

```none
lxc auth identity group add <authentication_method>/<identifier> <group_name>
```

For example, for OIDC clients:

```none
lxc auth identity group add oidc/<email_address> <group_name>
```

The identity is now a member of the group. To add permissions to the group, run:

```none
lxc auth group permission add <group_name> <entity_type> [<entity_name>] <entitlement> [<key>=<value>...]
```

Here are some examples:

- `lxc auth group permission add administrator server admin` grants members of `administrator` the `admin` entitlement on `server`.
- `lxc auth group permission add junior-dev project sandbox operator` grants members of `junior-dev` the `operator` entitlement on project `sandbox`.
- `lxc auth group permission add my-group instance c1 user project=default` grants members of `my-group` the `user` entitlement on instance `c1` in project `default`.

Some entity types require more than one supplementary argument to uniquely specify the entity.
For example, entities of type `storage_volume` and `storage_bucket` require an additional `pool=<storage_pool_name>` argument.

<a id="identity-provider-groups"></a>

### Use groups defined by the identity provider

It is common practice to manage users, roles, and groups centrally via an identity provider (IdP).
In LXD, identity provider groups allow groups that are defined by the IdP to be mapped to LXD groups.
When an OIDC client makes a request to LXD, any groups that can be extracted from the client’s identity token are mapped to LXD groups, giving the client the same effective permissions.

To configure IdP group mappings in LXD, first configure your IdP to add groups to identity and access tokens as a custom claim.
This configuration depends on your IdP.
In [<spellexception>Auth0</spellexception>](https://auth0.com/), for example, you can enable  which will add a “permissions” claim to tokens. Then, configure [automatic mapping to LXD authorization groups](../howto/oidc_auth0.md#oidc-auth0-automatic-group-mapping).
In Keycloak, you can define a [mapper](https://forum.keycloak.org/t/anyway-to-include-user-groups-into-my-jwt-token/8715) to set Keycloak groups in the token. In [Pocket ID](https://pocket-id.org/docs), you can set up [custom claims](../howto/oidc_pocket_id.md#oidc-pocket-id-automatic-group-mapping) in your admin dashboard.

Then configure LXD to extract this claim.
To do so, set the value of the [`oidc.groups.claim`](../server.md#server-oidc:oidc.groups.claim) configuration key to the value of the field name of the custom claim:

```none
lxc config set oidc.groups.claim=<claim_name>
```

LXD will then expect the identity and access tokens to contain a claim with this name.
The value of the claim must be a JSON array containing a string value for each IdP group name.
If the group names are extracted successfully, LXD will be aware of the IdP groups for the duration of the request.

Next, configure a mapping between an IdP group and a LXD group as follows:

```none
lxc auth identity-provider-group create <idp_group_name>
lxc auth identity-provider-group group add <idp_group_name> <lxd_group_name>
```

IdP groups can be mapped to multiple LXD groups, and multiple IdP groups can be mapped to the same LXD group.

#### IMPORTANT
LXD does not store the identity provider groups that are extracted from identity or access tokens.
This can obfuscate the true permissions of an identity.
For example, if an identity belongs to LXD group “foo”, an administrator can view the permissions of group “foo” to determine the level of access of the identity.
However, if identity provider group mappings are configured, direct group membership alone does not determine their level of access.
The command `lxc auth identity info` can be run by any identity to view a full list of their own effective groups and permissions as granted directly or indirectly via IdP groups.


# index.html.md

<a id="exp-csi"></a>

# The LXD CSI driver

The LXD CSI driver is an open source implementation of the [Container Storage Interface (CSI)](https://github.com/container-storage-interface/spec/blob/master/spec.md). It integrates LXD storage backends with Kubernetes.

It leverages LXD’s wide range of supported storage drivers, enabling dynamic provisioning of both local and remote volumes.
Depending on the storage pool, the CSI supports provisioning of both block and filesystem volumes.

The driver is compatible with standalone and clustered LXD deployments, including [MicroCloud](https://canonical.com/microcloud).

<a id="exp-csi-capabilities"></a>

## Storage capabilities

The LXD CSI driver supports all [Local](../reference/storage_drivers.md#storage-drivers-local), [Remote](../reference/storage_drivers.md#storage-drivers-remote), and [Shared](../reference/storage_drivers.md#storage-drivers-shared) storage drivers provided by LXD.
The table below lists its capabilities.

| Capability                | Supported       | Storage drivers                                                                                                                                                                                        | Description                                                                                                                                                                                     |
|---------------------------|-----------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Dynamic provisioning      | ✓               | [Local](../reference/storage_drivers.md#storage-drivers-local), [Remote](../reference/storage_drivers.md#storage-drivers-remote), and [Shared](../reference/storage_drivers.md#storage-drivers-shared) | Volumes are created and deleted on demand through PersistentVolumeClaims.                                                                                                                       |
| Filesystem volumes        | ✓               | [Local](../reference/storage_drivers.md#storage-drivers-local), [Remote](../reference/storage_drivers.md#storage-drivers-remote), and [Shared](../reference/storage_drivers.md#storage-drivers-shared) | Supported when the driver provides filesystem volumes.                                                                                                                                          |
| Shared filesystem volumes | - (coming-soon) | [Shared](../reference/storage_drivers.md#storage-drivers-shared)                                                                                                                                       | Allows attaching storage volume to multiple nodes simultaneously (through the use of volume access modes `ReadWriteMany` and `ReadOnlyMany`).                                                   |
| Block volumes             | ✓               | [Local](../reference/storage_drivers.md#storage-drivers-local) and [Remote](../reference/storage_drivers.md#storage-drivers-remote)                                                                    | Supported when the driver provides block volumes.                                                                                                                                               |
| Volume expansion          | ✓               | [Local](../reference/storage_drivers.md#storage-drivers-local), [Remote](../reference/storage_drivers.md#storage-drivers-remote), and [Shared](../reference/storage_drivers.md#storage-drivers-shared) | Allows increasing the storage volume capacity. Block volumes can be expanded only while offline (detached), whereas filesystem volumes can be expanded while online (attached).                 |
| Volume snapshots          | ✓               | [Local](../reference/storage_drivers.md#storage-drivers-local), [Remote](../reference/storage_drivers.md#storage-drivers-remote), and [Shared](../reference/storage_drivers.md#storage-drivers-shared) | Allows creating storage volume snapshots. This also requires snapshot custom resource definition (CRD).                                                                                         |
| Volume cloning            | ✓               | [Local](../reference/storage_drivers.md#storage-drivers-local), [Remote](../reference/storage_drivers.md#storage-drivers-remote), and [Shared](../reference/storage_drivers.md#storage-drivers-shared) | Allows using existing storage volume as a source for a new one.                                                                                                                                 |
| Topology-aware scheduling | ✓               | [Local](../reference/storage_drivers.md#storage-drivers-local)                                                                                                                                         | Access to local volumes is by default restricted to nodes on the same LXD cluster member. The driver sets topology constraints accordingly so the scheduler can place Pods on compatible nodes. |

<a id="exp-csi-architecture"></a>

## Architecture

The LXD CSI driver follows the Container Storage Interface (CSI) model.
It is deployed in Kubernetes as a set of controller and node components that interact with the Kubernetes API server, Kubelet, and the LXD API to provision and manage storage volumes.

The diagram below illustrates the main components and their interactions:

![LXD CSI driver architecture](images/csi/architecture.svg)

<a id="exp-csi-architecture-components"></a>

### Components

The LXD CSI driver primarily consists of the controller and node services.
The controller service is responsible for external volume management operations, such as creating storage volumes and attaching them to the Kubernetes nodes.
The node service, on the other hand, handles internal node operations, such as mounting attached volume to the desired Kubernetes Pod.

<a id="exp-csi-architecture-devlxd"></a>

#### LXD and DevLXD

LXD provides the storage backend for the LXD CSI driver.

The driver primarily interacts with the [DevLXD API](../dev-lxd.md#dev-lxd), which exposes LXD functionality to local processes inside an instance through the `/dev/lxd/sock` Unix socket.
In virtual machines, a LXD agent running inside the guest VM intercepts requests on this socket and delivers them to the DevLXD API over a Vsock connection, providing the same experience as in containers.

When a request is received, the DevLXD API first verifies that the caller is authorized to perform the requested operation on the target entity (for example, a storage volume).
If authorized, the corresponding handler in the main [LXD API](../rest-api.md#rest-api) is invoked to execute the operation against the configured storage backend.

<a id="exp-csi-architecture-cp"></a>

#### Control plane components

<a id="exp-csi-architecture-cp-k8s-api"></a>

##### Kubernetes API server

At the core of Kubernetes, the [API server ↗](https://kubernetes.io/docs/concepts/overview/kubernetes-api/) acts as the single source of truth for cluster state.
It stores objects such as Pods, PersistentVolumeClaims (PVCs), PersistentVolumes (PVs), and VolumeAttachments.
All CSI components, Kubelets, and controllers observe the API server for changes and reconcile state accordingly.

<a id="exp-csi-architecture-cp-controller"></a>

##### CSI controller service

The CSI controller service implements the controller-side Remote Procedure Calls (RPCs) defined by the CSI specification. It runs as a Kubernetes Deployment and communicates with the LXD API through the DevLXD socket. The controller is responsible for creating and deleting volumes, as well as attaching and detaching them from nodes.

Alongside the controller run the CSI controller sidecars, helper containers maintained by the Kubernetes CSI project. These integrate the controller with Kubernetes resources.

- `external-provisioner`: watches PVCs and PVs and invokes volume creation or deletion.
- `external-attacher`: watches VolumeAttachment objects and invokes volume attachment or detachment.
- `external-resizer`: watches for PVC updates and triggers volume expansion when user requests more storage on a PVC object.
- `livenessprobe`:  exposes an HTTP `/healthz` endpoint used by the Kubelet as a liveness probe to monitor the health of the CSI driver.

Leader election ensures that only one replica of the controller sidecars is active at a time.

<a id="exp-csi-architecture-node"></a>

#### Node components

<a id="exp-csi-architecture-node-kubelet"></a>

##### Kubelet

On every worker node, the [Kubelet ↗](https://kubernetes.io/docs/concepts/architecture/#kubelet) monitors the API server for Pods scheduled to run on that node. Before starting Pod containers, it invokes the CSI node plugin to stage and publish any required volumes.

<a id="exp-csi-architecture-node-node"></a>

##### CSI node service

The CSI node service runs as a DaemonSet on every worker node and implements the node-side RPCs of the CSI specification.
It bind-mounts volumes into Pods when requested and cleans up mount points when Pods are deleted.

Supporting the node service are the node CSI sidecars, most notably the `node-driver-registrar`, which registers the plugin with Kubelet so that it can receive volume operations.

The node service also communicates with the local DevLXD API socket to determine which LXD cluster member the node is running on.
This information is used to configure topology constraints, ensuring that the Kubernetes scheduler only places Pods on nodes that can access the required volumes, since local volumes created on one cluster member cannot be attached to another.

<a id="exp-csi-architecture-k8s-primitives"></a>

### Relation to Kubernetes primitives

The LXD CSI driver integrates directly with standard Kubernetes storage objects and translates them into LXD operations.

<a id="exp-csi-architecture-k8s-primitives-sc"></a>

#### StorageClass

A [StorageClass ↗](https://kubernetes.io/docs/concepts/storage/storage-classes/), as defined for the LXD CSI driver, represents a LXD storage pool where volumes are created and managed.
The StorageClass also defines default settings applied to every volume created with that StorageClass.
These settings cover provisioning timing, volume parameters, mount options, and reclaim behavior.
When a PersistentVolumeClaim references a StorageClass, the driver provisions the volume in the selected LXD storage pool using those settings.
Multiple StorageClasses can reference the same LXD storage pool while keeping different defaults.

<a id="exp-csi-architecture-k8s-primitives-pvc"></a>

#### PersistentVolumeClaim (PVC)

A [PVC ↗](https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims) represents a user request for storage volume.
When a PVC references a StorageClass for the LXD CSI driver, the `external-provisioner` sidecar detects it and invokes the driver’s controller over RPC to create the volume in the configured LXD storage pool.

<a id="exp-csi-architecture-k8s-primitives-pv"></a>

#### PersistentVolume (PV)

Each PVC that is successfully provisioned is bound to a [PV ↗](https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistent-volumes).
The PV contains metadata such as capacity, access mode, and an identifier managed by the driver, referencing the LXD volume.
The PV therefore serves as the Kubernetes-side representation of the LXD volume.

<a id="exp-csi-architecture-k8s-primitives-va"></a>

#### VolumeAttachment

When a volume is attached to a node, Kubernetes creates a [VolumeAttachment ↗](https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/volume-attachment-v1/) object to track the relationship between a volume and the node.
The `external-attacher` sidecar watches these objects and invokes the driver’s controller to attach or detach the volume as needed.
With the LXD CSI driver, this attaches or detaches the LXD volume to the target LXD instance.

<a id="exp-csi-architecture-k8s-primitives-vsclass"></a>

#### VolumeSnapshotClass

A [VolumeSnapshotClass ↗](https://kubernetes.io/docs/concepts/storage/volume-snapshot-classes/) is a snapshot equivalent of StorageClass.
It references a CSI driver to use when creating volume snapshots, the snapshot deletion policy, and any additional driver-specific parameters.

<a id="exp-csi-architecture-k8s-primitives-vs"></a>

#### VolumeSnapshot

A [VolumeSnapshot ↗](https://kubernetes.io/docs/concepts/storage/volume-snapshots) represents a user request for a snapshot of a specific PVC.
Each volume snapshot references a VolumeSnapshotClass and a source PVC.
The snapshot controller invokes the CSI driver to create a snapshot from a source volume, using the parameters defined in this class.

<a id="exp-csi-architecture-k8s-primitives-vsc"></a>

#### VolumeSnapshotContent

A [VolumeSnapshotContent ↗](https://kubernetes.io/docs/concepts/storage/volume-snapshots/#volume-snapshot-contents) represents the actual snapshot object created by the CSI driver.
For the LXD CSI driver, it represents a LXD volume snapshot, similar to how a PersistentVolume represents the actual LXD volume.
It stores driver-managed identifiers and metadata for the snapshot and is bound to the VolumeSnapshot that requested it.

<a id="exp-csi-lifecycle"></a>

## Life cycle

![LXD CSI driver life cycle](images/csi/lifecycle.svg)

The diagram above illustrates how a Pod with a PersistentVolumeClaim (PVC) progresses through the CSI volume life cycle.
It shows the interactions between the Kubernetes control plane, the LXD CSI driver, and the LXD storage backend.

1. An administrator creates a Pod that references a PVC.
2. The Kubernetes scheduler assigns the Pod to a specific worker node.
3. The `external-provisioner` sidecar requests volume creation from the CSI controller. If the volume is successfully created, the external-attacher similarly requests the volume to be attached to the previously selected node.
4. The request is authorized by the DevLXD API, which verifies that the desired operation is allowed to be executed on a particular LXD entity.
5. Upon successful authorization, the request is forwarded to the main LXD API.
6. The LXD API creates the requested volume in the configured storage pool.
7. The volume is attached to the node where the Pod was previously scheduled.
8. Kubelet invokes the CSI node service requesting the attached volume to be mounted into the Pod.
9. The node service bind-mounts the volume into the Pod.
10. With the volume mounted and available, Kubelet starts the Pod’s containers.

When the Pod and PVC are deleted, these steps run in reverse order.
The volume is unpublished, detached from the node, and finally deleted from the LXD storage pool.

<a id="exp-csi-security"></a>

## Security

The LXD CSI driver relies on the [DevLXD APIs](../dev-lxd.md#dev-lxd) for volume management.
These APIs are disabled by default and must be explicitly enabled on each instance that is hosting a Kubernetes node through the [`security.devlxd`](../reference/instance_options.md#instance-security:security.devlxd) and [`security.devlxd.management.volumes`](../reference/instance_options.md#instance-security:security.devlxd.management.volumes) configuration options.

DevLXD enforces project-level isolation, allowing access to LXD entities only within a project where an invoked instance is running.
As a result, each Kubernetes cluster must run inside a single LXD [project](projects.md#exp-projects).

Operations that require elevated permissions (such as creating or attaching volumes) use token-based authentication.
The token, stored as a Kubernetes Secret, identifies the caller and is checked by LXD’s [Fine-grained authorization](authorization.md#fine-grained-authorization) system.
Ownership of volumes, snapshots, and devices is tracked in the LXD configuration and ensures the identity can later manage only entities it has previously created.

## Related topics

How-to guides:

- [How to use the LXD CSI driver with Kubernetes](../howto/storage_csi.md#howto-storage-csi)

Reference:

- [LXD CSI driver reference](../reference/driver_csi.md#ref-csi)


# index.html.md

<a id="exp-clusters"></a>

# Clusters


            <p class="youtube_link">
              <a href="https://www.youtube.com/watch?v=nrOR6yaO_MY" target="_blank">
                <span title="Deep dive into LXD clustering" class="play_icon">▶</span>
                <span title="Deep dive into LXD clustering">Watch on YouTube</span>
              </a>
            </p>
        
To spread the total workload over several servers, LXD can be run in clustering mode.
In this scenario, any number of LXD servers share the same distributed database that holds the configuration for the cluster members and their instances.
The LXD cluster can be managed uniformly using the [`lxc`](../reference/manpages/lxc.md#lxc-md) client or the REST API.

This feature was introduced as part of the [`clustering`](../api-extensions.md#clustering) API extension and is available since LXD 3.0.

<a id="clustering-members"></a>

## Cluster members

A LXD cluster consists of one bootstrap server and at least two further cluster members.
It stores its state in a [distributed database](../database.md), which is a [Dqlite](https://canonical.com/dqlite) database replicated using the Raft algorithm.

While you could create a cluster with only two members, it is strongly recommended that the number of cluster members be at least three.
With this setup, the cluster can survive the loss of at least one member and still be able to establish quorum for its distributed state.

When you create the cluster, the Dqlite database runs on only the bootstrap server until a third member joins the cluster.
Then both the second and the third server receive a replica of the database.

See [How to form a cluster](../howto/cluster_form.md#cluster-form) for more information.

<a id="clustering-member-roles"></a>

### Member roles

In a cluster with three members, all members replicate the distributed database that stores the state of the cluster.
If the cluster has more members, only some of them replicate the database.
The remaining members have access to the database, but don’t replicate it.

At each time, there is an elected cluster leader that monitors the health of the other members.

Each member that replicates the database has either the role of a *voter* or of a *stand-by*.
If the cluster leader goes offline, one of the voters is elected as the new leader.
If a voter member goes offline, a stand-by member is automatically promoted to voter.
The database (and hence the cluster) remains available as long as a majority of voters is online.

The following roles can be assigned to LXD cluster members.
Automatic roles are assigned by LXD itself and cannot be modified by the user.

| Role               | Automatic   | Description                                                                                                                                                                             |
|--------------------|-------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `database-voter`   | yes         | Voting member of the distributed database                                                                                                                                               |
| `database-leader`  | yes         | Current leader of the distributed database                                                                                                                                              |
| `database-standby` | yes         | Stand-by (non-voting) member of the distributed database                                                                                                                                |
| `control-plane`    | no          | Eligible to participate in Raft as voter, standby, or leader; when control plane mode is active, members without this role are assigned as spares and excluded from automatic promotion |
| `ovn-chassis`      | no          | Uplink gateway candidate for OVN networks                                                                                                                                               |

The default number of voter members ([`cluster.max_voters`](../server.md#server-cluster:cluster.max_voters)) is three.
The default number of stand-by members ([`cluster.max_standby`](../server.md#server-cluster:cluster.max_standby)) is two.
With this configuration, your cluster will remain operational as long as you switch off at most one voting member at a time.

<a id="clustering-control-plane"></a>

#### Control plane mode

The `control-plane` role is optional and is not assigned by default.

It designates which members are eligible for database roles (voter, standby, leader), enabling safe auto-scaling with fixed database members and dynamic worker members.

Control plane mode activates when at least 3 members have the role assigned.
Once active, only members with the `control-plane` role can participate in Raft and be assigned as voters, standbys, or the leader.
Members without the `control-plane` role are automatically assigned the `RAFT_SPARE` role and are excluded from automatic promotion to database roles.
Spare members can still run instances and act as “worker” members for hosting workloads.

You can assign the `control-plane` role to more members than [`cluster.max_voters`](../server.md#server-cluster:cluster.max_voters) to create a pool of eligible candidates.

For example, if you assign `control-plane` to 5 members when `cluster.max_voters` is 3, all 5 members are eligible for database roles, but only 3 will be promoted to voters based on the configuration.

If no cluster members have the `control-plane` role assigned (the default), or if fewer than 3 members have the role, all members are eligible for automatic promotion to database roles.

When control plane mode is active, members with the `control-plane` role also act as event hubs for internal LXD events.
If control plane mode is inactive, the cluster uses full-mesh event connectivity.

See [Use control plane mode](../howto/cluster_manage.md#cluster-manage-control-plane) for instructions on using the `control-plane` role.

<a id="clustering-offline-members"></a>

#### Offline members and fault tolerance

If a cluster member is down for more than the configured offline threshold, its status is marked as offline.
In this case, no operations are possible on this member, and neither are operations that require a state change across all members.

As soon as the offline member comes back online, operations are available again.

If the member that goes offline is the leader itself, the other members will elect a new leader.

If you can’t or don’t want to bring the server back online, you can [delete it from the cluster](../howto/cluster_manage.md#cluster-manage-delete-members).

You can tweak the amount of seconds after which a non-responding member is considered offline by setting the [`cluster.offline_threshold`](../server.md#server-cluster:cluster.offline_threshold) configuration.
The default value is 20 seconds.
The minimum value is 10 seconds.

To automatically [evacuate](../howto/cluster_manage.md#cluster-evacuate) instances from an offline member, set the [`cluster.healing_threshold`](../server.md#server-cluster:cluster.healing_threshold) configuration to a non-zero value.

See [How to recover a cluster](../howto/cluster_recover.md#cluster-recover) for more information.

<a id="clustering-failure-domains"></a>

#### Failure domains

You can use failure domains to indicate which cluster members should be given preference when assigning roles to a cluster member that has gone offline.
For example, if a cluster member that currently has the `database-voter` role is shut down and control plane mode is active, LXD tries to promote another `control-plane` cluster member in the same failure domain to voter, if one is available. If no members have the `control-plane` role assigned (the default), any suitable member in the same failure domain can be promoted instead.

See [Manage failure domains](../howto/cluster_manage.md#cluster-manage-failure-domains) for more information.

<a id="clustering-member-config"></a>

### Member configuration

LXD cluster members are generally assumed to be identical systems.
This means that all LXD servers joining a cluster must have an identical configuration to the bootstrap server, in terms of storage pools and networks.

To accommodate things like slightly different disk ordering or network interface naming, there is an exception for some configuration options related to storage and networks, which are member-specific.

When such settings are present in a cluster, any server that is being added must provide a value for them.
Most often, this is done through the interactive `lxd init` command, which asks the user for the value for a number of configuration keys related to storage or networks.

Those settings typically include:

- The source device and size (quota) for a storage pool
- The name for a ZFS zpool, LVM thin pool or LVM volume group
- External interfaces and BGP next-hop for a bridged network
- The name of the parent network device for managed `physical` or `macvlan` networks

See [How to configure storage for a cluster](../howto/cluster_config_storage.md#howto-cluster-storage) and [How to configure networks for a cluster](../howto/cluster_config_networks.md#cluster-config-networks) for more information.

If you want to look up the questions ahead of time (which can be useful for scripting), query the `/1.0/cluster` API endpoint.
This can be done through `lxc query /1.0/cluster` or through other API clients.

## Images

By default, LXD replicates images on as many cluster members as there are database members.
This typically means up to three copies within the cluster.

You can increase that number to improve fault tolerance and the likelihood of the image being locally available.
To do so, set the [`cluster.images_minimal_replica`](../server.md#server-cluster:cluster.images_minimal_replica) configuration.
The special value of `-1` can be used to have the image copied to all cluster members.

<a id="cluster-groups"></a>

## Cluster groups

In a LXD cluster, you can add members to cluster groups.
You can use these cluster groups to launch instances on a cluster member that belongs to a subset of all available members.
For example, you could create a cluster group for all members that have a GPU and then launch all instances that require a GPU on this cluster group.

By default, all cluster members belong to the `default` group.

See [How to set up cluster groups](../howto/cluster_groups.md#howto-cluster-groups) and [Launch an instance on a specific cluster member](../howto/cluster_manage_instance.md#cluster-target-instance) for more information.

<a id="exp-cluster-links"></a>

## Cluster links

Cluster links enable authenticated communication between separate LXD clusters by establishing a bidirectional trust relationship using mutual TLS certificates.

### How cluster links work

1. **Trust establishment**: Each cluster presents its certificate to the other, establishing mutual trust.
2. **Identity creation**: LXD automatically creates a special identity for each linked cluster with type `Cluster link certificate`.
3. **Permission control**: The linked cluster’s permissions are managed through LXD’s [Fine-grained authorization](authorization.md#fine-grained-authorization) system.
4. **Secure communication**: All communication between clusters uses TLS encryption with certificate verification.

#### Connection process

Both clusters coordinate to create a link.

1. **Cluster A** creates a pending cluster link and generates a trust token.
2. **Cluster B** uses this token to establish the connection and send its certificate back.
3. Both clusters validate certificates and activate the bidirectional link.
4. The link becomes active and both clusters can communicate.

For more information, see: [How to create cluster links](../howto/cluster_links_create.md#howto-cluster-links-create).

<a id="exp-clusters-links-identity"></a>

### Identity management for cluster links

When you create a cluster link, LXD automatically creates an identity for the linked cluster. This identity is of type `Cluster link certificate` and is used to authenticate that cluster. These identities are managed using [Fine-grained authorization](authorization.md#fine-grained-authorization).

The identity can be in one of two states:

- **Pending**: When a trust token is generated but the link hasn’t been activated yet.
- **Active**: When both clusters have exchanged certificates and the link is operational.

#### Security considerations

- **Certificate validation**: All connections verify certificate fingerprints.
- **Fine-grained permissions**: Linked clusters can be granted specific entitlements (for example, only backup operations).
- **Identity isolation**: Each cluster link gets its own identity that can be managed independently.
- **Group membership**: Cluster link identities can be assigned to authentication groups for bulk permission management.

Together, these controls limit the blast radius of a compromised link by enforcing mutual authentication and least-privilege access. They also make it possible to revoke a single link’s access without impacting other cluster-to-cluster trust relationships.

#### Cluster link member status

A cluster link member can have one of the following statuses. You can see member status with `lxc cluster link info` (while `lxc cluster link list` shows the link identity status and link type); see [View cluster links](../howto/cluster_links_manage.md#howto-cluster-links-view).

- `ACTIVE`: Reachable and authenticated. The link is usable for requests according to the [entitlements](authorization.md#fine-grained-authorization) you granted.
- `UNAUTHENTICATED`: Reachable but not authenticated. The remote cluster cannot use the link yet; resolve the trust exchange before relying on it.
- `UNREACHABLE`: Not reachable. Requests that depend on the link will fail until connectivity is restored or the remote cluster is online.

<a id="clustering-instance-placement"></a>

## Automatic placement of instances

In a cluster setup, each instance lives on one of the cluster members.
When you launch an instance, you can target it to a specific cluster member, to a cluster group or have LXD automatically assign it to a cluster member.

By default, the automatic assignment picks the cluster member that has the lowest number of instances.
If several members have the same amount of instances, one of the members is chosen at random.

However, you can control this behavior with the [`scheduler.instance`](../reference/cluster_member_config.md#cluster-cluster:scheduler.instance) configuration option:

- If `scheduler.instance` is set to `all` for a cluster member, this cluster member is selected for an instance if:
  - The instance is created without `--target` and the cluster member has the lowest number of instances.
  - The instance is targeted to live on this cluster member.
  - The instance is targeted to live on a member of a cluster group that the cluster member is a part of, and the cluster member has the lowest number of instances compared to the other members of the cluster group.
- If `scheduler.instance` is set to `manual` for a cluster member, this cluster member is selected for an instance if:
  - The instance is targeted to live on this cluster member.
- If `scheduler.instance` is set to `group` for a cluster member, this cluster member is selected for an instance if:
  - The instance is targeted to live on this cluster member.
  - The instance is targeted to live on a member of a cluster group that the cluster member is a part of, and the cluster member has the lowest number of instances compared to the other members of the cluster group.

<a id="exp-clusters-placement"></a>

### Placement groups

Placement groups provide declarative control over how instances are distributed across cluster members.
They define both a **policy** (how instances should be distributed) and a **rigor** (how strictly the policy is enforced).

Placement groups are project-scoped resources, which means different projects can have placement groups with the same name without conflict.

See [How to use placement groups](../howto/cluster_placement_groups.md#cluster-placement-groups) for usage instructions and [Placement group configuration](../reference/placement_groups.md#ref-placement-groups) for reference documentation.

<a id="clusters-high-availability"></a>

## High availability

Clusters provide two types of high availability (HA):

- Control plane HA (ensuring that clients can always access the cluster)
- Data plane HA (ensuring that workloads continue to run)

<a id="clusters-high-availability-control"></a>

### High availability of the control plane (client access)

Each cluster member can [expose an API endpoint](../howto/server_expose.md#server-expose) through its [`core.https_address`](../server.md#server-core:core.https_address). Through this access point, a remote client can communicate with any cluster member in multiple ways:

- Through the API (see [Remote API authentication](../authentication.md#authentication) and [REST API](../rest-api.md#rest-api))
- Through the [LXD web UI client](../howto/access_ui.md#access-ui)
- By setting up [remote servers](../remotes.md#remotes) for CLI access

Because the cluster database is distributed, access to any member gives you access to the entire control plane. If one server goes down, you can still manage the cluster through the other members. This provides the basis for control plane HA.

The limitation is that on the client side, you must either manually switch to another member’s access point if your chosen server is unavailable, or implement your own client-side logic to cycle through a list of access points.

For a single, highly available access point to the control plane, you can add on a routing service that configures a virtual IP. See our how-to guide: [How to set up a highly available virtual IP for clusters](../howto/cluster_vip.md#howto-cluster-vip).

<a id="clusters-high-availability-data"></a>

### High availability of the data plane (workloads)

LXD clusters enable HA of workloads (instances) in multiple ways:

Cluster evacuation
: Instances can be manually evacuated from one cluster member to another, providing planned high availability during maintenance. This includes live migration for virtual machines. See: [Evacuate a cluster member](../howto/cluster_manage.md#cluster-evacuate).

Cluster healing
: If a cluster member fails and [`cluster.healing_threshold`](../server.md#server-cluster:cluster.healing_threshold) is set, it automatically restarts instances on that member on a healthy member of the cluster. See: [Cluster healing](../howto/cluster_manage.md#cluster-healing).

Virtual networking
: On clusters using [OVN networking](../reference/network_ovn.md#network-ovn), logical switches/routers are distributed across the cluster. This means that instance NICs remain reachable even if the server hosting one OVN chassis goes offline.

Storage redundancy
: On clusters using Ceph for storage, if a disk or cluster member fails, the data is still available elsewhere in the Ceph cluster.

Shared storage
: Volumes using the [Ceph RBD](../reference/storage_ceph.md#storage-ceph) and [CephFS](../reference/storage_cephfs.md#storage-cephfs) storage drivers are accessible from all cluster members. If the member hosting an instance fails, its volumes can be reattached to another member.

## Related topics

How-to guides:

- [Clustering](../clustering.md#clustering)

Reference:

- [Clusters](../reference/clusters.md#ref-clusters)


# index.html.md

<a id="instance-config"></a>

# Instance configuration

The instance configuration consists of different categories:

Instance properties
: Instance properties are specified when the instance is created.
  They include, for example, the instance name and architecture.
  Some of the properties are read-only and cannot be changed after creation, while others can be updated by [setting their property value](../howto/instances_configure.md#instances-configure-properties) or [editing the full instance configuration](../howto/instances_configure.md#instances-configure-edit).
  <br/>
  In the YAML configuration, properties are on the top level.
  <br/>
  See [Instance properties](../reference/instance_properties.md#instance-properties) for a reference of available instance properties.

Instance options
: Instance options are configuration options that are related directly to the instance.
  They include, for example, startup options, security settings, hardware limits, kernel modules, snapshots and user keys.
  These options can be specified as key/value pairs during instance creation (through the `--config key=value` flag).
  After creation, they can be configured with the [`lxc config set`](../reference/manpages/lxc/config/set.md#lxc-config-set-md) and [`lxc config unset`](../reference/manpages/lxc/config/unset.md#lxc-config-unset-md) commands.
  <br/>
  In the YAML configuration, options are located under the `config` entry.
  <br/>
  See [Instance options](../reference/instance_options.md#instance-options) for a reference of available instance options, and [Configure instance options](../howto/instances_configure.md#instances-configure-options) for instructions on how to configure the options.

Instance devices
: Instance devices are attached to an instance.
  They include, for example, network interfaces, mount points, USB and GPU devices.
  Devices are usually added after an instance is created with the [`lxc config device add`](../reference/manpages/lxc/config/device/add.md#lxc-config-device-add-md) command, but they can also be added to a profile or a YAML configuration file that is used to create an instance.
  <br/>
  Each type of device has its own specific set of options, referred to as *instance device options*.
  <br/>
  In the YAML configuration, devices are located under the `devices` entry.
  <br/>
  See [Devices](../reference/devices.md#devices) for a reference of available devices and the corresponding instance device options, and [Configure devices](../howto/instances_configure.md#instances-configure-devices) for instructions on how to add and configure instance devices.

## Related topics

How-to guides:

- [Instances](../instances.md#instances)

Explanation:

- [Instance types in LXD](instances.md#expl-instances)


# index.html.md

<a id="exp-storage"></a>

# Storage pools, volumes, and buckets

LXD stores its data in storage pools, divided into storage volumes of different content types (like images or instances).
You could think of a storage pool as the disk that is used to store data, while storage volumes are different partitions on this disk that are used for specific purposes.

In addition to storage volumes, there are storage buckets, which use the [Amazon](https://docs.aws.amazon.com/AmazonS3/latest/API/Welcome.html)  protocol.
Like storage volumes, storage buckets are part of a storage pool.

<a id="storage-pools"></a>

## Storage pools

During initialization, LXD prompts you to create a first storage pool.
If required, you can create additional storage pools later (see [Create a storage pool](../howto/storage_pools.md#howto-storage-pools-create)).

Each storage pool uses a storage driver.
The following storage drivers are supported:

- [Directory - `dir`](../reference/storage_dir.md#storage-dir)
- [Btrfs - `btrfs`](../reference/storage_btrfs.md#storage-btrfs)
- [LVM - `lvm`](../reference/storage_lvm.md#storage-lvm)
- [ZFS - `zfs`](../reference/storage_zfs.md#storage-zfs)
- [Ceph RBD - `ceph`](../reference/storage_ceph.md#storage-ceph)
- [CephFS - `cephfs`](../reference/storage_cephfs.md#storage-cephfs)
- [Ceph Object - `cephobject`](../reference/storage_cephobject.md#storage-cephobject)
- [Dell PowerFlex - `powerflex`](../reference/storage_powerflex.md#storage-powerflex)
- [Dell PowerStore - `powerstore`](../reference/storage_powerstore.md#storage-powerstore)
- [Pure Storage - `pure`](../reference/storage_pure.md#storage-pure)
- [HPE Alletra - `alletra`](../reference/storage_alletra.md#storage-alletra)

See the following how-to guides for additional information:

- [How to manage storage pools](../howto/storage_pools.md#howto-storage-pools)
- [How to create an instance in a specific storage pool](../howto/storage_create_instance.md#howto-storage-create-instance)

<a id="storage-location"></a>

### Data storage location

Where the LXD data is stored depends on the configuration and the selected storage driver.
Depending on the storage driver that is used, LXD can either share the file system with its host or keep its data separate.

| Storage driver   | Shared with the host   | Dedicated disk/partition   | Loop disk   | Remote storage   |
|------------------|------------------------|----------------------------|-------------|------------------|
| Directory        | ✓                      | -                          | -           | -                |
| Btrfs            | ✓                      | ✓                          | ✓           | -                |
| LVM              | -                      | ✓                          | ✓           | -                |
| ZFS              | ✓                      | ✓                          | ✓           | -                |
| Ceph (all)       | -                      | -                          | -           | ✓                |
| Dell PowerFlex   | -                      | -                          | -           | ✓                |
| Dell PowerStore  | -                      | -                          | -           | ✓                |
| Pure Storage     | -                      | -                          | -           | ✓                |
| HPE Alletra      | -                      | -                          | -           | ✓                |

#### Shared with the host

Sharing the file system with the host is usually the most space-efficient way to run LXD.
In most cases, it is also the easiest to manage.

This option is supported for the `dir` driver, the `btrfs` driver (if the host is Btrfs and you point LXD to a dedicated sub-volume) and the `zfs` driver (if the host is ZFS and you point LXD to a dedicated dataset on your zpool).

#### Dedicated disk or partition

Having LXD use an empty partition on your main disk or a full dedicated disk keeps its storage completely independent from the host.

This option is supported  for the `btrfs` driver, the `lvm` driver and the `zfs` driver.

#### Loop disk

LXD can create a loop file on your main drive and have the selected storage driver use that.
This method is functionally similar to using a disk or partition, but it uses a large file on your main drive instead.
This means that every write must go through the storage driver and your main drive’s file system, which leads to decreased performance.

The loop files reside in `/var/snap/lxd/common/lxd/disks/` if you are using the snap, or in `/var/lib/lxd/disks/` otherwise.

Loop files usually cannot be shrunk.
They will grow up to the configured limit, but deleting instances or images will not cause the file to shrink.
You can increase their size (quota) though; see [Resize a storage pool](../howto/storage_pools.md#howto-storage-pools-resize).

#### Remote storage

The `ceph`, `cephfs` and `cephobject` drivers store the data in a completely independent Ceph storage cluster that must be set up separately.
The same applies to the `powerflex`, `pure` and `alletra` drivers.

<a id="storage-default-pool"></a>

### Default storage pool

While a storage pool named ‘default’ may be created during initial setup, the name carries no special significance — no pool is automatically used by default across all projects.

When you create a storage volume, you must specify the storage pool to use.

When LXD automatically creates a storage volume during instance creation, it uses the storage pool that is configured for the instance.
This configuration can be set in either of the following ways:

- Directly on an instance: [`lxc launch <image> <instance_name> --storage <storage_pool>`](../reference/manpages/lxc/launch.md#lxc-launch-md)
- Through a profile: [`lxc profile device add <profile_name> root disk path=/ pool=<storage_pool>`](../reference/manpages/lxc/profile/device/add.md#lxc-profile-device-add-md) and [`lxc launch <image> <instance_name> --profile <profile_name>`](../reference/manpages/lxc/launch.md#lxc-launch-md)
- Through the default profile

In a profile, the storage pool to use is defined by the pool for the root disk device:

```yaml
  root:
    type: disk
    path: /
    pool: default
```

In the default profile, this pool is set to the storage pool that was created during initialization.

<a id="storage-volumes"></a>

## Storage volumes


            <p class="youtube_link">
              <a href="https://www.youtube.com/watch?v=dvQ111pbqtk" target="_blank">
                <span title="Custom storage volumes in LXD" class="play_icon">▶</span>
                <span title="Custom storage volumes in LXD">Watch on YouTube</span>
              </a>
            </p>
        
When you create an instance, LXD automatically creates the required storage volumes for it.
You can create additional storage volumes.

See the following how-to guides for additional information:

- [How to manage storage volumes](../howto/storage_volumes.md#howto-storage-volumes)
- [How to move or copy storage volumes](../howto/storage_move_volume.md#howto-storage-move-volume)
- [How to back up custom storage volumes](../howto/storage_backup_volume.md#howto-storage-backup-volume)

<a id="storage-volume-types"></a>

### Storage volume types

Storage volumes can be of the following types:

`container`/`virtual-machine`
: LXD automatically creates one of these storage volumes when you launch an instance.
  It is used as the root disk for the instance and is destroyed when the instance is deleted.
  <br/>
  The storage pool can be explicitly specified by providing the `--storage` flag to the [launch command](../reference/manpages/lxc/launch.md#lxc-launch-md).
  If no pool or profile is specified, LXD uses the storage pool of the default profile’s root disk device.

`image`
: LXD automatically creates one of these storage volumes when it unpacks an image to launch one or more instances from it.
  You can delete it after the instance has been created.
  If you do not delete it manually, it is deleted automatically ten days after it was last used to launch an instance.
  <br/>
  The image storage volume is created in the same storage pool as the instance storage volume, and only for storage pools that use a [storage driver](../reference/storage_drivers.md#storage-drivers) that supports optimized image storage.

`custom`
: You can add one or more custom storage volumes to hold data that you want to store separately from your instances.
  Custom storage volumes of content type `filesystem` or `iso` can be shared between instances, and they are retained until you delete them.
  <br/>
  You can also use custom storage volumes to hold your backups or images.
  <br/>
  You must specify the storage pool for the custom volume when you create it.

<a id="storage-content-types"></a>

### Content types

Each storage volume uses one of the following content types:

`filesystem`
: This content type is used for containers and container images.
  It is the default content type for custom storage volumes.
  <br/>
  Custom storage volumes of content type `filesystem` can be attached to both containers and virtual machines, and they can be shared between instances.

`block`
: This content type is used for virtual machines and virtual machine images.
  You can create a custom storage volume of type `block` by using the `--type=block` flag.
  <br/>
  Custom storage volumes of content type `block` can only be attached to virtual machines.
  By default, they can only be attached to one instance at a time, because simultaneous access can lead to data corruption.
  Sharing custom storage volumes of content type `block` is made possible through the usage of the `security.shared` configuration key.

`iso`
: This content type is used for custom ISO volumes.
  A custom storage volume of type `iso` can only be created by importing an ISO file using [`lxc storage volume import`](../reference/manpages/lxc/storage/volume/import.md#lxc-storage-volume-import-md) or by copying another volume.
  <br/>
  Custom storage volumes of content type `iso` can only be attached to virtual machines.
  They can be attached to multiple machines simultaneously as they are always read-only.

<a id="storage-buckets"></a>

## Storage buckets


            <p class="youtube_link">
              <a href="https://www.youtube.com/watch?v=T1EeXPrjkEY" target="_blank">
                <span title="LXD's S3 API" class="play_icon">▶</span>
                <span title="LXD's S3 API">Watch on YouTube</span>
              </a>
            </p>
        
Storage buckets provide object storage functionality via the S3 protocol.

They can be used in a way that is similar to custom storage volumes.
However, unlike storage volumes, storage buckets are not attached to an instance.
Instead, applications can access a storage bucket directly using its URL.

Each storage bucket is assigned one or more access keys, which the applications must use to access it.

Storage buckets must be located on [object storage backend](../reference/storage_drivers.md#storage-drivers-object) pools. For Ceph Object storage buckets, the [RADOS Gateway](../howto/storage_pools.md#howto-storage-pools-ceph-requirements-radosgw) configured on the Ceph cluster acts as an S3 interface.

See the following how-to guide for additional information:

- [How to manage storage buckets](../howto/storage_buckets.md#howto-storage-buckets)

## Related topics

How-to guides:

- [Storage](../storage.md#storage)

Reference:

- [Storage drivers](../reference/storage_drivers.md#storage-drivers)


# index.html.md

<a id="ref-release-notes-6-7"></a>

# LXD 6.7 release notes

This is a [feature release](../releases-snap.md#ref-releases-feature) and is not recommended for production use.

<a id="ref-release-notes-6-7-highlights"></a>

## Highlights

This section highlights new and improved features in this release.

### AMD GPU CDI support

LXD now supports AMD GPU passthrough for containers using the AMD CDI container-toolkit bundled in the snap package.

An AMD GPU device can be added to an instance using the command:

```default
lxc config device add <instance_name> <device_name> gpu gputype=physical id=amd.com/gpu=0
```

- Documentation: [gputype: physical](../devices_gpu.md#gpu-physical)
- API extension: [gpu_cdi_amd](../../api-extensions.md#extension-gpu-cdi-amd)

### Improved VM GPU passthrough support with major new QEMU and EDK2 versions

As we approach the next LXD LTS release the snap package has been updated with QEMU 10.2 and EDK2 firmware 2025.02.
These represent significant version increases from the previous QEMU 8.2.2 and EDK2 2023.11.

In particular VM GPU device passthrough now offers increased compatibility due to dynamic MMIO window size support being enabled.

### Simplified initial access to the LXD UI

The `lxd init` command now offers the option to generate an initial access link for the UI during initialization.

This initial access URL can be used to directly access the LXD UI as an admin user for 24 hours, after which time the URL stops working.

The intention is that this initial access can be used to quickly get started with LXD UI and allows for setting up permanent authentication methods such as [Permanent UI access using browser certificate](../../howto/access_ui.md#access-ui-setup-certificate) or [OpenID Connect authentication](../../authentication.md#authentication-openid).

- Documentation: [UI access using initial link](../../howto/access_ui.md#access-ui-setup-initial-access-link)

### Storage pool database recovery support for clusters

As part of the database recovery process it might be necessary to scan existing storage pools previously created by LXD that still exist on the storage device.
Previously this was only possible for standalone LXD servers by using the `lxd recover` tool.

We have now re-worked the database disaster recovery process to support LXD clusters.
As part of this storage pools need to be re-created in the LXD database before running the `lxd recover` tool.
For storage pools that still exist on the storage device a new `source.recover` option is available that allows creating the storage pool database record without modifying the data on the storage device.

Previously this was only partially possible for some of the drivers (e.g. by using `lvm.vg.force_reuse`), but not directly supported.
The new pool `source.recover` configuration key can be set per cluster member to allow reuse of an existing pool `source`.

The `source.recover` option does not allow reusing the same source for multiple storage pools, however the LVM storage driver has the specific `lvm.vg.force_reuse` configuration key for this purpose.

- Documentation: [How to recover instances in case of disaster](../../howto/disaster_recovery.md#disaster-recovery)
- API extension: [storage_source_recover](../../api-extensions.md#extension-storage-source-recover)

### Forced instance deletion through API

This adds support for a `force` query parameter to the `DELETE /1.0/instances/{name}` endpoint. When set, running instances will be forcibly stopped before deletion.

This is now supported by the `lxc` CLI, rather than previously performing a force stop API call followed by a delete API call.

- API extension: [instance_force_delete](../../api-extensions.md#extension-instance-force-delete)

### Bearer authentication method

A new identity type `bearer` has been added that allows authentication with the LXD API using bearer tokens.

If applicable, the endpoint `/1.0/auth/identities/current` now also exposes the credential expiration time.
The `expires_at` field is set when the current identity is trusted and the authentication method is either `bearer` or `tls`.
In these cases, it reports the expiration time of the bearer token or the TLS certificate, respectively.

- Documentation: [Bearer token authentication](../../authentication.md#authentication-bearer)
- API extension: [auth_bearer](../../api-extensions.md#extension-auth-bearer-lxd)

### VM bus port limits

There is now a [`limits.max_bus_ports`](../instance_options.md#instance-resource-limits:limits.max_bus_ports) configuration key for virtual machines.
This option controls the maximum allowed number of user configurable devices that require a dedicated PCI/PCIe bus port.
This limit includes both the devices attached before the instance start and the devices hotplugged when the instance is running.
When the limit is set higher than the number of bus ports required at VM start time then the remainder of ports are usable for hot-plugging devices.

This limit was introduced to avoid the previous behaviour where 8 spare hot-plugging ports were added to VMs at start time.
This was non-deterministic as after hot-plugging up to the spare number of ports and then rebooting the VM a further 8 more spare ports would be added, which eventually could lead to the guest OS not being bootable.

This new setting allows control over how many bus ports are added to the VM.

- API extension: [vm_limits_max_bus_ports](../../api-extensions.md#extension-vm-limits-max-bus-ports)

### Optimized instance state field retrieval

Added support for selective recursion of state fields to speed up querying for instances in circumstances where not all state information is required.

The API now supports selective state field fetching using semicolon-separated syntax in the `recursion` parameter:

* `recursion=2;fields=state.disk` - Fetch only disk information
* `recursion=2;fields=state.network` - Fetch only network information
* `recursion=2;fields=state.disk,state.network` - Fetch both disk and network
* `recursion=2;fields=` - Fetch no expensive state fields (disk and network skipped)
* `recursion=2` - Fetch all fields (default behavior)

The `lxc list` command now automatically optimizes queries based on requested columns.

- API extension: [instances_state_selective_recursion](../../api-extensions.md#extension-instances-state-selective-recursion)

### Container swap reporting on ZFS in `/proc/meminfo`

An updated LXCFS version has been bundled in the snap package that now allows a container’s swap usage on ZFS to be reported in the container’s `/proc/meminfo` file.

### `amd64v3` architecture variant support

Added support for running images built for the `amd64v3` architecture variant. Such optimized images are currently available for the upcoming release of Ubuntu Resolute.

## UI updates

This release includes significant improvements and new features across networking, instances, clustering, storage, authentication, and overall user experience in the LXD UI.

### Placement group management

Full management support for **placement groups** has been added.
You can now create, edit, delete, and manage placement groups directly in the UI, improving workload distribution and cluster-aware placement of instances.

### Instance console and usability improvements

Major improvements were made to the instance console and interaction model:

- Clipboard sync between desktop VM console and host OS (including Windows guests)
- Allow ALT and CTRL keys in console
- Proper numpad key handling
- Better graphic console scaling on narrow layouts
- Prevent spurious connection close errors when leaving console tabs

Overall, console reliability and UX are significantly improved.

### NIC device configuration UX improvements

Enhanced NIC device configuration for instances and profiles:

- Move NIC device edit mode into side panel
- Revamp NIC read mode
- Added UI support for static IP management
- Support for ACLs and ACL default actions on instance NICs

This provides more reliable and user-friendly network configuration.

### Rich chips and rich tooltips

The UI now includes expanded **rich chips** and **rich tooltips** across multiple entities:

- Instances
- Profiles
- Networks
- Projects
- Cluster members
- Storage pools

This improves discoverability and provides more contextual information.

### Cluster improvements

- Display total memory and CPU limits correctly across clusters
- Show memory information for stand-alone servers
- Add memory column to cluster member list
- Ensure partial network lists are shown when one cluster member is down

These enhancements improve cluster visibility and resilience in degraded scenarios.

### Error screens harmonization

All “Not found” and error screens were harmonized for consistency, improving UX coherence across the application.

### Cloud-init full-screen editor

The Cloud-init form now supports a full-screen editor mode, making large configuration editing significantly easier.

### Storage improvements

#### Migrate storage volumes between cluster members

The UI now supports migrating storage volumes to another cluster member, improving cluster flexibility and maintenance workflows.

#### Updated storage visuals

Storage pools, volumes, and buckets now use updated icons for better clarity.

### Force delete and protected instance handling

Instance and project deletion flows were improved:

- Support to force stop and delete running or frozen instances
- Added project force delete, also showing all contained entities that will be deleted

These updates make destructive actions clearer and more robust.

### Authentication and identity flow improvements

- Improved first user access flow
- Improved identity creation modal and validation

This strengthens onboarding and identity configuration clarity.

### Network and IPAM UI refinements

- Optimized column widths for IPAM and network leases
- Improved retry logic for network API requests
- Better handling when editing networks on localhost
- Ensure correct link generation for network forwards

These changes improve reliability and layout clarity in networking workflows.

### Instance UX refinements

Numerous refinements improve instance workflows:

- Highlight active configuration sections
- Allow ISO attach/detach while powered off
- Improved image selection handling
- Stable instance sorting during migration
- Adjust spacing in detail panel

These refinements create a more predictable and polished instance management experience.

### Local Network peering and IPAM improvements

The UI now supports management of **Local Network peering for OVN networks**.
Additionally, IPAM and network lease pages now link directly to NIC static IP configuration.

### Build and routing improvements

- Improved handling of relative URLs in deployments with a load balancer or reverse proxy
- Ensured correct root path handling across UI links
- Updated routing and internal dependency structure

<a id="ref-release-notes-6-7-bugfixes"></a>

## Bug fixes

The following bug fixes are included in this release.

- [<spellexception>Authenticated host RCE via unsanitized compression_algorithm in image and backup API endpoints (CVE-2026-28384)</spellexception>](https://github.com/canonical/lxd/security/advisories/GHSA-4rmf-rcp8-2r9g)
- [<spellexception>Container environment configuration newline injection (CVE-2026-23953 from Incus)</spellexception>](https://github.com/lxc/incus/security/advisories/GHSA-x6jc-phwx-hp32)
- [<spellexception>Container image templating arbitrary host file read and write (CVE-2026-23954 from Incus)</spellexception>](https://github.com/lxc/incus/security/advisories/GHSA-7f67-crqm-jgh7)
- [<spellexception>Container hook project command injection (from Incus)</spellexception>](https://github.com/lxc/incus/pull/2827/commits/0e0cf45ecdcc902a6f319f11971ed27df81bd29f)
- [<spellexception>security.syscalls.intercept.mknod no longer for docker</spellexception>](https://github.com/canonical/lxd/issues/14849)
- [<spellexception>Instance POST changing target and project/pool cannot be mixed</spellexception>](https://github.com/canonical/lxd/issues/15525)
- [<spellexception>zfs.clone_copy=rebase option does not work for copying volumes</spellexception>](https://github.com/canonical/lxd/issues/16449)
- [<spellexception>TOCTOU error if images are downloaded concurrently</spellexception>](https://github.com/canonical/lxd/issues/16687)
- [<spellexception>Used by list of ACL shows instance multiple times if instance has multiple ACLs</spellexception>](https://github.com/canonical/lxd/issues/17011)
- [<spellexception>systemd services with credentials fail to start in containers with systemd v259 (Resolute)</spellexception>](https://github.com/canonical/lxd/issues/17073)
- [<spellexception>Volume snapshots can be attached using source=<vol>/<snap> rather than requiring use of source.snapshot key</spellexception>](https://github.com/canonical/lxd/issues/17125)
- [<spellexception>Volume snapshots disk devices are writable</spellexception>](https://github.com/canonical/lxd/issues/17126)
- [<spellexception>Unable to upgrade from 5.21 to 6.6: Assertion </spellexception>header.wal_size == 0’ failed\`](https://github.com/canonical/lxd/issues/17174)
- [<spellexception>Network create leaves stale database record if interrupted (context canceled)</spellexception>](https://github.com/canonical/lxd/issues/17523)
- [<spellexception>Instance logs are left behind after instance deletion</spellexception>](https://github.com/canonical/lxd/issues/17618)
- [<spellexception>dnsmasq log files are left behind after deleting the associated network</spellexception>](https://github.com/canonical/lxd/issues/17619)

<a id="ref-release-notes-6-7-incompatible"></a>

## Backwards-incompatible changes

These changes are not compatible with older versions of LXD or its clients.

### Minimum system requirement changes

The minimum supported version of some components has changed:

- Kernel 6.8
- LXC 5.0.0
- QEMU 8.2.2
- virt-v2v 2.3.4
- ZFS 2.2

### VM `security.csm` and `security.secure_boot` options combined into `boot.mode` option

The `security.csm` and `security.secure_boot` VM options have been combined into the new [`boot.mode`](../instance_options.md#instance-boot:boot.mode) configuration key to control the VM boot firmware mode.

The new setting accepts:

* `uefi-secureboot` (default) - Use UEFI firmware with secure boot enabled
* `uefi-nosecureboot` - Use UEFI firmware with secure boot disabled
* `bios` - Use legacy BIOS firmware (SeaBIOS), `x86_64` (`amd64`) only

- API extension: [instance_boot_mode](../../api-extensions.md#extension-instance-boot-mode)

### Instance type specific API endpoints and Container specific Go SDK functions removed

The `/1.0/containers` and `/1.0/virtual-machines` endpoints have been removed along with all the container specific Go SDK functions.

Clients using these endpoints should be updated to use the combined `/1.0/instances` endpoints and `Instance` related Go SDK functions.

Documentation: [Main API specification](../../api.md#api-specification)

### Operation resources URL changes

Each [operation event](../../events.md#ref-events-operation) has a `resources` field that contains URLs of LXD entities that the operation depends on.

When an instance, instance backup, or storage volume backup is created, it is not strictly required for the caller to provide the name of the new resource.
In this case, the URL of the expected resource was added to the resources map for clients to inspect and use.
The `resources` field then contains both a dependency of the operation, and the newly created resource (which may not exist yet).

To improve consistency, an optional `entity_url` field has been added to operation metadata that contains the URL of the entity that will be created.
The field is only included when a resource is being created asynchronously (operation response), and where it is not required for the entity name to be specified by the client.
For synchronous resource creation, clients should inspect the `Location` header for the same information.

The `resources` field will no longer contain this information.

Additionally the URLs presented in the `resources` field have been reviewed and in several cases updated to reflect the correct existing entities.

- API extension: [operation_metadata_entity_url](../../api-extensions.md#extension-operation-metadata-entity-name)

### Asynchronous project deletion

The [forced project deletion](../../api-extensions.md#extension-projects-force-delete) API extension added support for forcibly deleting a project and all of its contents.
This can take a long time, but the `DELETE /1.0/projects/{name}` endpoint was previously returning a synchronous response.

Now this endpoint has been changed to an asynchronous operation response.
As with the [storage and profile operation extension](../../api-extensions.md#extension-storage-and-profile-operations), this extension is forward compatible only.

- API extension: [project_delete_operation](../../api-extensions.md#extension-project-delete-operation)

### Go SDK changes

The following backwards-incompatible changes were made to the LXD Go SDK and will require updates to consuming applications.
However these  client functions are made to be backward compatible with older LXD servers.

- [<spellexception>DeleteInstance force argument</spellexception>](https://github.com/canonical/lxd/commit/f4d9eb3d6f691afdbe6a4195804171a6e6945867)
- [<spellexception>DeleteProject to return an Operation</spellexception>](https://github.com/canonical/lxd/commit/c181ab91282d94e261f475fa993d776c75741c59)
- [<spellexception>GetInstancesFull requires GetInstancesFullArgs and GetInstancesFullAllProjects, GetInstancesFullWithFilter and GetInstancesFullAllProjectsWithFilter removed</spellexception>](https://github.com/canonical/lxd/commit/eedd2e4b456f3eaa4e43fd2f1ada3b50efb2ec06)

<a id="ref-release-notes-6-7-deprecated"></a>

## Deprecated features

These features are removed in this release.

### VM 9p filesystem support for custom disk devices removed

Due to the change to QEMU 10.2 (which removed virtfs-proxy-helper support) LXD no longer supports exporting custom filesystem disk devices to VM guest using the 9p protocol. Custom filesystem disk devices can now only be exported to the VM guest using the virtiofs protocol.

However the read-only config drive used to bootstrap the lxd-agent inside the guest is still exported via both the 9p and virtiofs protocols for maximum lxd-agent guest OS compatibility.

## Updated minimum Go version

If you are building LXD from source instead of using a package manager, the minimum version of Go required to build LXD is now 1.25.7.

## Snap packaging changes

- AMD container-toolkit added at `v1.2.0`
- EDK2 bumped to `2025.02-8ubuntu3`
- Dqlite bumped to `v1.18.5`
- LXC bumped to `v6.0.6`
- LXCFS bumped to `v6.0.6`
- LXD-UI bumped to `0.20`
- NVIDIA-container and toolkit bumped to `v1.18.2`
- QEMU bumped to `10.2.1+ds-1ubuntu1`
- ZFS bumped to `zfs-2.4.1`, `zfs-2.3.6`
- virtfs-proxy-helper removed (no longer supported by QEMU 10.2)

<a id="ref-release-notes-6-7-changelog"></a>

## Change log

View the [complete list of all changes in this release](https://github.com/canonical/lxd/compare/lxd-6.6...lxd-6.7).

## Downloads

The source tarballs and binary clients can be found on our [download page](https://github.com/canonical/lxd/releases/tag/lxd-6.7).

Binary packages are also available for:

- **Linux:** `snap install lxd --channel=6/stable`
- **MacOS client:** `brew install lxc`
- **Windows client:** `choco install lxc`


# index.html.md

<a id="ref-release-notes-6-6"></a>

# LXD 6.6 release notes

This is a [feature release](../releases-snap.md#ref-releases-feature) and is not recommended for production use.

<a id="ref-release-notes-6-6-highlights"></a>

## Highlights

This section highlights new and improved features in this release.

### Instance placement groups

This release adds the concept of [placement groups](../../explanation/clusters.md#exp-clusters-placement).
Placement groups provide declarative control over how instances are distributed across cluster members.
They define both a **policy** (how instances should be distributed) and a **rigor** (how strictly the policy is enforced).
Placement groups are project-scoped resources, which means different projects can have placement groups with the same name without conflict.

- Documentation: [Placement groups](../../explanation/clusters.md#exp-clusters-placement)
- API extension: [instance_placement_groups](../../api-extensions.md#extension-instance-placement-groups)

### Placement cluster member group recorded

When an instance is placed into a cluster member group using the `--target=@<group>` syntax, the group specified is now recorded into a new [`volatile.cluster.group`](../instance_options.md#instance-volatile:volatile.cluster.group) configuration key.

This is then used during cluster member evacuation when [restoring instances](../../howto/cluster_manage.md#cluster-restore) to ensure the instance placement remains within the specified group.

### Kubernetes Container Storage Interface (CSI) driver and `/dev/lxd` volume management

The LXD project now provides a CSI driver that allows Kubernetes to provision and manage volumes for K8s Pods.
The driver is an open source implementation of the Container Storage Interface (CSI) that integrates LXD storage backends with Kubernetes.
It leverages LXD’s wide range of supported storage drivers, enabling dynamic provisioning of both local and remote volumes.
Depending on the storage pool, the CSI supports provisioning of both block and filesystem volumes.

To enable this functionality, the `/dev/lxd` guest API has been extended to support fine-grained authorization (by way of bearer token authentication) and volume management.

- Documentation: [The LXD CSI driver](../../explanation/csi.md#exp-csi)
- Documentation: [How to authenticate to the DevLXD API](../../howto/devlxd_authenticate.md#devlxd-authenticate)
- API extension: [auth_bearer_devlxd](../../api-extensions.md#extension-auth-bearer-devlxd)
- API extension: [devlxd_volume_management](../../api-extensions.md#extension-devlxd-volume-management)

### Custom storage volume recovery improvements

Using the [backup_metadata_version](../../api-extensions.md#extension-backup-metadataversion) improvements added in LXD 6.5, the [lxd recover](../../howto/disaster_recovery.md#disaster-recovery) tool now allows more extensive recovery of custom volumes attached to instances. The full custom volume configuration can now be recovered. Additionally, the tool now supports recovery from [Dell PowerFlex - powerflex](../storage_powerflex.md#storage-powerflex) and [Pure Storage - pure](../storage_pure.md#storage-pure) pools which was previously not supported.

### Consistent instance and custom volume snapshots

Consistent snapshots of both an instance and its attached volumes can now be taken together.

The `lxc snapshot` command has been extended with the `--disk-volumes` flag that accepts either `root` or `all-exclusive` values.
When `root` is specified (the default behavior), a snapshot of just the instance’s root volume is taken.
In `all-exclusive` mode, the instance is paused while a snapshot of its root volume and all exclusively attached volumes is taken.

An instance snapshot and its custom volume snapshots can be restored together using `lxc restore --disk-volumes=all-exclusive`.

- Documentation: [Use snapshots for instance backup](../../howto/instances_backup.md#instances-snapshots)
- API extension: [instance_snapshots_multi_volume](../../api-extensions.md#extension-instance-snapshots-multi-volume)

### HPE Alletra storage driver

Initial support for using HPE Alletra storage appliances using iSCSI or NVME over TCP has been added.
Currently, instance and custom volume recovery is not supported (but it is planned).

- Documentation: [HPE Alletra - alletra](../storage_alletra.md#storage-alletra)
- API extension: [storage_driver_alletra](../../api-extensions.md#extension-storage-driver-alletra)

### Persistent VM PCIe bus allocation

Devices added to VMs now have their PCIe bus number persisted into volatile configuration keys so that the device maintains the same location on the bus when the instance is restarted. Previously, when a device was hot plugged into a running VM, it was possible for the operation to fail due to bus location conflicts or to succeed and then have its bus location change on a subsequent restart of the instance.

This change was also required to make the K8s CSI driver usable because it dynamically adds and removes custom filesystem volumes from running VMs.

- API extension: [vm_persistent_bus](../../api-extensions.md#extension-vm-persistent-bus)

### Per-project image and backup volumes

It has long been possible to specify that downloaded images and exported backups be stored in a custom volume on a particular storage pool.
It is now possible to specify these volumes on a per-project basis, allowing for images and backups to be stored in different custom volumes (and storage pools) for different projects.

Two new configuration keys have been introduced: [`storage.project.{name}.images_volume`](../../server.md#server-miscellaneous:storage.project.{name}.images_volume) and [`storage.project.{name}.backups_volume`](../../server.md#server-miscellaneous:storage.project.{name}.backups_volume) per each project, allowing for a storage volume on an existing pool to be used for storing the project-specific images and backups artifacts.

- API extension: [daemon_storage_per_project](../../api-extensions.md#extension-daemon-storage-per-project)

### OVN internal network forward and load balancers

This release adds support for internal OVN load balancers and network forwards.
This approach allows `ovn` networks to define ports on internal IP addresses that can be forwarded to other internal IPs inside their respective networks.
This change removes the previous limitation on `ovn` networks that load balancers and network forwards could only use external IP addresses to forward to internal IPs.

- API extension: [ovn_internal_load_balancer](../../api-extensions.md#extension-ovn-internal-load-balancer)

### OVN DHCP ranges

This release adds a new configuration key [`ipv4.dhcp.ranges`](../network_ovn.md#network-ovn-network-conf:ipv4.dhcp.ranges) for `ovn` networks.
This key allows specifying a list of IPv4 ranges reserved for dynamic allocation using DHCP.
This is useful when setting up a [network forward](../../howto/network_forwards.md#network-forwards) towards a floating IP inside an `ovn` network that needs to be prevented from being allocated via DHCP.

- API extension: [ovn_dhcp_ranges](../../api-extensions.md#extension-ovn-dhcp-ranges)

### OVN NIC acceleration parent interface option

This release adds support for specifying the OVN NIC acceleration physical function interfaces to allocate virtual functions from.

This avoids the need to add the physical function interfaces to the OVN integration bridge, which had prevented their use for host connectivity.

This change introduces a new configuration key for `ovn` networks and NICs:

- [`acceleration.parent`](../devices_nic.md#device-nic-ovn-device-conf:acceleration.parent) - Comma separated list of physical function (PF) interfaces from which to allocate virtual functions (VFs) from for hardware acceleration when [`acceleration`](../devices_nic.md#device-nic-ovn-device-conf:acceleration) is enabled.
- API extension: [ovn_nic_acceleration_parent](../../api-extensions.md#extension-ovn-nic-acceleration-parent)

### Improved OIDC authentication provider compatibility using sessions

This release adds session support for OIDC authentication. This enables compatibility with identity providers that issue opaque access tokens.

When a session expires, LXD re-verifies the login with the identity provider.
The duration of OIDC sessions defaults to one week and can be configured via the [`oidc.session.expiry`](../../server.md#server-oidc:oidc.session.expiry) configuration key.

Verification of an OIDC session depends on a new, cluster-wide core secret.

A new [`core.auth_secret_expiry`](../../server.md#server-core:core.auth_secret_expiry) configuration controls how long a secret remains valid before it expires.
This sets the upper bound of an OIDC session duration.

- API extension: [auth_oidc_sessions](../../api-extensions.md#extension-auth-oidc-sessions)

### Create custom filesystem volume from tarball contents

The `lxc storage volume import` command has gained support for creating a custom filesystem volume from the contents of a tarball.

A new supported value of `tar` has been added to the `--type` flag that causes the contents of the tarball to be unpacked into the newly created volume.

- API extension: [import_custom_volume_tar](../../api-extensions.md#extension-import-custom-volume-tar)

### Forced project deletion

It is now possible to forcefully delete a project and all of its entities using the `lxc project delete <project> --force` command.

- API extension: [projects_force_delete](../../api-extensions.md#extension-projects-force-delete)

### Operation requestor information

A new field `requestor` was added to operations, which contains information about the caller that initiated the operation.

- API extension: [operation_requestor](../../api-extensions.md#extension-operation-requestor)

### Resources disk used by information

A new field `used_by` was added to disks in the resources API to indicate its potential use by any virtual parent device, such as `bcache`.

- API extension: [resources_disk_used_by](../../api-extensions.md#extension-resources-disk-used-by)

## UI updates

This release includes several improvements and new features in the LXD UI.

### SSH key generation during instance creation

The UI now supports generating SSH key pairs during instance creation, making it easier to configure instance access without relying on external tools.

### Bulk operations: View details

Bulk actions now include an expanded View details interface, allowing you to inspect aggregated information and per-item results when managing multiple resources at once.
For example, when performing bulk instance deletion or bulk instance start, the UI now shows which instances succeeded, which failed, and any associated messages for each item.

### Mobile experience improvements

Mobile-focused UI refinements improve navigation, responsiveness, and readability across smaller screens.

### Login project selection in settings

A new login project setting is available in the Settings.
The selected project is stored in `localStorage`, ensuring the UI restores your working context on return.

### HPE storage driver support

The UI now includes configuration and management support for the HPE Alletra storage driver, enabling pool and volume interaction for environments using this backend.

### Saved terminal connection defaults

Users can now save terminal connection defaults as an instance user key, allowing persistent preferences for how the terminal connects to instances.

### ACL support on instances and profiles

ACLs can now be added directly on Instances and Profiles, not just at the network level, enabling more granular access control configuration directly.

### MTU and VLAN support for physical networks

Physical network configuration forms now include MTU and VLAN Id fields, enabling more complete network definition from within the UI.

### Project configuration: restricted backups

The Configuration screen now exposes the Instance option to restrict backup creation on a project.

<a id="ref-release-notes-6-6-bugfixes"></a>

## Bug fixes

The following bug fixes are included in this release.

- [<spellexception>Local privilege escalation through custom storage volumes (CVE-2025-64507)</spellexception>](https://github.com/canonical/lxd/security/advisories/GHSA-3g2j-vm47-x4mj)
- [<spellexception>Support for runc 1.3.3 inside containers</spellexception>](https://github.com/canonical/lxd/issues/16902)
- [<spellexception>Missing path encoding in non-recursive API responses</spellexception>](https://github.com/canonical/lxd/issues/16792)
- [<spellexception>S390x architecture name missing from architecture aliases</spellexception>](https://github.com/canonical/lxd/issues/13497)
- [<spellexception>lxc init doesn't immediately fail on duplicated instance name if the source image is not cached</spellexception>](https://github.com/canonical/lxd/issues/12554)
- [<spellexception>Restoring cluster member while evacuating breaks instance relationship with origin</spellexception>](https://github.com/canonical/lxd/issues/15877)
- [<spellexception>Cluster healing stops network on member that triggers healing</spellexception>](https://github.com/canonical/lxd/issues/16642)
- [<spellexception>NVIDIA CDI will not work with multiple GPUs when nvidia-persistenced is running</spellexception>](https://github.com/canonical/lxd/issues/16227)
- [<spellexception>Containers do not start again when the host is not shut down properly nvidia CDI</spellexception>](https://github.com/canonical/lxd/issues/14843)
- [<spellexception>Error parsing /proc/cpuinfo on Raspberry PI 5</spellexception>](https://github.com/canonical/lxd/issues/16481)
- [<spellexception>Listing instances through fine grained TLS auth is not reliable at scale</spellexception>](https://github.com/canonical/lxd/issues/16614)
- [<spellexception>Underlying storage uses 4096 bytes sector size when virtual machine images require 512 bytes</spellexception>](https://github.com/canonical/lxd/issues/16477)
- [<spellexception>Forcibly stopping an instance should not spam logs about leftover sftp server</spellexception>](https://github.com/canonical/lxd/issues/15925)
- [<spellexception>Concurrent (graphical) console connections to a VM don't close connections</spellexception>](https://github.com/canonical/lxd/issues/16073)
- [<spellexception>Help does not reflect, that there is a difference between lxc shell and lxc exec</spellexception>](https://github.com/canonical/lxd/issues/16159)
- [<spellexception>Network used by list incomplete</spellexception>](https://github.com/canonical/lxd/issues/16216)
- [<spellexception>The fanotify mechanism does not notice dynamic removal of underlying devices</spellexception>](https://github.com/canonical/lxd/issues/15894)
- [<spellexception>Removing a member from cluster group that is not in any other group silently ignores request</spellexception>](https://github.com/canonical/lxd/issues/16074)
- [<spellexception>Prune cached images during project delete</spellexception>](https://github.com/canonical/lxd/pull/16623)

<a id="ref-release-notes-6-6-incompatible"></a>

## Backwards-incompatible changes

These changes are not compatible with older versions of LXD or its clients.

### Asynchronous storage volume and profile API endpoints

Certain storage and profile endpoints that were previously synchronous now return an operation and behave asynchronously.

The latest LXD Go client detects the presence of this API extension. When it is available, the caller receives an operation object directly from the LXD server.
If the extension is not present on the server, then the server response is wrapped in a completed operation, allowing the caller to handle it as an operation while lacking a retrievable operation ID.

Older LXD Go clients are incompatible with servers that include this extension.
Instead of the expected successful response, they receive an operation response.

Endpoints converted to asynchronous behavior:

- `POST /storage-pools/{pool}/volumes/{type}` - Create storage volume
- `PUT /storage-pools/{pool}/volumes/{type}/{vol}` - Update storage volume
- `PATCH /storage-pools/{pool}/volumes/{type}/{vol}` - Patch storage volume
- `POST /storage-pools/{pool}/volumes/{type}/{vol}` - Rename storage volume
- `DELETE /storage-pools/{pool}/volumes/{type}/{vol}` - Delete storage volume
- `PUT /storage-pools/{pool}/volumes/{type}/{vol}/snapshots/{snap}` - Update storage volume snapshot
- `PATCH /storage-pools/{pool}/volumes/{type}/{vol}/snapshots/{snap}` - Patch storage volume snapshot
- `PUT /1.0/profiles/{name}` - Update profile
- `PATCH /1.0/profiles/{name}` - Patch profile

<!-- end list -->
- API extension: [storage_and_profile_operations](../../api-extensions.md#extension-storage-and-profile-operations)

<a id="ref-release-notes-6-6-deprecated"></a>

## Deprecated features

These features are removed in this release.

### Instance placement scriptlet removed

The instance placement scriptlet functionality (and the associated `instances_placement_scriptlet` API extension) has been removed in favor of the new [Placement groups](../../explanation/clusters.md#exp-clusters-placement) functionality.

If a scriptlet is set in the removed `instances.placement.scriptlet` configuration option, it is stored in the `user.instances.placement.script` configuration option when upgrading.

## Updated minimum Go version

If you are building LXD from source instead of using a package manager, the minimum version of Go required to build LXD is now 1.25.4.

## Snap packaging changes

- Settings to disable the AppArmor restricted user namespaces are persisted to `/run/sysctl.d/zz-lxd.conf`
- Dqlite bumped to `v1.18.3`
- LXC bumped to `v6.0.5`
- LXCFS bumped to `v6.0.5`
- Enable `lxcfs.pidfd=true` by default
- LXD-UI bumped to `0.19`
- NVIDIA-container and toolkit bumped to `1.18.0`
- QEMU bumped to `8.2.2+ds-0ubuntu1.10`
- ZFS bumped to `zfs-2.3.4`

<a id="ref-release-notes-6-6-changelog"></a>

## Change log

View the [complete list of all changes in this release](https://github.com/canonical/lxd/compare/lxd-6.5...lxd-6.6).

## Downloads

The source tarballs and binary clients can be found on our [download page](https://github.com/canonical/lxd/releases/tag/lxd-6.6).

Binary packages are also available for:

- **Linux:** `snap install lxd --channel=6/stable`
- **MacOS client:** `brew install lxc`
- **Windows client:** `choco install lxc`


# index.html.md

<a id="ref-release-notes-6-9"></a>

# LXD 6.9 release notes

This is a [feature release](../releases-snap.md#ref-releases-feature) and is not recommended for production use.

<a id="ref-release-notes-6-9-highlights"></a>

## Highlights

This section highlights new and improved features in this release.

### Network load balancer pools

Load balancer pools have been introduced for OVN networks, allowing instances to be grouped together as targets for load balancer traffic distribution.

Pools provide a way to manage collections of backend instances that receive forwarded traffic from load balancers, with health checking support and dynamic membership based on instance availability.

New `lxc network load-balancer pool` subcommands have been added to manage these pools.

- Documentation: [How to configure network load balancers](../../howto/network_load_balancers.md#network-load-balancers)
- API extension: [network_load_balancer_pool](../../api-extensions.md#extension-network-load-balancer-pool)

### PowerStore storage driver

A new `powerstore` storage driver has been added, enabling the use of Dell PowerStore storage arrays with LXD.

The driver supports iSCSI and Fibre Channel (FC) connectivity modes, providing flexible options for connecting to PowerStore volumes.

- Documentation: [Dell PowerStore - powerstore](../storage_powerstore.md#storage-powerstore)
- API extension: [storage_driver_powerstore](../../api-extensions.md#extension-storage-driver-powerstore)

### Fibre Channel storage connector

A new Fibre Channel (FC) storage connector has been added, enabling FC-based connectivity for remote storage drivers.

This allows supporting storage drivers like PowerStore to use FC transport for volume attachment, in addition to the existing iSCSI and NVMe/TCP options.

### PowerFlex 5 support

The PowerFlex storage driver has been updated to support Dell PowerFlex version 5, including thin clone support and updated API compatibility.

The driver now automatically detects the PowerFlex version and adapts its behavior accordingly, maintaining backwards compatibility with PowerFlex 4.

### Security events

A new `security` event type has been added, providing OWASP-compliant audit logging for security-relevant operations.

Security events cover authentication (login failures, token operations, certificate changes), authorization (permission denials, admin actions), and system events (startup, shutdown, monitoring changes).

These events can be routed to Grafana Loki by adding `security` to the `loki.types` server configuration.

- Documentation: [How to monitor security events](../../howto/security_events.md#howto-security-events)
- API extension: [event_security](../../api-extensions.md#extension-event-security)

### OIDC device client ID

A new [`oidc.device.client.id`](../../server.md#server-oidc:oidc.device.client.id) configuration key has been added to support separate OAuth clients for CLI authentication.

This allows administrators to configure a dedicated device authorization grant client for the `lxc` CLI, separate from the main OIDC client used by the LXD UI, enabling different authentication flows and security requirements for each.

- API extension: [oidc_device_client_id](../../api-extensions.md#extension-oidc-device-client-id)

### Optimized ZFS instance creation with image variants

The ZFS storage driver now supports optimized instance creation through image variants.

When creating instances, LXD can now cache and reuse ZFS clones that match the instance’s configuration (such as initial block mode or filesystem type), significantly improving creation time for subsequent instances using the same image variant.

Stale image variants are automatically cleaned up when pool configuration changes.

- Documentation: [ZFS storage driver internals](../storage_zfs_internals.md#storage-zfs-internals)

### Project replica mode

Projects now have an explicit `replica_mode` field that indicates whether a project is in `leader` or `standby` mode for replication purposes.

New `lxc project promote-replica` and `lxc project demote-replica` commands have been added to manage project replication state, and instances in standby projects are prevented from starting.

- API extension: [project_replica_mode](../../api-extensions.md#extension-project-replica-mode)

### Cluster links `used_by` field

Cluster links now include a `used_by` field that lists all entities referencing the link, such as replicators.

This enables better visibility into cluster link dependencies and prevents accidental deletion or renaming of in-use links.

- API extension: [cluster_links_used_by](../../api-extensions.md#extension-cluster-links-used-by)

### Switch to Go standard library HTTP router

The LXD daemon has switched from `gorilla/mux` to the Go standard library’s `http.ServeMux` for HTTP routing.

This reduces external dependencies and leverages the improved routing capabilities added in Go 1.22.

### OIDC verifier background initialization

The OIDC verifier is now initialized in the background on daemon startup, with automatic retry on failure.

This prevents LXD startup from being blocked by unavailable identity providers and adds a warning when OIDC authentication is unavailable.

### Cluster evacuation quorum protection and raft rebalancing

Cluster member evacuation now validates the raft quorum before proceeding and refuses to evacuate an online voter when doing so would drop the remaining online voters below the required majority.

During evacuation, LXD transfers leadership first when needed, marks the member as evacuated, and triggers an immediate raft rebalance so that evacuated members are demoted and excluded from promotion candidacy before workloads are migrated. Restore reverses this by prioritizing networks and instances before triggering a raft rebalance.

The quorum safety check can be bypassed by passing `force` to the evacuate action.

- API extension: [clustering_evacuation_force](../../api-extensions.md#extension-clustering-evacuation-force)

## UI updates

This release introduces replicator management, load balancer support, and an initial file explorer for instances, alongside cluster link enhancements, identity improvements, and a range of user-driven refinements.

### Replicators

- Added full replicator management, including:
  - Project configuration page to set up replicators and cluster links
  - Replicator list page
  - Detailed replicator view
  - Create and edit workflows
  - Run modal for manual execution
  - Rich status chips and visual indicators
  - Instance usage visibility per project
- Improved replicator validation, permissions handling, and overall user experience.

### Load balancers

- Added load balancer management for OVN networks to the UI.
- Added support for managing load balancer instances.

### Storage

- Improved Dell PowerStore support with updates to PowerStore configuration and management workflows.
- Improved storage-related form behavior and validation.

### Instance experience

- Introduced the initial Instance File Explorer implementation.
- Added support for file and directory deletion within the File Explorer.
- Improved instance creation workflow by automatically focusing newly added profiles.
- Fixed image tab state handling in the All Projects view.

### Identity and access management

- OIDC configuration can now be accessed directly from Settings when managing identities and permissions.
- Improved identity page header controls and alignment.

### Cluster management

- Enhanced cluster links with:
  - Rich chips for improved visibility
  - Better creation and confirmation workflows
  - Improved copy and guidance throughout the UI
  - Protection against deleting cluster links that are currently in use
- Cluster links are now displayed on single-node servers where applicable.
- Improved handling of cluster link tokens and redirects.
- The “Same for all members” option is now hidden when a cluster contains only a single member.

### User-driven improvements

- Improved cluster link onboarding and setup guidance.
- Standardized navigation and redirection behavior across cluster-linked environments.
- Replaced Monaco Editor with CodeMirror for YAML and configuration editing.

### Bug fixes

- Fixed issues with image registry renaming when rename permissions are unavailable.
- Fixed sorting of modified timestamps.
- Fixed several cluster link validation, token handling, and UX issues.

<a id="ref-release-notes-6-9-bugfixes"></a>

## Bug fixes

The following bug fixes are included in this release.

- [<spellexception>Fix replicator failing to process instances on remote cluster members</spellexception>](https://github.com/canonical/lxd/pull/18207)
- [<spellexception>Fix replicator backup file write errors on idempotent refresh operations</spellexception>](https://github.com/canonical/lxd/pull/18207)
- [<spellexception>Prevent duplicate replicators targeting the same cluster link</spellexception>](https://github.com/canonical/lxd/pull/18442)
- [<spellexception>Fix replicator restore for unclustered standby clusters</spellexception>](https://github.com/canonical/lxd/pull/18312)
- [<spellexception>Fix ZFS storage pool leak after shutdown due to lingering forkfile daemon</spellexception>](https://github.com/canonical/lxd/pull/18446)
- [<spellexception>Fix listing images with --all-projects flag</spellexception>](https://github.com/canonical/lxd/pull/18371)
- [<spellexception>Fix LVM thin-pool usage calculation accuracy</spellexception>](https://github.com/canonical/lxd/pull/18311)
- [<spellexception>Fix btrfs send failure during refresh migration</spellexception>](https://github.com/canonical/lxd/pull/18207)
- [<spellexception>Fix instance copy refresh when target does not exist</spellexception>](https://github.com/canonical/lxd/pull/18207)
- [<spellexception>Fix race condition in Rename with pending forkfile cleanup</spellexception>](https://github.com/canonical/lxd/pull/18254)
- [<spellexception>Fix events websocket disconnection logic in the client</spellexception>](https://github.com/canonical/lxd/pull/18365)
- [<spellexception>Fix hung goroutine on ReadJSON in events</spellexception>](https://github.com/canonical/lxd/pull/18359)
- [<spellexception>Address possible iSCSI race conditions</spellexception>](https://github.com/canonical/lxd/pull/18332)
- [<spellexception>Fix missing secure boot firmware message for VMs</spellexception>](https://github.com/canonical/lxd/pull/18375)
- [<spellexception>Improve snapshot config validation during import</spellexception>](https://github.com/canonical/lxd/pull/18301)
- [<spellexception>Fix backup file error handling for refresh</spellexception>](https://github.com/canonical/lxd/pull/18242)
- [<spellexception>Fix local config being wiped out by reverter</spellexception>](https://github.com/canonical/lxd/pull/18180)
- [<spellexception>Fix operation entity URLs for storage volumes/backups/snapshots</spellexception>](https://github.com/canonical/lxd/pull/18167)
- [<spellexception>Use merged node config for local pool creation</spellexception>](https://github.com/canonical/lxd/pull/18270)
- [<spellexception>Bypass HTTP proxy for cluster connections</spellexception>](https://github.com/canonical/lxd/pull/18338)
- [<spellexception>Bypass proxy when retrieving certificate during cluster join</spellexception>](https://github.com/canonical/lxd/pull/18354)
- [<spellexception>Include slab_reclaimable in MemAvailable metric</spellexception>](https://github.com/canonical/lxd/pull/18289)
- [<spellexception>Fix architecture filter to match displayed values in lxc image</spellexception>](https://github.com/canonical/lxd/pull/18292)
- [<spellexception>Validate snapshot.ExpiresAt is non-nil</spellexception>](https://github.com/canonical/lxd/pull/18320)
- [<spellexception>Use legacy CephFS mount syntax on kernel < 5.17</spellexception>](https://github.com/canonical/lxd/pull/18192)
- [<spellexception>Fix Identity API group management visibility</spellexception>](https://github.com/canonical/lxd/pull/18177)
- [<spellexception>Allow dynamic OVN NIC address updates</spellexception>](https://github.com/canonical/lxd/pull/18156)
- [<spellexception>Mount Ceph RBD snapshots read-only to support modern ext4</spellexception>](https://github.com/canonical/lxd/pull/18469)
- [<spellexception>Work with modern LVM</spellexception>](https://github.com/canonical/lxd/pull/18463)
- [<spellexception>Add missing content types for storage volume POST</spellexception>](https://github.com/canonical/lxd/pull/18457)

<a id="ref-release-notes-6-9-incompatible"></a>

## Backwards-incompatible changes

These changes are not compatible with older versions of LXD or its clients.

### NVMe/TCP storage pool mode renamed

The storage pool NVMe/TCP mode has been renamed from `nvme` to `nvme/tcp` for clarity and consistency with other transport modes.

Existing pools using the `nvme` mode are automatically migrated to use `nvme/tcp` on upgrade.

- API extension: [storage_nvme_tcp](../../api-extensions.md#extension-storage-nvme-tcp)

### Image import from client-specified URL removed

Support for importing images from a client-specified URL (the `direct` protocol) has been removed.

Images should be imported using the standard image server protocols (simplestreams or LXD).
Existing images using this deprecated source type will no longer auto-update.

### `lxc cluster evacuate` and `restore` flag changes

The `--force` flag of `lxc cluster evacuate` and `lxc cluster restore` no longer acts as a confirmation bypass. It now bypasses the server-side raft quorum safety check instead.

Use the new `--yes` flag to skip the interactive confirmation prompt, matching the convention used elsewhere in the `lxc` CLI.

- API extension: [clustering_evacuation_force](../../api-extensions.md#extension-clustering-evacuation-force)

<a id="ref-release-notes-6-9-known-issues"></a>

## Known issues

This section covers known temporary limitations and integration regressions in this release.

### CDI GPU passthrough failure on Ubuntu Core 26

Users attempting to pass through GPUs to containers on Ubuntu Core 26 environments using the `gpu-2604` interface (provided by the `mesa-2604` snap) will encounter a container startup failure:

```default
Error: Failed starting device "gpu0": Failed generating CDI spec: Failed determining NVIDIA driver root path: Failed running: /snap/lxd/<revision>/gpu-2604/bin/gpu-2604-provider-wrapper printenv NVIDIA_DRIVER_ROOT: exit status 1
```

This is caused by an upstream architectural mismatch on the Core 26 track between the `pc-kernel` snap and the `mesa-2604` graphics provider snap.
The `pc-kernel` snap exposes NVIDIA driver files using new interfaces, but the `mesa-2604` wrapper script is still looking for legacy `kernel-gpu-2604` directory paths.

There is currently no native LXD configuration workaround.

<a id="ref-release-notes-6-9-go"></a>

## Updated minimum Go version

If you are building LXD from source instead of using a package manager, the minimum version of Go required to build LXD is now 1.26.4.

<a id="ref-release-notes-6-9-snap"></a>

## Snap packaging changes

- LXCFS: Reverted partial backport of PSI functionality that prevented host machine suspend ([#17983](https://github.com/canonical/lxd/issues/17983)).
- libnvidia-container bumped to v1.19.1.
- AMD ROCm container toolkit bumped to v1.3.0.
- ZFS 2.2 bumped to 2.2.10.
- ZFS 2.3 bumped to 2.3.8.
- ZFS 2.4 bumped to 2.4.3.
- Removed unused `arptables` binary.
- Removed `libcephfs` from the snap due to unusable missing dependencies.
- Removed unneeded Python dependencies from Ceph.
- Various snap size optimizations (removed unused QEMU keymaps, LXD UI localization files, uefivars bloat).

<a id="ref-release-notes-6-9-changelog"></a>

## Change log

View the [complete list of all changes in this release](https://github.com/canonical/lxd/compare/lxd-6.8...lxd-6.9).

<a id="ref-release-notes-6-9-downloads"></a>

## Downloads

The source tarballs and binary clients can be found on our [download page](https://github.com/canonical/lxd/releases/tag/lxd-6.9).

Binary packages are also available for:

- **Linux:** `snap install lxd --channel=6/stable`
- **MacOS client:** `brew install lxc`
- **Windows client:** `choco install lxc`


# index.html.md

<a id="ref-release-notes"></a>

# Release notes

This page lists recent release notes for LXD, which highlight new features, bug fixes, and other important information for each release.

## Release policy and schedule

For details about the release policy and schedule, along with information about the LXD snap channels, see: [Releases and snap](../releases-snap.md#ref-releases-snap).

## Upgrade instructions

For full instructions on updating or upgrading LXD via its [snap package](https://snapcraft.io/lxd), see [How to manage the LXD snap](../../howto/snap.md#howto-snap):

- Feature releases are published on the [current feature track](../releases-snap.md#ref-snap-track-feature). If you are already following this track and you want to manually update to the most recent feature release, see the [Manual updates](../../howto/snap.md#howto-snap-updates-manual) section.
- To move from one LTS track to a higher LTS track or the feature track, see the [Change the snap channel](../../howto/snap.md#howto-snap-change) section.

<a id="ref-release-notes-releases"></a>

## Releases

* [LXD 6.9](release-notes-6.9.md)
* [LXD 6.8](release-notes-6.8.md)
* [LXD 6.7](release-notes-6.7.md)
* [LXD 6.6](release-notes-6.6.md)

For older release notes, see [our Discourse forum](https://discourse.ubuntu.com/tags/c/lxd/126/release).


# index.html.md

<a id="ref-release-notes-6-8"></a>

# LXD 6.8 release notes

This is a [feature release](../releases-snap.md#ref-releases-feature) and is not recommended for production use.

<a id="ref-release-notes-6-8-highlights"></a>

## Highlights

This section highlights new and improved features in this release.

### Cluster control-plane role

A new `control-plane` cluster member role has been added that can be manually assigned to designate which members participate in Raft consensus.

Control plane mode is inactive by default until at least 3 members are assigned the `control-plane` role.
While inactive, all cluster members remain eligible for automatic promotion to database roles (preserving existing behavior).
Once active, only `control-plane` members can become voters, standbys, or the database leader; members without the role are assigned `RAFT_SPARE` and excluded from automatic promotion.

When control plane mode is active, control-plane members also act as event hubs, replacing the now-deprecated `event-hub` role.

- Documentation: [Use control plane mode](../../howto/cluster_manage.md#cluster-manage-control-plane)
- API extension: [clustering_control_plane](../../api-extensions.md#extension-clustering-control-plane)

### Cluster links

Cluster links enable secure, authenticated communication between separate LXD clusters using mutual TLS certificates.

This release adds a full cluster links API, including create/list/show/edit/rename/delete operations and state inspection support.
Matching `lxc cluster link ...` subcommands have also been added.

- Documentation: [Cluster links](../../explanation/clusters.md#exp-cluster-links)
- API extension: [cluster_links](../../api-extensions.md#extension-cluster-links)

### Replicators

Replicators enable active-passive project level instance refresh for disaster recovery using the new bi-directional cluster links functionality.

Replicators support scheduled and manual execution for replicating instances between linked clusters.
The daemon gains a background task for running scheduled replicators, and matching `lxc replicator` subcommands have been added to the CLI.

- Documentation: [How to set up replicators](../../howto/replicators_create.md#howto-replicators-setup)
- API extension: [replicators](../../api-extensions.md#extension-replicators)

### GPU CDI hotplug support for containers

Building on the AMD CDI container support added in LXD 6.7, GPU CDI devices can now be hotplugged into running containers.

- API extension: [gpu_cdi_hotplug](../../api-extensions.md#extension-gpu-cdi-hotplug)

### Bulk instance state operations and metadata entity URL improvements

A new `recursion=2` mode for `GET /1.0/operations` returns the full parent-child relationship between operations.
`GET /1.0/operations/{id}` with `recursion=1` also now returns related child operations.

Parallel bulk instance state updates now create a parent operation with per-instance child operations, providing more granular status reporting.

Additionally operation metadata handling for `entity_url` has been tightened and expanded.
LXD now keeps the primary `entity_url` stable when metadata is updated and ensures it is present for applicable operations.

Rename operations can now expose both `entity_url` (the new target URL) and `original_entity_url` (the pre-rename URL), making rename tracking more reliable for API clients.

URL metadata coverage was also extended to additional create and rename operations, including project rename, instance rename/snapshot rename/backup rename, storage pool create, and storage volume create/snapshot rename/backup rename.

- API extension: [bulk_operations](../../api-extensions.md#extension-bulk-operations)

### ZFS volume promotion support

A new [`zfs.promote`](../storage_zfs.md#storage-zfs-volume-conf:zfs.promote) configuration key has been added.
When set to `true`, this instructs LXD to ZFS-promote the volume when creating (or recreating) it from a clone.

This key is primarily useful when combined with `initial.*` [disk device configuration options](../devices_disk.md#devices-disk-initial-config) and allows controlling ZFS promotion when creating instances from other instances.

- API extension: [storage_zfs_promote](../../api-extensions.md#extension-storage-zfs-promote)

### Ceph RBD default features changed

New volumes (and clones) in Ceph RBD (`ceph`) pools are no longer created with only `--image-feature layering`.
Instead the default RBD features configured in the Ceph cluster are used.

If `ceph.rbd.features` is already set on a pool, that value continues to be used unchanged.

- API extension: [storage_ceph_use_rbd_defaults](../../api-extensions.md#extension-storage-ceph-use-rbd-defaults)

### Ceph and CephFS support for messenger protocol v2

The Ceph storage driver now has support for the Ceph messenger protocol v2.

LXD now uses the native Ceph CLI tool (`ceph mon dump --format json`) instead of an internal `ceph.conf` parser for monitor discovery and FSID information. This enables Ceph messenger protocol v2 support.

These improvements enhance compatibility with modern Ceph deployments and provide more robust handling of various Ceph configurations, including those deployed through MicroCeph.

### Custom port numbers in NVMe and iSCSI storage connectors

The NVMe and iSCSI storage connectors now support custom port numbers, providing more flexibility when connecting to storage targets that do not use standard ports.

### OVN dynamic Northbound connection

When the [`network.ovn.northbound_connection`](../../server.md#server-miscellaneous:network.ovn.northbound_connection) server configuration is not set, LXD now dynamically determines the OVN Northbound database connection string based on the environment.
If the MicroOVN snap is used, LXD reads the configuration from the MicroOVN `ovn.env` file.
Otherwise, it defaults to `unix:/var/run/ovn/ovnnb_db.sock`.

This ensures that if the MicroOVN cluster membership changes, LXD will then use the updated OVN server connection configuration.

- API extension: [ovn_dynamic_northbound_connection](../../api-extensions.md#extension-ovn-dynamic-northbound-connection)

### Instance configuration refresh on copy

Instance `copy --refresh` operations now correctly apply target configuration, profile, and device updates server-side before the data transfer completes.
This applies to both direct copies and migration-based refresh operations.

- API extension: [instance_refresh_config](../../api-extensions.md#extension-instance-refresh-config)

### Extended image metadata from SimpleStreams

Two new optional fields, `release_codename` and `release_title`, have been added to the `api.Image` struct.
These are populated from the SimpleStreams index when available.
The generated image description for SimpleStreams images now includes the variant when available, and no longer includes the creation date or architecture.

- API extension: [image_extended_metadata](../../api-extensions.md#extension-image-extended-metadata)

### `lxc project get-current` command

A new `lxc project get-current` command has been added that outputs the name of the currently selected project, making it easy to use in scripts.

### `lxc --column`/`-c` flag for CSV output

The `--column`/`-c` flag is now supported by the `lxc` command everywhere that `--format csv` is accepted, allowing column selection to be combined with CSV output consistently across all `lxc` list commands.

### Stricter file permissions across the codebase

A large sweep of stricter file permissions has been applied across the codebase, reducing the risk of unintended access to sensitive files created by the LXD daemon and the `lxc` client.

### Widespread TOCTOU race condition fixes

Numerous time-of-check to time-of-use (TOCTOU) race conditions across the daemon, client, and storage drivers have been fixed, improving correctness and security under concurrent workloads.

### CSRF protection using Go standard library

The daemon now uses the CSRF protection provided by the Go standard library, replacing the previous custom implementation.

### Constant-time secret comparison

All secret comparison operations (exec, console, migration, and certificate token secrets) now use constant-time comparison to prevent timing side-channel attacks.

### HTTP hardening

Several HTTP hardening improvements have been applied to the daemon:

- Dropped the deprecated `X-XSS-Protection` response header.
- Added a `Referrer-Policy` header to prevent leaking referrer information.
- Applied HTTP timeouts to the pprof, Loki, and endpoint listeners.
- TCP keep alive and TCP user timeout configured on incoming API connections for faster stale connection detection.

## UI updates

This release introduces cluster links, improves instance configuration visibility, and enhances responsiveness across the UI, alongside a range of user-driven fixes and refinements.

### Cluster management

- The UI now supports cluster links for connecting multiple clusters.
- The UI now supports full create, edit, and delete management for cluster member roles.

### Instance experience

- The YAML editor now provides an expanded view that surfaces inherited configuration values (such as from profiles) alongside instance-level settings.
- More responsive instance creation with live progress updates via events.
- Ubuntu-themed terminal for instances.

### Forms and input enhancements

- Introduced prefixed inputs for IP address assignments for clearer networking configuration.
- Added output fields to forms where applicable.

### Asynchronous operations

- Improved handling of long-running operations with asynchronous support for:
  - Networks
  - Network peerings
  - Network ACLs
  - Storage pools
  - Storage buckets and bucket keys

### User-driven improvements

- Instances uploaded from file now appear immediately in the instance list while processing.
- Improved visibility of available storage pool size.
- Enhanced storage driver selection with more details.
- Added icons for full-screen mode and ISO usage in the instance terminal.
- Removed expiry field from instance export (system defaults are now applied).

### Bug fixes

- Fixed issue where the admin group was incorrectly immutable.
- Fixed terminal behavior to display content when a connection closes or errors occur.

<a id="ref-release-notes-6-8-bugfixes"></a>

## Bug fixes

The following bug fixes are included in this release.

- [<spellexception>VM lowlevel restriction bypass via raw.apparmor and raw.qemu.conf (CVE-2026-34177)</spellexception>](https://github.com/canonical/lxd/security/advisories/GHSA-fm2x-c5qw-4h6f)
- [<spellexception>Update of type field in restricted TLS certificate allows privilege escalation to cluster admin (CVE-2026-34179)</spellexception>](https://github.com/canonical/lxd/security/advisories/GHSA-c3h3-89qf-jqm5)
- [<spellexception>Importing a crafted backup leads to project restriction bypass (CVE-2026-34178)</spellexception>](https://github.com/canonical/lxd/security/advisories/GHSA-q96j-3fmm-7fv4)
- [<spellexception>Arbitrary file read and write through pongo templates (CVE-2026-33897 from Incus)</spellexception>](https://github.com/lxc/incus/security/advisories/GHSA-83xr-5xxr-mh92)
- [<spellexception>Verify combined fingerprint when downloading images from simplestreams servers (CVE-2026-33542 from Incus)</spellexception>](https://github.com/lxc/incus/security/advisories/GHSA-p8mm-23gg-jc9r)
- [<spellexception>Fix creating instances using a local image from another project</spellexception>](https://github.com/canonical/lxd/pull/17924)
- [<spellexception>Require can_view on source instance and volume when copying</spellexception>](https://github.com/canonical/lxd/pull/17914)
- [<spellexception>Migration: Don't allow pull mode in restricted projects</spellexception>](https://github.com/canonical/lxd/pull/17988)
- [<spellexception>Use correct name in create-from-backup entity URL</spellexception>](https://github.com/canonical/lxd/pull/17810)
- [<spellexception>GPU CDI device fixes</spellexception>](https://github.com/canonical/lxd/pull/17958)
- [<spellexception>Fix snapshot URL in clustered mode</spellexception>](https://github.com/canonical/lxd/pull/17794)
- [<spellexception>Fix recursive file pull failing on existing directories and symlinks</spellexception>](https://github.com/canonical/lxd/pull/17739)
- [<spellexception>Fix --profile and --no-profiles flags being ignored on cluster moves</spellexception>](https://github.com/canonical/lxd/pull/17756)
- [<spellexception>Fix mutex leak and unclosed files</spellexception>](https://github.com/canonical/lxd/pull/17778)
- [<spellexception>Prevent concurrent evacuations</spellexception>](https://github.com/canonical/lxd/pull/17475)
- [<spellexception>Fix image fingerprint validation being too permissive</spellexception>](https://github.com/canonical/lxd/pull/17985)
- [<spellexception>Fix UI and documentation MIME type</spellexception>](https://github.com/canonical/lxd/pull/18043)
- [<spellexception>Enforce project limits.instances in clustered instance creation</spellexception>](https://github.com/canonical/lxd/pull/17822)
- [<spellexception>dnsmasq: clean up orphaned .removing files on bridge network start</spellexception>](https://github.com/canonical/lxd/pull/17869)
- [<spellexception>Improve phantom volume error reporting during cluster moves</spellexception>](https://github.com/canonical/lxd/pull/18101)
- [<spellexception>Fix instance copy to keep source architecture type</spellexception>](https://github.com/canonical/lxd/pull/18102)
- [<spellexception>Fix inverted TLS verification logic in Alletra client</spellexception>](https://github.com/canonical/lxd/pull/18087)
- [<spellexception>Mark images as cached consistently</spellexception>](https://github.com/canonical/lxd/pull/16686)
- [<spellexception>Fix deadlock by only taking storage pool and network creation lock for external API requests</spellexception>](https://github.com/canonical/lxd/pull/18115)
- [<spellexception>Network: Set veth/vtap host interface MTU to the larger of parent bridge or instance MTU</spellexception>](https://github.com/canonical/lxd/pull/18127)
- [<spellexception>Cluster: Fix cluster healing functionality</spellexception>](https://github.com/canonical/lxd/pull/18151)

<a id="ref-release-notes-6-8-incompatible"></a>

## Backwards-incompatible changes

These changes are not compatible with older versions of LXD or its clients.

### MAAS controller support removed

The MAAS controller integration has been removed from LXD.
This removes all `maas.api.url`, `maas.api.key`, and `maas.machine` configuration keys, as well as the `maas.subnet.ipv4` and `maas.subnet.ipv6` NIC device options.

On upgrade, a patch automatically removes any MAAS-related configuration keys from the database.

### MinIO local object storage buckets removed

Local (non-Ceph) storage drivers no longer support object storage buckets.
Object storage buckets are now only supported by the `cephobject` driver.

The bundled `minio` binary and the `core.storage_buckets_address` configuration have been removed.
The `storage_buckets_local` API extension is no longer advertised.

### Ceph RBD and CephFS `source` configuration key dropped

The `source` configuration key for the `ceph` and `cephfs` storage drivers has been removed.
Use `ceph.osd.pool_name` for Ceph RBD pools and `cephfs.path` for CephFS pools instead.

On upgrade, a patch automatically unsets any stored `source` configuration keys for affected pools.

- API extension: [storage_remote_drop_source](../../api-extensions.md#extension-storage-remote-drop-source)

### FAN bridge `fan.type=ipip` support removed

Support for `fan.type=ipip` in bridge networks has been removed.
Only `fan.type=vxlan` (the default) remains supported.

### Cluster role `event-hub` removed

The `event-hub` cluster role has been removed in favor of the new `control-plane` role, which provides equivalent event-hub behaviour alongside full Raft control-plane functionality.
Existing `event-hub` role assignments are automatically migrated to `control-plane` on upgrade.

- API extension: [clustering_control_plane](../../api-extensions.md#extension-clustering-control-plane)

### Asynchronous storage pool, network, and storage bucket endpoints

Storage and network endpoints that were previously synchronous now return background operations.
This affects create, update, delete, and rename actions.

This includes storage pools, storage buckets (including bucket keys), networks, network ACLs, network zones, network zone records, network forwards, network load balancers and network peers.

Clients should check for this extension and handle the asynchronous response by waiting on the returned operation.
Operation metadata may include additional data, such as storage bucket admin credentials on bucket creation.

- API extension: [storage_and_network_operations](../../api-extensions.md#extension-storage-and-network-operations)

### Operation `resources` metadata no longer populated

Operation `resources` entries are now intentionally emptied and should no longer be relied upon by clients.

Historically, some clients used `resources` to infer the URL of entities created or affected by asynchronous operations.
With the 6.8 changes, clients should treat `entity_url` as authoritative for the operation target and, for rename operations, use `original_entity_url` (old URL) together with `entity_url` (new URL).

The `resources` field will be used in the future to record associated entities for an operation.

- API extension: [bulk_operations](../../api-extensions.md#extension-bulk-operations)

### Public images restricted to the default project

Public images can no longer be created in non-default projects.
Attempts to mark images as public in non-default projects via image creation or update API endpoints will be rejected.

Images in non-default projects cannot be accessed by unauthenticated or unauthorized clients; only authenticated clients with appropriate permissions can view them.
To share images publicly, they must be created in or moved to the default project.

This change supports the forthcoming Image Registries feature.

### Migration pull mode into restricted projects no longer allowed

It is no longer possible to migrate instances and storage volumes into a restricted project when using `pull` migration mode.

### Go SDK changes

The following backwards-incompatible changes were made to the LXD Go SDK and will require updates to consuming applications.
These client functions are made to be backward compatible with older LXD servers.

- Storage pool `Create`, `Update`, and `Delete` functions now return an `Operation`.
- Storage bucket and bucket key `Create`, `Update`, and `Delete` functions now return an `Operation`.
- Network `Create`, `Update`, `Delete`, and `Rename` functions now return an `Operation`.
- Network ACL `Create`, `Update`, `Delete`, and `Rename` functions now return an `Operation`.
- Network peer `Create`, `Update`, and `Delete` functions now return an `Operation`.
- Network zone and network zone record `Create`, `Update`, and `Delete` functions now return an `Operation`.
- `GetInstances` variants unified into a single `GetInstances` method accepting an `args` struct.

<a id="ref-release-notes-6-8-deprecated"></a>

## Deprecated features

These features are removed in this release.

### MAAS integration removed

All MAAS-related configuration options have been removed (see [Backwards-incompatible changes]() above).

### Local MinIO storage buckets removed

Local object storage bucket support using MinIO has been removed (see [Backwards-incompatible changes]() above).

## Known issues

### ARM64 VM Boot Failures (Synchronous Exception)

Booting virtual machines on ARM64 hardware (such as Raspberry Pi 4 and 5) may result in a Synchronous Exception early in the UEFI boot process.

Impact: Ubuntu 22.04 VMs fail to boot immediately. Ubuntu 24.04 VMs are also affected, with the failure threshold depending on the host’s available memory.
Cause: This bug is tied to Secure Boot and is hypothesized to be related to memory availability and layout.

The workaround for now is disabling Secure Boot (setting [`boot.mode`](../instance_options.md#instance-boot:boot.mode) to `uefi-nosecureboot`).

### EDK2 update: vTPM measurement shift

The EDK2 rebase to `2025.11-3ubuntu7` updates the authenticated UEFI variables (`KEK` and `db`), which modifies the platform state and causes a shift in measurements within the virtual Trusted Platform Module (`vTPM`).

Consequently, integrity validation will fail during the next boot for guests using TPM-bound LUKS profiles on Linux or BitLocker Device Encryption on modern Windows (11+). These systems will require manual entry of a recovery key or passphrase to proceed from recovery mode.

Administrators must secure and back up all guest recovery keys (BitLocker) and passphrases (LUKS) before upgrading LXD or restarting virtual machine instances.

For more details, see [<spellexception>[FFe + SRU] edk2: Introduce FirmwareSecvarUpdater for MS 2023 CA rollout</spellexception>](https://bugs.launchpad.net/ubuntu/+source/edk2/+bug/2146560) and the [Discourse post](https://discourse.ubuntu.com/t/microsoft-uefi-ca-rotation-what-it-means-for-ubuntu-users-and-vendors/82652) accompanying it.

<a id="ref-release-notes-6-8-go"></a>

## Updated minimum Go version

If you are building LXD from source instead of using a package manager, the minimum version of Go required to build LXD is now 1.26.2.

<a id="ref-release-notes-6-8-snap"></a>

## Snap packaging changes

- Minimum required `snapd` raised to `2.64`.
- Dqlite bumped to `v1.18.6`.
- QEMU bumped to `10.2.1+ds-1ubuntu3`.
- EDK2 rebased to `2025.11-3ubuntu7`.
- NVIDIA container toolkit updated to `1.19.0`.
- Go toolchain for snap builds bumped to `go1.26`.
- Removed MinIO-related snap config (`minio.path`) and MinIO support bits.
- Added the `ovn-env` plug for MicroOVN integration.
- Updated LXCFS handling to align with `pidfs` defaults and removed obsolete `lxcfs.pidfd` options/checks.
- Refactored ZFS setup through a dedicated `setup-zfs` helper script, including improved error handling and fallback behavior.

<a id="ref-release-notes-6-8-changelog"></a>

## Change log

View the [complete list of all changes in this release](https://github.com/canonical/lxd/compare/lxd-6.7...lxd-6.8).

<a id="ref-release-notes-6-8-downloads"></a>

## Downloads

The source tarballs and binary clients can be found on our [download page](https://github.com/canonical/lxd/releases/tag/lxd-6.8).

Binary packages are also available for:

- **Linux:** `snap install lxd --channel=6/stable`
- **MacOS client:** `brew install lxc`
- **Windows client:** `choco install lxc`


# index.html.md

<a id="lxc-md"></a>

# `lxc`

Command line client for LXD

## Synopsis

Description:
Command line client for LXD

All of LXD’s features can be driven through the various commands below.
For help with any of those, simply call them with –help.

## Options

```none
      --all            Show less common commands
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc alias](lxc/alias.md#lxc-alias-md)	 - Manage command aliases
* [lxc auth](lxc/auth.md#lxc-auth-md)	 - Manage user authorization
* [lxc cluster](lxc/cluster.md#lxc-cluster-md)	 - Manage cluster members
* [lxc completion](lxc/completion.md#lxc-completion-md)	 - Generate the autocompletion script for the specified shell
* [lxc config](lxc/config.md#lxc-config-md)	 - Manage instance and server configuration options
* [lxc console](lxc/console.md#lxc-console-md)	 - Attach to instance consoles
* [lxc copy](lxc/copy.md#lxc-copy-md)	 - Copy instance within or in between LXD servers
* [lxc delete](lxc/delete.md#lxc-delete-md)	 - Delete instances and snapshots
* [lxc exec](lxc/exec.md#lxc-exec-md)	 - Execute command in instance
* [lxc export](lxc/export.md#lxc-export-md)	 - Export instance backups
* [lxc file](lxc/file.md#lxc-file-md)	 - Manage files in instances
* [lxc image](lxc/image.md#lxc-image-md)	 - Manage images
* [lxc import](lxc/import.md#lxc-import-md)	 - Import instance backups
* [lxc info](lxc/info.md#lxc-info-md)	 - Show instance or server information
* [lxc init](lxc/init.md#lxc-init-md)	 - Create instances from images
* [lxc launch](lxc/launch.md#lxc-launch-md)	 - Create and start instances from images
* [lxc list](lxc/list.md#lxc-list-md)	 - List instances
* [lxc manpage](lxc/manpage.md#lxc-manpage-md)	 - Generate manpages for all commands
* [lxc monitor](lxc/monitor.md#lxc-monitor-md)	 - Monitor a local or remote LXD server
* [lxc move](lxc/move.md#lxc-move-md)	 - Move instance within or in between LXD servers
* [lxc network](lxc/network.md#lxc-network-md)	 - Manage and attach instances to networks
* [lxc operation](lxc/operation.md#lxc-operation-md)	 - Manage background operations
* [lxc pause](lxc/pause.md#lxc-pause-md)	 - Pause instances
* [lxc placement-group](lxc/placement-group.md#lxc-placement-group-md)	 - Manage placement groups
* [lxc profile](lxc/profile.md#lxc-profile-md)	 - Manage profiles
* [lxc project](lxc/project.md#lxc-project-md)	 - Manage projects
* [lxc publish](lxc/publish.md#lxc-publish-md)	 - Publish instance as images
* [lxc query](lxc/query.md#lxc-query-md)	 - Send a raw query to LXD
* [lxc rebuild](lxc/rebuild.md#lxc-rebuild-md)	 - Rebuild instance
* [lxc remote](lxc/remote.md#lxc-remote-md)	 - Manage the list of remote servers
* [lxc rename](lxc/rename.md#lxc-rename-md)	 - Rename instances and snapshots
* [lxc replicator](lxc/replicator.md#lxc-replicator-md)	 - Manage replicators
* [lxc restart](lxc/restart.md#lxc-restart-md)	 - Restart instances
* [lxc restore](lxc/restore.md#lxc-restore-md)	 - Restore instances from snapshots
* [lxc snapshot](lxc/snapshot.md#lxc-snapshot-md)	 - Create instance snapshot
* [lxc start](lxc/start.md#lxc-start-md)	 - Start instances
* [lxc stop](lxc/stop.md#lxc-stop-md)	 - Stop instances
* [lxc storage](lxc/storage.md#lxc-storage-md)	 - Manage storage pools and volumes
* [lxc version](lxc/version.md#lxc-version-md)	 - Show local and remote versions
* [lxc warning](lxc/warning.md#lxc-warning-md)	 - Manage warnings


# index.html.md

<a id="lxc-rename-md"></a>

# `lxc rename`

Rename instances and snapshots

## Synopsis

Description:
Rename instances and snapshots

```none
lxc rename [<remote>:]<instance>[/<snapshot>] <instance>[/<snapshot>] [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc](../lxc.md#lxc-md)	 - Command line client for LXD


# index.html.md

<a id="lxc-start-md"></a>

# `lxc start`

Start instances

## Synopsis

Description:
Start instances

```none
lxc start [<remote>:]<instance> [[<remote>:]<instance>...] [flags]
```

## Options

```none
      --all                   Run against all instances
      --console[="console"]   Immediately attach to the console
      --stateless             Ignore the instance state
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc](../lxc.md#lxc-md)	 - Command line client for LXD


# index.html.md

<a id="lxc-delete-md"></a>

# `lxc delete`

Delete instances and snapshots

## Synopsis

Description:
Delete instances and snapshots

```none
lxc delete [<remote>:]<instance>[/<snapshot>] [[<remote>:]<instance>[/<snapshot>]...] [flags]
```

## Options

```none
      --disk-volumes   Disk volumes mode for snapshot deletion. Possible values are "root" (default) and "all-exclusive". "root" only deletes the instance's root disk volume snapshot. "all-exclusive" deletes the instance's root disk volume snapshot and any exclusively attached volumes (non-shared) snapshots.
  -f, --force          Force the removal of running instances
  -i, --interactive    Require user confirmation
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc](../lxc.md#lxc-md)	 - Command line client for LXD


# index.html.md

<a id="lxc-storage-md"></a>

# `lxc storage`

Manage storage pools and volumes

## Synopsis

Description:
Manage storage pools and volumes

```none
lxc storage [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc](../lxc.md#lxc-md)	 - Command line client for LXD
* [lxc storage bucket](storage/bucket.md#lxc-storage-bucket-md)	 - Manage storage buckets
* [lxc storage create](storage/create.md#lxc-storage-create-md)	 - Create storage pools
* [lxc storage delete](storage/delete.md#lxc-storage-delete-md)	 - Delete storage pool
* [lxc storage edit](storage/edit.md#lxc-storage-edit-md)	 - Edit storage pool configurations as YAML
* [lxc storage get](storage/get.md#lxc-storage-get-md)	 - Get value for storage pool configuration key
* [lxc storage info](storage/info.md#lxc-storage-info-md)	 - Show useful information about storage pool
* [lxc storage list](storage/list.md#lxc-storage-list-md)	 - List available storage pools
* [lxc storage set](storage/set.md#lxc-storage-set-md)	 - Set storage pool configuration key
* [lxc storage show](storage/show.md#lxc-storage-show-md)	 - Show storage pool configurations and resources
* [lxc storage unset](storage/unset.md#lxc-storage-unset-md)	 - Unset storage pool configuration key
* [lxc storage volume](storage/volume.md#lxc-storage-volume-md)	 - Manage storage volumes


# index.html.md

<a id="lxc-remote-md"></a>

# `lxc remote`

Manage the list of remote servers

## Synopsis

Description:
Manage the list of remote servers

```none
lxc remote [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc](../lxc.md#lxc-md)	 - Command line client for LXD
* [lxc remote add](remote/add.md#lxc-remote-add-md)	 - Add new remote server
* [lxc remote get-default](remote/get-default.md#lxc-remote-get-default-md)	 - Show the default remote
* [lxc remote list](remote/list.md#lxc-remote-list-md)	 - List the available remotes
* [lxc remote remove](remote/remove.md#lxc-remote-remove-md)	 - Remove remote
* [lxc remote rename](remote/rename.md#lxc-remote-rename-md)	 - Rename remote
* [lxc remote set-url](remote/set-url.md#lxc-remote-set-url-md)	 - Set the URL for the remote
* [lxc remote switch](remote/switch.md#lxc-remote-switch-md)	 - Switch the default remote


# index.html.md

<a id="lxc-copy-md"></a>

# `lxc copy`

Copy instance within or in between LXD servers

## Synopsis

Description:
Copy instance within or in between LXD servers

Transfer modes (–mode):

- pull: Target server pulls the data from the source server (source must listen on network)
- push: Source server pushes the data to the target server (target must listen on network)
- relay: The CLI connects to both source and server and proxies the data (both source and target must listen on network)

The pull transfer mode is the default as it is compatible with all LXD versions.

```none
lxc copy [<remote>:]<source>[/<snapshot>] [[<remote>:]<destination>] [flags]
```

## Options

```none
      --allow-inconsistent   Ignore copy errors for volatile files
  -c, --config               Config key/value to apply to the new instance
  -d, --device               New key/value to apply to a specific device
  -e, --ephemeral            Ephemeral instance
      --instance-only        Copy the instance without its snapshots
      --mode                 Transfer mode. One of pull, push or relay (default "pull")
      --no-profiles          Create the instance with no profiles applied
  -p, --profile              Profile to apply to the new instance
      --refresh              Perform an incremental copy
      --start                Start instance after copy
      --stateless            Copy a stateful instance stateless
  -s, --storage              Storage pool name
      --target               Cluster member name
      --target-project       Copy to a project different from the source
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc](../lxc.md#lxc-md)	 - Command line client for LXD


# index.html.md

<a id="lxc-restore-md"></a>

# `lxc restore`

Restore instances from snapshots

## Synopsis

Description:
Restore instances from snapshots

If –stateful is passed, then the running state will be restored too.

```none
lxc restore [<remote>:]<instance> <snapshot> [flags]
```

## Examples

```none
  lxc snapshot u1 snap0
      Create the snapshot.

  lxc restore u1 snap0
      Restore the snapshot.
```

## Options

```none
      --disk-volumes string   Disk volumes mode. Possible values are "root" (default) and "all-exclusive". "root" only restores the instance's root disk volume. "all-exclusive" restores the instance's root disk and any exclusively attached volumes (non-shared) snapshots.
      --stateful              Whether or not to restore the instance's running state from snapshot (if available)
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc](../lxc.md#lxc-md)	 - Command line client for LXD


# index.html.md

<a id="lxc-monitor-md"></a>

# `lxc monitor`

Monitor a local or remote LXD server

## Synopsis

Description:
Monitor a local or remote LXD server

By default the monitor will listen to all message types.

```none
lxc monitor [<remote>:] [flags]
```

## Examples

```none
  lxc monitor --type=logging
      Only show log messages.

  lxc monitor --pretty --type=logging --loglevel=info
      Show a pretty log of messages with info level or higher.

  lxc monitor --type=lifecycle
      Only show lifecycle events.
```

## Options

```none
      --all-projects   Show events from all projects
  -f, --format         Format (json|pretty|yaml) (default "yaml")
      --loglevel       Minimum level for log messages (only available when using pretty format)
      --pretty         Pretty rendering (short for --format=pretty)
      --type           Event type to listen for
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc](../lxc.md#lxc-md)	 - Command line client for LXD


# index.html.md

<a id="lxc-info-md"></a>

# `lxc info`

Show instance or server information

## Synopsis

Description:
Show instance or server information

```none
lxc info [<remote>:][<instance>] [flags]
```

## Examples

```none
  lxc info [<remote>:]<instance> [--show-log]
      For instance information.

  lxc info [<remote>:] [--resources]
      For LXD server information.
```

## Options

```none
      --resources   Show the resources available to the server
      --show-log    Show the instance's last 100 log lines
      --target      Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc](../lxc.md#lxc-md)	 - Command line client for LXD


# index.html.md

<a id="lxc-image-md"></a>

# `lxc image`

Manage images

## Synopsis

Description:
Manage images

In LXD instances are created from images. Those images were themselves
either generated from an existing instance or downloaded from an image
server.

When using remote images, LXD will automatically cache images for you
and remove them upon expiration.

The image unique identifier is the hash (sha-256) of its representation
as a compressed tarball (or for split images, the concatenation of the
metadata and rootfs tarballs).

Images can be referenced by their full hash, shortest unique partial
hash or alias name (if one is set).

```none
lxc image [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc](../lxc.md#lxc-md)	 - Command line client for LXD
* [lxc image alias](image/alias.md#lxc-image-alias-md)	 - Manage image aliases
* [lxc image copy](image/copy.md#lxc-image-copy-md)	 - Copy image between servers
* [lxc image delete](image/delete.md#lxc-image-delete-md)	 - Delete images
* [lxc image edit](image/edit.md#lxc-image-edit-md)	 - Edit image properties
* [lxc image export](image/export.md#lxc-image-export-md)	 - Export and download images
* [lxc image get-property](image/get-property.md#lxc-image-get-property-md)	 - Get image property
* [lxc image import](image/import.md#lxc-image-import-md)	 - Import image into the image store
* [lxc image info](image/info.md#lxc-image-info-md)	 - Show useful information about image
* [lxc image list](image/list.md#lxc-image-list-md)	 - List images
* [lxc image refresh](image/refresh.md#lxc-image-refresh-md)	 - Refresh images
* [lxc image set-property](image/set-property.md#lxc-image-set-property-md)	 - Set image property
* [lxc image show](image/show.md#lxc-image-show-md)	 - Show image properties
* [lxc image unset-property](image/unset-property.md#lxc-image-unset-property-md)	 - Unset image property


# index.html.md

<a id="lxc-rebuild-md"></a>

# `lxc rebuild`

Rebuild instance

## Synopsis

Description:
Wipe the instance root disk and re-initialize.
The original image is used to re-initialize the instance if a different image or –empty is not specified.

Note: The –project flag sets the project for both the image remote and the instance remote.
If the image remote is a public remote (e.g. simplestreams) then this project is ignored by the image remote.
If the image remote is another LXD server, specify the source project for the image remote
with –project and the instance remote with –target-project (if different from –project).

```none
lxc rebuild [<remote>:]<image> [<remote>:]<instance> [flags]
```

## Options

```none
      --empty            Rebuild as an empty instance
  -f, --force            If an instance is running, stop it and then rebuild it
      --target-project   Project containing the instance (if different from --project)
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc](../lxc.md#lxc-md)	 - Command line client for LXD


# index.html.md

<a id="lxc-stop-md"></a>

# `lxc stop`

Stop instances

## Synopsis

Description:
Stop instances

```none
lxc stop [<remote>:]<instance> [[<remote>:]<instance>...] [flags]
```

## Options

```none
      --all                   Run against all instances
      --console[="console"]   Immediately attach to the console
  -f, --force                 Force the instance to stop
      --stateful              Store the instance state
      --timeout               Time to wait for the instance to shutdown cleanly (default -1)
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc](../lxc.md#lxc-md)	 - Command line client for LXD


# index.html.md

<a id="lxc-auth-md"></a>

# `lxc auth`

Manage user authorization

## Synopsis

Description:
Manage user authorization

```none
lxc auth [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc](../lxc.md#lxc-md)	 - Command line client for LXD
* [lxc auth group](auth/group.md#lxc-auth-group-md)	 - Manage groups
* [lxc auth identity](auth/identity.md#lxc-auth-identity-md)	 - Manage identities
* [lxc auth identity-provider-group](auth/identity-provider-group.md#lxc-auth-identity-provider-group-md)	 - Manage groups
* [lxc auth oidc-session](auth/oidc-session.md#lxc-auth-oidc-session-md)	 - Manage OIDC sessions
* [lxc auth permission](auth/permission.md#lxc-auth-permission-md)	 - Inspect permissions


# index.html.md

<a id="lxc-console-md"></a>

# `lxc console`

Attach to instance consoles

## Synopsis

Description:
Attach to instance consoles

This command allows you to interact with the boot console of an instance
as well as retrieve past log entries from it.

```none
lxc console [<remote>:]<instance> [flags]
```

## Options

```none
      --show-log   Retrieve the container's console log
  -t, --type       Type of connection to establish: 'console' for serial console, 'vga' for SPICE graphical output (default "console")
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc](../lxc.md#lxc-md)	 - Command line client for LXD


# index.html.md

<a id="lxc-pause-md"></a>

# `lxc pause`

Pause instances

## Synopsis

Description:
Pause instances

The opposite of “lxc pause” is “lxc start”.

```none
lxc pause [<remote>:]<instance> [[<remote>:]<instance>...] [flags]
```

## Options

```none
      --all   Run against all instances
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc](../lxc.md#lxc-md)	 - Command line client for LXD


# index.html.md

<a id="lxc-network-md"></a>

# `lxc network`

Manage and attach instances to networks

## Synopsis

Description:
Manage and attach instances to networks

```none
lxc network [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc](../lxc.md#lxc-md)	 - Command line client for LXD
* [lxc network acl](network/acl.md#lxc-network-acl-md)	 - Manage network ACLs
* [lxc network attach](network/attach.md#lxc-network-attach-md)	 - Attach network interface to instance
* [lxc network attach-profile](network/attach-profile.md#lxc-network-attach-profile-md)	 - Attach network interface to profile
* [lxc network create](network/create.md#lxc-network-create-md)	 - Create new network
* [lxc network delete](network/delete.md#lxc-network-delete-md)	 - Delete network
* [lxc network detach](network/detach.md#lxc-network-detach-md)	 - Detach network interface from instance
* [lxc network detach-profile](network/detach-profile.md#lxc-network-detach-profile-md)	 - Detach network interface from profile
* [lxc network edit](network/edit.md#lxc-network-edit-md)	 - Edit network configuration as YAML
* [lxc network forward](network/forward.md#lxc-network-forward-md)	 - Manage network forwards
* [lxc network get](network/get.md#lxc-network-get-md)	 - Get value for network configuration key
* [lxc network info](network/info.md#lxc-network-info-md)	 - Get runtime information on network
* [lxc network list](network/list.md#lxc-network-list-md)	 - List networks
* [lxc network list-allocations](network/list-allocations.md#lxc-network-list-allocations-md)	 - List network allocations in use
* [lxc network list-leases](network/list-leases.md#lxc-network-list-leases-md)	 - List DHCP leases
* [lxc network load-balancer](network/load-balancer.md#lxc-network-load-balancer-md)	 - Manage network load balancers
* [lxc network peer](network/peer.md#lxc-network-peer-md)	 - Manage network peerings
* [lxc network rename](network/rename.md#lxc-network-rename-md)	 - Rename network
* [lxc network set](network/set.md#lxc-network-set-md)	 - Set network configuration keys
* [lxc network show](network/show.md#lxc-network-show-md)	 - Show network configurations
* [lxc network unset](network/unset.md#lxc-network-unset-md)	 - Unset network configuration key
* [lxc network zone](network/zone.md#lxc-network-zone-md)	 - Manage network zones


# index.html.md

<a id="lxc-profile-md"></a>

# `lxc profile`

Manage profiles

## Synopsis

Description:
Manage profiles

```none
lxc profile [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc](../lxc.md#lxc-md)	 - Command line client for LXD
* [lxc profile add](profile/add.md#lxc-profile-add-md)	 - Add profile to instance
* [lxc profile assign](profile/assign.md#lxc-profile-assign-md)	 - Assign sets of profiles to instance
* [lxc profile copy](profile/copy.md#lxc-profile-copy-md)	 - Copy profile
* [lxc profile create](profile/create.md#lxc-profile-create-md)	 - Create profile
* [lxc profile delete](profile/delete.md#lxc-profile-delete-md)	 - Delete profile
* [lxc profile device](profile/device.md#lxc-profile-device-md)	 - Manage devices
* [lxc profile edit](profile/edit.md#lxc-profile-edit-md)	 - Edit profile configurations as YAML
* [lxc profile get](profile/get.md#lxc-profile-get-md)	 - Get value for profile configuration key
* [lxc profile list](profile/list.md#lxc-profile-list-md)	 - List profiles
* [lxc profile remove](profile/remove.md#lxc-profile-remove-md)	 - Remove profile from instance
* [lxc profile rename](profile/rename.md#lxc-profile-rename-md)	 - Rename profile
* [lxc profile set](profile/set.md#lxc-profile-set-md)	 - Set profile configuration keys
* [lxc profile show](profile/show.md#lxc-profile-show-md)	 - Show profile configurations
* [lxc profile unset](profile/unset.md#lxc-profile-unset-md)	 - Unset profile configuration key


# index.html.md

<a id="lxc-export-md"></a>

# `lxc export`

Export instance backups

## Synopsis

Description:
Export instances as backup tarballs.

```none
lxc export [<remote>:]<instance> [target] [--instance-only] [--optimized-storage] [flags]
```

## Examples

```none
  lxc export u1 backup0.tar.gz
      Download a backup tarball of the u1 instance.
```

## Options

```none
      --compression         Compression algorithm to use (none for uncompressed)
      --export-version      Use a different metadata format version than the latest one supported by the server (to support imports on older LXD versions)
      --instance-only       Whether or not to only backup the instance (without snapshots)
      --optimized-storage   Use storage driver optimized format (can only be restored on a similar pool)
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc](../lxc.md#lxc-md)	 - Command line client for LXD


# index.html.md

<a id="lxc-file-md"></a>

# `lxc file`

Manage files in instances

## Synopsis

Description:
Manage files in instances

```none
lxc file [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc](../lxc.md#lxc-md)	 - Command line client for LXD
* [lxc file create](file/create.md#lxc-file-create-md)	 - Create file, directory or symlink in instance
* [lxc file delete](file/delete.md#lxc-file-delete-md)	 - Delete files in instances
* [lxc file edit](file/edit.md#lxc-file-edit-md)	 - Edit file in instance
* [lxc file mount](file/mount.md#lxc-file-mount-md)	 - Mount path from instance
* [lxc file pull](file/pull.md#lxc-file-pull-md)	 - Pull files from instances
* [lxc file push](file/push.md#lxc-file-push-md)	 - Push files into instances


# index.html.md

<a id="lxc-query-md"></a>

# `lxc query`

Send a raw query to LXD

## Synopsis

Description:
Send a raw query to LXD

```none
lxc query [<remote>:]<API path> [flags]
```

## Examples

```none
  lxc query -X DELETE --wait /1.0/instances/c1
      Delete local instance "c1".
```

## Options

```none
  -d, --data      Input data
      --raw       Print the raw response
  -X, --request   Action (default "GET")
      --wait      Wait for the operation to complete
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc](../lxc.md#lxc-md)	 - Command line client for LXD


# index.html.md

<a id="lxc-exec-md"></a>

# `lxc exec`

Execute command in instance

## Synopsis

Description:
Execute command in instance

The command is executed directly using exec, so there is no shell and
shell patterns (variables, file redirects, …) will not be understood.
If you need a shell environment you need to execute the shell
executable, passing the shell commands as arguments, for example:

```none
lxc exec <instance> -- sh -c "cd /tmp && pwd"
```

For interactive sessions, a convenient ‘shell’ alias is provided to
spawn a login shell inside the instance:

```none
lxc shell <instance>
```

This ‘shell’ alias is a shorthand for:

```none
lxc exec <instance> -- su -l
```

Note: due to using ‘su -l’, most environment variables will be reset.

Mode defaults to non-interactive, interactive mode is selected if both stdin AND stdout are terminals (stderr is ignored).

```none
lxc exec [<remote>:]<instance> [flags] [--] <command line>
```

## Options

```none
      --cwd                    Directory to run the command in (default /root)
  -n, --disable-stdin          Disable stdin (reads from /dev/null)
      --env                    Environment variable to set (e.g. HOME=/home/foo)
  -t, --force-interactive      Force pseudo-terminal allocation
  -T, --force-noninteractive   Disable pseudo-terminal allocation
      --group                  Group ID to run the command as (default 0)
      --mode                   Override the terminal mode (auto, interactive or non-interactive) (default "auto")
      --user                   User ID to run the command as (default 0)
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc](../lxc.md#lxc-md)	 - Command line client for LXD


# index.html.md

<a id="lxc-publish-md"></a>

# `lxc publish`

Publish instance as images

## Synopsis

Description:
Publish instance as images

```none
lxc publish [<remote>:]<instance>[/<snapshot>] [<remote>:] [flags] [key=value...]
```

## Options

```none
      --alias              New alias to define at target
      --compression none   Compression algorithm to use (none for uncompressed)``
      --expire             Image expiration date (format: rfc3339)
  -f, --force              Stop the instance if currently running
      --public             Make the image public (accessible to unauthenticated clients as well)
      --reuse              If the image alias already exists, delete and create a new one
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc](../lxc.md#lxc-md)	 - Command line client for LXD


# index.html.md

<a id="lxc-alias-md"></a>

# `lxc alias`

Manage command aliases

## Synopsis

Description:
Manage command aliases

```none
lxc alias [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc](../lxc.md#lxc-md)	 - Command line client for LXD
* [lxc alias add](alias/add.md#lxc-alias-add-md)	 - Add new alias
* [lxc alias edit](alias/edit.md#lxc-alias-edit-md)	 - Edit aliases
* [lxc alias list](alias/list.md#lxc-alias-list-md)	 - List aliases
* [lxc alias remove](alias/remove.md#lxc-alias-remove-md)	 - Remove alias
* [lxc alias rename](alias/rename.md#lxc-alias-rename-md)	 - Rename alias
* [lxc alias show](alias/show.md#lxc-alias-show-md)	 - Show aliases in YAML format


# index.html.md

<a id="lxc-warning-md"></a>

# `lxc warning`

Manage warnings

## Synopsis

Description:
Manage warnings

```none
lxc warning [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc](../lxc.md#lxc-md)	 - Command line client for LXD
* [lxc warning acknowledge](warning/acknowledge.md#lxc-warning-acknowledge-md)	 - Acknowledge warning
* [lxc warning delete](warning/delete.md#lxc-warning-delete-md)	 - Delete warning
* [lxc warning list](warning/list.md#lxc-warning-list-md)	 - List warnings
* [lxc warning show](warning/show.md#lxc-warning-show-md)	 - Show warning


# index.html.md

<a id="lxc-project-md"></a>

# `lxc project`

Manage projects

## Synopsis

Description:
Manage projects

```none
lxc project [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc](../lxc.md#lxc-md)	 - Command line client for LXD
* [lxc project create](project/create.md#lxc-project-create-md)	 - Create project
* [lxc project delete](project/delete.md#lxc-project-delete-md)	 - Delete project
* [lxc project demote-replica](project/demote-replica.md#lxc-project-demote-replica-md)	 - Demote project to standby mode for replication
* [lxc project edit](project/edit.md#lxc-project-edit-md)	 - Edit project configurations as YAML
* [lxc project get](project/get.md#lxc-project-get-md)	 - Get value for project configuration key
* [lxc project get-current](project/get-current.md#lxc-project-get-current-md)	 - Show the current project
* [lxc project info](project/info.md#lxc-project-info-md)	 - Get a summary of resource allocations
* [lxc project list](project/list.md#lxc-project-list-md)	 - List projects
* [lxc project promote-replica](project/promote-replica.md#lxc-project-promote-replica-md)	 - Promote project to leader mode for replication
* [lxc project rename](project/rename.md#lxc-project-rename-md)	 - Rename project
* [lxc project set](project/set.md#lxc-project-set-md)	 - Set project configuration keys
* [lxc project show](project/show.md#lxc-project-show-md)	 - Show project options
* [lxc project switch](project/switch.md#lxc-project-switch-md)	 - Switch the current project
* [lxc project unset](project/unset.md#lxc-project-unset-md)	 - Unset project configuration key


# index.html.md

<a id="lxc-completion-md"></a>

# `lxc completion`

Generate the autocompletion script for the specified shell

## Synopsis

Generate the autocompletion script for lxc for the specified shell.
See each sub-command’s help for details on how to use the generated script.

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc](../lxc.md#lxc-md)	 - Command line client for LXD
* [lxc completion bash](completion/bash.md#lxc-completion-bash-md)	 - Generate the autocompletion script for bash
* [lxc completion fish](completion/fish.md#lxc-completion-fish-md)	 - Generate the autocompletion script for fish
* [lxc completion powershell](completion/powershell.md#lxc-completion-powershell-md)	 - Generate the autocompletion script for powershell
* [lxc completion zsh](completion/zsh.md#lxc-completion-zsh-md)	 - Generate the autocompletion script for zsh


# index.html.md

<a id="lxc-import-md"></a>

# `lxc import`

Import instance backups

## Synopsis

Description:
Import backups of instances including their snapshots.

```none
lxc import [<remote>:] <backup file> [<instance name>] [flags]
```

## Examples

```none
  lxc import backup0.tar.gz
      Create a new instance using backup0.tar.gz as the source.
```

## Options

```none
  -d, --device    New key/value to apply to a specific device
  -s, --storage   Storage pool name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc](../lxc.md#lxc-md)	 - Command line client for LXD


# index.html.md

<a id="lxc-init-md"></a>

# `lxc init`

Create instances from images

## Synopsis

Description:
Create instances from images

```none
lxc init [<remote>:]<image> [<remote>:][<name>] [flags]
```

## Examples

```none
  lxc init ubuntu:24.04 u1
      Create a container (but do not start it)

  lxc init ubuntu:24.04 u1 < config.yaml
      Create a container with configuration from config.yaml

  lxc init ubuntu:24.04 v1 --vm -c limits.cpu=4 -c limits.memory=4GiB
      Create a virtual machine with 4 vCPUs and 4GiB of RAM

  lxc init ubuntu:24.04 v1 --vm -c limits.cpu=2 -c limits.memory=8GiB -d root,size=32GiB
      Create a virtual machine with 2 vCPUs, 8GiB of RAM and a root disk of 32GiB

  Note: The --project flag sets the project for both the image remote and the instance remote.
  If the image remote is a public remote (e.g. simplestreams) then this project is ignored by the image remote.
  If the image remote is another LXD server, specify the source project for the image remote 
  with --project and the instance remote with --target-project (if different from --project).

```

## Options

```none
  -c, --config           Config key/value to apply to the new instance
  -d, --device           New key/value to apply to a specific device
      --empty            Create an empty instance
  -e, --ephemeral        Ephemeral instance
  -n, --network          Network name
      --no-profiles      Create the instance with no profiles applied
  -p, --profile          Profile to apply to the new instance
  -s, --storage          Storage pool name
      --target           Cluster member name
      --target-project   Project to create the instance in (if different from --project)
  -t, --type             Instance type
      --vm               Create a virtual machine
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc](../lxc.md#lxc-md)	 - Command line client for LXD


# index.html.md

<a id="lxc-config-md"></a>

# `lxc config`

Manage instance and server configuration options

## Synopsis

Description:
Manage instance and server configuration options

```none
lxc config [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc](../lxc.md#lxc-md)	 - Command line client for LXD
* [lxc config device](config/device.md#lxc-config-device-md)	 - Manage devices
* [lxc config edit](config/edit.md#lxc-config-edit-md)	 - Edit instance or server configurations as YAML
* [lxc config get](config/get.md#lxc-config-get-md)	 - Get value for instance or server configuration key
* [lxc config metadata](config/metadata.md#lxc-config-metadata-md)	 - Manage instance metadata files
* [lxc config set](config/set.md#lxc-config-set-md)	 - Set instance or server configuration keys
* [lxc config show](config/show.md#lxc-config-show-md)	 - Show instance or server configurations
* [lxc config template](config/template.md#lxc-config-template-md)	 - Manage instance file templates
* [lxc config trust](config/trust.md#lxc-config-trust-md)	 - Manage trusted clients
* [lxc config uefi](config/uefi.md#lxc-config-uefi-md)	 - Manage instance UEFI variables
* [lxc config unset](config/unset.md#lxc-config-unset-md)	 - Unset instance or server configuration key


# index.html.md

<a id="lxc-manpage-md"></a>

# `lxc manpage`

Generate manpages for all commands

## Synopsis

Description:
Generate manpages for all commands

```none
lxc manpage <target> [flags]
```

## Options

```none
  -f, --format   Format (man|md|rest|yaml) (default "man")
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc](../lxc.md#lxc-md)	 - Command line client for LXD


# index.html.md

<a id="lxc-snapshot-md"></a>

# `lxc snapshot`

Create instance snapshot

## Synopsis

Description:
Create instance snapshot

When –stateful is used, LXD attempts to checkpoint the instance’s
running state, including process memory state, TCP connections, …

```none
lxc snapshot [<remote>:]<instance> [<snapshot name>] [flags]
```

## Examples

```none
  lxc snapshot u1 snap0
  	Create a snapshot of "u1" called "snap0".

  	lxc snapshot u1 snap0 < config.yaml
  		Create a snapshot of "u1" called "snap0" with the configuration from "config.yaml".
```

## Options

```none
      --disk-volumes   Disk volumes mode. Possible values are "root" (default) and "all-exclusive". "root" only snapshots the instance's root disk volume. "all-exclusive" snapshots the instance's root disk and any exclusively attached volumes (non-shared).
      --no-expiry      Ignore any configured auto-expiry for the instance
      --reuse          If the snapshot name already exists, delete and create a new one
      --stateful       Whether or not to snapshot the instance's running state
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc](../lxc.md#lxc-md)	 - Command line client for LXD


# index.html.md

<a id="lxc-cluster-md"></a>

# `lxc cluster`

Manage cluster members

## Synopsis

Description:
Manage cluster members

```none
lxc cluster [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc](../lxc.md#lxc-md)	 - Command line client for LXD
* [lxc cluster add](cluster/add.md#lxc-cluster-add-md)	 - Request a join token for adding a cluster member
* [lxc cluster edit](cluster/edit.md#lxc-cluster-edit-md)	 - Edit cluster member configurations as YAML
* [lxc cluster enable](cluster/enable.md#lxc-cluster-enable-md)	 - Enable clustering on a single non-clustered LXD server
* [lxc cluster evacuate](cluster/evacuate.md#lxc-cluster-evacuate-md)	 - Evacuate cluster member
* [lxc cluster failure-domain](cluster/failure-domain.md#lxc-cluster-failure-domain-md)	 - Manage cluster member failure domains
* [lxc cluster get](cluster/get.md#lxc-cluster-get-md)	 - Get value for cluster member configuration key
* [lxc cluster group](cluster/group.md#lxc-cluster-group-md)	 - Manage cluster groups
* [lxc cluster info](cluster/info.md#lxc-cluster-info-md)	 - Show useful information about a cluster member
* [lxc cluster link](cluster/link.md#lxc-cluster-link-md)	 - Manage cluster links
* [lxc cluster list](cluster/list.md#lxc-cluster-list-md)	 - List all the cluster members
* [lxc cluster list-tokens](cluster/list-tokens.md#lxc-cluster-list-tokens-md)	 - List all active cluster member join tokens
* [lxc cluster remove](cluster/remove.md#lxc-cluster-remove-md)	 - Remove a member from the cluster
* [lxc cluster rename](cluster/rename.md#lxc-cluster-rename-md)	 - Rename a cluster member
* [lxc cluster restore](cluster/restore.md#lxc-cluster-restore-md)	 - Restore cluster member
* [lxc cluster revoke-token](cluster/revoke-token.md#lxc-cluster-revoke-token-md)	 - Revoke cluster member join token
* [lxc cluster role](cluster/role.md#lxc-cluster-role-md)	 - Manage cluster roles
* [lxc cluster set](cluster/set.md#lxc-cluster-set-md)	 - Set a cluster member’s configuration keys
* [lxc cluster show](cluster/show.md#lxc-cluster-show-md)	 - Show details of a cluster member
* [lxc cluster unset](cluster/unset.md#lxc-cluster-unset-md)	 - Unset a cluster member’s configuration key
* [lxc cluster update-certificate](cluster/update-certificate.md#lxc-cluster-update-certificate-md)	 - Update cluster certificate


# index.html.md

<a id="lxc-placement-group-md"></a>

# `lxc placement-group`

Manage placement groups

## Synopsis

Description:
Manage placement groups

```none
lxc placement-group [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc](../lxc.md#lxc-md)	 - Command line client for LXD
* [lxc placement-group create](placement-group/create.md#lxc-placement-group-create-md)	 - Create new placement group
* [lxc placement-group delete](placement-group/delete.md#lxc-placement-group-delete-md)	 - Delete placement group
* [lxc placement-group edit](placement-group/edit.md#lxc-placement-group-edit-md)	 - Edit placement group configurations as YAML
* [lxc placement-group get](placement-group/get.md#lxc-placement-group-get-md)	 - Get value for placement group configuration key
* [lxc placement-group list](placement-group/list.md#lxc-placement-group-list-md)	 - List available placement groups
* [lxc placement-group rename](placement-group/rename.md#lxc-placement-group-rename-md)	 - Rename placement group
* [lxc placement-group set](placement-group/set.md#lxc-placement-group-set-md)	 - Set placement group configuration keys
* [lxc placement-group show](placement-group/show.md#lxc-placement-group-show-md)	 - Show placement group configurations
* [lxc placement-group unset](placement-group/unset.md#lxc-placement-group-unset-md)	 - Unset placement group configuration key


# index.html.md

<a id="lxc-operation-md"></a>

# `lxc operation`

Manage background operations

## Synopsis

Description:
Manage background operations

```none
lxc operation [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc](../lxc.md#lxc-md)	 - Command line client for LXD
* [lxc operation delete](operation/delete.md#lxc-operation-delete-md)	 - Delete a background operation (will attempt to cancel)
* [lxc operation list](operation/list.md#lxc-operation-list-md)	 - List background operations
* [lxc operation show](operation/show.md#lxc-operation-show-md)	 - Show details of a background operation


# index.html.md

<a id="lxc-list-md"></a>

# `lxc list`

List instances

## Synopsis

Description:
List instances

Default column layout: ns46tS
Fast column layout: nsacPt

A single keyword like “web” which will list any instance with a name starting with “web”.
A regular expression on the instance name. (e.g. .\*web.\*01$).
A key/value pair referring to a configuration item. For those, the
namespace can be abbreviated to the smallest unambiguous identifier.
A key/value pair where the key is a shorthand. Multiple values must be delimited by ‘,’. Available shorthands:
- type={instance type}
- status={instance current lifecycle status}
- architecture={instance architecture}
- location={location name}
- ipv4={ip or CIDR}
- ipv6={ip or CIDR}

Examples:
- “user.blah=abc” will list all instances with the “blah” user property set to “abc”.
- “u.blah=abc” will do the same
- “security.privileged=true” will list all privileged instances
- “s.privileged=true” will do the same
- “type=container” will list all container instances
- “type=container status=running” will list all running container instances

A regular expression matching a configuration item or its value. (e.g. volatile.eth0.hwaddr=00:16:3e:.\*).

When multiple filters are passed, they are added one on top of the other,
selecting instances which satisfy them all.

== Columns ==
The -c option takes a comma separated list of arguments that control
which instance attributes to output when displaying in table or csv
format.

Column arguments are either pre-defined shorthand chars (see below),
or (extended) config keys.

Commas between consecutive shorthand chars are optional.

Pre-defined column shorthand chars:
4 - IPv4 address
6 - IPv6 address
a - Architecture
b - Storage pool
c - Creation date
d - Description
D - disk usage
e - Project name
l - Last used date
m - Memory usage
M - Memory usage (%)
n - Name
N - Number of Processes
p - PID of the instance’s init process
P - Profiles
s - State
S - Number of snapshots
t - Type (container or virtual-machine, ephemeral indicated if applicable)
u - CPU usage (in seconds)
L - Location of the instance (e.g. its cluster member)
f - Base Image Fingerprint (short)
F - Base Image Fingerprint (long)

Custom columns are defined with “[config:|devices:]key[:name][:maxWidth]”:
KEY: The (extended) config or devices key to display. If [config:|devices:] is omitted then it defaults to config key.
NAME: Name to display in the column header.
Defaults to the key if not specified or empty.

```none
MAXWIDTH: Max width of the column (longer results are truncated).
Defaults to -1 (unlimited). Use 0 to limit to the column header size.
```

```none
lxc list [<remote>:] [<filter>...] [flags]
```

## Examples

```none
  lxc list -c nFs46,volatile.eth0.hwaddr:MAC,config:image.os,devices:eth0.parent:ETHP
    Show instances using the "NAME", "BASE IMAGE", "STATE", "IPV4", "IPV6" and "MAC" columns.
    "BASE IMAGE", "MAC" and "IMAGE OS" are custom columns generated from instance configuration keys.
    "ETHP" is a custom column generated from a device key.

  lxc list -c ns,user.comment:comment
    List instances with their running state and user comment.
```

## Options

```none
      --all-projects   Display instances from all projects
  -c, --columns        Columns (default "ns46tSL")
      --fast           Fast mode (same as --columns=nsacPt)
  -f, --format         Format (csv|json|table|yaml|compact) (default "table")
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc](../lxc.md#lxc-md)	 - Command line client for LXD


# index.html.md

<a id="lxc-launch-md"></a>

# `lxc launch`

Create and start instances from images

## Synopsis

Description:
Create and start instances from images

```none
lxc launch [<remote>:]<image> [<remote>:][<name>] [flags]
```

## Examples

```none
  lxc launch ubuntu:24.04 u1
      Create and start a container

  lxc launch ubuntu:24.04 u1 < config.yaml
      Create and start a container with configuration from config.yaml

  lxc launch ubuntu:24.04 u2 -t aws:t2.micro
      Create and start a container using the same size as an AWS t2.micro (1 vCPU, 1GiB of RAM)

  lxc launch ubuntu:24.04 v1 --vm -c limits.cpu=4 -c limits.memory=4GiB
      Create and start a virtual machine with 4 vCPUs and 4GiB of RAM

  lxc launch ubuntu:24.04 v1 --vm -c limits.cpu=2 -c limits.memory=8GiB -d root,size=32GiB
      Create and start a virtual machine with 2 vCPUs, 8GiB of RAM and a root disk of 32GiB
```

## Options

```none
  -c, --config                Config key/value to apply to the new instance
      --console[="console"]   Immediately attach to the console
  -d, --device                New key/value to apply to a specific device
      --empty                 Create an empty instance
  -e, --ephemeral             Ephemeral instance
  -n, --network               Network name
      --no-profiles           Create the instance with no profiles applied
  -p, --profile               Profile to apply to the new instance
  -s, --storage               Storage pool name
      --target                Cluster member name
      --target-project        Project to create the instance in (if different from --project)
  -t, --type                  Instance type
      --vm                    Create a virtual machine
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc](../lxc.md#lxc-md)	 - Command line client for LXD


# index.html.md

<a id="lxc-version-md"></a>

# `lxc version`

Show local and remote versions

## Synopsis

Description:
Show local and remote versions

```none
lxc version [<remote>:] [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc](../lxc.md#lxc-md)	 - Command line client for LXD


# index.html.md

<a id="lxc-move-md"></a>

# `lxc move`

Move instance within or in between LXD servers

## Synopsis

Description:
Move instance within or in between LXD servers

Transfer modes (–mode):

- pull: Target server pulls the data from the source server (source must listen on network)
- push: Source server pushes the data to the target server (target must listen on network)
- relay: The CLI connects to both source and server and proxies the data (both source and target must listen on network)

The pull transfer mode is the default as it is compatible with all LXD versions.

```none
lxc move [<remote>:]<instance>[/<snapshot>] [<remote>:][<instance>[/<snapshot>]] [flags]
```

## Examples

```none
  lxc move [<remote>:]<source instance> [<remote>:][<destination instance>] [--instance-only]
      Move an instance between two hosts, renaming it if destination name differs.

  lxc move <old name> <new name> [--instance-only]
      Rename a local instance.

  lxc move <instance>/<old snapshot name> <instance>/<new snapshot name>
      Rename a snapshot.
```

## Options

```none
      --allow-inconsistent   Ignore copy errors for volatile files
  -c, --config               Config key/value to apply to the target instance
  -d, --device               New key/value to apply to a specific device
      --instance-only        Move the instance without its snapshots
      --mode                 Transfer mode. One of pull, push or relay. (default "pull")
      --no-profiles          Unset all profiles on the target instance
  -p, --profile              Profile to apply to the target instance
      --stateless            Copy a stateful instance as stateless
  -s, --storage              Storage pool name
      --target               Cluster member name
      --target-project       Copy to a project different from the source
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc](../lxc.md#lxc-md)	 - Command line client for LXD


# index.html.md

<a id="lxc-restart-md"></a>

# `lxc restart`

Restart instances

## Synopsis

Description:
Restart instances

```none
lxc restart [<remote>:]<instance> [[<remote>:]<instance>...] [flags]
```

## Options

```none
      --all                   Run against all instances
      --console[="console"]   Immediately attach to the console
  -f, --force                 Force the instance to stop
      --timeout               Time to wait for the instance to shutdown cleanly (default -1)
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc](../lxc.md#lxc-md)	 - Command line client for LXD


# index.html.md

<a id="lxc-replicator-md"></a>

# `lxc replicator`

Manage replicators

## Synopsis

Description:
Manage replicators

```none
lxc replicator [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc](../lxc.md#lxc-md)	 - Command line client for LXD
* [lxc replicator create](replicator/create.md#lxc-replicator-create-md)	 - Create replicators
* [lxc replicator delete](replicator/delete.md#lxc-replicator-delete-md)	 - Delete replicators
* [lxc replicator edit](replicator/edit.md#lxc-replicator-edit-md)	 - Edit replicator configurations as YAML
* [lxc replicator get](replicator/get.md#lxc-replicator-get-md)	 - Get values for replicator configuration keys
* [lxc replicator info](replicator/info.md#lxc-replicator-info-md)	 - Show replicator state and job information
* [lxc replicator list](replicator/list.md#lxc-replicator-list-md)	 - List replicators
* [lxc replicator rename](replicator/rename.md#lxc-replicator-rename-md)	 - Rename a replicator
* [lxc replicator run](replicator/run.md#lxc-replicator-run-md)	 - Run a replicator
* [lxc replicator set](replicator/set.md#lxc-replicator-set-md)	 - Set replicator configuration keys
* [lxc replicator show](replicator/show.md#lxc-replicator-show-md)	 - Show replicator configurations
* [lxc replicator unset](replicator/unset.md#lxc-replicator-unset-md)	 - Unset replicator configuration keys


# index.html.md

<a id="lxc-warning-show-md"></a>

# `lxc warning show`

Show warning

## Synopsis

Description:
Show warning

```none
lxc warning show [<remote>:]<warning-uuid> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc warning](../warning.md#lxc-warning-md)	 - Manage warnings


# index.html.md

<a id="lxc-warning-acknowledge-md"></a>

# `lxc warning acknowledge`

Acknowledge warning

## Synopsis

Description:
Acknowledge warning

```none
lxc warning acknowledge [<remote>:]<warning-uuid> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc warning](../warning.md#lxc-warning-md)	 - Manage warnings


# index.html.md

<a id="lxc-warning-delete-md"></a>

# `lxc warning delete`

Delete warning

## Synopsis

Description:
Delete warning

```none
lxc warning delete [<remote>:][<warning-uuid>] [flags]
```

## Options

```none
  -a, --all   Delete all warnings
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc warning](../warning.md#lxc-warning-md)	 - Manage warnings


# index.html.md

<a id="lxc-warning-list-md"></a>

# `lxc warning list`

List warnings

## Synopsis

Description:
List warnings

The -c option takes a (optionally comma-separated) list of arguments
that control which warning attributes to output when displaying in table
or csv format.

Default column layout is: utSscpLl

Column shorthand chars:

```none
  c - Count
  l - Last seen
  L - Location
  f - First seen
  p - Project
  s - Severity
  S - Status
  u - UUID
  t - Type
```

```none
lxc warning list [<remote>:] [flags]
```

## Options

```none
  -a, --all       List all warnings
  -c, --columns   Columns (default "utSscpLl")
  -f, --format    Format (csv|json|table|yaml|compact) (default "table")
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc warning](../warning.md#lxc-warning-md)	 - Manage warnings


# index.html.md

<a id="lxc-project-switch-md"></a>

# `lxc project switch`

Switch the current project

## Synopsis

Description:
Switch the current project

```none
lxc project switch [<remote>:]<project> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc project](../project.md#lxc-project-md)	 - Manage projects


# index.html.md

<a id="lxc-project-set-md"></a>

# `lxc project set`

Set project configuration keys

## Synopsis

Description:
Set project configuration keys

For backward compatibility, a single configuration key may still be set with:
lxc project set [<remote>:]<project> <key> <value>

```none
lxc project set [<remote>:]<project> <key>=<value>... [flags]
```

## Options

```none
  -p, --property   Set the key as a project property
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc project](../project.md#lxc-project-md)	 - Manage projects


# index.html.md

<a id="lxc-project-unset-md"></a>

# `lxc project unset`

Unset project configuration key

## Synopsis

Description:
Unset project configuration key

```none
lxc project unset [<remote>:]<project> <key> [flags]
```

## Options

```none
  -p, --property   Unset the key as a project property
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc project](../project.md#lxc-project-md)	 - Manage projects


# index.html.md

<a id="lxc-project-info-md"></a>

# `lxc project info`

Get a summary of resource allocations

## Synopsis

Description:
Get a summary of resource allocations

```none
lxc project info [<remote>:]<project> [flags]
```

## Options

```none
  -f, --format   Format (csv|json|table|yaml|compact) (default "table")
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc project](../project.md#lxc-project-md)	 - Manage projects


# index.html.md

<a id="lxc-project-promote-replica-md"></a>

# `lxc project promote-replica`

Promote project to leader mode for replication

## Synopsis

Description:
Promotes the project to leader mode for replication.

This validates that all replicator targets are in standby mode unless –force is specified.

```none
lxc project promote-replica [<remote>:]<project> [flags]
```

## Options

```none
  -f, --force   Skip validation of remote project states
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc project](../project.md#lxc-project-md)	 - Manage projects


# index.html.md

<a id="lxc-project-edit-md"></a>

# `lxc project edit`

Edit project configurations as YAML

## Synopsis

Description:
Edit project configurations as YAML

```none
lxc project edit [<remote>:]<project> [flags]
```

## Examples

```none
  lxc project edit <project> < project.yaml
      Update a project using the content of project.yaml
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc project](../project.md#lxc-project-md)	 - Manage projects


# index.html.md

<a id="lxc-project-get-md"></a>

# `lxc project get`

Get value for project configuration key

## Synopsis

Description:
Get value for project configuration key

```none
lxc project get [<remote>:]<project> <key> [flags]
```

## Options

```none
  -p, --property   Get the key as a project property
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc project](../project.md#lxc-project-md)	 - Manage projects


# index.html.md

<a id="lxc-project-demote-replica-md"></a>

# `lxc project demote-replica`

Demote project to standby mode for replication

## Synopsis

Description:
Demotes the project to standby mode for replication.

The project must have replica.cluster config set to identify which cluster can replicate to it, unless –force is specified.

```none
lxc project demote-replica [<remote>:]<project> [flags]
```

## Options

```none
  -f, --force   Skip validation of replica.cluster config
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc project](../project.md#lxc-project-md)	 - Manage projects


# index.html.md

<a id="lxc-project-show-md"></a>

# `lxc project show`

Show project options

## Synopsis

Description:
Show project options

```none
lxc project show [<remote>:]<project> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc project](../project.md#lxc-project-md)	 - Manage projects


# index.html.md

<a id="lxc-project-get-current-md"></a>

# `lxc project get-current`

Show the current project

## Synopsis

Description:
Show the current project

```none
lxc project get-current [<remote>:] [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc project](../project.md#lxc-project-md)	 - Manage projects


# index.html.md

<a id="lxc-project-delete-md"></a>

# `lxc project delete`

Delete project

## Synopsis

Description:
Delete project

```none
lxc project delete [<remote>:]<project> [flags]
```

## Options

```none
  -f, --force   Force delete project and its entities
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc project](../project.md#lxc-project-md)	 - Manage projects


# index.html.md

<a id="lxc-project-create-md"></a>

# `lxc project create`

Create project

## Synopsis

Description:
Create project

```none
lxc project create [<remote>:]<project> [flags]
```

## Examples

```none
  lxc project create p1

  lxc project create p1 < config.yaml
      Create a project with configuration from config.yaml
```

## Options

```none
  -c, --config    Config key/value to apply to the new project
  -n, --network   Add a NIC device to the default profile connected to the specified network
  -s, --storage   Add a storage pool to be used as the root device in the default profile
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc project](../project.md#lxc-project-md)	 - Manage projects


# index.html.md

<a id="lxc-project-rename-md"></a>

# `lxc project rename`

Rename project

## Synopsis

Description:
Rename project

```none
lxc project rename [<remote>:]<project> <new-name> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc project](../project.md#lxc-project-md)	 - Manage projects


# index.html.md

<a id="lxc-project-list-md"></a>

# `lxc project list`

List projects

## Synopsis

Description:
List projects

```none
lxc project list [<remote>:] [flags]
```

## Options

```none
  -c, --columns   Columns (default "nIPvbNzdur")
  -f, --format    Format (csv|json|table|yaml|compact) (default "table")
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc project](../project.md#lxc-project-md)	 - Manage projects


# index.html.md

<a id="lxc-replicator-list-md"></a>

# `lxc replicator list`

List replicators

## Synopsis

Description:
List replicators

```none
lxc replicator list [<remote>:] [flags]
```

## Options

```none
  -f, --format string   Format (csv|json|table|yaml|compact) (default "table")
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc replicator](../replicator.md#lxc-replicator-md)	 - Manage replicators


# index.html.md

<a id="lxc-replicator-delete-md"></a>

# `lxc replicator delete`

Delete replicators

## Synopsis

Description:
Delete replicators

```none
lxc replicator delete [<remote>:]<replicator> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc replicator](../replicator.md#lxc-replicator-md)	 - Manage replicators


# index.html.md

<a id="lxc-replicator-create-md"></a>

# `lxc replicator create`

Create replicators

## Synopsis

Description:
Create replicators

The “cluster” configuration key is required and must be set to the name of an existing cluster link.

```none
lxc replicator create [<remote>:]<replicator> [key=value...] [flags]
```

## Examples

```none
  lxc replicator create my-replicator cluster=lxd_two
      Create a replicator called "my-replicator" targeting the cluster link "lxd_two".

  lxc replicator create my-replicator cluster=lxd_two --project myproject
      Create a replicator in the project "myproject" targeting cluster link "lxd_two".

  lxc replicator create my-replicator < config.yaml
      Create a replicator with the configuration from "config.yaml".
```

## Options

```none
  -d, --description   Replicator description
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc replicator](../replicator.md#lxc-replicator-md)	 - Manage replicators


# index.html.md

<a id="lxc-replicator-unset-md"></a>

# `lxc replicator unset`

Unset replicator configuration keys

## Synopsis

Description:
Unset replicator configuration keys

```none
lxc replicator unset [<remote>:]<replicator> <key> [flags]
```

## Options

```none
  -p, --property   Unset the key as a replicator property
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc replicator](../replicator.md#lxc-replicator-md)	 - Manage replicators


# index.html.md

<a id="lxc-replicator-rename-md"></a>

# `lxc replicator rename`

Rename a replicator

## Synopsis

Description:
Rename a replicator

```none
lxc replicator rename [<remote>:]<replicator> <new-name> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc replicator](../replicator.md#lxc-replicator-md)	 - Manage replicators


# index.html.md

<a id="lxc-replicator-run-md"></a>

# `lxc replicator run`

Run a replicator

## Synopsis

Description:
Run a replicator

Runs the replicator, copying all instances in the source project to the target cluster.

```none
lxc replicator run [<remote>:]<replicator> [flags]
```

## Examples

```none
  lxc replicator run my-replicator
      Run the replicator "my-replicator".

  lxc replicator run my-replicator --restore
      Run the replicator "my-replicator" in restore mode, copying instances back from the target cluster.
```

## Options

```none
      --restore   Restore instances from the target cluster back to the source project
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc replicator](../replicator.md#lxc-replicator-md)	 - Manage replicators


# index.html.md

<a id="lxc-replicator-get-md"></a>

# `lxc replicator get`

Get values for replicator configuration keys

## Synopsis

Description:
Get values for replicator configuration keys

```none
lxc replicator get [<remote>:]<replicator> <key> [flags]
```

## Options

```none
  -p, --property   Get the key as a replicator property
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc replicator](../replicator.md#lxc-replicator-md)	 - Manage replicators


# index.html.md

<a id="lxc-replicator-info-md"></a>

# `lxc replicator info`

Show replicator state and job information

## Synopsis

Description:
Show replicator state and job information

Displays the current state of the replicator including status, source project,
instances in the project, and child operation details when a run is in progress.

```none
lxc replicator info [<remote>:]<replicator> [flags]
```

## Examples

```none
  lxc replicator info my-replicator
      Show the current state of the replicator "my-replicator".
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc replicator](../replicator.md#lxc-replicator-md)	 - Manage replicators


# index.html.md

<a id="lxc-replicator-show-md"></a>

# `lxc replicator show`

Show replicator configurations

## Synopsis

Description:
Show replicator configurations

```none
lxc replicator show [<remote>:]<replicator> [flags]
```

## Examples

```none
  lxc replicator show my-replicator
      Show the properties of the replicator "my-replicator".
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc replicator](../replicator.md#lxc-replicator-md)	 - Manage replicators


# index.html.md

<a id="lxc-replicator-edit-md"></a>

# `lxc replicator edit`

Edit replicator configurations as YAML

## Synopsis

Description:
Edit replicator configurations as YAML

```none
lxc replicator edit [<remote>:]<replicator> [flags]
```

## Examples

```none
  lxc replicator edit my-replicator
      Edit the replicator "my-replicator" in the default editor.

  lxc replicator edit my-replicator < config.yaml
      Update the replicator "my-replicator" using the content of "config.yaml".
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc replicator](../replicator.md#lxc-replicator-md)	 - Manage replicators


# index.html.md

<a id="lxc-replicator-set-md"></a>

# `lxc replicator set`

Set replicator configuration keys

## Synopsis

Description:
Set replicator configuration keys

For backward compatibility, a single configuration key may still be set with:
lxc replicator set [<remote>:]<replicator> <key> <value>

```none
lxc replicator set [<remote>:]<replicator> <key>=<value>... [flags]
```

## Options

```none
  -p, --property   Set the key as a replicator property
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc replicator](../replicator.md#lxc-replicator-md)	 - Manage replicators


# index.html.md

<a id="lxc-config-edit-md"></a>

# `lxc config edit`

Edit instance or server configurations as YAML

## Synopsis

Description:
Edit instance or server configurations as YAML

```none
lxc config edit [<remote>:][<instance>[/<snapshot>]] [flags]
```

## Examples

```none
  lxc config edit <instance> < instance.yaml
      Update the instance configuration from config.yaml.
```

## Options

```none
      --target   Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc config](../config.md#lxc-config-md)	 - Manage instance and server configuration options


# index.html.md

<a id="lxc-config-set-md"></a>

# `lxc config set`

Set instance or server configuration keys

## Synopsis

Description:
Set instance or server configuration keys

For backward compatibility, a single configuration key may still be set with:
lxc config set [<remote>:][<instance>] <key> <value>

```none
lxc config set [<remote>:][<instance>] <key>=<value>... [flags]
```

## Examples

```none
  lxc config set [<remote>:]<instance> limits.cpu=2
      Will set a CPU limit of "2" for the instance.

  lxc config set core.https_address=[::]:8443
      Will have LXD listen on IPv4 and IPv6 port 8443.
```

## Options

```none
  -p, --property   Set the key as an instance property
      --target     Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc config](../config.md#lxc-config-md)	 - Manage instance and server configuration options


# index.html.md

<a id="lxc-config-device-md"></a>

# `lxc config device`

Manage devices

## Synopsis

Description:
Manage devices

```none
lxc config device [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc config](../config.md#lxc-config-md)	 - Manage instance and server configuration options
* [lxc config device add](device/add.md#lxc-config-device-add-md)	 - Add instance devices
* [lxc config device get](device/get.md#lxc-config-device-get-md)	 - Get value for device configuration key
* [lxc config device list](device/list.md#lxc-config-device-list-md)	 - List instance devices
* [lxc config device override](device/override.md#lxc-config-device-override-md)	 - Copy profile inherited devices and override configuration keys
* [lxc config device remove](device/remove.md#lxc-config-device-remove-md)	 - Remove instance devices
* [lxc config device set](device/set.md#lxc-config-device-set-md)	 - Set device configuration keys
* [lxc config device show](device/show.md#lxc-config-device-show-md)	 - Show full device configuration
* [lxc config device unset](device/unset.md#lxc-config-device-unset-md)	 - Unset device configuration key


# index.html.md

<a id="lxc-config-show-md"></a>

# `lxc config show`

Show instance or server configurations

## Synopsis

Description:
Show instance or server configurations

```none
lxc config show [<remote>:][<instance>[/<snapshot>]] [flags]
```

## Options

```none
  -e, --expanded   Show the expanded configuration
      --target     Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc config](../config.md#lxc-config-md)	 - Manage instance and server configuration options


# index.html.md

<a id="lxc-config-uefi-md"></a>

# `lxc config uefi`

Manage instance UEFI variables

## Synopsis

Description:
Manage instance UEFI variables

```none
lxc config uefi [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc config](../config.md#lxc-config-md)	 - Manage instance and server configuration options
* [lxc config uefi edit](uefi/edit.md#lxc-config-uefi-edit-md)	 - Edit instance UEFI variables
* [lxc config uefi get](uefi/get.md#lxc-config-uefi-get-md)	 - Get UEFI variable for instance
* [lxc config uefi set](uefi/set.md#lxc-config-uefi-set-md)	 - Set UEFI variable for instance
* [lxc config uefi show](uefi/show.md#lxc-config-uefi-show-md)	 - Show instance UEFI variables
* [lxc config uefi unset](uefi/unset.md#lxc-config-uefi-unset-md)	 - Unset UEFI variable for instance


# index.html.md

<a id="lxc-config-template-md"></a>

# `lxc config template`

Manage instance file templates

## Synopsis

Description:
Manage instance file templates

```none
lxc config template [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc config](../config.md#lxc-config-md)	 - Manage instance and server configuration options
* [lxc config template create](template/create.md#lxc-config-template-create-md)	 - Create new instance file template
* [lxc config template delete](template/delete.md#lxc-config-template-delete-md)	 - Delete instance file template
* [lxc config template edit](template/edit.md#lxc-config-template-edit-md)	 - Edit instance file template
* [lxc config template list](template/list.md#lxc-config-template-list-md)	 - List instance file templates
* [lxc config template show](template/show.md#lxc-config-template-show-md)	 - Show content of instance file template


# index.html.md

<a id="lxc-config-metadata-md"></a>

# `lxc config metadata`

Manage instance metadata files

## Synopsis

Description:
Manage instance metadata files

```none
lxc config metadata [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc config](../config.md#lxc-config-md)	 - Manage instance and server configuration options
* [lxc config metadata edit](metadata/edit.md#lxc-config-metadata-edit-md)	 - Edit instance metadata files
* [lxc config metadata show](metadata/show.md#lxc-config-metadata-show-md)	 - Show instance metadata files


# index.html.md

<a id="lxc-config-get-md"></a>

# `lxc config get`

Get value for instance or server configuration key

## Synopsis

Description:
Get value for instance or server configuration key

```none
lxc config get [<remote>:][<instance>] <key> [flags]
```

## Options

```none
  -e, --expanded   Access the expanded configuration
  -p, --property   Get the key as an instance property
      --target     Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc config](../config.md#lxc-config-md)	 - Manage instance and server configuration options


# index.html.md

<a id="lxc-config-unset-md"></a>

# `lxc config unset`

Unset instance or server configuration key

## Synopsis

Description:
Unset instance or server configuration key

```none
lxc config unset [<remote>:][<instance>] <key> [flags]
```

## Options

```none
  -p, --property   Unset the key as an instance property
      --target     Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc config](../config.md#lxc-config-md)	 - Manage instance and server configuration options


# index.html.md

<a id="lxc-config-trust-md"></a>

# `lxc config trust`

Manage trusted clients

## Synopsis

Description:
Manage trusted clients

```none
lxc config trust [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc config](../config.md#lxc-config-md)	 - Manage instance and server configuration options
* [lxc config trust add](trust/add.md#lxc-config-trust-add-md)	 - Add new trusted client
* [lxc config trust edit](trust/edit.md#lxc-config-trust-edit-md)	 - Edit trust configurations as YAML
* [lxc config trust list](trust/list.md#lxc-config-trust-list-md)	 - List trusted clients
* [lxc config trust list-tokens](trust/list-tokens.md#lxc-config-trust-list-tokens-md)	 - List all active certificate add tokens
* [lxc config trust remove](trust/remove.md#lxc-config-trust-remove-md)	 - Remove trusted client
* [lxc config trust revoke-token](trust/revoke-token.md#lxc-config-trust-revoke-token-md)	 - Revoke certificate add token
* [lxc config trust show](trust/show.md#lxc-config-trust-show-md)	 - Show trust configurations


# index.html.md

<a id="lxc-image-alias-md"></a>

# `lxc image alias`

Manage image aliases

## Synopsis

Description:
Manage image aliases

```none
lxc image alias [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc image](../image.md#lxc-image-md)	 - Manage images
* [lxc image alias create](alias/create.md#lxc-image-alias-create-md)	 - Create alias for an image
* [lxc image alias delete](alias/delete.md#lxc-image-alias-delete-md)	 - Delete image alias
* [lxc image alias list](alias/list.md#lxc-image-alias-list-md)	 - List image aliases
* [lxc image alias rename](alias/rename.md#lxc-image-alias-rename-md)	 - Rename alias


# index.html.md

<a id="lxc-image-delete-md"></a>

# `lxc image delete`

Delete images

## Synopsis

Description:
Delete images

```none
lxc image delete [<remote>:]<image> [[<remote>:]<image>...] [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc image](../image.md#lxc-image-md)	 - Manage images


# index.html.md

<a id="lxc-image-refresh-md"></a>

# `lxc image refresh`

Refresh images

## Synopsis

Description:
Refresh images

```none
lxc image refresh [<remote>:]<image> [[<remote>:]<image>...] [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc image](../image.md#lxc-image-md)	 - Manage images


# index.html.md

<a id="lxc-image-list-md"></a>

# `lxc image list`

List images

## Synopsis

Description:
List images

Filters may be of the <key>=<value> form for property based filtering,
or part of the image hash or part of the image alias name.

The -c option takes a (optionally comma-separated) list of arguments
that control which image attributes to output when displaying in table
or csv format.

Default column layout is: lfpdatsu

Column shorthand chars:

```none
  l - Shortest image alias (and optionally number of other aliases)
  L - Newline-separated list of all image aliases
  f - Fingerprint (short)
  F - Fingerprint (long)
  p - Whether image is public
  d - Description
  e - Project (may be empty unless using --all-projects)
  a - Architecture
  s - Size
  u - Upload date
  t - Type
```

```none
lxc image list [<remote>:] [<filter>...] [flags]
```

## Options

```none
      --all-projects   Display images from all projects
  -c, --columns        Columns (default "lfpdatsu")
  -f, --format         Format (csv|json|table|yaml|compact) (default "table")
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc image](../image.md#lxc-image-md)	 - Manage images


# index.html.md

<a id="lxc-image-set-property-md"></a>

# `lxc image set-property`

Set image property

## Synopsis

Description:
Set image property

```none
lxc image set-property [<remote>:]<image> <key> <value> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc image](../image.md#lxc-image-md)	 - Manage images


# index.html.md

<a id="lxc-image-export-md"></a>

# `lxc image export`

Export and download images

## Synopsis

Description:
Export and download images

The output target is optional and defaults to the working directory.

```none
lxc image export [<remote>:]<image> [<target>] [flags]
```

## Options

```none
      --vm   Query virtual machine images
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc image](../image.md#lxc-image-md)	 - Manage images


# index.html.md

<a id="lxc-image-unset-property-md"></a>

# `lxc image unset-property`

Unset image property

## Synopsis

Description:
Unset image property

```none
lxc image unset-property [<remote>:]<image> <key> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc image](../image.md#lxc-image-md)	 - Manage images


# index.html.md

<a id="lxc-image-import-md"></a>

# `lxc image import`

Import image into the image store

## Synopsis

Description:
Import image into the image store

Directory import is only available on Linux and must be performed as root.

Descriptive properties can be set by providing key=value pairs. Example: os=Ubuntu release=noble variant=cloud.

```none
lxc image import <tarball>|<directory>|<URL> [<rootfs tarball>] [<remote>:] [key=value...] [flags]
```

## Options

```none
      --alias    New aliases to add to the image
      --public   Make image public
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc image](../image.md#lxc-image-md)	 - Manage images


# index.html.md

<a id="lxc-image-copy-md"></a>

# `lxc image copy`

Copy image between servers

## Synopsis

Description:
Copy image between servers

The auto-update flag instructs the server to keep this image up to date.
It requires the source to be an alias and for it to be public.

```none
lxc image copy [<remote>:]<image> <remote>: [flags]
```

## Options

```none
      --alias            New aliases to add to the image
      --auto-update      Keep the image up to date after initial copy
      --copy-aliases     Copy aliases from source
      --mode             Transfer mode. One of pull (default), push or relay (default "pull")
  -p, --profile          Profile to apply to the new image
      --public           Make image public
      --target-project   Copy to a project different from the source
      --vm               Copy virtual machine images
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc image](../image.md#lxc-image-md)	 - Manage images


# index.html.md

<a id="lxc-image-get-property-md"></a>

# `lxc image get-property`

Get image property

## Synopsis

Description:
Get image property

```none
lxc image get-property [<remote>:]<image> <key> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc image](../image.md#lxc-image-md)	 - Manage images


# index.html.md

<a id="lxc-image-edit-md"></a>

# `lxc image edit`

Edit image properties

## Synopsis

Description:
Edit image properties

```none
lxc image edit [<remote>:]<image> [flags]
```

## Examples

```none
  lxc image edit <image>
      Launch a text editor to edit the properties

  lxc image edit <image> < image.yaml
      Load the image properties from a YAML file
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc image](../image.md#lxc-image-md)	 - Manage images


# index.html.md

<a id="lxc-image-show-md"></a>

# `lxc image show`

Show image properties

## Synopsis

Description:
Show image properties

```none
lxc image show [<remote>:]<image> [flags]
```

## Options

```none
      --vm   Query virtual machine images
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc image](../image.md#lxc-image-md)	 - Manage images


# index.html.md

<a id="lxc-image-info-md"></a>

# `lxc image info`

Show useful information about image

## Synopsis

Description:
Show useful information about image

```none
lxc image info [<remote>:]<image> [flags]
```

## Options

```none
      --vm   Query virtual machine images
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc image](../image.md#lxc-image-md)	 - Manage images


# index.html.md

<a id="lxc-network-list-allocations-md"></a>

# `lxc network list-allocations`

List network allocations in use

## Synopsis

Description:
List network allocations in use

```none
lxc network list-allocations [flags]
```

## Options

```none
      --all-projects   Run against all projects
  -c, --columns        Columns (default "uantNh")
  -f, --format         Format (csv|json|table|yaml|compact) (default "table")
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network](../network.md#lxc-network-md)	 - Manage and attach instances to networks


# index.html.md

<a id="lxc-network-peer-md"></a>

# `lxc network peer`

Manage network peerings

## Synopsis

Description:
Manage network peerings

```none
lxc network peer [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network](../network.md#lxc-network-md)	 - Manage and attach instances to networks
* [lxc network peer create](peer/create.md#lxc-network-peer-create-md)	 - Create new network peering
* [lxc network peer delete](peer/delete.md#lxc-network-peer-delete-md)	 - Delete network peering
* [lxc network peer edit](peer/edit.md#lxc-network-peer-edit-md)	 - Edit network peer configurations as YAML
* [lxc network peer get](peer/get.md#lxc-network-peer-get-md)	 - Get value for network peer configuration key
* [lxc network peer list](peer/list.md#lxc-network-peer-list-md)	 - List available network peers
* [lxc network peer set](peer/set.md#lxc-network-peer-set-md)	 - Set network peer keys
* [lxc network peer show](peer/show.md#lxc-network-peer-show-md)	 - Show network peer configurations
* [lxc network peer unset](peer/unset.md#lxc-network-peer-unset-md)	 - Unset network peer configuration key


# index.html.md

<a id="lxc-network-list-md"></a>

# `lxc network list`

List networks

## Synopsis

Description:
List networks

```none
lxc network list [<remote>:] [flags]
```

## Options

```none
      --all-projects   Display networks from all projects
  -c, --columns        Columns (default "ntm46dus")
  -f, --format         Format (csv|json|table|yaml|compact) (default "table")
      --target         Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network](../network.md#lxc-network-md)	 - Manage and attach instances to networks


# index.html.md

<a id="lxc-network-set-md"></a>

# `lxc network set`

Set network configuration keys

## Synopsis

Description:
Set network configuration keys

For backward compatibility, a single configuration key may still be set with:
lxc network set [<remote>:]<network> <key> <value>

```none
lxc network set [<remote>:]<network> <key>=<value>... [flags]
```

## Options

```none
  -p, --property   Set the key as a network property
      --target     Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network](../network.md#lxc-network-md)	 - Manage and attach instances to networks


# index.html.md

<a id="lxc-network-detach-profile-md"></a>

# `lxc network detach-profile`

Detach network interface from profile

## Synopsis

Description:
Detach network interface from profile

```none
lxc network detach-profile [<remote>:]<network> <profile> [<device name>] [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network](../network.md#lxc-network-md)	 - Manage and attach instances to networks


# index.html.md

<a id="lxc-network-acl-md"></a>

# `lxc network acl`

Manage network ACLs

## Synopsis

Description:
Manage network ACLs

```none
lxc network acl [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network](../network.md#lxc-network-md)	 - Manage and attach instances to networks
* [lxc network acl create](acl/create.md#lxc-network-acl-create-md)	 - Create new network ACL
* [lxc network acl delete](acl/delete.md#lxc-network-acl-delete-md)	 - Delete network ACL
* [lxc network acl edit](acl/edit.md#lxc-network-acl-edit-md)	 - Edit network ACL configurations as YAML
* [lxc network acl get](acl/get.md#lxc-network-acl-get-md)	 - Get value for network ACL configuration key
* [lxc network acl list](acl/list.md#lxc-network-acl-list-md)	 - List network ACLs
* [lxc network acl rename](acl/rename.md#lxc-network-acl-rename-md)	 - Rename network ACL
* [lxc network acl rule](acl/rule.md#lxc-network-acl-rule-md)	 - Manage network ACL rules
* [lxc network acl set](acl/set.md#lxc-network-acl-set-md)	 - Set network ACL configuration keys
* [lxc network acl show](acl/show.md#lxc-network-acl-show-md)	 - Show network ACL configurations
* [lxc network acl show-log](acl/show-log.md#lxc-network-acl-show-log-md)	 - Show network ACL log
* [lxc network acl unset](acl/unset.md#lxc-network-acl-unset-md)	 - Unset network ACL configuration key


# index.html.md

<a id="lxc-network-list-leases-md"></a>

# `lxc network list-leases`

List DHCP leases

## Synopsis

Description:
List DHCP leases

```none
lxc network list-leases [<remote>:]<network> [flags]
```

## Options

```none
  -f, --format   Format (csv|json|table|yaml|compact) (default "table")
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network](../network.md#lxc-network-md)	 - Manage and attach instances to networks


# index.html.md

<a id="lxc-network-load-balancer-md"></a>

# `lxc network load-balancer`

Manage network load balancers

## Synopsis

Description:
Manage network load balancers

```none
lxc network load-balancer [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network](../network.md#lxc-network-md)	 - Manage and attach instances to networks
* [lxc network load-balancer backend](load-balancer/backend.md#lxc-network-load-balancer-backend-md)	 - Manage network load balancer backends
* [lxc network load-balancer create](load-balancer/create.md#lxc-network-load-balancer-create-md)	 - Create new network load balancer
* [lxc network load-balancer delete](load-balancer/delete.md#lxc-network-load-balancer-delete-md)	 - Delete network load balancer
* [lxc network load-balancer edit](load-balancer/edit.md#lxc-network-load-balancer-edit-md)	 - Edit network load balancer configurations as YAML
* [lxc network load-balancer get](load-balancer/get.md#lxc-network-load-balancer-get-md)	 - Get value for network load balancer configuration key
* [lxc network load-balancer list](load-balancer/list.md#lxc-network-load-balancer-list-md)	 - List available network load balancers
* [lxc network load-balancer pool](load-balancer/pool.md#lxc-network-load-balancer-pool-md)	 - Manage network load balancer pools
* [lxc network load-balancer port](load-balancer/port.md#lxc-network-load-balancer-port-md)	 - Manage network load balancer ports
* [lxc network load-balancer set](load-balancer/set.md#lxc-network-load-balancer-set-md)	 - Set network load balancer keys
* [lxc network load-balancer show](load-balancer/show.md#lxc-network-load-balancer-show-md)	 - Show network load balancer configurations
* [lxc network load-balancer unset](load-balancer/unset.md#lxc-network-load-balancer-unset-md)	 - Unset network load balancer configuration key


# index.html.md

<a id="lxc-network-attach-profile-md"></a>

# `lxc network attach-profile`

Attach network interface to profile

## Synopsis

Description:
Attach network interface to profile

```none
lxc network attach-profile [<remote>:]<network> <profile> [<device name>] [<interface name>] [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network](../network.md#lxc-network-md)	 - Manage and attach instances to networks


# index.html.md

<a id="lxc-network-get-md"></a>

# `lxc network get`

Get value for network configuration key

## Synopsis

Description:
Get value for network configuration key

```none
lxc network get [<remote>:]<network> <key> [flags]
```

## Options

```none
  -p, --property   Get the key as a network property
      --target     Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network](../network.md#lxc-network-md)	 - Manage and attach instances to networks


# index.html.md

<a id="lxc-network-rename-md"></a>

# `lxc network rename`

Rename network

## Synopsis

Description:
Rename network

```none
lxc network rename [<remote>:]<network> <new-name> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network](../network.md#lxc-network-md)	 - Manage and attach instances to networks


# index.html.md

<a id="lxc-network-attach-md"></a>

# `lxc network attach`

Attach network interface to instance

## Synopsis

Description:
Attach network interface to instance

```none
lxc network attach [<remote>:]<network> <instance> [<device name>] [<interface name>] [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network](../network.md#lxc-network-md)	 - Manage and attach instances to networks


# index.html.md

<a id="lxc-network-zone-md"></a>

# `lxc network zone`

Manage network zones

## Synopsis

Description:
Manage network zones

```none
lxc network zone [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network](../network.md#lxc-network-md)	 - Manage and attach instances to networks
* [lxc network zone create](zone/create.md#lxc-network-zone-create-md)	 - Create new network zone
* [lxc network zone delete](zone/delete.md#lxc-network-zone-delete-md)	 - Delete network zone
* [lxc network zone edit](zone/edit.md#lxc-network-zone-edit-md)	 - Edit network zone configurations as YAML
* [lxc network zone get](zone/get.md#lxc-network-zone-get-md)	 - Get value for network zone configuration key
* [lxc network zone list](zone/list.md#lxc-network-zone-list-md)	 - List available network zones
* [lxc network zone record](zone/record.md#lxc-network-zone-record-md)	 - Manage network zone records
* [lxc network zone set](zone/set.md#lxc-network-zone-set-md)	 - Set network zone configuration keys
* [lxc network zone show](zone/show.md#lxc-network-zone-show-md)	 - Show network zone configurations
* [lxc network zone unset](zone/unset.md#lxc-network-zone-unset-md)	 - Unset network zone configuration key


# index.html.md

<a id="lxc-network-detach-md"></a>

# `lxc network detach`

Detach network interface from instance

## Synopsis

Description:
Detach network interface from instance

```none
lxc network detach [<remote>:]<network> <instance> [<device name>] [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network](../network.md#lxc-network-md)	 - Manage and attach instances to networks


# index.html.md

<a id="lxc-network-info-md"></a>

# `lxc network info`

Get runtime information on network

## Synopsis

Description:
Get runtime information on network

```none
lxc network info [<remote>:]<network> [flags]
```

## Options

```none
      --target   Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network](../network.md#lxc-network-md)	 - Manage and attach instances to networks


# index.html.md

<a id="lxc-network-forward-md"></a>

# `lxc network forward`

Manage network forwards

## Synopsis

Description:
Manage network forwards

```none
lxc network forward [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network](../network.md#lxc-network-md)	 - Manage and attach instances to networks
* [lxc network forward create](forward/create.md#lxc-network-forward-create-md)	 - Create new network forward
* [lxc network forward delete](forward/delete.md#lxc-network-forward-delete-md)	 - Delete network forward
* [lxc network forward edit](forward/edit.md#lxc-network-forward-edit-md)	 - Edit network forward configurations as YAML
* [lxc network forward get](forward/get.md#lxc-network-forward-get-md)	 - Get value for network forward configuration key
* [lxc network forward list](forward/list.md#lxc-network-forward-list-md)	 - List available network forwards
* [lxc network forward port](forward/port.md#lxc-network-forward-port-md)	 - Manage network forward ports
* [lxc network forward set](forward/set.md#lxc-network-forward-set-md)	 - Set network forward keys
* [lxc network forward show](forward/show.md#lxc-network-forward-show-md)	 - Show network forward configurations
* [lxc network forward unset](forward/unset.md#lxc-network-forward-unset-md)	 - Unset network forward configuration key


# index.html.md

<a id="lxc-network-edit-md"></a>

# `lxc network edit`

Edit network configuration as YAML

## Synopsis

Description:
Edit network configuration as YAML

```none
lxc network edit [<remote>:]<network> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network](../network.md#lxc-network-md)	 - Manage and attach instances to networks


# index.html.md

<a id="lxc-network-show-md"></a>

# `lxc network show`

Show network configurations

## Synopsis

Description:
Show network configurations

```none
lxc network show [<remote>:]<network> [flags]
```

## Options

```none
      --target   Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network](../network.md#lxc-network-md)	 - Manage and attach instances to networks


# index.html.md

<a id="lxc-network-delete-md"></a>

# `lxc network delete`

Delete network

## Synopsis

Description:
Delete network

```none
lxc network delete [<remote>:]<network> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network](../network.md#lxc-network-md)	 - Manage and attach instances to networks


# index.html.md

<a id="lxc-network-create-md"></a>

# `lxc network create`

Create new network

## Synopsis

Description:
Create new network

```none
lxc network create [<remote>:]<network> [key=value...] [flags]
```

## Examples

```none
  lxc network create foo
      Create a new network called foo

  lxc network create bar network=baz --type ovn
      Create a new OVN network called bar using baz as its uplink network
```

## Options

```none
      --target   Cluster member name
  -t, --type     Network type
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network](../network.md#lxc-network-md)	 - Manage and attach instances to networks


# index.html.md

<a id="lxc-network-unset-md"></a>

# `lxc network unset`

Unset network configuration key

## Synopsis

Description:
Unset network configuration key

```none
lxc network unset [<remote>:]<network> <key> [flags]
```

## Options

```none
  -p, --property   Unset the key as a network property
      --target     Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network](../network.md#lxc-network-md)	 - Manage and attach instances to networks


# index.html.md

<a id="lxc-placement-group-edit-md"></a>

# `lxc placement-group edit`

Edit placement group configurations as YAML

## Synopsis

Description:
Edit placement group configurations as YAML

```none
lxc placement-group edit [<remote>:]<placement_group> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc placement-group](../placement-group.md#lxc-placement-group-md)	 - Manage placement groups


# index.html.md

<a id="lxc-placement-group-show-md"></a>

# `lxc placement-group show`

Show placement group configurations

## Synopsis

Description:
Show placement group configurations

```none
lxc placement-group show [<remote>:]<placement_group> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc placement-group](../placement-group.md#lxc-placement-group-md)	 - Manage placement groups


# index.html.md

<a id="lxc-placement-group-unset-md"></a>

# `lxc placement-group unset`

Unset placement group configuration key

## Synopsis

Description:
Unset placement group configuration key

```none
lxc placement-group unset [<remote>:]<placement_group> <key> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc placement-group](../placement-group.md#lxc-placement-group-md)	 - Manage placement groups


# index.html.md

<a id="lxc-placement-group-get-md"></a>

# `lxc placement-group get`

Get value for placement group configuration key

## Synopsis

Description:
Get value for placement group configuration key

```none
lxc placement-group get [<remote>:]<placement_group> <key> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc placement-group](../placement-group.md#lxc-placement-group-md)	 - Manage placement groups


# index.html.md

<a id="lxc-placement-group-rename-md"></a>

# `lxc placement-group rename`

Rename placement group

## Synopsis

Description:
Rename placement group

```none
lxc placement-group rename [<remote>:]<old_name> <new_name> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc placement-group](../placement-group.md#lxc-placement-group-md)	 - Manage placement groups


# index.html.md

<a id="lxc-placement-group-set-md"></a>

# `lxc placement-group set`

Set placement group configuration keys

## Synopsis

Description:
Set placement group configuration keys

For backward compatibility, a single configuration key may still be set with:
lxc placement-group set [<remote>:]<placement_group> <key> <value>

```none
lxc placement-group set [<remote>:]<placement_group> <key>=<value>... [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc placement-group](../placement-group.md#lxc-placement-group-md)	 - Manage placement groups


# index.html.md

<a id="lxc-placement-group-delete-md"></a>

# `lxc placement-group delete`

Delete placement group

## Synopsis

Description:
Delete placement group

```none
lxc placement-group delete [<remote>:]<placement_group> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc placement-group](../placement-group.md#lxc-placement-group-md)	 - Manage placement groups


# index.html.md

<a id="lxc-placement-group-list-md"></a>

# `lxc placement-group list`

List available placement groups

## Synopsis

Description:
List available placement groups

```none
lxc placement-group list [<remote>:] [flags]
```

## Options

```none
      --all-projects   Display placement groups from all projects
  -c, --columns        Columns (default "ndpru")
  -f, --format         Format (csv|json|table|yaml|compact) (default "table")
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc placement-group](../placement-group.md#lxc-placement-group-md)	 - Manage placement groups


# index.html.md

<a id="lxc-placement-group-create-md"></a>

# `lxc placement-group create`

Create new placement group

## Synopsis

Description:
Create new placement group

```none
lxc placement-group create [<remote>:]<placement_group> [key=value...] [flags]
```

## Examples

```none
  lxc placement-group create pg1 policy=spread rigor=strict

  lxc placement-group create pg1 policy=compact rigor=permissive

  lxc placement-group create pg1 < config.yaml
      Create placement group pg1 with configuration from config.yaml
```

## Options

```none
  -c, --config        Config key/value to apply to the new placement group
      --description   Description of the placement group
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc placement-group](../placement-group.md#lxc-placement-group-md)	 - Manage placement groups


# index.html.md

<a id="lxc-completion-fish-md"></a>

# `lxc completion fish`

Generate the autocompletion script for fish

## Synopsis

Generate the autocompletion script for the fish shell.

To load completions in your current shell session:

```none
lxc completion fish | source
```

To load completions for every new session, execute once:

```none
lxc completion fish > ~/.config/fish/completions/lxc.fish
```

You will need to start a new shell for this setup to take effect.

```none
lxc completion fish [flags]
```

## Options

```none
      --no-descriptions   disable completion descriptions
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc completion](../completion.md#lxc-completion-md)	 - Generate the autocompletion script for the specified shell


# index.html.md

<a id="lxc-completion-zsh-md"></a>

# `lxc completion zsh`

Generate the autocompletion script for zsh

## Synopsis

Generate the autocompletion script for the zsh shell.

If shell completion is not already enabled in your environment you will need
to enable it.  You can execute the following once:

```none
echo "autoload -U compinit; compinit" >> ~/.zshrc
```

To load completions in your current shell session:

```none
source <(lxc completion zsh)
```

To load completions for every new session, execute once:

### Linux:

```none
lxc completion zsh > "${fpath[1]}/_lxc"
```

### macOS:

```none
lxc completion zsh > $(brew --prefix)/share/zsh/site-functions/_lxc
```

You will need to start a new shell for this setup to take effect.

```none
lxc completion zsh [flags]
```

## Options

```none
      --no-descriptions   disable completion descriptions
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc completion](../completion.md#lxc-completion-md)	 - Generate the autocompletion script for the specified shell


# index.html.md

<a id="lxc-completion-bash-md"></a>

# `lxc completion bash`

Generate the autocompletion script for bash

## Synopsis

Generate the autocompletion script for the bash shell.

This script depends on the ‘bash-completion’ package.
If it is not installed already, you can install it via your OS’s package manager.

To load completions in your current shell session:

```none
source <(lxc completion bash)
```

To load completions for every new session, execute once:

### Linux:

```none
lxc completion bash > /etc/bash_completion.d/lxc
```

### macOS:

```none
lxc completion bash > $(brew --prefix)/etc/bash_completion.d/lxc
```

You will need to start a new shell for this setup to take effect.

```none
lxc completion bash
```

## Options

```none
      --no-descriptions   disable completion descriptions
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc completion](../completion.md#lxc-completion-md)	 - Generate the autocompletion script for the specified shell


# index.html.md

<a id="lxc-completion-powershell-md"></a>

# `lxc completion powershell`

Generate the autocompletion script for powershell

## Synopsis

Generate the autocompletion script for powershell.

To load completions in your current shell session:

```none
lxc completion powershell | Out-String | Invoke-Expression
```

To load completions for every new session, add the output of the above command
to your powershell profile.

```none
lxc completion powershell [flags]
```

## Options

```none
      --no-descriptions   disable completion descriptions
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc completion](../completion.md#lxc-completion-md)	 - Generate the autocompletion script for the specified shell


# index.html.md

<a id="lxc-alias-list-md"></a>

# `lxc alias list`

List aliases

## Synopsis

Description:
List aliases

```none
lxc alias list [flags]
```

## Options

```none
  -c, --columns   Columns (default "at")
  -f, --format    Format (csv|json|table|yaml|compact) (default "table")
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc alias](../alias.md#lxc-alias-md)	 - Manage command aliases


# index.html.md

<a id="lxc-alias-rename-md"></a>

# `lxc alias rename`

Rename alias

## Synopsis

Description:
Rename alias

```none
lxc alias rename <old alias> <new alias> [flags]
```

## Examples

```none
  lxc alias rename list my-list
      Rename existing alias "list" to "my-list".
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc alias](../alias.md#lxc-alias-md)	 - Manage command aliases


# index.html.md

<a id="lxc-alias-show-md"></a>

# `lxc alias show`

Show aliases in YAML format

## Synopsis

Description:
Show aliases in YAML format

```none
lxc alias show [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc alias](../alias.md#lxc-alias-md)	 - Manage command aliases


# index.html.md

<a id="lxc-alias-edit-md"></a>

# `lxc alias edit`

Edit aliases

```none
lxc alias edit [flags]
```

## Examples

```none
  lxc alias edit
  	Edit the aliases via interactive terminal.

  lxc alias edit < aliases.yaml
  	Edit the aliases from "aliases.yaml".
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc alias](../alias.md#lxc-alias-md)	 - Manage command aliases


# index.html.md

<a id="lxc-alias-add-md"></a>

# `lxc alias add`

Add new alias

## Synopsis

Description:
Add new alias

```none
lxc alias add <alias> <target> [flags]
```

## Examples

```none
  lxc alias add list "list -c ns46S"
      Overwrite the "list" command to pass -c ns46S.
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc alias](../alias.md#lxc-alias-md)	 - Manage command aliases


# index.html.md

<a id="lxc-alias-remove-md"></a>

# `lxc alias remove`

Remove alias

## Synopsis

Description:
Remove alias

```none
lxc alias remove <alias> [flags]
```

## Examples

```none
  lxc alias remove my-list
      Remove the "my-list" alias.
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc alias](../alias.md#lxc-alias-md)	 - Manage command aliases


# index.html.md

<a id="lxc-cluster-info-md"></a>

# `lxc cluster info`

Show useful information about a cluster member

## Synopsis

Description:
Show useful information about a cluster member

```none
lxc cluster info [<remote>:]<member> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc cluster](../cluster.md#lxc-cluster-md)	 - Manage cluster members


# index.html.md

<a id="lxc-cluster-edit-md"></a>

# `lxc cluster edit`

Edit cluster member configurations as YAML

## Synopsis

Description:
Edit cluster member configurations as YAML

```none
lxc cluster edit [<remote>:]<member> [flags]
```

## Examples

```none
  lxc cluster edit <cluster member> < member.yaml
      Update a cluster member using the content of member.yaml
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc cluster](../cluster.md#lxc-cluster-md)	 - Manage cluster members


# index.html.md

<a id="lxc-cluster-unset-md"></a>

# `lxc cluster unset`

Unset a cluster member’s configuration key

## Synopsis

Description:
Unset a cluster member’s configuration key

```none
lxc cluster unset [<remote>:]<member> <key> [flags]
```

## Options

```none
  -p, --property   Unset the key as a cluster property
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc cluster](../cluster.md#lxc-cluster-md)	 - Manage cluster members


# index.html.md

<a id="lxc-cluster-link-md"></a>

# `lxc cluster link`

Manage cluster links

## Synopsis

Description:
Manage cluster links

```none
lxc cluster link [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc cluster](../cluster.md#lxc-cluster-md)	 - Manage cluster members
* [lxc cluster link create](link/create.md#lxc-cluster-link-create-md)	 - Create cluster links
* [lxc cluster link delete](link/delete.md#lxc-cluster-link-delete-md)	 - Delete cluster links
* [lxc cluster link edit](link/edit.md#lxc-cluster-link-edit-md)	 - Edit cluster link configurations as YAML
* [lxc cluster link get](link/get.md#lxc-cluster-link-get-md)	 - Get values for cluster link configuration keys
* [lxc cluster link info](link/info.md#lxc-cluster-link-info-md)	 - Get information on cluster links
* [lxc cluster link list](link/list.md#lxc-cluster-link-list-md)	 - List cluster links
* [lxc cluster link rename](link/rename.md#lxc-cluster-link-rename-md)	 - Rename a cluster link
* [lxc cluster link set](link/set.md#lxc-cluster-link-set-md)	 - Set cluster link configuration keys
* [lxc cluster link show](link/show.md#lxc-cluster-link-show-md)	 - Show cluster link configurations
* [lxc cluster link unset](link/unset.md#lxc-cluster-link-unset-md)	 - Unset cluster link configuration keys


# index.html.md

<a id="lxc-cluster-role-md"></a>

# `lxc cluster role`

Manage cluster roles

## Synopsis

Description:
Manage cluster roles

```none
lxc cluster role [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc cluster](../cluster.md#lxc-cluster-md)	 - Manage cluster members
* [lxc cluster role add](role/add.md#lxc-cluster-role-add-md)	 - Add roles to a cluster member
* [lxc cluster role remove](role/remove.md#lxc-cluster-role-remove-md)	 - Remove roles from a cluster member


# index.html.md

<a id="lxc-cluster-update-certificate-md"></a>

# `lxc cluster update-certificate`

Update cluster certificate

## Synopsis

Description:
Update cluster certificate with PEM certificate and key read from input files.

```none
lxc cluster update-certificate [<remote>:] <cert.crt> <cert.key> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc cluster](../cluster.md#lxc-cluster-md)	 - Manage cluster members


# index.html.md

<a id="lxc-cluster-show-md"></a>

# `lxc cluster show`

Show details of a cluster member

## Synopsis

Description:
Show details of a cluster member

```none
lxc cluster show [<remote>:]<member> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc cluster](../cluster.md#lxc-cluster-md)	 - Manage cluster members


# index.html.md

<a id="lxc-cluster-list-tokens-md"></a>

# `lxc cluster list-tokens`

List all active cluster member join tokens

```none
lxc cluster list-tokens [<remote>:] [flags]
```

## Options

```none
  -f, --format   Format (csv|json|table|yaml|compact) (default "table")
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc cluster](../cluster.md#lxc-cluster-md)	 - Manage cluster members


# index.html.md

<a id="lxc-cluster-revoke-token-md"></a>

# `lxc cluster revoke-token`

Revoke cluster member join token

```none
lxc cluster revoke-token [<remote>:]<member> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc cluster](../cluster.md#lxc-cluster-md)	 - Manage cluster members


# index.html.md

<a id="lxc-cluster-remove-md"></a>

# `lxc cluster remove`

Remove a member from the cluster

## Synopsis

Description:
Remove a member from the cluster

```none
lxc cluster remove [<remote>:]<member> [flags]
```

## Options

```none
  -f, --force   Force removing a member, even if degraded
      --yes     Do not require user confirmation for using --force
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc cluster](../cluster.md#lxc-cluster-md)	 - Manage cluster members


# index.html.md

<a id="lxc-cluster-evacuate-md"></a>

# `lxc cluster evacuate`

Evacuate cluster member

## Synopsis

Description:
Evacuate cluster member

Evacuation actions:

- stop: stop all instances on the member
- migrate: migrate all instances on the member to other members
- live-migrate: live migrate eligible instances on the member to other members

Note: Live migration is supported for virtual machines only.
If no target member is available, an instance is skipped.
If a live migration attempt fails, the evacuation operation fails.

```none
lxc cluster evacuate [<remote>:]<member> [flags]
```

## Options

```none
      --action   Force a particular instance evacuation action. One of stop, migrate or live-migrate
      --force    Allow evacuation even if it would cause loss of Raft quorum
      --yes      Do not require user confirmation
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc cluster](../cluster.md#lxc-cluster-md)	 - Manage cluster members


# index.html.md

<a id="lxc-cluster-add-md"></a>

# `lxc cluster add`

Request a join token for adding a cluster member

```none
lxc cluster add [[<remote>:]<member>] [flags]
```

## Options

```none
      --name   Cluster member name (alternative to passing it as an argument)
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc cluster](../cluster.md#lxc-cluster-md)	 - Manage cluster members


# index.html.md

<a id="lxc-cluster-restore-md"></a>

# `lxc cluster restore`

Restore cluster member

```none
lxc cluster restore [<remote>:]<member> [flags]
```

## Options

```none
      --action   Force a particular instance restore action. Use "skip" to restore only the cluster member status without starting local instances or migrating back evacuated instances
      --force    Force restoration without user confirmation
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc cluster](../cluster.md#lxc-cluster-md)	 - Manage cluster members


# index.html.md

<a id="lxc-cluster-group-md"></a>

# `lxc cluster group`

Manage cluster groups

## Synopsis

Description:
Manage cluster groups

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc cluster](../cluster.md#lxc-cluster-md)	 - Manage cluster members
* [lxc cluster group add](group/add.md#lxc-cluster-group-add-md)	 - Add member to group
* [lxc cluster group assign](group/assign.md#lxc-cluster-group-assign-md)	 - Assign sets of groups to cluster members
* [lxc cluster group create](group/create.md#lxc-cluster-group-create-md)	 - Create a cluster group
* [lxc cluster group delete](group/delete.md#lxc-cluster-group-delete-md)	 - Delete a cluster group
* [lxc cluster group edit](group/edit.md#lxc-cluster-group-edit-md)	 - Edit a cluster group
* [lxc cluster group list](group/list.md#lxc-cluster-group-list-md)	 - List all the cluster groups
* [lxc cluster group remove](group/remove.md#lxc-cluster-group-remove-md)	 - Remove member from group
* [lxc cluster group rename](group/rename.md#lxc-cluster-group-rename-md)	 - Rename a cluster group
* [lxc cluster group show](group/show.md#lxc-cluster-group-show-md)	 - Show cluster group configurations


# index.html.md

<a id="lxc-cluster-list-md"></a>

# `lxc cluster list`

List all the cluster members

## Synopsis

Description:
List all the cluster members

```none
lxc cluster list [<remote>:] [flags]
```

## Options

```none
  -f, --format   Format (csv|json|table|yaml|compact) (default "table")
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc cluster](../cluster.md#lxc-cluster-md)	 - Manage cluster members


# index.html.md

<a id="lxc-cluster-enable-md"></a>

# `lxc cluster enable`

Enable clustering on a single non-clustered LXD server

## Synopsis

Description:
Enable clustering on a single non-clustered LXD server

```none
This command turns a non-clustered LXD server into the first member of a new
LXD cluster, which will have the given name.

It's required that LXD is already available on the network. You can check
this by running 'lxc config get core.https_address'. If either an IP address
and port is displayed, or both, LXD is already available on the network. If
no value is set, use 'lxc config set core.https_address' to set it.
```

```none
lxc cluster enable [<remote>:] <name> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc cluster](../cluster.md#lxc-cluster-md)	 - Manage cluster members


# index.html.md

<a id="lxc-cluster-get-md"></a>

# `lxc cluster get`

Get value for cluster member configuration key

## Synopsis

Description:
Get value for cluster member configuration key

```none
lxc cluster get [<remote>:]<member> <key> [flags]
```

## Options

```none
  -p, --property   Get the key as a cluster property
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc cluster](../cluster.md#lxc-cluster-md)	 - Manage cluster members


# index.html.md

<a id="lxc-cluster-rename-md"></a>

# `lxc cluster rename`

Rename a cluster member

## Synopsis

Description:
Rename a cluster member

```none
lxc cluster rename [<remote>:]<member> <new-name> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc cluster](../cluster.md#lxc-cluster-md)	 - Manage cluster members


# index.html.md

<a id="lxc-cluster-set-md"></a>

# `lxc cluster set`

Set a cluster member’s configuration keys

## Synopsis

Description:
Set a cluster member’s configuration keys

```none
lxc cluster set [<remote>:]<member> <key>=<value>... [flags]
```

## Options

```none
  -p, --property   Set the key as a cluster property
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc cluster](../cluster.md#lxc-cluster-md)	 - Manage cluster members


# index.html.md

<a id="lxc-cluster-failure-domain-md"></a>

# `lxc cluster failure-domain`

Manage cluster member failure domains

## Synopsis

Description:
Manage cluster member failure domains

```none
lxc cluster failure-domain [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc cluster](../cluster.md#lxc-cluster-md)	 - Manage cluster members
* [lxc cluster failure-domain get](failure-domain/get.md#lxc-cluster-failure-domain-get-md)	 - Get the failure domain for a cluster member
* [lxc cluster failure-domain set](failure-domain/set.md#lxc-cluster-failure-domain-set-md)	 - Set the failure domain for a cluster member
* [lxc cluster failure-domain unset](failure-domain/unset.md#lxc-cluster-failure-domain-unset-md)	 - Unset the failure domain for a cluster member


# index.html.md

<a id="lxc-operation-list-md"></a>

# `lxc operation list`

List background operations

## Synopsis

Description:
List background operations

```none
lxc operation list [<remote>:] [flags]
```

## Options

```none
      --all-projects   List operations from all projects
  -c, --columns        Columns (default "itdscC")
  -f, --format         Format (csv|json|table|yaml|compact) (default "table")
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc operation](../operation.md#lxc-operation-md)	 - Manage background operations


# index.html.md

<a id="lxc-operation-show-md"></a>

# `lxc operation show`

Show details of a background operation

## Synopsis

Description:
Show details of a background operation

```none
lxc operation show [<remote>:]<operation> [flags]
```

## Examples

```none
  lxc operation show 344a79e4-d88a-45bf-9c39-c72c26f6ab8a
      Show details on that operation UUID
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc operation](../operation.md#lxc-operation-md)	 - Manage background operations


# index.html.md

<a id="lxc-operation-delete-md"></a>

# `lxc operation delete`

Delete a background operation (will attempt to cancel)

## Synopsis

Description:
Delete a background operation (will attempt to cancel)

```none
lxc operation delete [<remote>:]<operation> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc operation](../operation.md#lxc-operation-md)	 - Manage background operations


# index.html.md

<a id="lxc-file-create-md"></a>

# `lxc file create`

Create file, directory or symlink in instance

## Synopsis

Description:
Create file, directory or symlink in instance

```none
lxc file create [<remote>:]<instance>/<path> [<symlink target path>] [flags]
```

## Examples

```none
  lxc file create foo/bar
  	   To create a file /bar in the foo instance.
  lxc file create --type=symlink foo/bar baz
  	   To create a symlink /bar in instance foo whose target is baz.
```

## Options

```none
  -p, --create-dirs   Create any directories necessary
  -f, --force         Force creating files or directories
      --gid int       Set the file's gid on create (default -1)
      --mode          Set the file's perms on create
      --type          The type to create (file, symlink, or directory) (default "file")
      --uid int       Set the file's uid on create (default -1)
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc file](../file.md#lxc-file-md)	 - Manage files in instances


# index.html.md

<a id="lxc-file-delete-md"></a>

# `lxc file delete`

Delete files in instances

## Synopsis

Description:
Delete files in instances

```none
lxc file delete [<remote>:]<instance>/<path> [[<remote>:]<instance>/<path>...] [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc file](../file.md#lxc-file-md)	 - Manage files in instances


# index.html.md

<a id="lxc-file-push-md"></a>

# `lxc file push`

Push files into instances

## Synopsis

Description:
Push files into instances

```none
lxc file push <source path>... [<remote>:]<instance>/<path> [flags]
```

## Examples

```none
  lxc file push /etc/hosts foo/etc/hosts
     To push /etc/hosts into the instance "foo".
```

## Options

```none
  -p, --create-dirs   Create any directories necessary
      --gid int       Set the file's gid on push (default -1)
      --mode          Set the file's perms on push
  -r, --recursive     Recursively transfer files
      --uid int       Set the file's uid on push (default -1)
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc file](../file.md#lxc-file-md)	 - Manage files in instances


# index.html.md

<a id="lxc-file-mount-md"></a>

# `lxc file mount`

Mount path from instance

## Synopsis

Description:
Mount path from instance

```none
lxc file mount [<remote>:]<instance>[/<path>] [<target path>] [flags]
```

## Examples

```none
  lxc file mount foo/root fooroot
     To mount /root from the instance foo onto the local fooroot directory.
```

## Options

```none
      --auth-user   Set authentication user when using SSH SFTP listener
      --listen      Setup SSH SFTP listener on address:port instead of mounting
      --no-auth     Disable authentication when using SSH SFTP listener
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc file](../file.md#lxc-file-md)	 - Manage files in instances


# index.html.md

<a id="lxc-file-pull-md"></a>

# `lxc file pull`

Pull files from instances

## Synopsis

Description:
Pull files from instances

```none
lxc file pull [<remote>:]<instance>/<path> [[<remote>:]<instance>/<path>...] <target path> [flags]
```

## Examples

```none
  lxc file pull foo/etc/hosts .
     To pull /etc/hosts from the instance and write it to the current directory.
```

## Options

```none
  -p, --create-dirs   Create any directories necessary
  -r, --recursive     Recursively transfer files
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc file](../file.md#lxc-file-md)	 - Manage files in instances


# index.html.md

<a id="lxc-file-edit-md"></a>

# `lxc file edit`

Edit file in instance

## Synopsis

Description:
Edit file in instance

```none
lxc file edit [<remote>:]<instance>/<path> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc file](../file.md#lxc-file-md)	 - Manage files in instances


# index.html.md

<a id="lxc-auth-identity-provider-group-md"></a>

# `lxc auth identity-provider-group`

Manage groups

## Synopsis

Description:
Manage groups

```none
lxc auth identity-provider-group [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc auth](../auth.md#lxc-auth-md)	 - Manage user authorization
* [lxc auth identity-provider-group create](identity-provider-group/create.md#lxc-auth-identity-provider-group-create-md)	 - Create identity provider group
* [lxc auth identity-provider-group delete](identity-provider-group/delete.md#lxc-auth-identity-provider-group-delete-md)	 - Delete identity provider group
* [lxc auth identity-provider-group edit](identity-provider-group/edit.md#lxc-auth-identity-provider-group-edit-md)	 - Edit identity provider groups as YAML
* [lxc auth identity-provider-group group](identity-provider-group/group.md#lxc-auth-identity-provider-group-group-md)	 - Manage identity provider group mappings
* [lxc auth identity-provider-group list](identity-provider-group/list.md#lxc-auth-identity-provider-group-list-md)	 - List identity provider groups
* [lxc auth identity-provider-group rename](identity-provider-group/rename.md#lxc-auth-identity-provider-group-rename-md)	 - Rename identity provider group
* [lxc auth identity-provider-group show](identity-provider-group/show.md#lxc-auth-identity-provider-group-show-md)	 - Show an identity provider group


# index.html.md

<a id="lxc-auth-oidc-session-md"></a>

# `lxc auth oidc-session`

Manage OIDC sessions

## Synopsis

Description:
Manage OIDC sessions

```none
lxc auth oidc-session [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc auth](../auth.md#lxc-auth-md)	 - Manage user authorization
* [lxc auth oidc-session delete](oidc-session/delete.md#lxc-auth-oidc-session-delete-md)	 - Delete OIDC session
* [lxc auth oidc-session list](oidc-session/list.md#lxc-auth-oidc-session-list-md)	 - List OIDC sessions
* [lxc auth oidc-session show](oidc-session/show.md#lxc-auth-oidc-session-show-md)	 - Show OIDC session


# index.html.md

<a id="lxc-auth-group-md"></a>

# `lxc auth group`

Manage groups

## Synopsis

Description:
Manage groups

```none
lxc auth group [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc auth](../auth.md#lxc-auth-md)	 - Manage user authorization
* [lxc auth group create](group/create.md#lxc-auth-group-create-md)	 - Create group
* [lxc auth group delete](group/delete.md#lxc-auth-group-delete-md)	 - Delete group
* [lxc auth group edit](group/edit.md#lxc-auth-group-edit-md)	 - Edit groups as YAML
* [lxc auth group list](group/list.md#lxc-auth-group-list-md)	 - List groups
* [lxc auth group permission](group/permission.md#lxc-auth-group-permission-md)	 - Manage permissions
* [lxc auth group rename](group/rename.md#lxc-auth-group-rename-md)	 - Rename group
* [lxc auth group show](group/show.md#lxc-auth-group-show-md)	 - Show group configurations


# index.html.md

<a id="lxc-auth-permission-md"></a>

# `lxc auth permission`

Inspect permissions

## Synopsis

Description:
Inspect permissions

```none
lxc auth permission [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc auth](../auth.md#lxc-auth-md)	 - Manage user authorization
* [lxc auth permission list](permission/list.md#lxc-auth-permission-list-md)	 - List permissions


# index.html.md

<a id="lxc-auth-identity-md"></a>

# `lxc auth identity`

Manage identities

## Synopsis

Description:
Manage identities

```none
lxc auth identity [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc auth](../auth.md#lxc-auth-md)	 - Manage user authorization
* [lxc auth identity create](identity/create.md#lxc-auth-identity-create-md)	 - Create an identity
* [lxc auth identity delete](identity/delete.md#lxc-auth-identity-delete-md)	 - Delete an identity
* [lxc auth identity edit](identity/edit.md#lxc-auth-identity-edit-md)	 - Edit an identity as YAML
* [lxc auth identity group](identity/group.md#lxc-auth-identity-group-md)	 - Manage groups for the identity
* [lxc auth identity info](identity/info.md#lxc-auth-identity-info-md)	 - View the current identity
* [lxc auth identity list](identity/list.md#lxc-auth-identity-list-md)	 - List identities
* [lxc auth identity show](identity/show.md#lxc-auth-identity-show-md)	 - View an identity
* [lxc auth identity token](identity/token.md#lxc-auth-identity-token-md)	 - Manage bearer identity tokens


# index.html.md

<a id="lxc-storage-create-md"></a>

# `lxc storage create`

Create storage pools

## Synopsis

Description:
Create storage pools

```none
lxc storage create [<remote>:]<pool> <driver> [key=value...] [flags]
```

## Examples

```none
  lxc storage create s1 dir

  lxc storage create s1 dir < config.yaml
      Create a storage pool using the content of config.yaml.
```

## Options

```none
      --target   Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc storage](../storage.md#lxc-storage-md)	 - Manage storage pools and volumes


# index.html.md

<a id="lxc-storage-delete-md"></a>

# `lxc storage delete`

Delete storage pool

## Synopsis

Description:
Delete storage pool

```none
lxc storage delete [<remote>:]<pool> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc storage](../storage.md#lxc-storage-md)	 - Manage storage pools and volumes


# index.html.md

<a id="lxc-storage-info-md"></a>

# `lxc storage info`

Show useful information about storage pool

## Synopsis

Description:
Show useful information about storage pool

```none
lxc storage info [<remote>:]<pool> [flags]
```

## Options

```none
      --bytes    Show the used and free space in bytes
      --target   Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc storage](../storage.md#lxc-storage-md)	 - Manage storage pools and volumes


# index.html.md

<a id="lxc-storage-bucket-md"></a>

# `lxc storage bucket`

Manage storage buckets

## Synopsis

Description:
Manage storage buckets

```none
lxc storage bucket [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc storage](../storage.md#lxc-storage-md)	 - Manage storage pools and volumes
* [lxc storage bucket create](bucket/create.md#lxc-storage-bucket-create-md)	 - Create new custom storage buckets
* [lxc storage bucket delete](bucket/delete.md#lxc-storage-bucket-delete-md)	 - Delete storage bucket
* [lxc storage bucket edit](bucket/edit.md#lxc-storage-bucket-edit-md)	 - Edit storage bucket configurations as YAML
* [lxc storage bucket get](bucket/get.md#lxc-storage-bucket-get-md)	 - Get value for storage bucket configuration key
* [lxc storage bucket key](bucket/key.md#lxc-storage-bucket-key-md)	 - Manage storage bucket keys
* [lxc storage bucket list](bucket/list.md#lxc-storage-bucket-list-md)	 - List storage buckets
* [lxc storage bucket set](bucket/set.md#lxc-storage-bucket-set-md)	 - Set storage bucket configuration keys
* [lxc storage bucket show](bucket/show.md#lxc-storage-bucket-show-md)	 - Show storage bucket configurations
* [lxc storage bucket unset](bucket/unset.md#lxc-storage-bucket-unset-md)	 - Unset storage bucket configuration key


# index.html.md

<a id="lxc-storage-edit-md"></a>

# `lxc storage edit`

Edit storage pool configurations as YAML

## Synopsis

Description:
Edit storage pool configurations as YAML

```none
lxc storage edit [<remote>:]<pool> [flags]
```

## Examples

```none
  lxc storage edit [<remote>:]<pool> < pool.yaml
      Update a storage pool using the content of pool.yaml.
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc storage](../storage.md#lxc-storage-md)	 - Manage storage pools and volumes


# index.html.md

<a id="lxc-storage-show-md"></a>

# `lxc storage show`

Show storage pool configurations and resources

## Synopsis

Description:
Show storage pool configurations and resources

```none
lxc storage show [<remote>:]<pool> [flags]
```

## Options

```none
      --resources   Show the resources available to the storage pool
      --target      Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc storage](../storage.md#lxc-storage-md)	 - Manage storage pools and volumes


# index.html.md

<a id="lxc-storage-volume-md"></a>

# `lxc storage volume`

Manage storage volumes

## Synopsis

Description:
Manage storage volumes

Unless specified through a prefix, all volume operations affect “custom” (user created) volumes.

```none
lxc storage volume [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc storage](../storage.md#lxc-storage-md)	 - Manage storage pools and volumes
* [lxc storage volume attach](volume/attach.md#lxc-storage-volume-attach-md)	 - Attach new storage volume to instance
* [lxc storage volume attach-profile](volume/attach-profile.md#lxc-storage-volume-attach-profile-md)	 - Attach new storage volume to profile
* [lxc storage volume copy](volume/copy.md#lxc-storage-volume-copy-md)	 - Copy storage volume
* [lxc storage volume create](volume/create.md#lxc-storage-volume-create-md)	 - Create new custom storage volume
* [lxc storage volume delete](volume/delete.md#lxc-storage-volume-delete-md)	 - Delete storage volume
* [lxc storage volume detach](volume/detach.md#lxc-storage-volume-detach-md)	 - Detach storage volume from instance
* [lxc storage volume detach-profile](volume/detach-profile.md#lxc-storage-volume-detach-profile-md)	 - Detach storage volume from profile
* [lxc storage volume edit](volume/edit.md#lxc-storage-volume-edit-md)	 - Edit storage volume configurations as YAML
* [lxc storage volume export](volume/export.md#lxc-storage-volume-export-md)	 - Export custom storage volume
* [lxc storage volume get](volume/get.md#lxc-storage-volume-get-md)	 - Get value for storage volume configuration key
* [lxc storage volume import](volume/import.md#lxc-storage-volume-import-md)	 - Import storage volumes
* [lxc storage volume info](volume/info.md#lxc-storage-volume-info-md)	 - Show storage volume state information
* [lxc storage volume list](volume/list.md#lxc-storage-volume-list-md)	 - List storage volumes
* [lxc storage volume move](volume/move.md#lxc-storage-volume-move-md)	 - Move storage volumes between pools
* [lxc storage volume rename](volume/rename.md#lxc-storage-volume-rename-md)	 - Rename storage volume and storage volume snapshot
* [lxc storage volume restore](volume/restore.md#lxc-storage-volume-restore-md)	 - Restore storage volume snapshot
* [lxc storage volume set](volume/set.md#lxc-storage-volume-set-md)	 - Set storage volume configuration keys
* [lxc storage volume show](volume/show.md#lxc-storage-volume-show-md)	 - Show storage volume configurations
* [lxc storage volume snapshot](volume/snapshot.md#lxc-storage-volume-snapshot-md)	 - Snapshot storage volume
* [lxc storage volume unset](volume/unset.md#lxc-storage-volume-unset-md)	 - Unset storage volume configuration key


# index.html.md

<a id="lxc-storage-set-md"></a>

# `lxc storage set`

Set storage pool configuration key

## Synopsis

Description:
Set storage pool configuration key

For backward compatibility, a single configuration key may still be set with:
lxc storage set [<remote>:]<pool> <key> <value>

```none
lxc storage set [<remote>:]<pool> <key> <value> [flags]
```

## Options

```none
  -p, --property   Set the key as a storage property
      --target     Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc storage](../storage.md#lxc-storage-md)	 - Manage storage pools and volumes


# index.html.md

<a id="lxc-storage-list-md"></a>

# `lxc storage list`

List available storage pools

## Synopsis

Description:
List available storage pools

```none
lxc storage list [<remote>:] [flags]
```

## Options

```none
  -c, --columns   Columns (default "nDsduS")
  -f, --format    Format (csv|json|table|yaml|compact) (default "table")
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc storage](../storage.md#lxc-storage-md)	 - Manage storage pools and volumes


# index.html.md

<a id="lxc-storage-unset-md"></a>

# `lxc storage unset`

Unset storage pool configuration key

## Synopsis

Description:
Unset storage pool configuration key

```none
lxc storage unset [<remote>:]<pool> <key> [flags]
```

## Options

```none
  -p, --property   Unset the key as a storage property
      --target     Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc storage](../storage.md#lxc-storage-md)	 - Manage storage pools and volumes


# index.html.md

<a id="lxc-storage-get-md"></a>

# `lxc storage get`

Get value for storage pool configuration key

## Synopsis

Description:
Get value for storage pool configuration key

```none
lxc storage get [<remote>:]<pool> <key> [flags]
```

## Options

```none
  -p, --property   Get the key as a storage property
      --target     Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc storage](../storage.md#lxc-storage-md)	 - Manage storage pools and volumes


# index.html.md

<a id="lxc-remote-get-default-md"></a>

# `lxc remote get-default`

Show the default remote

## Synopsis

Description:
Show the default remote

```none
lxc remote get-default [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc remote](../remote.md#lxc-remote-md)	 - Manage the list of remote servers


# index.html.md

<a id="lxc-remote-rename-md"></a>

# `lxc remote rename`

Rename remote

## Synopsis

Description:
Rename remote

```none
lxc remote rename <remote> <new-name> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc remote](../remote.md#lxc-remote-md)	 - Manage the list of remote servers


# index.html.md

<a id="lxc-remote-set-url-md"></a>

# `lxc remote set-url`

Set the URL for the remote

## Synopsis

Description:
Set the URL for the remote

```none
lxc remote set-url <remote> <URL> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc remote](../remote.md#lxc-remote-md)	 - Manage the list of remote servers


# index.html.md

<a id="lxc-remote-switch-md"></a>

# `lxc remote switch`

Switch the default remote

## Synopsis

Description:
Switch the default remote

```none
lxc remote switch <remote> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc remote](../remote.md#lxc-remote-md)	 - Manage the list of remote servers


# index.html.md

<a id="lxc-remote-add-md"></a>

# `lxc remote add`

Add new remote server

## Synopsis

Description:
Add new remote server

URL for remote resources must be HTTPS (https://).

Basic authentication can be used when combined with the “simplestreams” protocol:
lxc remote add some-name [https://LOGIN:PASSWORD@example.com/some/path](https://LOGIN:PASSWORD@example.com/some/path) –protocol=simplestreams

```none
lxc remote add [<remote>] <IP|FQDN|URL|token> [flags]
```

## Options

```none
      --accept-certificate   Accept certificate
      --auth-type            Server authentication type (tls or oidc
      --password             Remote admin password
      --project              Project to use for the remote
      --protocol             Server protocol (lxd or simplestreams
      --public               Public image server
      --token                Remote trust token
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc remote](../remote.md#lxc-remote-md)	 - Manage the list of remote servers


# index.html.md

<a id="lxc-remote-remove-md"></a>

# `lxc remote remove`

Remove remote

## Synopsis

Description:
Remove remote

```none
lxc remote remove <remote> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc remote](../remote.md#lxc-remote-md)	 - Manage the list of remote servers


# index.html.md

<a id="lxc-remote-list-md"></a>

# `lxc remote list`

List the available remotes

## Synopsis

Description:
List the available remotes

```none
lxc remote list [flags]
```

## Options

```none
  -c, --columns   Columns (default "nupaPSg")
  -f, --format    Format (csv|json|table|yaml|compact) (default "table")
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc remote](../remote.md#lxc-remote-md)	 - Manage the list of remote servers


# index.html.md

<a id="lxc-profile-copy-md"></a>

# `lxc profile copy`

Copy profile

## Synopsis

Description:
Copy profile

```none
lxc profile copy [<remote>:]<profile> [<remote>:]<profile> [flags]
```

## Options

```none
      --refresh          Update the target profile from the source if it already exists
      --target-project   Copy to a project different from the source
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc profile](../profile.md#lxc-profile-md)	 - Manage profiles


# index.html.md

<a id="lxc-profile-create-md"></a>

# `lxc profile create`

Create profile

## Synopsis

Description:
Create profile

```none
lxc profile create [<remote>:]<profile> [flags]
```

## Examples

```none
  lxc profile create p1

  lxc profile create p1 < config.yaml
      Create profile with configuration from config.yaml
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc profile](../profile.md#lxc-profile-md)	 - Manage profiles


# index.html.md

<a id="lxc-profile-delete-md"></a>

# `lxc profile delete`

Delete profile

## Synopsis

Description:
Delete profile

```none
lxc profile delete [<remote>:]<profile> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc profile](../profile.md#lxc-profile-md)	 - Manage profiles


# index.html.md

<a id="lxc-profile-rename-md"></a>

# `lxc profile rename`

Rename profile

## Synopsis

Description:
Rename profile

```none
lxc profile rename [<remote>:]<profile> <new-name> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc profile](../profile.md#lxc-profile-md)	 - Manage profiles


# index.html.md

<a id="lxc-profile-get-md"></a>

# `lxc profile get`

Get value for profile configuration key

## Synopsis

Description:
Get value for profile configuration key

```none
lxc profile get [<remote>:]<profile> <key> [flags]
```

## Options

```none
  -p, --property   Get the key as a profile property
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc profile](../profile.md#lxc-profile-md)	 - Manage profiles


# index.html.md

<a id="lxc-profile-unset-md"></a>

# `lxc profile unset`

Unset profile configuration key

## Synopsis

Description:
Unset profile configuration key

```none
lxc profile unset [<remote>:]<profile> <key> [flags]
```

## Options

```none
  -p, --property   Unset the key as a profile property
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc profile](../profile.md#lxc-profile-md)	 - Manage profiles


# index.html.md

<a id="lxc-profile-set-md"></a>

# `lxc profile set`

Set profile configuration keys

## Synopsis

Description:
Set profile configuration keys

For backward compatibility, a single configuration key may still be set with:
lxc profile set [<remote>:]<profile> <key> <value>

```none
lxc profile set [<remote>:]<profile> <key>=<value>... [flags]
```

## Options

```none
  -p, --property   Set the key as a profile property
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc profile](../profile.md#lxc-profile-md)	 - Manage profiles


# index.html.md

<a id="lxc-profile-edit-md"></a>

# `lxc profile edit`

Edit profile configurations as YAML

## Synopsis

Description:
Edit profile configurations as YAML

```none
lxc profile edit [<remote>:]<profile> [flags]
```

## Examples

```none
  lxc profile edit <profile> < profile.yaml
      Update a profile using the content of profile.yaml
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc profile](../profile.md#lxc-profile-md)	 - Manage profiles


# index.html.md

<a id="lxc-profile-show-md"></a>

# `lxc profile show`

Show profile configurations

## Synopsis

Description:
Show profile configurations

```none
lxc profile show [<remote>:]<profile> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc profile](../profile.md#lxc-profile-md)	 - Manage profiles


# index.html.md

<a id="lxc-profile-remove-md"></a>

# `lxc profile remove`

Remove profile from instance

## Synopsis

Description:
Remove profile from instance

```none
lxc profile remove [<remote>:]<instance> <profile> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc profile](../profile.md#lxc-profile-md)	 - Manage profiles


# index.html.md

<a id="lxc-profile-list-md"></a>

# `lxc profile list`

List profiles

## Synopsis

Description:
List profiles

The -c option takes a (optionally comma-separated) list of arguments
that control which profile attributes to output when displaying in table
or csv format.

Default column layout is: ndu

Column shorthand chars:
n - Profile Name
d - Description
e - Project (only when using –all-projects)
u - Used By

```none
lxc profile list [<remote>:] [flags]
```

## Options

```none
      --all-projects   Display profiles from all projects
  -c, --columns        Columns (default "ndu")
  -f, --format         Format (csv|json|table|yaml|compact) (default "table")
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc profile](../profile.md#lxc-profile-md)	 - Manage profiles


# index.html.md

<a id="lxc-profile-device-md"></a>

# `lxc profile device`

Manage devices

## Synopsis

Description:
Manage devices

```none
lxc profile device [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc profile](../profile.md#lxc-profile-md)	 - Manage profiles
* [lxc profile device add](device/add.md#lxc-profile-device-add-md)	 - Add instance devices
* [lxc profile device get](device/get.md#lxc-profile-device-get-md)	 - Get value for device configuration key
* [lxc profile device list](device/list.md#lxc-profile-device-list-md)	 - List instance devices
* [lxc profile device remove](device/remove.md#lxc-profile-device-remove-md)	 - Remove instance devices
* [lxc profile device set](device/set.md#lxc-profile-device-set-md)	 - Set device configuration keys
* [lxc profile device show](device/show.md#lxc-profile-device-show-md)	 - Show full device configuration
* [lxc profile device unset](device/unset.md#lxc-profile-device-unset-md)	 - Unset device configuration key


# index.html.md

<a id="lxc-profile-add-md"></a>

# `lxc profile add`

Add profile to instance

## Synopsis

Description:
Add profile to instance

```none
lxc profile add [<remote>:]<instance> <profile> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc profile](../profile.md#lxc-profile-md)	 - Manage profiles


# index.html.md

<a id="lxc-profile-assign-md"></a>

# `lxc profile assign`

Assign sets of profiles to instance

## Synopsis

Description:
Assign sets of profiles to instance

```none
lxc profile assign [<remote>:]<instance> <profiles> [flags]
```

## Examples

```none
  lxc profile assign foo default,bar
      Set the profiles for "foo" to "default" and "bar".

  lxc profile assign foo default
      Reset "foo" to only using the "default" profile.

  lxc profile assign foo ''
      Remove all profile from "foo"
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc profile](../profile.md#lxc-profile-md)	 - Manage profiles


# index.html.md

<a id="lxc-config-uefi-get-md"></a>

# `lxc config uefi get`

Get UEFI variable for instance

## Synopsis

Description:
Get UEFI variable for instance

```none
lxc config uefi get [<remote>:]<instance> <key> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc config uefi](../uefi.md#lxc-config-uefi-md)	 - Manage instance UEFI variables


# index.html.md

<a id="lxc-config-uefi-unset-md"></a>

# `lxc config uefi unset`

Unset UEFI variable for instance

## Synopsis

Description:
Unset UEFI variable for instance

```none
lxc config uefi unset [<remote>:]<instance> <key> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc config uefi](../uefi.md#lxc-config-uefi-md)	 - Manage instance UEFI variables


# index.html.md

<a id="lxc-config-uefi-set-md"></a>

# `lxc config uefi set`

Set UEFI variable for instance

## Synopsis

Description:
Set UEFI variable for instance

```none
lxc config uefi set [<remote>:]<instance> <key>=<value>... [flags]
```

## Examples

```none
  lxc config uefi set [<remote>:]<instance> testvar-9073e4e0-60ec-4b6e-9903-4c223c260f3c=aabb
      Set a UEFI variable with name "testvar", GUID 9073e4e0-60ec-4b6e-9903-4c223c260f3c and value "aabb" (HEX-encoded) for the instance.
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc config uefi](../uefi.md#lxc-config-uefi-md)	 - Manage instance UEFI variables


# index.html.md

<a id="lxc-config-uefi-edit-md"></a>

# `lxc config uefi edit`

Edit instance UEFI variables

## Synopsis

Description:
Edit instance UEFI variables

```none
lxc config uefi edit [<remote>:]<instance> [flags]
```

## Examples

```none
  lxc config uefi edit <instance> < instance_uefi_vars.yaml
      Set the instance UEFI variables from instance_uefi_vars.yaml.
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc config uefi](../uefi.md#lxc-config-uefi-md)	 - Manage instance UEFI variables


# index.html.md

<a id="lxc-config-uefi-show-md"></a>

# `lxc config uefi show`

Show instance UEFI variables

## Synopsis

Description:
Show instance UEFI variables

```none
lxc config uefi show [<remote>:]<instance> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc config uefi](../uefi.md#lxc-config-uefi-md)	 - Manage instance UEFI variables


# index.html.md

<a id="lxc-config-trust-add-md"></a>

# `lxc config trust add`

Add new trusted client

## Synopsis

Description:
Add new trusted client

The following certificate types are supported:

- client (default)
- metrics

If the certificate is omitted, a token will be generated and returned. A client
providing a valid token will have its client certificate added to the trusted list
and the consumed token will be invalidated. Similar to certificates, tokens can be
restricted to one or more projects.

Note: The –projects flag requires –restricted to be set. Projects can only be
used to restrict certificate access when the certificate is marked as restricted.

```none
lxc config trust add [<remote>:] [<cert>] [flags]
```

## Options

```none
      --name         Alternative certificate name
      --projects     List of projects to restrict the certificate to (requires --restricted)
      --restricted   Restrict the certificate to one or more projects
      --type         Type of certificate (default "client")
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc config trust](../trust.md#lxc-config-trust-md)	 - Manage trusted clients


# index.html.md

<a id="lxc-config-trust-revoke-token-md"></a>

# `lxc config trust revoke-token`

Revoke certificate add token

## Synopsis

Description:
Revoke certificate add token

```none
lxc config trust revoke-token [<remote>:] <name> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc config trust](../trust.md#lxc-config-trust-md)	 - Manage trusted clients


# index.html.md

<a id="lxc-config-trust-edit-md"></a>

# `lxc config trust edit`

Edit trust configurations as YAML

## Synopsis

Description:
Edit trust configurations as YAML

```none
lxc config trust edit [<remote>:]<fingerprint> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc config trust](../trust.md#lxc-config-trust-md)	 - Manage trusted clients


# index.html.md

<a id="lxc-config-trust-show-md"></a>

# `lxc config trust show`

Show trust configurations

## Synopsis

Description:
Show trust configurations

```none
lxc config trust show [<remote>:]<fingerprint> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc config trust](../trust.md#lxc-config-trust-md)	 - Manage trusted clients


# index.html.md

<a id="lxc-config-trust-remove-md"></a>

# `lxc config trust remove`

Remove trusted client

## Synopsis

Description:
Remove trusted client

```none
lxc config trust remove [<remote>:]<fingerprint> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc config trust](../trust.md#lxc-config-trust-md)	 - Manage trusted clients


# index.html.md

<a id="lxc-config-trust-list-md"></a>

# `lxc config trust list`

List trusted clients

## Synopsis

Description:
List trusted clients

```none
lxc config trust list [<remote>:] [flags]
```

## Options

```none
  -c, --columns   Columns (default "tncfie")
  -f, --format    Format (csv|json|table|yaml|compact) (default "table")
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc config trust](../trust.md#lxc-config-trust-md)	 - Manage trusted clients


# index.html.md

<a id="lxc-config-trust-list-tokens-md"></a>

# `lxc config trust list-tokens`

List all active certificate add tokens

## Synopsis

Description:
List all active certificate add tokens

```none
lxc config trust list-tokens [<remote>:] [flags]
```

## Options

```none
  -c, --columns   Columns (default "nte")
  -f, --format    Format (csv|json|table|yaml|compact) (default "table")
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc config trust](../trust.md#lxc-config-trust-md)	 - Manage trusted clients


# index.html.md

<a id="lxc-config-metadata-show-md"></a>

# `lxc config metadata show`

Show instance metadata files

## Synopsis

Description:
Show instance metadata files

```none
lxc config metadata show [<remote>:]<instance> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc config metadata](../metadata.md#lxc-config-metadata-md)	 - Manage instance metadata files


# index.html.md

<a id="lxc-config-metadata-edit-md"></a>

# `lxc config metadata edit`

Edit instance metadata files

## Synopsis

Description:
Edit instance metadata files

```none
lxc config metadata edit [<remote>:]<instance> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc config metadata](../metadata.md#lxc-config-metadata-md)	 - Manage instance metadata files


# index.html.md

<a id="lxc-config-template-show-md"></a>

# `lxc config template show`

Show content of instance file template

## Synopsis

Description:
Show content of instance file template

```none
lxc config template show [<remote>:]<instance> <template> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc config template](../template.md#lxc-config-template-md)	 - Manage instance file templates


# index.html.md

<a id="lxc-config-template-edit-md"></a>

# `lxc config template edit`

Edit instance file template

## Synopsis

Description:
Edit instance file template

```none
lxc config template edit [<remote>:]<instance> <template> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc config template](../template.md#lxc-config-template-md)	 - Manage instance file templates


# index.html.md

<a id="lxc-config-template-delete-md"></a>

# `lxc config template delete`

Delete instance file template

## Synopsis

Description:
Delete instance file template

```none
lxc config template delete [<remote>:]<instance> <template> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc config template](../template.md#lxc-config-template-md)	 - Manage instance file templates


# index.html.md

<a id="lxc-config-template-create-md"></a>

# `lxc config template create`

Create new instance file template

## Synopsis

Description:
Create new instance file template

```none
lxc config template create [<remote>:]<instance> <template> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc config template](../template.md#lxc-config-template-md)	 - Manage instance file templates


# index.html.md

<a id="lxc-config-template-list-md"></a>

# `lxc config template list`

List instance file templates

## Synopsis

Description:
List instance file templates

```none
lxc config template list [<remote>:]<instance> [flags]
```

## Options

```none
  -c, --columns   Columns (default "f")
  -f, --format    Format (csv|json|table|yaml|compact) (default "table")
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc config template](../template.md#lxc-config-template-md)	 - Manage instance file templates


# index.html.md

<a id="lxc-config-device-list-md"></a>

# `lxc config device list`

List instance devices

## Synopsis

Description:
List instance devices

```none
lxc config device list [<remote>:]<instance> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc config device](../device.md#lxc-config-device-md)	 - Manage devices


# index.html.md

<a id="lxc-config-device-override-md"></a>

# `lxc config device override`

Copy profile inherited devices and override configuration keys

## Synopsis

Description:
Copy profile inherited devices and override configuration keys

```none
lxc config device override [<remote>:]<instance> <device> [key=value...] [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc config device](../device.md#lxc-config-device-md)	 - Manage devices


# index.html.md

<a id="lxc-config-device-add-md"></a>

# `lxc config device add`

Add instance devices

## Synopsis

Description:
Add instance devices

```none
lxc config device add [<remote>:]<instance> <device> <type> [key=value...] [flags]
```

## Examples

```none
  lxc config device add [<remote>:]instance1 <device-name> disk source=/share/c1 path=/opt
      Will mount the host's /share/c1 onto /opt in the instance.

  lxc config device add [<remote>:]instance1 <device-name> disk pool=some-pool source=some-volume path=/opt
      Will mount the some-volume volume on some-pool onto /opt in the instance.
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc config device](../device.md#lxc-config-device-md)	 - Manage devices


# index.html.md

<a id="lxc-config-device-unset-md"></a>

# `lxc config device unset`

Unset device configuration key

## Synopsis

Description:
Unset device configuration key

```none
lxc config device unset [<remote>:]<instance> <device> <key> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc config device](../device.md#lxc-config-device-md)	 - Manage devices


# index.html.md

<a id="lxc-config-device-show-md"></a>

# `lxc config device show`

Show full device configuration

## Synopsis

Description:
Show full device configuration

```none
lxc config device show [<remote>:]<instance> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc config device](../device.md#lxc-config-device-md)	 - Manage devices


# index.html.md

<a id="lxc-config-device-set-md"></a>

# `lxc config device set`

Set device configuration keys

## Synopsis

Description:
Set device configuration keys

For backward compatibility, a single configuration key may still be set with:
lxc config device set [<remote>:]<instance> <device> <key> <value>

```none
lxc config device set [<remote>:]<instance> <device> <key>=<value>... [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc config device](../device.md#lxc-config-device-md)	 - Manage devices


# index.html.md

<a id="lxc-config-device-remove-md"></a>

# `lxc config device remove`

Remove instance devices

## Synopsis

Description:
Remove instance devices

```none
lxc config device remove [<remote>:]<instance> <name>... [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc config device](../device.md#lxc-config-device-md)	 - Manage devices


# index.html.md

<a id="lxc-config-device-get-md"></a>

# `lxc config device get`

Get value for device configuration key

## Synopsis

Description:
Get value for device configuration key

```none
lxc config device get [<remote>:]<instance> <device> <key> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc config device](../device.md#lxc-config-device-md)	 - Manage devices


# index.html.md

<a id="lxc-image-alias-create-md"></a>

# `lxc image alias create`

Create alias for an image

## Synopsis

Description:
Create alias for an image

```none
lxc image alias create [<remote>:]<alias> <fingerprint> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc image alias](../alias.md#lxc-image-alias-md)	 - Manage image aliases


# index.html.md

<a id="lxc-image-alias-delete-md"></a>

# `lxc image alias delete`

Delete image alias

## Synopsis

Description:
Delete image alias

```none
lxc image alias delete [<remote>:]<alias> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc image alias](../alias.md#lxc-image-alias-md)	 - Manage image aliases


# index.html.md

<a id="lxc-image-alias-rename-md"></a>

# `lxc image alias rename`

Rename alias

## Synopsis

Description:
Rename alias

```none
lxc image alias rename [<remote>:]<alias> <new-name> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc image alias](../alias.md#lxc-image-alias-md)	 - Manage image aliases


# index.html.md

<a id="lxc-image-alias-list-md"></a>

# `lxc image alias list`

List image aliases

## Synopsis

Description:
List image aliases

Filters may be part of the image hash or part of the image alias name.

```none
lxc image alias list [<remote>:] [<filters>...] [flags]
```

## Options

```none
  -c, --columns   Columns (default "aftd")
  -f, --format    Format (csv|json|table|yaml|compact) (default "table")
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc image alias](../alias.md#lxc-image-alias-md)	 - Manage image aliases


# index.html.md

<a id="lxc-network-peer-unset-md"></a>

# `lxc network peer unset`

Unset network peer configuration key

## Synopsis

Description:
Unset network peer configuration key

```none
lxc network peer unset [<remote>:]<network> <peer_name> <key> [flags]
```

## Options

```none
  -p, --property   Unset the key as a network peer property
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network peer](../peer.md#lxc-network-peer-md)	 - Manage network peerings


# index.html.md

<a id="lxc-network-peer-list-md"></a>

# `lxc network peer list`

List available network peers

## Synopsis

Description:
List available network peers

```none
lxc network peer list [<remote>:]<network> [flags]
```

## Options

```none
  -c, --columns   Columns (default "ndps")
  -f, --format    Format (csv|json|table|yaml|compact) (default "table")
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network peer](../peer.md#lxc-network-peer-md)	 - Manage network peerings


# index.html.md

<a id="lxc-network-peer-get-md"></a>

# `lxc network peer get`

Get value for network peer configuration key

## Synopsis

Description:
Get value for network peer configuration key

```none
lxc network peer get [<remote>:]<network> <peer_name> <key> [flags]
```

## Options

```none
  -p, --property   Get the key as a network peer property
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network peer](../peer.md#lxc-network-peer-md)	 - Manage network peerings


# index.html.md

<a id="lxc-network-peer-edit-md"></a>

# `lxc network peer edit`

Edit network peer configurations as YAML

## Synopsis

Description:
Edit network peer configurations as YAML

```none
lxc network peer edit [<remote>:]<network> <peer_name> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network peer](../peer.md#lxc-network-peer-md)	 - Manage network peerings


# index.html.md

<a id="lxc-network-peer-delete-md"></a>

# `lxc network peer delete`

Delete network peering

## Synopsis

Description:
Delete network peering

```none
lxc network peer delete [<remote>:]<network> <peer_name> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network peer](../peer.md#lxc-network-peer-md)	 - Manage network peerings


# index.html.md

<a id="lxc-network-peer-create-md"></a>

# `lxc network peer create`

Create new network peering

## Synopsis

Description:
Create new network peering

```none
lxc network peer create [<remote>:]<network> <peer_name> <[target project/]target_network> [key=value...] [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network peer](../peer.md#lxc-network-peer-md)	 - Manage network peerings


# index.html.md

<a id="lxc-network-peer-set-md"></a>

# `lxc network peer set`

Set network peer keys

## Synopsis

Description:
Set network peer keys

For backward compatibility, a single configuration key may still be set with:
lxc network set [<remote>:]<network> <peer_name> <key> <value>

```none
lxc network peer set [<remote>:]<network> <peer_name> <key>=<value>... [flags]
```

## Options

```none
  -p, --property   Set the key as a network peer property
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network peer](../peer.md#lxc-network-peer-md)	 - Manage network peerings


# index.html.md

<a id="lxc-network-peer-show-md"></a>

# `lxc network peer show`

Show network peer configurations

## Synopsis

Description:
Show network peer configurations

```none
lxc network peer show [<remote>:]<network> <peer name> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network peer](../peer.md#lxc-network-peer-md)	 - Manage network peerings


# index.html.md

<a id="lxc-network-zone-set-md"></a>

# `lxc network zone set`

Set network zone configuration keys

## Synopsis

Description:
Set network zone configuration keys

For backward compatibility, a single configuration key may still be set with:
lxc network set [<remote>:]<Zone> <key> <value>

```none
lxc network zone set [<remote>:]<Zone> <key>=<value>... [flags]
```

## Options

```none
  -p, --property   Set the key as a network zone property
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network zone](../zone.md#lxc-network-zone-md)	 - Manage network zones


# index.html.md

<a id="lxc-network-zone-get-md"></a>

# `lxc network zone get`

Get value for network zone configuration key

## Synopsis

Description:
Get value for network zone configuration key

```none
lxc network zone get [<remote>:]<Zone> <key> [flags]
```

## Options

```none
  -p, --property   Get the key as a network zone property
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network zone](../zone.md#lxc-network-zone-md)	 - Manage network zones


# index.html.md

<a id="lxc-network-zone-list-md"></a>

# `lxc network zone list`

List available network zones

## Synopsis

Description:
List available network zones

```none
lxc network zone list [<remote>:] [flags]
```

## Options

```none
      --all-projects   Display network zones from all projects
  -c, --columns        Columns (default "ndu")
  -f, --format         Format (csv|json|table|yaml|compact) (default "table")
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network zone](../zone.md#lxc-network-zone-md)	 - Manage network zones


# index.html.md

<a id="lxc-network-zone-unset-md"></a>

# `lxc network zone unset`

Unset network zone configuration key

## Synopsis

Description:
Unset network zone configuration key

```none
lxc network zone unset [<remote>:]<Zone> <key> [flags]
```

## Options

```none
  -p, --property   Unset the key as a network zone property
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network zone](../zone.md#lxc-network-zone-md)	 - Manage network zones


# index.html.md

<a id="lxc-network-zone-show-md"></a>

# `lxc network zone show`

Show network zone configurations

## Synopsis

Description:
Show network zone configurations

```none
lxc network zone show [<remote>:]<Zone> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network zone](../zone.md#lxc-network-zone-md)	 - Manage network zones


# index.html.md

<a id="lxc-network-zone-create-md"></a>

# `lxc network zone create`

Create new network zone

## Synopsis

Description:
Create new network zone

```none
lxc network zone create [<remote>:]<Zone> [key=value...] [flags]
```

## Examples

```none
  lxc network zone create z1

  lxc network zone create z1 < config.yaml
      Create network zone z1 with configuration from config.yaml
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network zone](../zone.md#lxc-network-zone-md)	 - Manage network zones


# index.html.md

<a id="lxc-network-zone-delete-md"></a>

# `lxc network zone delete`

Delete network zone

## Synopsis

Description:
Delete network zone

```none
lxc network zone delete [<remote>:]<Zone> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network zone](../zone.md#lxc-network-zone-md)	 - Manage network zones


# index.html.md

<a id="lxc-network-zone-record-md"></a>

# `lxc network zone record`

Manage network zone records

## Synopsis

Description:
Manage network zone records

```none
lxc network zone record [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network zone](../zone.md#lxc-network-zone-md)	 - Manage network zones
* [lxc network zone record create](record/create.md#lxc-network-zone-record-create-md)	 - Create new network zone record
* [lxc network zone record delete](record/delete.md#lxc-network-zone-record-delete-md)	 - Delete network zone record
* [lxc network zone record edit](record/edit.md#lxc-network-zone-record-edit-md)	 - Edit network zone record configurations as YAML
* [lxc network zone record entry](record/entry.md#lxc-network-zone-record-entry-md)	 - Manage network zone record entries
* [lxc network zone record get](record/get.md#lxc-network-zone-record-get-md)	 - Get value for network zone record configuration key
* [lxc network zone record list](record/list.md#lxc-network-zone-record-list-md)	 - List available network zone records
* [lxc network zone record set](record/set.md#lxc-network-zone-record-set-md)	 - Set network zone record configuration keys
* [lxc network zone record show](record/show.md#lxc-network-zone-record-show-md)	 - Show network zone record configuration
* [lxc network zone record unset](record/unset.md#lxc-network-zone-record-unset-md)	 - Unset network zone record configuration key


# index.html.md

<a id="lxc-network-zone-edit-md"></a>

# `lxc network zone edit`

Edit network zone configurations as YAML

## Synopsis

Description:
Edit network zone configurations as YAML

```none
lxc network zone edit [<remote>:]<Zone> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network zone](../zone.md#lxc-network-zone-md)	 - Manage network zones


# index.html.md

<a id="lxc-network-forward-port-md"></a>

# `lxc network forward port`

Manage network forward ports

## Synopsis

Description:
Manage network forward ports

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network forward](../forward.md#lxc-network-forward-md)	 - Manage network forwards
* [lxc network forward port add](port/add.md#lxc-network-forward-port-add-md)	 - Add ports to a forward
* [lxc network forward port remove](port/remove.md#lxc-network-forward-port-remove-md)	 - Remove ports from a forward


# index.html.md

<a id="lxc-network-forward-list-md"></a>

# `lxc network forward list`

List available network forwards

## Synopsis

Description:
List available network forwards

```none
lxc network forward list [<remote>:]<network> [flags]
```

## Options

```none
  -c, --columns   Columns (default "ldtp")
  -f, --format    Format (csv|json|table|yaml|compact) (default "table")
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network forward](../forward.md#lxc-network-forward-md)	 - Manage network forwards


# index.html.md

<a id="lxc-network-forward-delete-md"></a>

# `lxc network forward delete`

Delete network forward

## Synopsis

Description:
Delete network forward

```none
lxc network forward delete [<remote>:]<network> <listen_address> [flags]
```

## Options

```none
      --target   Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network forward](../forward.md#lxc-network-forward-md)	 - Manage network forwards


# index.html.md

<a id="lxc-network-forward-create-md"></a>

# `lxc network forward create`

Create new network forward

## Synopsis

Description:
Create new network forward

```none
lxc network forward create [<remote>:]<network> [<listen_address>] [key=value...] [flags]
```

## Examples

```none
  lxc network forward create n1 127.0.0.1

  lxc network forward create n1 127.0.0.1 < config.yaml
      Create a new network forward for network n1 from config.yaml
```

## Options

```none
      --allocate   Auto-allocate an IPv4 or IPv6 listen address. One of 'ipv4', 'ipv6'.
      --target     Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network forward](../forward.md#lxc-network-forward-md)	 - Manage network forwards


# index.html.md

<a id="lxc-network-forward-set-md"></a>

# `lxc network forward set`

Set network forward keys

## Synopsis

Description:
Set network forward keys

For backward compatibility, a single configuration key may still be set with:
lxc network set [<remote>:]<network> <listen_address> <key> <value>

```none
lxc network forward set [<remote>:]<network> <listen_address> <key>=<value>... [flags]
```

## Options

```none
  -p, --property   Set the key as a network forward property
      --target     Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network forward](../forward.md#lxc-network-forward-md)	 - Manage network forwards


# index.html.md

<a id="lxc-network-forward-edit-md"></a>

# `lxc network forward edit`

Edit network forward configurations as YAML

## Synopsis

Description:
Edit network forward configurations as YAML

```none
lxc network forward edit [<remote>:]<network> <listen_address> [flags]
```

## Options

```none
      --target   Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network forward](../forward.md#lxc-network-forward-md)	 - Manage network forwards


# index.html.md

<a id="lxc-network-forward-unset-md"></a>

# `lxc network forward unset`

Unset network forward configuration key

## Synopsis

Description:
Unset network forward configuration key

```none
lxc network forward unset [<remote>:]<network> <listen_address> <key> [flags]
```

## Options

```none
  -p, --property   Unset the key as a network forward property
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network forward](../forward.md#lxc-network-forward-md)	 - Manage network forwards


# index.html.md

<a id="lxc-network-forward-show-md"></a>

# `lxc network forward show`

Show network forward configurations

## Synopsis

Description:
Show network forward configurations

```none
lxc network forward show [<remote>:]<network> <listen_address> [flags]
```

## Options

```none
      --target   Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network forward](../forward.md#lxc-network-forward-md)	 - Manage network forwards


# index.html.md

<a id="lxc-network-forward-get-md"></a>

# `lxc network forward get`

Get value for network forward configuration key

## Synopsis

Description:
Get value for network forward configuration key

```none
lxc network forward get [<remote>:]<network> <listen_address> <key> [flags]
```

## Options

```none
  -p, --property   Get the key as a network forward property
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network forward](../forward.md#lxc-network-forward-md)	 - Manage network forwards


# index.html.md

<a id="lxc-network-acl-rename-md"></a>

# `lxc network acl rename`

Rename network ACL

## Synopsis

Description:
Rename network ACL

```none
lxc network acl rename [<remote>:]<ACL> <new-name> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network acl](../acl.md#lxc-network-acl-md)	 - Manage network ACLs


# index.html.md

<a id="lxc-network-acl-create-md"></a>

# `lxc network acl create`

Create new network ACL

## Synopsis

Description:
Create new network ACL

```none
lxc network acl create [<remote>:]<ACL> [key=value...] [flags]
```

## Examples

```none
  lxc network acl create a1

  lxc network acl create a1 < config.yaml
      Create network acl with configuration from config.yaml
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network acl](../acl.md#lxc-network-acl-md)	 - Manage network ACLs


# index.html.md

<a id="lxc-network-acl-delete-md"></a>

# `lxc network acl delete`

Delete network ACL

## Synopsis

Description:
Delete network ACL

```none
lxc network acl delete [<remote>:]<ACL> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network acl](../acl.md#lxc-network-acl-md)	 - Manage network ACLs


# index.html.md

<a id="lxc-network-acl-show-md"></a>

# `lxc network acl show`

Show network ACL configurations

## Synopsis

Description:
Show network ACL configurations

```none
lxc network acl show [<remote>:]<ACL> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network acl](../acl.md#lxc-network-acl-md)	 - Manage network ACLs


# index.html.md

<a id="lxc-network-acl-edit-md"></a>

# `lxc network acl edit`

Edit network ACL configurations as YAML

## Synopsis

Description:
Edit network ACL configurations as YAML

```none
lxc network acl edit [<remote>:]<ACL> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network acl](../acl.md#lxc-network-acl-md)	 - Manage network ACLs


# index.html.md

<a id="lxc-network-acl-unset-md"></a>

# `lxc network acl unset`

Unset network ACL configuration key

## Synopsis

Description:
Unset network ACL configuration key

```none
lxc network acl unset [<remote>:]<ACL> <key> [flags]
```

## Options

```none
  -p, --property   Unset the key as a network ACL property
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network acl](../acl.md#lxc-network-acl-md)	 - Manage network ACLs


# index.html.md

<a id="lxc-network-acl-list-md"></a>

# `lxc network acl list`

List network ACLs

## Synopsis

Description:
List network ACLs

```none
lxc network acl list [<remote>:] [flags]
```

## Options

```none
      --all-projects   Display network ACLs from all projects
  -c, --columns        Columns (default "ndu")
  -f, --format         Format (csv|json|table|yaml|compact) (default "table")
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network acl](../acl.md#lxc-network-acl-md)	 - Manage network ACLs


# index.html.md

<a id="lxc-network-acl-rule-md"></a>

# `lxc network acl rule`

Manage network ACL rules

## Synopsis

Description:
Manage network ACL rules

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network acl](../acl.md#lxc-network-acl-md)	 - Manage network ACLs
* [lxc network acl rule add](rule/add.md#lxc-network-acl-rule-add-md)	 - Add rule to an ACL
* [lxc network acl rule remove](rule/remove.md#lxc-network-acl-rule-remove-md)	 - Remove rule from an ACL


# index.html.md

<a id="lxc-network-acl-show-log-md"></a>

# `lxc network acl show-log`

Show network ACL log

## Synopsis

Description:
Show network ACL log

```none
lxc network acl show-log [<remote>:]<ACL> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network acl](../acl.md#lxc-network-acl-md)	 - Manage network ACLs


# index.html.md

<a id="lxc-network-acl-get-md"></a>

# `lxc network acl get`

Get value for network ACL configuration key

## Synopsis

Description:
Get value for network ACL configuration key

```none
lxc network acl get [<remote>:]<ACL> <key> [flags]
```

## Options

```none
  -p, --property   Get the key as a network ACL property
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network acl](../acl.md#lxc-network-acl-md)	 - Manage network ACLs


# index.html.md

<a id="lxc-network-acl-set-md"></a>

# `lxc network acl set`

Set network ACL configuration keys

## Synopsis

Description:
Set network ACL configuration keys

For backward compatibility, a single configuration key may still be set with:
lxc network set [<remote>:]<ACL> <key> <value>

```none
lxc network acl set [<remote>:]<ACL> <key>=<value>... [flags]
```

## Options

```none
  -p, --property   Set the key as a network ACL property
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network acl](../acl.md#lxc-network-acl-md)	 - Manage network ACLs


# index.html.md

<a id="lxc-network-load-balancer-unset-md"></a>

# `lxc network load-balancer unset`

Unset network load balancer configuration key

## Synopsis

Description:
Unset network load balancer configuration key

```none
lxc network load-balancer unset [<remote>:]<network> <listen_address> <key> [flags]
```

## Options

```none
  -p, --property   Unset the key as a network load balancer property
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network load-balancer](../load-balancer.md#lxc-network-load-balancer-md)	 - Manage network load balancers


# index.html.md

<a id="lxc-network-load-balancer-pool-md"></a>

# `lxc network load-balancer pool`

Manage network load balancer pools

## Synopsis

Description:
Manage network load balancer pools

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network load-balancer](../load-balancer.md#lxc-network-load-balancer-md)	 - Manage network load balancers
* [lxc network load-balancer pool create](pool/create.md#lxc-network-load-balancer-pool-create-md)	 - Add load balancer pool to a network
* [lxc network load-balancer pool delete](pool/delete.md#lxc-network-load-balancer-pool-delete-md)	 - Delete load balancer pool
* [lxc network load-balancer pool edit](pool/edit.md#lxc-network-load-balancer-pool-edit-md)	 - Edit load balancer pool configurations as YAML
* [lxc network load-balancer pool get](pool/get.md#lxc-network-load-balancer-pool-get-md)	 - Get value for network load balancer pool configuration key
* [lxc network load-balancer pool instance](pool/instance.md#lxc-network-load-balancer-pool-instance-md)	 - Manage instances of network load balancer pool
* [lxc network load-balancer pool list](pool/list.md#lxc-network-load-balancer-pool-list-md)	 - List available network load balancer pools
* [lxc network load-balancer pool set](pool/set.md#lxc-network-load-balancer-pool-set-md)	 - Set network load balancer pool keys
* [lxc network load-balancer pool show](pool/show.md#lxc-network-load-balancer-pool-show-md)	 - Show load balancer pool
* [lxc network load-balancer pool unset](pool/unset.md#lxc-network-load-balancer-pool-unset-md)	 - Unset network load balancer pool configuration key


# index.html.md

<a id="lxc-network-load-balancer-create-md"></a>

# `lxc network load-balancer create`

Create new network load balancer

## Synopsis

Description:
Create new network load balancer

```none
lxc network load-balancer create [<remote>:]<network> [<listen_address>] [key=value...] [flags]
```

## Examples

```none
  lxc network load-balancer create n1 127.0.0.1

  lxc network load-balancer create n1 127.0.0.1 < config.yaml
      Create network load-balancer for network n1 with configuration from config.yaml
```

## Options

```none
      --allocate   Auto-allocate an IPv4 or IPv6 listen address. One of 'ipv4', 'ipv6'.
      --target     Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network load-balancer](../load-balancer.md#lxc-network-load-balancer-md)	 - Manage network load balancers


# index.html.md

<a id="lxc-network-load-balancer-delete-md"></a>

# `lxc network load-balancer delete`

Delete network load balancer

## Synopsis

Description:
Delete network load balancer

```none
lxc network load-balancer delete [<remote>:]<network> <listen_address> [flags]
```

## Options

```none
      --target   Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network load-balancer](../load-balancer.md#lxc-network-load-balancer-md)	 - Manage network load balancers


# index.html.md

<a id="lxc-network-load-balancer-backend-md"></a>

# `lxc network load-balancer backend`

Manage network load balancer backends

## Synopsis

Description:
Manage network load balancer backends

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network load-balancer](../load-balancer.md#lxc-network-load-balancer-md)	 - Manage network load balancers
* [lxc network load-balancer backend add](backend/add.md#lxc-network-load-balancer-backend-add-md)	 - Add backends to a load balancer
* [lxc network load-balancer backend remove](backend/remove.md#lxc-network-load-balancer-backend-remove-md)	 - Remove backends from a load balancer


# index.html.md

<a id="lxc-network-load-balancer-edit-md"></a>

# `lxc network load-balancer edit`

Edit network load balancer configurations as YAML

## Synopsis

Description:
Edit network load balancer configurations as YAML

```none
lxc network load-balancer edit [<remote>:]<network> <listen_address> [flags]
```

## Options

```none
      --target   Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network load-balancer](../load-balancer.md#lxc-network-load-balancer-md)	 - Manage network load balancers


# index.html.md

<a id="lxc-network-load-balancer-show-md"></a>

# `lxc network load-balancer show`

Show network load balancer configurations

## Synopsis

Description:
Show network load balancer configurations

```none
lxc network load-balancer show [<remote>:]<network> <listen_address> [flags]
```

## Options

```none
      --target   Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network load-balancer](../load-balancer.md#lxc-network-load-balancer-md)	 - Manage network load balancers


# index.html.md

<a id="lxc-network-load-balancer-set-md"></a>

# `lxc network load-balancer set`

Set network load balancer keys

## Synopsis

Description:
Set network load balancer keys

For backward compatibility, a single configuration key may still be set with:
lxc network set [<remote>:]<network> <listen_address> <key> <value>

```none
lxc network load-balancer set [<remote>:]<network> <listen_address> <key>=<value>... [flags]
```

## Options

```none
  -p, --property   Set the key as a network load balancer property
      --target     Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network load-balancer](../load-balancer.md#lxc-network-load-balancer-md)	 - Manage network load balancers


# index.html.md

<a id="lxc-network-load-balancer-port-md"></a>

# `lxc network load-balancer port`

Manage network load balancer ports

## Synopsis

Description:
Manage network load balancer ports

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network load-balancer](../load-balancer.md#lxc-network-load-balancer-md)	 - Manage network load balancers
* [lxc network load-balancer port add](port/add.md#lxc-network-load-balancer-port-add-md)	 - Add ports to a load balancer
* [lxc network load-balancer port remove](port/remove.md#lxc-network-load-balancer-port-remove-md)	 - Remove ports from a load balancer


# index.html.md

<a id="lxc-network-load-balancer-list-md"></a>

# `lxc network load-balancer list`

List available network load balancers

## Synopsis

Description:
List available network load balancers

```none
lxc network load-balancer list [<remote>:]<network> [flags]
```

## Options

```none
  -c, --columns   Columns (default "ldp")
  -f, --format    Format (csv|json|table|yaml|compact) (default "table")
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network load-balancer](../load-balancer.md#lxc-network-load-balancer-md)	 - Manage network load balancers


# index.html.md

<a id="lxc-network-load-balancer-get-md"></a>

# `lxc network load-balancer get`

Get value for network load balancer configuration key

## Synopsis

Description:
Get value for network load balancer configuration key

```none
lxc network load-balancer get [<remote>:]<network> <listen_address> <key> [flags]
```

## Options

```none
  -p, --property   Get the key as a network load balancer property
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network load-balancer](../load-balancer.md#lxc-network-load-balancer-md)	 - Manage network load balancers


# index.html.md

<a id="lxc-network-zone-record-show-md"></a>

# `lxc network zone record show`

Show network zone record configuration

## Synopsis

Description:
Show network zone record configuration

```none
lxc network zone record show [<remote>:]<zone> <record> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network zone record](../record.md#lxc-network-zone-record-md)	 - Manage network zone records


# index.html.md

<a id="lxc-network-zone-record-edit-md"></a>

# `lxc network zone record edit`

Edit network zone record configurations as YAML

## Synopsis

Description:
Edit network zone record configurations as YAML

```none
lxc network zone record edit [<remote>:]<zone> <record> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network zone record](../record.md#lxc-network-zone-record-md)	 - Manage network zone records


# index.html.md

<a id="lxc-network-zone-record-unset-md"></a>

# `lxc network zone record unset`

Unset network zone record configuration key

## Synopsis

Description:
Unset network zone record configuration key

```none
lxc network zone record unset [<remote>:]<zone> <record> <key> [flags]
```

## Options

```none
  -p, --property   Unset the key as a network zone record property
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network zone record](../record.md#lxc-network-zone-record-md)	 - Manage network zone records


# index.html.md

<a id="lxc-network-zone-record-entry-md"></a>

# `lxc network zone record entry`

Manage network zone record entries

## Synopsis

Description:
Manage network zone record entries

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network zone record](../record.md#lxc-network-zone-record-md)	 - Manage network zone records
* [lxc network zone record entry add](entry/add.md#lxc-network-zone-record-entry-add-md)	 - Add a network zone record entry
* [lxc network zone record entry remove](entry/remove.md#lxc-network-zone-record-entry-remove-md)	 - Remove a network zone record entry


# index.html.md

<a id="lxc-network-zone-record-delete-md"></a>

# `lxc network zone record delete`

Delete network zone record

## Synopsis

Description:
Delete network zone record

```none
lxc network zone record delete [<remote>:]<zone> <record> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network zone record](../record.md#lxc-network-zone-record-md)	 - Manage network zone records


# index.html.md

<a id="lxc-network-zone-record-create-md"></a>

# `lxc network zone record create`

Create new network zone record

## Synopsis

Description:
Create new network zone record

```none
lxc network zone record create [<remote>:]<zone> <record> [key=value...] [flags]
```

## Examples

```none
  lxc network zone record create z1 r1

  lxc network zone record create z1 r1 < config.yaml
      Create record r1 for zone z1 with configuration from config.yaml
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network zone record](../record.md#lxc-network-zone-record-md)	 - Manage network zone records


# index.html.md

<a id="lxc-network-zone-record-get-md"></a>

# `lxc network zone record get`

Get value for network zone record configuration key

## Synopsis

Description:
Get value for network zone record configuration key

```none
lxc network zone record get [<remote>:]<zone> <record> <key> [flags]
```

## Options

```none
  -p, --property   Get the key as a network zone record property
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network zone record](../record.md#lxc-network-zone-record-md)	 - Manage network zone records


# index.html.md

<a id="lxc-network-zone-record-list-md"></a>

# `lxc network zone record list`

List available network zone records

## Synopsis

Description:
List available network zone records

```none
lxc network zone record list [<remote>:]<zone> [flags]
```

## Options

```none
  -c, --columns   Columns (default "nde")
  -f, --format    Format (csv|json|table|yaml|compact) (default "table")
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network zone record](../record.md#lxc-network-zone-record-md)	 - Manage network zone records


# index.html.md

<a id="lxc-network-zone-record-set-md"></a>

# `lxc network zone record set`

Set network zone record configuration keys

## Synopsis

Description:
Set network zone record configuration keys

```none
lxc network zone record set [<remote>:]<zone> <record> <key>=<value>... [flags]
```

## Options

```none
  -p, --property   Set the key as a network zone record property
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network zone record](../record.md#lxc-network-zone-record-md)	 - Manage network zone records


# index.html.md

<a id="lxc-network-zone-record-entry-add-md"></a>

# `lxc network zone record entry add`

Add a network zone record entry

## Synopsis

Description:
Add a network zone record entry

```none
lxc network zone record entry add [<remote>:]<zone> <record> <type> <value> [flags]
```

## Options

```none
      --ttl uint   Entry TTL
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network zone record entry](../entry.md#lxc-network-zone-record-entry-md)	 - Manage network zone record entries


# index.html.md

<a id="lxc-network-zone-record-entry-remove-md"></a>

# `lxc network zone record entry remove`

Remove a network zone record entry

## Synopsis

Description:
Remove a network zone record entry

```none
lxc network zone record entry remove [<remote>:]<zone> <record> <type> <value> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network zone record entry](../entry.md#lxc-network-zone-record-entry-md)	 - Manage network zone record entries


# index.html.md

<a id="lxc-network-forward-port-add-md"></a>

# `lxc network forward port add`

Add ports to a forward

## Synopsis

Description:
Add ports to a forward

```none
lxc network forward port add [<remote>:]<network> <listen_address> <protocol> <listen_port(s)> <target_address> [<target_port(s)>] [flags]
```

## Options

```none
      --target   Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network forward port](../port.md#lxc-network-forward-port-md)	 - Manage network forward ports


# index.html.md

<a id="lxc-network-forward-port-remove-md"></a>

# `lxc network forward port remove`

Remove ports from a forward

## Synopsis

Description:
Remove ports from a forward

```none
lxc network forward port remove [<remote>:]<network> <listen_address> [<protocol>] [<listen_port(s)>] [flags]
```

## Options

```none
      --force    Remove all ports that match
      --target   Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network forward port](../port.md#lxc-network-forward-port-md)	 - Manage network forward ports


# index.html.md

<a id="lxc-network-acl-rule-add-md"></a>

# `lxc network acl rule add`

Add rule to an ACL

## Synopsis

Description:
Add rule to an ACL

```none
lxc network acl rule add [<remote>:]<ACL> <direction> <key>=<value>... [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network acl rule](../rule.md#lxc-network-acl-rule-md)	 - Manage network ACL rules


# index.html.md

<a id="lxc-network-acl-rule-remove-md"></a>

# `lxc network acl rule remove`

Remove rule from an ACL

## Synopsis

Description:
Remove rule from an ACL

```none
lxc network acl rule remove [<remote>:]<ACL> <direction> <key>=<value>... [flags]
```

## Options

```none
      --force   Remove all rules that match
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network acl rule](../rule.md#lxc-network-acl-rule-md)	 - Manage network ACL rules


# index.html.md

<a id="lxc-network-load-balancer-pool-unset-md"></a>

# `lxc network load-balancer pool unset`

Unset network load balancer pool configuration key

## Synopsis

Description:
Unset network load balancer pool configuration key

```none
lxc network load-balancer pool unset [<remote>:]<network> <pool_name> <key> [flags]
```

## Options

```none
  -p, --property   Get the key as a network load balancer pool property
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network load-balancer pool](../pool.md#lxc-network-load-balancer-pool-md)	 - Manage network load balancer pools


# index.html.md

<a id="lxc-network-load-balancer-pool-set-md"></a>

# `lxc network load-balancer pool set`

Set network load balancer pool keys

## Synopsis

Description:
Set network load balancer pool keys

```none
lxc network load-balancer pool set [<remote>:]<network> <pool_name> <key>=<value>... [flags]
```

## Options

```none
  -p, --property   Get the key as a network load balancer pool property
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network load-balancer pool](../pool.md#lxc-network-load-balancer-pool-md)	 - Manage network load balancer pools


# index.html.md

<a id="lxc-network-load-balancer-pool-list-md"></a>

# `lxc network load-balancer pool list`

List available network load balancer pools

## Synopsis

Description:
List available network load balancer pools

```none
lxc network load-balancer pool list [<remote>:]<network> [flags]
```

## Options

```none
  -f, --format   Format (csv|json|table|yaml|compact) (default "table")
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network load-balancer pool](../pool.md#lxc-network-load-balancer-pool-md)	 - Manage network load balancer pools


# index.html.md

<a id="lxc-network-load-balancer-pool-get-md"></a>

# `lxc network load-balancer pool get`

Get value for network load balancer pool configuration key

## Synopsis

Description:
Get value for network load balancer pool configuration key

```none
lxc network load-balancer pool get [<remote>:]<network> <pool_name> <key> [flags]
```

## Options

```none
  -p, --property   Get the key as a network load balancer pool property
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network load-balancer pool](../pool.md#lxc-network-load-balancer-pool-md)	 - Manage network load balancer pools


# index.html.md

<a id="lxc-network-load-balancer-pool-instance-md"></a>

# `lxc network load-balancer pool instance`

Manage instances of network load balancer pool

## Synopsis

Description:
Manage instances of network load balancer pool

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network load-balancer pool](../pool.md#lxc-network-load-balancer-pool-md)	 - Manage network load balancer pools
* [lxc network load-balancer pool instance add](instance/add.md#lxc-network-load-balancer-pool-instance-add-md)	 - Add an instance to a network load balancer pool
* [lxc network load-balancer pool instance remove](instance/remove.md#lxc-network-load-balancer-pool-instance-remove-md)	 - Remove an instance from a network load balancer pool


# index.html.md

<a id="lxc-network-load-balancer-pool-edit-md"></a>

# `lxc network load-balancer pool edit`

Edit load balancer pool configurations as YAML

## Synopsis

Description:
Edit load balancer pool configurations as YAML

```none
lxc network load-balancer pool edit [<remote>:]<network> <pool_name> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network load-balancer pool](../pool.md#lxc-network-load-balancer-pool-md)	 - Manage network load balancer pools


# index.html.md

<a id="lxc-network-load-balancer-pool-show-md"></a>

# `lxc network load-balancer pool show`

Show load balancer pool

## Synopsis

Description:
Show load balancer pool

```none
lxc network load-balancer pool show [<remote>:]<network> <pool_name> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network load-balancer pool](../pool.md#lxc-network-load-balancer-pool-md)	 - Manage network load balancer pools


# index.html.md

<a id="lxc-network-load-balancer-pool-delete-md"></a>

# `lxc network load-balancer pool delete`

Delete load balancer pool

## Synopsis

Description:
Delete load balancer pool

```none
lxc network load-balancer pool delete [<remote>:]<network> <pool_name> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network load-balancer pool](../pool.md#lxc-network-load-balancer-pool-md)	 - Manage network load balancer pools


# index.html.md

<a id="lxc-network-load-balancer-pool-create-md"></a>

# `lxc network load-balancer pool create`

Add load balancer pool to a network

## Synopsis

Description:
Add load balancer pool to a network

```none
lxc network load-balancer pool create [<remote>:]<network> <pool_name> <key>=<value>... [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network load-balancer pool](../pool.md#lxc-network-load-balancer-pool-md)	 - Manage network load balancer pools


# index.html.md

<a id="lxc-network-load-balancer-backend-remove-md"></a>

# `lxc network load-balancer backend remove`

Remove backends from a load balancer

## Synopsis

Description:
Remove backends from a load balancer

```none
lxc network load-balancer backend remove [<remote>:]<network> <listen_address> <backend_name> [flags]
```

## Options

```none
      --target   Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network load-balancer backend](../backend.md#lxc-network-load-balancer-backend-md)	 - Manage network load balancer backends


# index.html.md

<a id="lxc-network-load-balancer-backend-add-md"></a>

# `lxc network load-balancer backend add`

Add backends to a load balancer

## Synopsis

Description:
Add backends to a load balancer

```none
lxc network load-balancer backend add [<remote>:]<network> <listen_address> <backend_name> <target_address> [<target_port(s)>] [flags]
```

## Options

```none
      --target   Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network load-balancer backend](../backend.md#lxc-network-load-balancer-backend-md)	 - Manage network load balancer backends


# index.html.md

<a id="lxc-network-load-balancer-port-add-md"></a>

# `lxc network load-balancer port add`

Add ports to a load balancer

## Synopsis

Description:
Add ports to a load balancer

```none
lxc network load-balancer port add [<remote>:]<network> <listen_address> <protocol> <listen_port(s)> <key>=<value> [flags]
```

## Options

```none
      --target   Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network load-balancer port](../port.md#lxc-network-load-balancer-port-md)	 - Manage network load balancer ports


# index.html.md

<a id="lxc-network-load-balancer-port-remove-md"></a>

# `lxc network load-balancer port remove`

Remove ports from a load balancer

## Synopsis

Description:
Remove ports from a load balancer

```none
lxc network load-balancer port remove [<remote>:]<network> <listen_address> [<protocol>] [<listen_port(s)>] [flags]
```

## Options

```none
      --force    Remove all ports that match
      --target   Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network load-balancer port](../port.md#lxc-network-load-balancer-port-md)	 - Manage network load balancer ports


# index.html.md

<a id="lxc-network-load-balancer-pool-instance-remove-md"></a>

# `lxc network load-balancer pool instance remove`

Remove an instance from a network load balancer pool

## Synopsis

Description:
Remove an instance from a network load balancer pool

```none
lxc network load-balancer pool instance remove [<remote>:]<network> <pool_name> <instance_name> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network load-balancer pool instance](../instance.md#lxc-network-load-balancer-pool-instance-md)	 - Manage instances of network load balancer pool


# index.html.md

<a id="lxc-network-load-balancer-pool-instance-add-md"></a>

# `lxc network load-balancer pool instance add`

Add an instance to a network load balancer pool

## Synopsis

Description:
Add an instance to a network load balancer pool

```none
lxc network load-balancer pool instance add [<remote>:]<network> <pool_name> <instance_name> [<target_port>] [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc network load-balancer pool instance](../instance.md#lxc-network-load-balancer-pool-instance-md)	 - Manage instances of network load balancer pool


# index.html.md

<a id="lxc-cluster-role-add-md"></a>

# `lxc cluster role add`

Add roles to a cluster member

## Synopsis

Description:
Add roles to a cluster member

```none
lxc cluster role add [<remote>:]<member> <role[,role...]> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc cluster role](../role.md#lxc-cluster-role-md)	 - Manage cluster roles


# index.html.md

<a id="lxc-cluster-role-remove-md"></a>

# `lxc cluster role remove`

Remove roles from a cluster member

## Synopsis

Description:
Remove roles from a cluster member

```none
lxc cluster role remove [<remote>:]<member> <role[,role...]> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc cluster role](../role.md#lxc-cluster-role-md)	 - Manage cluster roles


# index.html.md

<a id="lxc-cluster-failure-domain-set-md"></a>

# `lxc cluster failure-domain set`

Set the failure domain for a cluster member

## Synopsis

Description:
Set the failure domain for a cluster member

```none
lxc cluster failure-domain set [<remote>:]<member> <domain> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc cluster failure-domain](../failure-domain.md#lxc-cluster-failure-domain-md)	 - Manage cluster member failure domains


# index.html.md

<a id="lxc-cluster-failure-domain-get-md"></a>

# `lxc cluster failure-domain get`

Get the failure domain for a cluster member

## Synopsis

Description:
Get the failure domain for a cluster member

```none
lxc cluster failure-domain get [<remote>:]<member> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc cluster failure-domain](../failure-domain.md#lxc-cluster-failure-domain-md)	 - Manage cluster member failure domains


# index.html.md

<a id="lxc-cluster-failure-domain-unset-md"></a>

# `lxc cluster failure-domain unset`

Unset the failure domain for a cluster member

## Synopsis

Description:
Unset the failure domain for a cluster member (resets to “default”)

```none
lxc cluster failure-domain unset [<remote>:]<member> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc cluster failure-domain](../failure-domain.md#lxc-cluster-failure-domain-md)	 - Manage cluster member failure domains


# index.html.md

<a id="lxc-cluster-link-set-md"></a>

# `lxc cluster link set`

Set cluster link configuration keys

## Synopsis

Description:
Set cluster link configuration keys

For backward compatibility, a single configuration key may still be set with
lxc cluster link set [<remote>:]<link> <key> <value>

```none
lxc cluster link set [<remote>:]<link> <key>=<value>... [flags]
```

## Options

```none
  -p, --property   Set the key as a cluster link property
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc cluster link](../link.md#lxc-cluster-link-md)	 - Manage cluster links


# index.html.md

<a id="lxc-cluster-link-get-md"></a>

# `lxc cluster link get`

Get values for cluster link configuration keys

## Synopsis

Description:
Get values for cluster link configuration keys

```none
lxc cluster link get [<remote>:]<link> <key> [flags]
```

## Options

```none
  -p, --property   Get the key as a cluster link property
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc cluster link](../link.md#lxc-cluster-link-md)	 - Manage cluster links


# index.html.md

<a id="lxc-cluster-link-list-md"></a>

# `lxc cluster link list`

List cluster links

## Synopsis

Description:
List cluster links

```none
lxc cluster link list [<remote>:] [flags]
```

## Options

```none
  -f, --format   Format (csv|json|table|yaml|compact) (default "table")
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc cluster link](../link.md#lxc-cluster-link-md)	 - Manage cluster links


# index.html.md

<a id="lxc-cluster-link-delete-md"></a>

# `lxc cluster link delete`

Delete cluster links

## Synopsis

Description:
Delete cluster links

```none
lxc cluster link delete [<remote>:]<link> [flags]
```

## Examples

```none
  On main-cluster: lxc cluster link delete backup-cluster
  	Delete cluster link backup-cluster and its associated identity.

  		On backup-cluster: lxc cluster link delete main-cluster
  	Delete cluster link main-cluster and its associated identity.
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc cluster link](../link.md#lxc-cluster-link-md)	 - Manage cluster links


# index.html.md

<a id="lxc-cluster-link-create-md"></a>

# `lxc cluster link create`

Create cluster links

## Synopsis

Description:
Create cluster links

When run with the –token flag, creates an active cluster link.
When run without a token, creates a pending cluster link that must be activated by creating a cluster link on the remote cluster.

```none
lxc cluster link create [<remote>:]<link> [key=value...] [flags]
```

## Examples

```none
  lxc cluster link create backup-cluster --auth-group backups
      Create a pending cluster link reachable at "192.0.2.1:8443" and "192.0.2.2:8443" called "backup-cluster", belonging to the authentication group "backups".

  lxc cluster link create main-cluster --token <token from backup-cluster> --auth-group backups
      Create a cluster link with "backup-cluster" called "main-cluster", belonging to the auth group "backups".

  lxc cluster link create backup-cluster < config.yaml
      Create a pending cluster link with the configuration from "config.yaml" called "backup-cluster".
```

## Options

```none
  -g, --auth-group    Authentication groups to add the newly created cluster link identity to
  -d, --description   Cluster link description
  -t, --token         Trust token to use when creating cluster link
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc cluster link](../link.md#lxc-cluster-link-md)	 - Manage cluster links


# index.html.md

<a id="lxc-cluster-link-rename-md"></a>

# `lxc cluster link rename`

Rename a cluster link

## Synopsis

Description:
Rename a cluster link

```none
lxc cluster link rename [<remote>:]<link> <new-name> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc cluster link](../link.md#lxc-cluster-link-md)	 - Manage cluster links


# index.html.md

<a id="lxc-cluster-link-edit-md"></a>

# `lxc cluster link edit`

Edit cluster link configurations as YAML

## Synopsis

Description:
Edit cluster link configurations as YAML

```none
lxc cluster link edit [<remote>:]<link> [flags]
```

## Examples

```none
  lxc cluster link edit [<remote>:]<name> < link.yaml
      Update a cluster link using the content of link.yaml.
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc cluster link](../link.md#lxc-cluster-link-md)	 - Manage cluster links


# index.html.md

<a id="lxc-cluster-link-show-md"></a>

# `lxc cluster link show`

Show cluster link configurations

## Synopsis

Description:
Show cluster link configurations

```none
lxc cluster link show [<remote>:]<link> [flags]
```

## Examples

```none
  lxc cluster link show backup-cluster
      Will show the properties of a cluster link called "backup-cluster".
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc cluster link](../link.md#lxc-cluster-link-md)	 - Manage cluster links


# index.html.md

<a id="lxc-cluster-link-unset-md"></a>

# `lxc cluster link unset`

Unset cluster link configuration keys

## Synopsis

Description:
Unset cluster link configuration keys

```none
lxc cluster link unset [<remote>:]<link> <key> [flags]
```

## Options

```none
  -p, --property   Unset the key as a cluster link property
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc cluster link](../link.md#lxc-cluster-link-md)	 - Manage cluster links


# index.html.md

<a id="lxc-cluster-link-info-md"></a>

# `lxc cluster link info`

Get information on cluster links

## Synopsis

Description:
Get information on cluster links

```none
lxc cluster link info [<remote>:]<link> [flags]
```

## Examples

```none
  lxc cluster link info backup-cluster
      Will show information for a cluster link called "backup-cluster".
```

## Options

```none
      --target   Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc cluster link](../link.md#lxc-cluster-link-md)	 - Manage cluster links


# index.html.md

<a id="lxc-cluster-group-create-md"></a>

# `lxc cluster group create`

Create a cluster group

## Synopsis

Description:
Create a cluster group

```none
lxc cluster group create [<remote>:]<group> [flags]
```

## Examples

```none
  lxc cluster group create g1

  lxc cluster group create g1 < config.yaml
  	Create a cluster group with configuration from config.yaml
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc cluster group](../group.md#lxc-cluster-group-md)	 - Manage cluster groups


# index.html.md

<a id="lxc-cluster-group-delete-md"></a>

# `lxc cluster group delete`

Delete a cluster group

## Synopsis

Description:
Delete a cluster group

```none
lxc cluster group delete [<remote>:]<group> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc cluster group](../group.md#lxc-cluster-group-md)	 - Manage cluster groups


# index.html.md

<a id="lxc-cluster-group-edit-md"></a>

# `lxc cluster group edit`

Edit a cluster group

## Synopsis

Description:
Edit a cluster group

```none
lxc cluster group edit [<remote>:]<group> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc cluster group](../group.md#lxc-cluster-group-md)	 - Manage cluster groups


# index.html.md

<a id="lxc-cluster-group-add-md"></a>

# `lxc cluster group add`

Add member to group

## Synopsis

Description:
Add a cluster member to a cluster group

```none
lxc cluster group add [<remote>:]<member> <group> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc cluster group](../group.md#lxc-cluster-group-md)	 - Manage cluster groups


# index.html.md

<a id="lxc-cluster-group-show-md"></a>

# `lxc cluster group show`

Show cluster group configurations

## Synopsis

Description:
Show cluster group configurations

```none
lxc cluster group show [<remote>:]<group> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc cluster group](../group.md#lxc-cluster-group-md)	 - Manage cluster groups


# index.html.md

<a id="lxc-cluster-group-rename-md"></a>

# `lxc cluster group rename`

Rename a cluster group

## Synopsis

Description:
Rename a cluster group

```none
lxc cluster group rename [<remote>:]<group> <new-name> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc cluster group](../group.md#lxc-cluster-group-md)	 - Manage cluster groups


# index.html.md

<a id="lxc-cluster-group-assign-md"></a>

# `lxc cluster group assign`

Assign sets of groups to cluster members

## Synopsis

Description:
Assign sets of groups to cluster members

```none
lxc cluster group assign [<remote>:]<member> <group> [flags]
```

## Examples

```none
  lxc cluster group assign foo default,bar
      Set the groups for "foo" to "default" and "bar".

  lxc cluster group assign foo default
      Reset "foo" to only using the "default" cluster group.
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc cluster group](../group.md#lxc-cluster-group-md)	 - Manage cluster groups


# index.html.md

<a id="lxc-cluster-group-list-md"></a>

# `lxc cluster group list`

List all the cluster groups

## Synopsis

Description:
List all the cluster groups

```none
lxc cluster group list [<remote>:] [flags]
```

## Options

```none
  -c, --columns   Columns (default "ndm")
  -f, --format    Format (csv|json|table|yaml|compact) (default "table")
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc cluster group](../group.md#lxc-cluster-group-md)	 - Manage cluster groups


# index.html.md

<a id="lxc-cluster-group-remove-md"></a>

# `lxc cluster group remove`

Remove member from group

## Synopsis

Description:
Remove a cluster member from a cluster group

```none
lxc cluster group remove [<remote>:]<member> <group> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc cluster group](../group.md#lxc-cluster-group-md)	 - Manage cluster groups


# index.html.md

<a id="lxc-auth-group-permission-md"></a>

# `lxc auth group permission`

Manage permissions

## Synopsis

Description:
Manage permissions

```none
lxc auth group permission [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc auth group](../group.md#lxc-auth-group-md)	 - Manage groups
* [lxc auth group permission add](permission/add.md#lxc-auth-group-permission-add-md)	 - Add permissions to groups
* [lxc auth group permission remove](permission/remove.md#lxc-auth-group-permission-remove-md)	 - Remove permissions from groups


# index.html.md

<a id="lxc-auth-group-edit-md"></a>

# `lxc auth group edit`

Edit groups as YAML

## Synopsis

Description:
Edit groups as YAML

```none
lxc auth group edit [<remote>:]<group> [flags]
```

## Examples

```none
  lxc auth group edit <group> < group.yaml
     Update a group using the content of group.yaml
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc auth group](../group.md#lxc-auth-group-md)	 - Manage groups


# index.html.md

<a id="lxc-auth-group-show-md"></a>

# `lxc auth group show`

Show group configurations

## Synopsis

Description:
Show group configurations

```none
lxc auth group show [<remote>:]<group> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc auth group](../group.md#lxc-auth-group-md)	 - Manage groups


# index.html.md

<a id="lxc-auth-group-rename-md"></a>

# `lxc auth group rename`

Rename group

## Synopsis

Description:
Rename group

```none
lxc auth group rename [<remote>:]<group> <new_name> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc auth group](../group.md#lxc-auth-group-md)	 - Manage groups


# index.html.md

<a id="lxc-auth-group-create-md"></a>

# `lxc auth group create`

Create group

## Synopsis

Description:
Create group

```none
lxc auth group create [<remote>:]<group> [flags]
```

## Options

```none
  -d, --description string   Group description
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc auth group](../group.md#lxc-auth-group-md)	 - Manage groups


# index.html.md

<a id="lxc-auth-group-delete-md"></a>

# `lxc auth group delete`

Delete group

## Synopsis

Description:
Delete group

```none
lxc auth group delete [<remote>:]<group> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc auth group](../group.md#lxc-auth-group-md)	 - Manage groups


# index.html.md

<a id="lxc-auth-group-list-md"></a>

# `lxc auth group list`

List groups

## Synopsis

Description:
List groups

```none
lxc auth group list [<remote>:] [flags]
```

## Options

```none
  -c, --columns   Columns (default "nd")
  -f, --format    Format (csv|json|table|yaml|compact) (default "table")
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc auth group](../group.md#lxc-auth-group-md)	 - Manage groups


# index.html.md

<a id="lxc-auth-identity-provider-group-show-md"></a>

# `lxc auth identity-provider-group show`

Show an identity provider group

## Synopsis

Description:
Show an identity provider group

```none
lxc auth identity-provider-group show [<remote>:]<identity_provider_group> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc auth identity-provider-group](../identity-provider-group.md#lxc-auth-identity-provider-group-md)	 - Manage groups


# index.html.md

<a id="lxc-auth-identity-provider-group-edit-md"></a>

# `lxc auth identity-provider-group edit`

Edit identity provider groups as YAML

## Synopsis

Description:
Edit identity provider groups as YAML

```none
lxc auth identity-provider-group edit [<remote>:]<identity_provider_group> [flags]
```

## Examples

```none
  lxc auth identity-provider-group edit <identity_provider_group> < identity-provider-group.yaml
     Update an identity provider group using the content of identity-provider-group.yaml
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc auth identity-provider-group](../identity-provider-group.md#lxc-auth-identity-provider-group-md)	 - Manage groups


# index.html.md

<a id="lxc-auth-identity-provider-group-group-md"></a>

# `lxc auth identity-provider-group group`

Manage identity provider group mappings

## Synopsis

Description:
Manage identity provider group mappings

```none
lxc auth identity-provider-group group [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc auth identity-provider-group](../identity-provider-group.md#lxc-auth-identity-provider-group-md)	 - Manage groups
* [lxc auth identity-provider-group group add](group/add.md#lxc-auth-identity-provider-group-group-add-md)	 - Add a group to an identity provider group
* [lxc auth identity-provider-group group remove](group/remove.md#lxc-auth-identity-provider-group-group-remove-md)	 - Remove a LXD group from an identity provider group


# index.html.md

<a id="lxc-auth-identity-provider-group-list-md"></a>

# `lxc auth identity-provider-group list`

List identity provider groups

## Synopsis

Description:
List identity provider groups

```none
lxc auth identity-provider-group list [<remote>:] [flags]
```

## Options

```none
  -c, --columns   Columns (default "ng")
  -f, --format    Format (csv|json|table|yaml|compact) (default "table")
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc auth identity-provider-group](../identity-provider-group.md#lxc-auth-identity-provider-group-md)	 - Manage groups


# index.html.md

<a id="lxc-auth-identity-provider-group-delete-md"></a>

# `lxc auth identity-provider-group delete`

Delete identity provider group

## Synopsis

Description:
Delete identity provider group

```none
lxc auth identity-provider-group delete [<remote>:]<identity_provider_group> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc auth identity-provider-group](../identity-provider-group.md#lxc-auth-identity-provider-group-md)	 - Manage groups


# index.html.md

<a id="lxc-auth-identity-provider-group-create-md"></a>

# `lxc auth identity-provider-group create`

Create identity provider group

## Synopsis

Description:
Create identity provider group

```none
lxc auth identity-provider-group create [<remote>:]<group> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc auth identity-provider-group](../identity-provider-group.md#lxc-auth-identity-provider-group-md)	 - Manage groups


# index.html.md

<a id="lxc-auth-identity-provider-group-rename-md"></a>

# `lxc auth identity-provider-group rename`

Rename identity provider group

## Synopsis

Description:
Rename identity provider group

```none
lxc auth identity-provider-group rename [<remote>:]<identity_provider_group> <new_name> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc auth identity-provider-group](../identity-provider-group.md#lxc-auth-identity-provider-group-md)	 - Manage groups


# index.html.md

<a id="lxc-auth-identity-info-md"></a>

# `lxc auth identity info`

View the current identity

## Synopsis

Description:
Show the current identity

This command will display permissions for the current user.
This includes contextual information, such as effective groups and permissions
that are granted via identity provider group mappings.

```none
lxc auth identity info [<remote>:] [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc auth identity](../identity.md#lxc-auth-identity-md)	 - Manage identities


# index.html.md

<a id="lxc-auth-identity-token-md"></a>

# `lxc auth identity token`

Manage bearer identity tokens

## Synopsis

Description:
Issue and revoke tokens for bearer identities

```none
lxc auth identity token [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc auth identity](../identity.md#lxc-auth-identity-md)	 - Manage identities
* [lxc auth identity token issue](token/issue.md#lxc-auth-identity-token-issue-md)	 - Issue a token for a bearer identity
* [lxc auth identity token revoke](token/revoke.md#lxc-auth-identity-token-revoke-md)	 - Revoke the current token for a bearer identity


# index.html.md

<a id="lxc-auth-identity-create-md"></a>

# `lxc auth identity create`

Create an identity

## Synopsis

Description:
Create a TLS identity

```none
lxc auth identity create [<remote>:]<type>/<name> [<path to PEM encoded certificate>] [[--group <group_name>]] [flags]
```

## Options

```none
  -g, --group strings   Groups to add to the identity
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc auth identity](../identity.md#lxc-auth-identity-md)	 - Manage identities


# index.html.md

<a id="lxc-auth-identity-delete-md"></a>

# `lxc auth identity delete`

Delete an identity

## Synopsis

Description:
Delete an identity

```none
lxc auth identity delete [<remote>:]<type>/<name_or_identifier> [flags]
```

## Examples

```none
  lxc auth identity delete oidc/jane.doe@example.com
  	Delete the OIDC identity with email address "jane.doe@example.com" in the default remote.

  lxc auth identity delete oidc/'Jane Doe'
  	Delete the OIDC identity with name "Jane Doe" in the default remote (there must be only one OIDC identity on the server with this name).

  lxc auth identity delete my-remote:tls/12beaccbf9e7b7445185581b70099a5962c927e85006d5883856d909fe79f976
  	Delete the TLS identity with certificate fingerprint "12beaccbf9e7b7445185581b70099a5962c927e85006d5883856d909fe79f976" in remote "my-remote".

  lxc auth identity delete my-remote:tls/jane-doe
  	Delete the TLS identity with name "jane-doe" in remote "my-remote" (there must be only one TLS identity on "my-remote" with this name).

```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc auth identity](../identity.md#lxc-auth-identity-md)	 - Manage identities


# index.html.md

<a id="lxc-auth-identity-edit-md"></a>

# `lxc auth identity edit`

Edit an identity as YAML

## Synopsis

Description:
Edit an identity as YAML

```none
lxc auth identity edit [<remote>:]<group> [flags]
```

## Examples

```none
  lxc auth identity edit <type>/<name_or_identifier> < identity.yaml
     Update an identity using the content of identity.yaml
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc auth identity](../identity.md#lxc-auth-identity-md)	 - Manage identities


# index.html.md

<a id="lxc-auth-identity-show-md"></a>

# `lxc auth identity show`

View an identity

## Synopsis

Description:
Show identity configurations

The argument must be a concatenation of the authentication method and either the
name or identifier of the identity, delimited by a forward slash. This command
will fail if an identity name is used that is not unique within the authentication
method. Use the identifier instead if this occurs.

```none
lxc auth identity show [<remote>:]<type>/<name_or_identifier> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc auth identity](../identity.md#lxc-auth-identity-md)	 - Manage identities


# index.html.md

<a id="lxc-auth-identity-group-md"></a>

# `lxc auth identity group`

Manage groups for the identity

## Synopsis

Description:
Manage groups for the identity

```none
lxc auth identity group [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc auth identity](../identity.md#lxc-auth-identity-md)	 - Manage identities
* [lxc auth identity group add](group/add.md#lxc-auth-identity-group-add-md)	 - Add a group to an identity
* [lxc auth identity group remove](group/remove.md#lxc-auth-identity-group-remove-md)	 - Remove a group from an identity


# index.html.md

<a id="lxc-auth-identity-list-md"></a>

# `lxc auth identity list`

List identities

## Synopsis

Description:
List identities

```none
lxc auth identity list [<remote>:] [flags]
```

## Options

```none
  -c, --columns   Columns (default "atnig")
  -f, --format    Format (csv|json|table|yaml|compact) (default "table")
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc auth identity](../identity.md#lxc-auth-identity-md)	 - Manage identities


# index.html.md

<a id="lxc-auth-oidc-session-delete-md"></a>

# `lxc auth oidc-session delete`

Delete OIDC session

## Synopsis

Description:
Delete OIDC session

```none
lxc auth oidc-session delete [<remote>:]<session_id> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc auth oidc-session](../oidc-session.md#lxc-auth-oidc-session-md)	 - Manage OIDC sessions


# index.html.md

<a id="lxc-auth-oidc-session-list-md"></a>

# `lxc auth oidc-session list`

List OIDC sessions

## Synopsis

Description:
List OIDC sessions

```none
lxc auth oidc-session list [<remote>:] [flags]
```

## Options

```none
  -f, --format   Format (csv|json|table|yaml|compact) (default "table")
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc auth oidc-session](../oidc-session.md#lxc-auth-oidc-session-md)	 - Manage OIDC sessions


# index.html.md

<a id="lxc-auth-oidc-session-show-md"></a>

# `lxc auth oidc-session show`

Show OIDC session

## Synopsis

Description:
Show OIDC session

```none
lxc auth oidc-session show [<remote>:]<session ID> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc auth oidc-session](../oidc-session.md#lxc-auth-oidc-session-md)	 - Manage OIDC sessions


# index.html.md

<a id="lxc-auth-permission-list-md"></a>

# `lxc auth permission list`

List permissions

## Synopsis

Description:
List permissions

```none
lxc auth permission list [<remote>:] [project=<project_name>] [entity_type=<entity_type>] [flags]
```

## Options

```none
  -c, --columns                Columns (default "tue")
  -f, --format string          Display format (json, yaml, table, compact, csv) (default "table")
      --max-entitlements int   Maximum number of unassigned entitlements to display before overflowing (set to zero to display all) (default 3)
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc auth permission](../permission.md#lxc-auth-permission-md)	 - Inspect permissions


# index.html.md

<a id="lxc-auth-group-permission-add-md"></a>

# `lxc auth group permission add`

Add permissions to groups

## Synopsis

Description:
Add permissions to groups

```none
lxc auth group permission add [<remote>:]<group> <entity_type> [<entity_name>] <entitlement> [<key>=<value>...] [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc auth group permission](../permission.md#lxc-auth-group-permission-md)	 - Manage permissions


# index.html.md

<a id="lxc-auth-group-permission-remove-md"></a>

# `lxc auth group permission remove`

Remove permissions from groups

## Synopsis

Description:
Remove permissions from groups

```none
lxc auth group permission remove [<remote>:]<group> <entity_type> [<entity_name>] <entitlement> [<key>=<value>...] [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc auth group permission](../permission.md#lxc-auth-group-permission-md)	 - Manage permissions


# index.html.md

<a id="lxc-auth-identity-provider-group-group-add-md"></a>

# `lxc auth identity-provider-group group add`

Add a group to an identity provider group

## Synopsis

Description:
Add a group to an identity provider group

```none
lxc auth identity-provider-group group add [<remote>:]<identity_provider_group> <group> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc auth identity-provider-group group](../group.md#lxc-auth-identity-provider-group-group-md)	 - Manage identity provider group mappings


# index.html.md

<a id="lxc-auth-identity-provider-group-group-remove-md"></a>

# `lxc auth identity-provider-group group remove`

Remove a LXD group from an identity provider group

## Synopsis

Description:
Remove a LXD group from an identity provider group

```none
lxc auth identity-provider-group group remove [<remote>:]<identity_provider_group> <group> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc auth identity-provider-group group](../group.md#lxc-auth-identity-provider-group-group-md)	 - Manage identity provider group mappings


# index.html.md

<a id="lxc-auth-identity-token-issue-md"></a>

# `lxc auth identity token issue`

Issue a token for a bearer identity

## Synopsis

Description:
Issue a token for a bearer identity

Note that this revokes the current token if one is issued

```none
lxc auth identity token issue [<remote>:]<type>/<name> [flags]
```

## Options

```none
      --expiry string   Token expiration as a space separated list of durations in the form (\d)+(S|M|H|d|w|m|y)
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc auth identity token](../token.md#lxc-auth-identity-token-md)	 - Manage bearer identity tokens


# index.html.md

<a id="lxc-auth-identity-token-revoke-md"></a>

# `lxc auth identity token revoke`

Revoke the current token for a bearer identity

## Synopsis

Description:
Revoke the current token for a bearer identity

```none
lxc auth identity token revoke [<remote>:]<authentication_method>/<name_or_identifier> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc auth identity token](../token.md#lxc-auth-identity-token-md)	 - Manage bearer identity tokens


# index.html.md

<a id="lxc-auth-identity-group-remove-md"></a>

# `lxc auth identity group remove`

Remove a group from an identity

## Synopsis

Description:
Remove a group from an identity

```none
lxc auth identity group remove [<remote>:]<type>/<name_or_identifier> <group> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc auth identity group](../group.md#lxc-auth-identity-group-md)	 - Manage groups for the identity


# index.html.md

<a id="lxc-auth-identity-group-add-md"></a>

# `lxc auth identity group add`

Add a group to an identity

## Synopsis

Description:
Add a group to an identity

```none
lxc auth identity group add [<remote>:]<type>/<name_or_identifier> <group> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc auth identity group](../group.md#lxc-auth-identity-group-md)	 - Manage groups for the identity


# index.html.md

<a id="lxc-storage-volume-restore-md"></a>

# `lxc storage volume restore`

Restore storage volume snapshot

## Synopsis

Description:
Restore storage volume snapshot

```none
lxc storage volume restore [<remote>:]<pool> <volume> <snapshot> [flags]
```

## Options

```none
      --target   Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc storage volume](../volume.md#lxc-storage-volume-md)	 - Manage storage volumes


# index.html.md

<a id="lxc-storage-volume-import-md"></a>

# `lxc storage volume import`

Import storage volumes

## Synopsis

Description:
Import custom volume backups, iso images, or tarballs.

```none
lxc storage volume import [<remote>:]<pool> <import file> [<volume name>] [flags]
```

## Examples

```none
  lxc storage volume import default backup0.tar.gz
  		Create a new custom volume using backup0.tar.gz with included snapshots as the source.
```

## Options

```none
      --target   Cluster member name
      --type     Type of the import file. Valid options are:
                 - backup: custom volume backup (default option)
                 - iso: iso image, will be imported as iso volume
                 - tar: tarball, will be imported as custom filesystem volume
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc storage volume](../volume.md#lxc-storage-volume-md)	 - Manage storage volumes


# index.html.md

<a id="lxc-storage-volume-set-md"></a>

# `lxc storage volume set`

Set storage volume configuration keys

## Synopsis

Description:
Set storage volume configuration keys

For backward compatibility, a single configuration key may still be set with:
lxc storage volume set [<remote>:]<pool> [<type>/]<volume> <key> <value>

```none
lxc storage volume set [<remote>:]<pool> [<type>/]<volume> <key>=<value>... [flags]
```

## Examples

```none
  Provide the type of the storage volume if it is not custom.
  Supported types are custom, image, container and virtual-machine.

  lxc storage volume set default data size=1GiB
      Sets the size of a custom volume "data" in pool "default" to 1 GiB.

  lxc storage volume set default virtual-machine/data snapshots.expiry=7d
      Sets the snapshot expiration period for a virtual machine "data" in pool "default" to seven days.
```

## Options

```none
  -p, --property   Set the key as a storage volume property
      --target     Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc storage volume](../volume.md#lxc-storage-volume-md)	 - Manage storage volumes


# index.html.md

<a id="lxc-storage-volume-export-md"></a>

# `lxc storage volume export`

Export custom storage volume

## Synopsis

Description:
Export custom storage volume

```none
lxc storage volume export [<remote>:]<pool> <volume> [<path>] [flags]
```

## Options

```none
      --compression         Define a compression algorithm: for backup or none
      --export-version      Use a different metadata format version than the latest one supported by the server (to support imports on older LXD versions)
      --optimized-storage   Use storage driver optimized format (can only be restored on a similar pool)
      --target              Cluster member name
      --volume-only         Export the volume without its snapshots
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc storage volume](../volume.md#lxc-storage-volume-md)	 - Manage storage volumes


# index.html.md

<a id="lxc-storage-volume-copy-md"></a>

# `lxc storage volume copy`

Copy storage volume

## Synopsis

Description:
Copy storage volume

```none
lxc storage volume copy [<remote>:]<pool>/<volume>[/<snapshot>] [<remote>:]<pool>/<volume> [flags]
```

## Options

```none
      --destination-target   Destination cluster member name
      --mode                 Transfer mode. One of pull (default), push or relay. (default "pull")
      --refresh              Refresh and update the existing storage volume copies
      --target               Cluster member name
      --target-project       Copy to a project different from the source
      --volume-only          Copy the volume without its snapshots
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc storage volume](../volume.md#lxc-storage-volume-md)	 - Manage storage volumes


# index.html.md

<a id="lxc-storage-volume-show-md"></a>

# `lxc storage volume show`

Show storage volume configurations

## Synopsis

Description:
Show storage volume configurations

```none
lxc storage volume show [<remote>:]<pool> [<type>/]<volume>[/<snapshot>] [flags]
```

## Examples

```none
  Provide the type of the storage volume if it is not custom.
  Supported types are custom, image, container and virtual-machine.

  Add the name of the snapshot if type is one of custom, container or virtual-machine.

  lxc storage volume show default data
      Will show the properties of a custom volume called "data" in the "default" pool.

  lxc storage volume show default container/data
      Will show the properties of the filesystem for a container called "data" in the "default" pool.

  lxc storage volume show default virtual-machine/data/snap0
      Will show the properties of snapshot "snap0" for a virtual machine called "data" in the "default" pool.
```

## Options

```none
      --target   Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc storage volume](../volume.md#lxc-storage-volume-md)	 - Manage storage volumes


# index.html.md

<a id="lxc-storage-volume-edit-md"></a>

# `lxc storage volume edit`

Edit storage volume configurations as YAML

## Synopsis

Description:
Edit storage volume configurations as YAML

```none
lxc storage volume edit [<remote>:]<pool> [<type>/]<volume> [flags]
```

## Examples

```none
  Provide the type of the storage volume if it is not custom.
  Supported types are custom, image, container and virtual-machine.

  lxc storage volume edit [<remote>:]<pool> [<type>/]<volume> < volume.yaml
      Update a storage volume using the content of pool.yaml.
```

## Options

```none
      --target   Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc storage volume](../volume.md#lxc-storage-volume-md)	 - Manage storage volumes


# index.html.md

<a id="lxc-storage-volume-unset-md"></a>

# `lxc storage volume unset`

Unset storage volume configuration key

## Synopsis

Description:
Unset storage volume configuration key

```none
lxc storage volume unset [<remote>:]<pool> [<type>/]<volume> <key> [flags]
```

## Examples

```none
  Provide the type of the storage volume if it is not custom.
  Supported types are custom, image, container and virtual-machine.

  lxc storage volume unset default data size
      Removes the size/quota of a custom volume "data" in pool "default".

  lxc storage volume unset default virtual-machine/data snapshots.expiry
      Removes the snapshot expiration period for a virtual machine "data" in pool "default".
```

## Options

```none
  -p, --property   Unset the key as a storage volume property
      --target     Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc storage volume](../volume.md#lxc-storage-volume-md)	 - Manage storage volumes


# index.html.md

<a id="lxc-storage-volume-get-md"></a>

# `lxc storage volume get`

Get value for storage volume configuration key

## Synopsis

Description:
Get value for storage volume configuration key

```none
lxc storage volume get [<remote>:]<pool> [<type>/]<volume>[/<snapshot>] <key> [flags]
```

## Examples

```none
  Provide the type of the storage volume if it is not custom.
  Supported types are custom, image, container and virtual-machine.

  Add the name of the snapshot if type is one of custom, container or virtual-machine.

  lxc storage volume get default data size
      Returns the size of a custom volume "data" in pool "default".

  lxc storage volume get default virtual-machine/data snapshots.expiry
      Returns the snapshot expiration period for a virtual machine "data" in pool "default".
```

## Options

```none
  -p, --property   Get the key as a storage volume property
      --target     Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc storage volume](../volume.md#lxc-storage-volume-md)	 - Manage storage volumes


# index.html.md

<a id="lxc-storage-volume-info-md"></a>

# `lxc storage volume info`

Show storage volume state information

## Synopsis

Description:
Show storage volume state information

```none
lxc storage volume info [<remote>:]<pool> [<type>/]<volume> [flags]
```

## Examples

```none
  Provide the type of the storage volume if it is not custom.
  Supported types are custom, container and virtual-machine.

  lxc storage volume info default data
      Returns state information for a custom volume "data" in pool "default".

  lxc storage volume info default virtual-machine/data
      Returns state information for a virtual machine "data" in pool "default".
```

## Options

```none
      --target   Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc storage volume](../volume.md#lxc-storage-volume-md)	 - Manage storage volumes


# index.html.md

<a id="lxc-storage-volume-delete-md"></a>

# `lxc storage volume delete`

Delete storage volume

## Synopsis

Description:
Delete storage volume

```none
lxc storage volume delete [<remote>:]<pool> <volume>[/<snapshot>] [flags]
```

## Options

```none
      --target   Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc storage volume](../volume.md#lxc-storage-volume-md)	 - Manage storage volumes


# index.html.md

<a id="lxc-storage-volume-create-md"></a>

# `lxc storage volume create`

Create new custom storage volume

## Synopsis

Description:
Create new custom storage volume

```none
lxc storage volume create [<remote>:]<pool> <volume> [key=value...] [flags]
```

## Examples

```none
  lxc storage volume create p1 v1

  lxc storage volume create p1 v1 < config.yaml
  	Create storage volume v1 for pool p1 with configuration from config.yaml.
```

## Options

```none
      --target   Cluster member name
      --type     Content type, block or filesystem (default "filesystem")
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc storage volume](../volume.md#lxc-storage-volume-md)	 - Manage storage volumes


# index.html.md

<a id="lxc-storage-volume-detach-md"></a>

# `lxc storage volume detach`

Detach storage volume from instance

## Synopsis

Description:
Detach storage volume from instance

```none
lxc storage volume detach [<remote>:]<pool> [<type>/]<volume>[/<snapshot>] <instance> [<device name>] [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc storage volume](../volume.md#lxc-storage-volume-md)	 - Manage storage volumes


# index.html.md

<a id="lxc-storage-volume-detach-profile-md"></a>

# `lxc storage volume detach-profile`

Detach storage volume from profile

## Synopsis

Description:
Detach storage volume from profile

```none
lxc storage volume detach-profile [<remote:>]<pool> [<type>/]<volume>[/<snapshot>] <profile> [<device name>] [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc storage volume](../volume.md#lxc-storage-volume-md)	 - Manage storage volumes


# index.html.md

<a id="lxc-storage-volume-attach-md"></a>

# `lxc storage volume attach`

Attach new storage volume to instance

## Synopsis

Description:
Attach new storage volume to instance

<type> must be one of “custom” or “virtual-machine”

```none
lxc storage volume attach [<remote>:]<pool> [<type>/]<volume>[/<snapshot>] <instance> [<device name>] [<path>] [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc storage volume](../volume.md#lxc-storage-volume-md)	 - Manage storage volumes


# index.html.md

<a id="lxc-storage-volume-rename-md"></a>

# `lxc storage volume rename`

Rename storage volume and storage volume snapshot

## Synopsis

Description:
Rename storage volume and storage volume snapshot

```none
lxc storage volume rename [<remote>:]<pool> <old name>[/<old snapshot name>] <new name>[/<new snapshot name>] [flags]
```

## Options

```none
      --target   Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc storage volume](../volume.md#lxc-storage-volume-md)	 - Manage storage volumes


# index.html.md

<a id="lxc-storage-volume-snapshot-md"></a>

# `lxc storage volume snapshot`

Snapshot storage volume

## Synopsis

Description:
Snapshot storage volume

```none
lxc storage volume snapshot [<remote>:]<pool> <volume> [<snapshot>] [flags]
```

## Examples

```none
  lxc storage volume snapshot default v1 snap0
         Create a snapshot of "v1" in pool "default" called "snap0".

  lxc storage volume snapshot default v1 snap0 < config.yaml
         Create a snapshot of "v1" in pool "default" called "snap0" with the configuration from "config.yaml".
```

## Options

```none
      --no-expiry   Ignore any configured auto-expiry for the storage volume
      --reuse       If the snapshot name already exists, delete and create a new one
      --target      Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc storage volume](../volume.md#lxc-storage-volume-md)	 - Manage storage volumes


# index.html.md

<a id="lxc-storage-volume-list-md"></a>

# `lxc storage volume list`

List storage volumes

## Synopsis

Description:
List storage volumes

The -c option takes a (optionally comma-separated) list of arguments
that control which image attributes to output when displaying in table
or csv format.

Column shorthand chars:
p - Storage pool name
c - Content type (filesystem or block)
d - Description
e - Project name
L - Location of the instance (e.g. its cluster member)
n - Name
t - Type of volume (custom, image, container or virtual-machine)
u - Number of references (used by)
U - Current disk usage

```none
lxc storage volume list [<remote>:][<pool>] [<filter>...] [flags]
```

## Options

```none
      --all-projects   All projects
  -c, --columns        Columns (default "petndcuL")
  -f, --format         Format (csv|json|table|yaml|compact) (default "table")
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc storage volume](../volume.md#lxc-storage-volume-md)	 - Manage storage volumes


# index.html.md

<a id="lxc-storage-volume-attach-profile-md"></a>

# `lxc storage volume attach-profile`

Attach new storage volume to profile

## Synopsis

Description:
Attach new storage volume to profile

<type> must be one of “custom” or “virtual-machine”

```none
lxc storage volume attach-profile [<remote:>]<pool> [<type>/]<volume>[/<snapshot>] <profile> [<device name>] [<path>] [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc storage volume](../volume.md#lxc-storage-volume-md)	 - Manage storage volumes


# index.html.md

<a id="lxc-storage-volume-move-md"></a>

# `lxc storage volume move`

Move storage volumes between pools

## Synopsis

Description:
Move storage volumes between pools

```none
lxc storage volume move [<remote>:]<pool>/<volume> [<remote>:]<pool>/<volume> [flags]
```

## Options

```none
      --destination-target   Destination cluster member name
      --mode                 Transfer mode, one of pull (default), push or relay (default "pull")
      --target               Cluster member name
      --target-project       Move to a project different from the source
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc storage volume](../volume.md#lxc-storage-volume-md)	 - Manage storage volumes


# index.html.md

<a id="lxc-storage-bucket-get-md"></a>

# `lxc storage bucket get`

Get value for storage bucket configuration key

## Synopsis

Description:
Get value for storage bucket configuration key

```none
lxc storage bucket get [<remote>:]<pool> <bucket> <key> [flags]
```

## Options

```none
  -p, --property   Get the key as a storage bucket property
      --target     Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc storage bucket](../bucket.md#lxc-storage-bucket-md)	 - Manage storage buckets


# index.html.md

<a id="lxc-storage-bucket-edit-md"></a>

# `lxc storage bucket edit`

Edit storage bucket configurations as YAML

## Synopsis

Description:
Edit storage bucket configurations as YAML

```none
lxc storage bucket edit [<remote>:]<pool> <bucket> [flags]
```

## Examples

```none
  lxc storage bucket edit [<remote>:]<pool> <bucket> < bucket.yaml
      Update a storage bucket using the content of bucket.yaml.
```

## Options

```none
      --target   Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc storage bucket](../bucket.md#lxc-storage-bucket-md)	 - Manage storage buckets


# index.html.md

<a id="lxc-storage-bucket-show-md"></a>

# `lxc storage bucket show`

Show storage bucket configurations

## Synopsis

Description:
Show storage bucket configurations

```none
lxc storage bucket show [<remote>:]<pool> <bucket> [flags]
```

## Examples

```none
  lxc storage bucket show default data
      Will show the properties of a bucket called "data" in the "default" pool.
```

## Options

```none
      --target   Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc storage bucket](../bucket.md#lxc-storage-bucket-md)	 - Manage storage buckets


# index.html.md

<a id="lxc-storage-bucket-set-md"></a>

# `lxc storage bucket set`

Set storage bucket configuration keys

## Synopsis

Description:
Set storage bucket configuration keys

For backward compatibility, a single configuration key may still be set with:
lxc storage bucket set [<remote>:]<pool> <bucket> <key> <value>

```none
lxc storage bucket set [<remote>:]<pool> <bucket> <key>=<value>... [flags]
```

## Options

```none
  -p, --property   Set the key as a storage bucket property
      --target     Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc storage bucket](../bucket.md#lxc-storage-bucket-md)	 - Manage storage buckets


# index.html.md

<a id="lxc-storage-bucket-create-md"></a>

# `lxc storage bucket create`

Create new custom storage buckets

## Synopsis

Description:
Create new custom storage buckets

```none
lxc storage bucket create [<remote>:]<pool> <bucket> [key=value...] [flags]
```

## Examples

```none
  lxc storage bucket create p1 b01
  	Create a new storage bucket name b01 in storage pool p1

  lxc storage bucket create p1 b01 < config.yaml
  	Create a new storage bucket name b01 in storage pool p1 using the content of config.yaml
```

## Options

```none
      --target   Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc storage bucket](../bucket.md#lxc-storage-bucket-md)	 - Manage storage buckets


# index.html.md

<a id="lxc-storage-bucket-delete-md"></a>

# `lxc storage bucket delete`

Delete storage bucket

## Synopsis

Description:
Delete storage bucket

```none
lxc storage bucket delete [<remote>:]<pool> <bucket> [flags]
```

## Options

```none
      --target   Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc storage bucket](../bucket.md#lxc-storage-bucket-md)	 - Manage storage buckets


# index.html.md

<a id="lxc-storage-bucket-key-md"></a>

# `lxc storage bucket key`

Manage storage bucket keys

## Synopsis

Description:
Manage storage bucket keys

```none
lxc storage bucket key [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc storage bucket](../bucket.md#lxc-storage-bucket-md)	 - Manage storage buckets
* [lxc storage bucket key create](key/create.md#lxc-storage-bucket-key-create-md)	 - Create key for a storage bucket
* [lxc storage bucket key delete](key/delete.md#lxc-storage-bucket-key-delete-md)	 - Delete key from a storage bucket
* [lxc storage bucket key edit](key/edit.md#lxc-storage-bucket-key-edit-md)	 - Edit storage bucket key as YAML
* [lxc storage bucket key list](key/list.md#lxc-storage-bucket-key-list-md)	 - List storage bucket keys
* [lxc storage bucket key show](key/show.md#lxc-storage-bucket-key-show-md)	 - Show storage bucket key configurations


# index.html.md

<a id="lxc-storage-bucket-list-md"></a>

# `lxc storage bucket list`

List storage buckets

## Synopsis

Description:
List storage buckets

```none
lxc storage bucket list [<remote>:]<pool> [flags]
```

## Options

```none
      --all-projects   Display storage pool buckets from all projects
  -c, --columns        Columns (default "nd")
  -f, --format         Format (csv|json|table|yaml|compact) (default "table")
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc storage bucket](../bucket.md#lxc-storage-bucket-md)	 - Manage storage buckets


# index.html.md

<a id="lxc-storage-bucket-unset-md"></a>

# `lxc storage bucket unset`

Unset storage bucket configuration key

## Synopsis

Description:
Unset storage bucket configuration key

```none
lxc storage bucket unset [<remote>:]<pool> <bucket> <key> [flags]
```

## Options

```none
  -p, --property   Unset the key as a storage bucket property
      --target     Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc storage bucket](../bucket.md#lxc-storage-bucket-md)	 - Manage storage buckets


# index.html.md

<a id="lxc-storage-bucket-key-list-md"></a>

# `lxc storage bucket key list`

List storage bucket keys

## Synopsis

Description:
List storage bucket keys

```none
lxc storage bucket key list [<remote>:]<pool> <bucket> [flags]
```

## Options

```none
  -c, --columns   Columns (default "ndr")
  -f, --format    Format (csv|json|table|yaml|compact) (default "table")
      --target    Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc storage bucket key](../key.md#lxc-storage-bucket-key-md)	 - Manage storage bucket keys


# index.html.md

<a id="lxc-storage-bucket-key-edit-md"></a>

# `lxc storage bucket key edit`

Edit storage bucket key as YAML

## Synopsis

Description:
Edit storage bucket key as YAML

```none
lxc storage bucket key edit [<remote>:]<pool> <bucket> <key> [flags]
```

## Examples

```none
  lxc storage bucket edit [<remote>:]<pool> <bucket> <key> < key.yaml
      Update a storage bucket key using the content of key.yaml.
```

## Options

```none
      --target   Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc storage bucket key](../key.md#lxc-storage-bucket-key-md)	 - Manage storage bucket keys


# index.html.md

<a id="lxc-storage-bucket-key-show-md"></a>

# `lxc storage bucket key show`

Show storage bucket key configurations

## Synopsis

Description:
Show storage bucket key configurations

```none
lxc storage bucket key show [<remote>:]<pool> <bucket> <key> [flags]
```

## Examples

```none
  lxc storage bucket key show default data foo
      Will show the properties of a bucket key called "foo" for a bucket called "data" in the "default" pool.
```

## Options

```none
      --target   Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc storage bucket key](../key.md#lxc-storage-bucket-key-md)	 - Manage storage bucket keys


# index.html.md

<a id="lxc-storage-bucket-key-create-md"></a>

# `lxc storage bucket key create`

Create key for a storage bucket

## Synopsis

Description:
Create key for a storage bucket

```none
lxc storage bucket key create [<remote>:]<pool> <bucket> <key> [flags]
```

## Examples

```none
  lxc storage bucket key create p1 b01 k1
  	Create a key called k1 for the bucket b01 in the pool p1.

  lxc storage bucket key create p1 b01 k1 < config.yaml
  	Create a key called k1 for the bucket b01 in the pool p1 using the content of config.yaml.
```

## Options

```none
      --access-key   Access key (auto-generated if empty
      --role         Role (admin or read-only (default "read-only")
      --secret-key   Secret key (auto-generated if empty
      --target       Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc storage bucket key](../key.md#lxc-storage-bucket-key-md)	 - Manage storage bucket keys


# index.html.md

<a id="lxc-storage-bucket-key-delete-md"></a>

# `lxc storage bucket key delete`

Delete key from a storage bucket

## Synopsis

Description:
Delete key from a storage bucket

```none
lxc storage bucket key delete [<remote>:]<pool> <bucket> <key> [flags]
```

## Options

```none
      --target   Cluster member name
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc storage bucket key](../key.md#lxc-storage-bucket-key-md)	 - Manage storage bucket keys


# index.html.md

<a id="lxc-profile-device-get-md"></a>

# `lxc profile device get`

Get value for device configuration key

## Synopsis

Description:
Get value for device configuration key

```none
lxc profile device get [<remote>:]<profile> <device> <key> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc profile device](../device.md#lxc-profile-device-md)	 - Manage devices


# index.html.md

<a id="lxc-profile-device-set-md"></a>

# `lxc profile device set`

Set device configuration keys

## Synopsis

Description:
Set device configuration keys

For backward compatibility, a single configuration key may still be set with:
lxc profile device set [<remote>:]<profile> <device> <key> <value>

```none
lxc profile device set [<remote>:]<profile> <device> <key>=<value>... [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc profile device](../device.md#lxc-profile-device-md)	 - Manage devices


# index.html.md

<a id="lxc-profile-device-list-md"></a>

# `lxc profile device list`

List instance devices

## Synopsis

Description:
List instance devices

```none
lxc profile device list [<remote>:]<profile> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc profile device](../device.md#lxc-profile-device-md)	 - Manage devices


# index.html.md

<a id="lxc-profile-device-unset-md"></a>

# `lxc profile device unset`

Unset device configuration key

## Synopsis

Description:
Unset device configuration key

```none
lxc profile device unset [<remote>:]<profile> <device> <key> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc profile device](../device.md#lxc-profile-device-md)	 - Manage devices


# index.html.md

<a id="lxc-profile-device-remove-md"></a>

# `lxc profile device remove`

Remove instance devices

## Synopsis

Description:
Remove instance devices

```none
lxc profile device remove [<remote>:]<profile> <name>... [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc profile device](../device.md#lxc-profile-device-md)	 - Manage devices


# index.html.md

<a id="lxc-profile-device-add-md"></a>

# `lxc profile device add`

Add instance devices

## Synopsis

Description:
Add instance devices

```none
lxc profile device add [<remote>:]<profile> <device> <type> [key=value...] [flags]
```

## Examples

```none
  lxc profile device add [<remote>:]profile1 <device-name> disk source=/share/c1 path=/opt
      Will mount the host's /share/c1 onto /opt in the instance.

  lxc profile device add [<remote>:]profile1 <device-name> disk pool=some-pool source=some-volume path=/opt
      Will mount the some-volume volume on some-pool onto /opt in the instance.
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc profile device](../device.md#lxc-profile-device-md)	 - Manage devices


# index.html.md

<a id="lxc-profile-device-show-md"></a>

# `lxc profile device show`

Show full device configuration

## Synopsis

Description:
Show full device configuration

```none
lxc profile device show [<remote>:]<profile> [flags]
```

## Options inherited from parent commands

```none
      --debug          Show all debug messages
      --force-local    Force using the local unix socket
  -h, --help           Print help
      --project        Override the source project
  -q, --quiet          Do not show progress information
      --sub-commands   Use with help or --help to view sub-commands
  -v, --verbose        Show all information messages
      --version        Print version number
```

## SEE ALSO

* [lxc profile device](../device.md#lxc-profile-device-md)	 - Manage devices


