You can build you own images, but I recommend using cloud init to install the package when you first launch the instance. You can add the configuration to your default profile.
The images at https://images.linuxcontainers.org/ are quite lean, which means that they do not have openssh-server, neither curl, nor wget, etc.
The exact wording though, is that these images do not include by default those packages and in fact any packages that are not universally required. This is quite important when you launch hundreds of instances. Every bit of unneeded packages will add up, and take space and memory.
As already mentioned, you can setup your system with the appropriate profile so that any instance that you create, will install upon creation, the packages of your liking.
Create an Incus profile called, for example, addpackages and add the following.
Then, launch a container with that added profile. We must include the default profile as well, along with the additional profile. Note that you can add the instructions of the additional profile to your default profile so that all your instances will get those packages installed upon creation (of each instance).
The first part is to get the bash-completion package to get installed upon creation of the instance. I think this is covered in the earlier example above. Ask if you want an example for that.
The second part is how to get a shell into the instance so that the shell will make use of the bash-completion. If that package is installed, then a login shell will automatically get the bash-completion enabled. Which means that you probably do not need something extra to configure.
Let’s see. We launch an instance, then get a login shell (incus shell is su -l, therefore a login shell which loads up all config files). Without bash-completion, when we cd .<TAB>, it shows both files and directories. That’s wrong; you cannot cd into a file. We then install the package, logout and log in again, and now completion works. cd .<TAB> shows only the .ssh/ directory, which is the outcome of bash-completion working fine.
$ incus launch images:debian/12/cloud myinstance
Launching myinstance
$ incus shell myinstance
root@myinstance:~# cd .<TAB>
./ ../ .bashrc .profile .ssh/
root@myinstance:~# touch one two
root@myinstance:~# cd
.bashrc one .profile .ssh/ two
root@myinstance:~# apt install bash-completion
...
root@myinstance:~# logout
$ incus shell myinstance
root@myinstance:~# cd .<TAB>
root@myinstance:~# cd .ssh/
root@myinstance:~/.ssh# logout
$
I used the double-tab as an example to demonstrate whether completion is loaded or not. Another way is to run complete (as a command) and see whether there are rules loaded. I think that demonstrating visual with double-tab was a good choice.
Indeed, there are many other facilities that are provided with the shell completion that not so many users are aware of them.
Note that among all programs that provide configuration for Bash completion, Incus is one of them. The completion rules can be found at /usr/share/bash-completion/completions/ and a program just needs to put in there their own completion rules.
Here are the Incus rules, /usr/share/bash-completion/completions/incus.