You need to have the devcontainers/cli command line tool installed into your execution path. For that you need a working node/npm setup. Then you can install the tool with
npm install -g @devcontainers/cli
Of course you also need a working docker installation and probably also docker. Alternatively you can also use podman.
devcontainer-modecompiledevcontainer-mode ¶In order to use devcontainers you should activate devcontainer-mode.
It is a global major mode that recognizes if a project needs or supports
devcontainers and then automatically forwards commands to the devcontainer.
There are couple of commands to start and stop devcontainers. They are pretty straight forward.
devcontainer-updevcontainer-up ¶devcontainer-up starts the devcontainer of the current
project. Usually you would use it to start the devcontainer, when you start
working on a project after relaunching your computer. You’ll get a
notification in the echo area as soon as the container is launched. In order
to examine failures you can examine the buffer *devcontainer startup*.
If the startup of the container needs secrets to access resources like package dependencies you can define a file where these secrets are stored in devcontainer-startup-secrets-file.
If there is no image for the container available on your system it is built according the the project’s devcontainer definition. Note that this command does not rebuild the container. Nothing will be updated. The software state will be the same as when the container has been built lastly.
devcontainer-restart stops and restart the devcontainer of the
current project without rebuilding it. There is actually one rare use case and
that is when the container reached a state which can only or easiest be reset
by a reastart.
devcontainer-rebuild-and-restart stops the current project’s
devcontainer, deletes its docker images and rebuilds it. This is useful, when
you for example changed the Dockerfile of your devcontainer. However,
it also does not rebuild or update the containers that are defined as other
services in docker-compose.yml in the project’s devcontainer definition.
devcontainer-execute-command executes an arbitrary command
inside the devcontainer. This is meant for long running, non-interactive
commands like running a server or some kind of batch job. When called
interactively it prompts for a command.
devcontainer-execute-command-interactive execute an arbitrary command
inside the devcontainer interactively. This is meant for interactive commands
that you would run in a terminal. When called interactively it prompts for a
command.
devcontainer-term provides a terminal for a shell inside the
container. By default it tries to launch the bash shell. You can
customize that by the devcontainer-term-shell. If you experience wired
control sequences in your terminal you might want to adjust the TERM
variable inside the container using
(setq devcontainer-term-environment '(("TERM" . "xterm-256color")))
compile ¶If you need to forward some process call into the devcontainer which is
not done by the compile command of Emacs, you can use
devcontainer-advise-command to prepend the
devcontainer exec call in front of your command. If you are not
sure if devcontainer is always available you can use the
following call, which modifies your command if devcontainer is
available and if the command modification is advisable.
(funcall (or (symbol-function 'devcontainer-advise-command) #'identity) command)
An alternative way of using the package is to edit the files inside the
container itself using Emacs’ builtin
TRAMP facility. There are
pros and cons to it. In order to use it, you can let
devcontainer-mode deactivated and use the function
devcontainer-tramp-dired to open a dired window inside the
container. Then you can open files of your project inside the container.
If devcontainer-mode is activated it refrains from advising
compile functions, if the current buffer is a file inside the
devcontainer.
Devcontainers can demand customizations to the user’s IDE. That is useful to ensure that all the IDEs of all the teams members are aligned. Whereas in the VSCode world you can also request extension packages to be installed when working on the devcontainer driven project, this Emacs package only allows you to set Emacs variables and call Emacs functions when opening a file that belongs to a devcontainer driven project.
Customizations are defined in the customization section of
devcontainer.json file. For every IDE supporting devcontainers can
there can be a subsection. To set variables for buffers of the project you can
use the emacs subsection. In order to set the variable
fill-column you can use the following example.
{
...
"customizations": {
"emacs": {
"fill-column": 79
}
}
}
Also mode specific settings are possible. The following example sets
fill-column to 79 for text-mode, to 88 for python-mode
and to 80 for all other modes.
{
...
"customizations": {
"emacs": {
"modes": {
"text-mode": {
"fill-column": 79
},
"python-mode": {
"fill-column": 88
}
},
"fill-column": 80
}
}
}
Note that derived modes are also affected from those settings if they don’t
override it. In the above example the fill-column is also set to 79 in
markdown-mode as markdown-mode is a derived mode of
text-mode.
In order to perform commands as customization you can use lisp commands as
variable name and letting the value null like so:
{
...
"customizations": {
"emacs": {
"(auto-fill-mode -1)": null
}
}
}
So theoretically you could perform complicated lisp code there and even install packages. However it is strongly discouraged to do anything more than setting variables and ensuring that minor modes are switched on or off.
This customization mechanism in principle allows authors of the project to perform any lisp code on you Emacs. That is a potential security risk. So you can decide if you want to trust projects that you work on or not. You can do that setting devcontainer-apply-customization.