This is devcontainer.info, produced by makeinfo version 6.8 from
devcontainer.texi.

     Copyright (C) 2025 - 2026 Johannes Mueller
     <github@johannes-mueller.org>

     You can redistribute this document and/or modify it under the terms
     of the GNU General Public License as published by the Free Software
     Foundation, either version 3 of the License, or (at your option)
     any later version.

     This document is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     General Public License for more details.

INFO-DIR-SECTION Emacs
START-INFO-DIR-ENTRY
* devcontainer: (devcontainer).       Working on projects that use a devcontainer
END-INFO-DIR-ENTRY


File: devcontainer.info,  Node: Top,  Next: Usage,  Up: (dir)

The package devcontainer.el
***************************

Rudimentary devcontainer support for Emacs

   This package lets you handle i.e. start, restart devcontainers of
your projects and forwards all your ‘compile’ commands into the
devcontainer by advising ‘compilation-start’.  So as long you use
‘compile’ to build, test and run (parts of your) software, all will be
executed inside the devcontainer.

     Please consider this package experimental as long as there is no
     release yet.  There might be breaking changes like changing
     function and variable names out of the blue.  So please consider
     checking the git history when updating.

   Source code: <https://github.com/johannes-mueller/devcontainer.el>

* Menu:

* Usage::
* Configuration::

1 Introduction
**************

1.1 What are devcontainers?
===========================

Devcontainers (https://containers.dev/) become increasingly popular in
modern software development.  The idea is to put everything the software
you are developing needs in order to run into a docker container or a
stack of docker (https://docker.com) containers.  Then all your local
builds and testing is performed inside that container.  So your
development basically takes place inside the docker container – hence
the name “devcontainer”.

   The initiative came from the Visual Studio Code community.  They
actually run the complete tooling inside the container, even their IDE.
The configuration of the IDE – i.e. which extensions are to be installed
– is also defined by the definition of the devcontainer.

1.2 Approach for support in Emacs
=================================

While you technically don’t need to use devcontainers even though your
team is using them, it is convenient for you also to use devcontainers
at least to some degree.  Of course, you won’t install an Emacs instance
inside the devcontainer, but it is really helpful for you to manage
devcontainers from within Emacs and interact with the installation of
your software inside of it.  That’s where the ‘devcontainer’ package
comes in.

   ‘devcontainer’ provides a set Emacs commands to build, launch, stop,
erase and rebuild the devcontainer according to its definition in the
project’s repo.  In order for you to run and test your software inside
the devcontainer, ‘devcontainer-mode’ advises Emacs’ ‘compilation-start’
function to prepend ‘devcontainer exec --workspace-folder .’ to your
compilation command and thus runs the compilation command inside the
container.

   Usually you would mount your local working directory into your
devcontainer.  Then you edit files just like without using devcontainer.
Then, launching any kind of ‘compile’ command, it is actually performed
inside your devcontainer.


File: devcontainer.info,  Node: Usage,  Next: Configuration,  Prev: Top,  Up: Top

2 Setup and usage
*****************

2.1 Setup
=========

You need to have the devcontainers/cli
(https://github.com/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 (https://docker.com)
installation and probably also docker compose
(https://docs.docker.com/compose/).  Alternatively you can also use
podman (https://podman.io/).

2.2 Usage
=========

2.2.1 Activate ‘devcontainer-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.

2.2.2 Commands
--------------

There are couple of commands to start and stop devcontainers.  They are
pretty straight forward.

2.2.2.1 Launching the devcontainer ‘devcontainer-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.

2.2.2.2 Restarting the container
................................

‘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.

2.2.2.3 Starting programs inside the devcontainer
.................................................

‘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")))

2.2.3 Forwarding commands that are not using ‘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)

2.2.4 Using TRAMP
-----------------

An alternative way of using the package is to edit the files inside the
container itself using Emacs’ builtin TRAMP
(https://www.gnu.org/software/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.

2.2.5 Customizations of 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.


File: devcontainer.info,  Node: Configuration,  Prev: Usage,  Up: Top

3 Configuration
***************

The following things are customizable at this point.  For a complete
list of configuration options refer to the ‘devcontainer’ configuration
group.

3.1 General configuration and startup
=====================================

DEVCONTAINER-ENGINE defines the container engine you want to use.  The
options are either ‘'docker’ (default) or ‘'podman’.

   DEVCONTAINER-STARTUP-SECRETS-FILE defines the file that is passed to
the ‘devcontainer’ command as ‘--secrets-file’ option.  It can be used
to inject environment variable into the built/startup process of the
container without putting them into the container definition.  Thus
secrets like tokens to access resources like package dependencies don’t
need to be put into the code base.

   DEVCONTAINER-APPLY-CUSTOMIZATION defines whether to apply the
customization defined for Emacs in ‘devcontainer.json’.  By default
(‘'ask’) it will ask you if you want to apply it.  Other options are
‘'always’ and ‘'never’.  For trusted projects you can set it project
local in ‘.dir-locals.el’.

   DEVCONTAINER-POST-STARTUP-HOOK is a hook variable that can provide
functions that are called after the container has been started.  They
take a couple of arguments.  It receives information on the devcontainer
as parameters.  See the functions’ documentation for details.

   One example use case is to hook in the function
DEVCONTAINER-TRAMP-DIRED to open a ‘dired’ window inside the container
right after the start of the container.

3.2 Command execution inside the container
==========================================

DEVCONTAINER-EXECUTE-OUTSIDE-CONTAINER.  Maybe you don’t want to execute
all programs that Emacs launches by the ‘compile’ command insider the
container.  For example programs like ‘grep’ are preferably launched
outside the container.  You can set list of programs, not to be executed
inside the container but on the host system.

   There are the customization variables DEVCONTAINER-TERM-COMMAND,
DEVCONTAINER-TERM-SHELL and DEVCONTAINER-TERM-ENVIRONMENT to customize
the terminal launched by ‘devcontainer-term’.


Tag Table:
Node: Top812
Node: Usage3678
Node: Configuration10973

End Tag Table


Local Variables:
coding: utf-8
End:
