5

In the context of VS Code Remote Development inside a container I can see that extensions to install can be specified in the devcontainers.json file, as shown in the samples in the vscode-dev-containers repo, like this example:

"extensions": [
        "dbaeumer.vscode-eslint"
]

I have a VSIX file based extension locally that I'd also like to specify here so that it gets installed into the container. But I'm not sure how best to declare it here, path-wise.

I looked in the output of the container build step and noticed that the local project directory is mounted into the container (linebreaks added for readability):

Run: docker run -a STDOUT -a STDERR -p 127.0.0.1:4004:4004 
  -v /Users/dj/local/projects/test1:/workspaces/test1 
  -v /Users/dj/.gitconfig:/root/.gitconfig 
  -l vsch.quality=insider 
  -l vsch.local.folder=/Users/dj/local/projects/test1 
  -l vsch.remote.devPort=9753 
  vsc-test1-304320e2e9560b5557f6f7871801047f 
  /bin/sh -c echo Container started ;  while sleep 1; do :; done

so I placed my VSIX file in the root of the project (/Users/dj/local/projects/test1/vscode-cds-1.1.4.vsix) and this was then available in the container. Adding the fully qualified path to this file in the container to the extensions property thus:

"extensions": [
        "dbaeumer.vscode-eslint",
        "/workspaces/test1/vscode-cds-1.1.4.vsix"
]

did indeed result in a successful installation of this extension into the container:

Installing extensions...
Installing extension 'dbaeumer.vscode-eslint' v1.8.2...
Extension 'dbaeumer.vscode-eslint' v1.8.2 was successfully installed.
Extension 'vscode-cds-1.1.4.vsix' was successfully installed.    <----

Great!

But this hack requires me to hard code the name of the directory in which the .devcontainer/ directory is (i.e. test1/), which of course I want to avoid.

Is there a way of doing this without hard coding the whole project directory name in the devcontainer.json file?

Thank you.

qmacro
  • 3,025
  • 23
  • 33

2 Answers2

6

About 10 mins after asking this question I thought of a different approach which is perhaps still a hack, but it avoids having to use the project directory name. I put the VSIX file in the .devcontainer/ directory, and then added a COPY command to the end of my Dockerfile thus:

COPY vscode-cds-1.1.4.vsix /tmp/

and could then specify this neutral path in the extensions property thus:

"extensions": [
        "dbaeumer.vscode-eslint",
        "/tmp/vscode-cds-1.1.4.vsix"
]

This works. Wondering if there's a better way though.

qmacro
  • 3,025
  • 23
  • 33
  • 2
    using a volume mount instead of `COPY` command also works. That way you don't need to pollute your `Dockerfile` and all the configuration is in your `.devcontainer.json` file. This also means you can provide an absolute path to your volume mount and reuse the same vsix file instead of copying it to all your projects. – Cnoor0171 Jun 16 '20 at 19:58
  • This doesn't work for me. It just doesn't load the vsix in this way. `code --install-extension /tmp/my-ext.vsix` works manually but none of the lifecycle callbacks (`postAttachCommand` etc.) can actually use `code` as a command. – Jacob Phillips May 13 '23 at 05:23
2

devcontainer.json has access to the following variables:

https://containers.dev/implementors/json_reference/#variables-in-devcontainerjson

So in your example it would be:

"extensions": [
        "dbaeumer.vscode-eslint",
        "${containerWorkspaceFolder}/vscode-cds-1.1.4.vsix"
]

Additional variable support was added in this PR

Kerry Liu
  • 2,072
  • 16
  • 16