vscode-remote-release icon indicating copy to clipboard operation
vscode-remote-release copied to clipboard

Add envFile to devcontainer.json and handle missing env file gracefully

Open njbmartin opened this issue 4 years ago • 17 comments

I'm using "runArgs": ["--env-file","devcontainer.env"] to spin up the container with some environment variables. This devcontainer.env file isn't committed, so when the repo is cloned for the first time, it doesn't exist. This results in a hard failure.

It would be great if you could specify this via an envFile in the container config, and if the file doesn't exist, it warns you instead of resulting in a hard failure.

njbmartin avatar May 15 '20 23:05 njbmartin

I vote for it!. Also service configs to pass such content as local Docker repositories URL's, Local gerrit URls, etc.

PavelSosin-320 avatar May 17 '20 08:05 PavelSosin-320

I just ran into this same problem, and I would also love if this gave a warning as opposed to a hard failure!

erlloyd avatar Jun 08 '20 19:06 erlloyd

1.46 adds the ability to go into a recovery container where you can add files and then rebuild the container much like you can when using the local filesystem.

Chuxel avatar Jun 09 '20 00:06 Chuxel

@Chuxel So does it automatically go into a recovery container any time it encounters an error? That's pretty cool - but I still see the need for a warning / graceful handling of no env file. For example, I have a repo where a developer can still do most things without needing the env variable. So it's annoying to tell developers that don't need the env variable that they still have to create an empty .env file

erlloyd avatar Jun 09 '20 23:06 erlloyd

Yeah, re-reading, I jumped to the assumption that this was a "open repository in container" scenario (due to so when the repo is cloned). To clarify, the new feature in 1.46 is that, when the error appears, there is a button in the error dialog for "open repository in container" flow to "open in recovery container". The flow is much like clicking on "Reopen Locally" to fix errors when opening a folder from the local filesystem. In open repository case, it just uses a simple container with Git and a few other things in it to connect to the volume with the source code.

In terms of filtering out the env file if it's missing, I don't know that we can do that for Docker Compose since that's a Docker format and tool. We could add it as a property for other scenarios, but out of curiosity, why does the repo not contain a env file with the expected defaults for developers (at least as a template)?

Chuxel avatar Jun 10 '20 00:06 Chuxel

Good question! In my particular case it has to do with AWS credentials. Some of the tasks a developer may perform include needing to access our AWS environment (uploading files to s3, for example, as part of a deploy to a temporary environment). However, the AWS creds are not necessary for every developer. In fact, most developers can run the app and do all of their daily work without needing to worry at all about AWS creds.

Obviously, I'm not opposed to a template .env file, and if a .env file is required it's easy enough to tell devs to just create an empty file. But it just seems like a step I shouldn't have to tell all developers.

docker-compose already supports this (kind of) because in the docker-compose.yml file, if you reference a host environment variable, docker-compose will look for a .env file in the same directory and use values in it if it is present, but fall back to just looking at host variables if the file isn't present.

So it's also interesting you mention "open repository in container" because the whole reason I went away from using docker-compose.yml files with my .devcontainer configuration is because "open repository in container" doesn't work with docker-compose! But then I encountered this issue, where even with a normal clone-to-host workflow (not "open repository in container") forced me to require a .env file.

There's also a chance there's just a bug that needs to be fixed. The VSCode remote containers documentation indicates that a .env file in the project root should just be picked up:

VS Code will automatically pick up a file called .env in your workspace root, but you can also create one in another location.

That never worked for me.

Ok, sorry for all the information, but hopefully that helps give some context!

erlloyd avatar Jun 10 '20 13:06 erlloyd

I consider a soft fail on a missing .env file as problematic. It's much easier to do a touch .devcontainer/.env than to search for hours why your software is not behaving as expected. Especially as a new team member. When it's failing you know some configuration is expected here.

ascheucher avatar Nov 22 '20 17:11 ascheucher

There's also a chance there's just a bug that needs to be fixed. The VSCode remote containers documentation indicates that a .env file in the project root should just be picked up:

VS Code will automatically pick up a file called .env in your workspace root, but you can also create one in another location.

That never worked for me.

I'm also confused by this... putting a .env in the workspace root does not appear to be picked up automatically as suggested in the documentation... what a I missing?

janhurst avatar Mar 10 '22 16:03 janhurst

I consider a soft fail on a missing .env file as problematic.

That's why I think the most graceful way to handle this would be a prompt at the container build time. Here is what I'd consider a perfect way to build this feature IMO:

  • Let say my docker-compose.yml file contains a line like: env_file: .env.local. Of course, .env.local is not versioned and need to be added my myself.
  • In my devcontainer.json, I add this line: "prompted_files": [".env.local"], supposing that this file doesn't exist in the repository to be cloned.
  • When I try to create my container using Clone Repository in Container Volume, VS Code immediately prompts a window, asking me to upload a file named .env.local to be able to create the container.
  • The container is created with no trouble.

This way, no soft fail, no hard fail, just a simple config line to specify expected missing files, and a simple prompt to help user upload this file at the container build time.

ddahan avatar May 11 '22 08:05 ddahan

I'm also confused by this... putting a .env in the workspace root does not appear to be picked up automatically as suggested in the documentation... what a I missing?

You are not missing anything here, this really is jut not working at all.

I'm a bit confused here as to why there would be such a feature designed like this. As OP stated, this file cannot exist if someone clones the container/repo for the first time.

I agree with @ddahan that an implementation similar to this would be what I'd expect as well.

Ponjimon avatar May 31 '22 10:05 Ponjimon

I managed to solve my issue doing a initCommand copying the .env to the .devcontainer folder:

devcontainer.json "initializeCommand": "cp .env .devcontainer/.env"

luis-gmonkey avatar Jan 17 '23 17:01 luis-gmonkey

@luis-gmonkey where did you put that initialize command?

gcarvajal1222 avatar May 18 '23 22:05 gcarvajal1222

@gcarvajal1222 - this goes in devcontainer.json

thatnerdjosh avatar Aug 17 '23 18:08 thatnerdjosh

I managed to solve my issue doing a initCommand copying the .env to the .devcontainer folder:

I'm not sure how it solves the initial issue. What if you forget to create the .env file? You'll get a hard failure too, right?

ddahan avatar Sep 10 '23 09:09 ddahan

@ddahan - this creates it, but it does in fact have an issue though - if the .env already exists it'll overwrite it. To alleviate that, I've added the no clobber (-n) flag

thatnerdjosh avatar Sep 10 '23 18:09 thatnerdjosh

Wouldn't

// devcontainer.json
"initializeCommand": "touch .env",

be a better workaround? If the user does not require (AWS) credentials - and such does not create an .env file before the first run - we would create an empty file and the container build should succeed. If the user requires credentials he creates a respective .env file himself - maybe from a template - and the touch command does not matter.

Of course, that's still just a workaround, I would much prefer if devcontainer themself could gracefully handle either the absence of an .env file when specified - or fix the behavior of not automatically picking up .env files 🤔

fex01 avatar Nov 10 '23 08:11 fex01

This works in some use cases, but if you have devs running a mix of OSes this will break as initializeCommnad runs on the host so for instance if your host is windows touch or cp will not work. You could have everyone install powershell maybe since it's cross platform but ideally I wouldn't install anything other than docker and vs code on the host. Anyone come up with a cross-platform solution?

Edit: I found a solution. Make two files, init.cmd and init. The init.cmd runs on windows and plain init runs on unix, then in .devcontainer use "initializeCommand": [".devcontainer/init"]. Note there is no extension here.

alexwaibel avatar Feb 14 '24 01:02 alexwaibel