The 'Couldn't find env file' error in Docker Compose occurs when the env_file directive references a file that doesn't exist or can't be found. This is typically resolved by creating the missing .env file, correcting the file path, or removing the env_file directive if not needed.
The "Couldn't find env file" error indicates that Docker Compose is looking for an environment file that doesn't exist at the specified location. This commonly occurs when your `docker-compose.yml` contains an `env_file:` directive pointing to a file that hasn't been created yet. Docker Compose uses environment files to inject environment variables into containers at runtime. The `env_file:` directive in your Compose file tells Docker where to find these variables. When Docker Compose starts, it validates that all referenced files exist before attempting to create containers. This error is particularly common when: 1. Cloning a project that uses `.env` files but doesn't commit them to version control (for security reasons) 2. The `.env` file exists but is in a different directory than expected 3. There's a typo in the filename (like `.env.dev` vs `.env_dev`) 4. The file was accidentally deleted or not yet created Note that Docker Compose has two different concepts involving env files: - The `.env` file in the project root (used for variable substitution in the Compose file itself) - The `env_file:` directive (used to pass variables to containers) This error specifically relates to files referenced by the `env_file:` directive.
The simplest fix is to create the .env file that Docker Compose is looking for:
# Navigate to your project directory (where docker-compose.yml is)
cd /path/to/your/project
# Create an empty .env file
touch .env
# Or create it with some variables
cat > .env << 'EOF'
# Environment variables
DATABASE_URL=postgres://user:pass@localhost:5432/db
API_KEY=your-api-key
NODE_ENV=development
EOFIf your project has a .env.example or .env.sample file, copy it as a starting point:
cp .env.example .envThen edit the .env file to add your actual values.
Verify that the env_file: path in your docker-compose.yml matches where your .env file actually is:
services:
web:
image: myapp
env_file:
- ./.env # Relative to docker-compose.yml location
- ./config/.env # In a subdirectory
- .env.local # Same directory, different nameCommon path issues:
- ./env vs ./.env (missing the dot prefix)
- .env.dev vs .env_dev (dot vs underscore)
- Paths are relative to the docker-compose.yml file, not your current directory
To verify what Docker Compose is looking for:
# Show the full resolved config (will fail but shows the path)
docker-compose configDocker Compose resolves relative paths from the directory containing the docker-compose.yml file. Make sure you're running commands from the right location:
# Check your current directory
pwd
# List files to confirm docker-compose.yml and .env are present
ls -la
# If .env is in a parent directory, navigate there
cd /path/to/project
# Or specify the project directory explicitly
docker-compose --project-directory /path/to/project upYou can also use the --env-file flag to specify a different location:
docker-compose --env-file /path/to/.env upNote: The --env-file flag is for the Compose file variable substitution, not for the env_file: directive in services.
If you don't actually need to pass environment variables from a file, remove the env_file: directive:
Before:
services:
web:
image: nginx
env_file:
- .envAfter:
services:
web:
image: nginxAlternatively, if you only need a few variables, use the environment: directive instead:
services:
web:
image: nginx
environment:
- NODE_ENV=production
- API_URL=https://api.example.comThis approach avoids the need for a separate .env file entirely.
Environment file names are case-sensitive on Linux and may have hidden issues:
# List all files including hidden ones
ls -la
# Look for files starting with .env
ls -la .env*
# Check for hidden characters or spaces in filenames
ls -la | cat -ACommon filename issues:
- .env (trailing space)
- .ENV (uppercase on case-sensitive systems)
- .env.dev vs .env_dev
- Curly quotes copied from documentation
If you see unusual characters, rename the file:
# Rename to remove any issues
mv ".env.dev " .env.devIf the file exists but Docker can't read it, check permissions:
# Check current permissions
ls -la .env
# Make the file readable
chmod 644 .env
# If running Docker as a different user, ensure that user can read it
# For Docker Desktop on Mac/Windows, this is usually not an issueOn Linux with rootless Docker, you may need to ensure the file is readable by the user running the Docker daemon:
# Check who owns the file
ls -la .env
# Change ownership if needed
sudo chown $USER:$USER .envWith Docker Compose V2, you can make env_file optional using the required: false attribute:
services:
web:
image: myapp
env_file:
- path: ./.env
required: false # Won't fail if file doesn't exist
- path: ./.env.local
required: falseThis is useful when:
- You want to support optional local overrides
- The .env file is only needed in certain environments
- You're building an image that doesn't need env vars at build time
Note: This syntax requires Docker Compose V2.17.0 or later. Check your version:
docker compose version### Understanding Docker Compose Environment Variable Loading
Docker Compose has three distinct mechanisms for environment variables, which can be confusing:
1. The `.env` file (Compose file substitution)
- Located in the same directory as docker-compose.yml
- Variables are used for substitution within the Compose file itself
- Example: image: ${REGISTRY}/myapp:${TAG}
- Override with: docker-compose --env-file ./other.env up
2. The `env_file:` directive (Container variables)
- Specified per-service in docker-compose.yml
- Variables are passed INTO the container at runtime
- Not available during Compose file parsing
- This is where the "Couldn't find env file" error originates
3. The `environment:` directive (Inline variables)
- Explicitly defined in the Compose file
- Can reference Compose file substitution variables
- Takes precedence over env_file values
### Order of Precedence
When the same variable is defined in multiple places, Docker Compose uses this precedence (highest to lowest):
1. Values set with docker-compose run -e VAR=value
2. Values in the environment: directive
3. Values in the env_file: directive
4. Values in the Dockerfile ENV instruction
5. Values from the shell environment
### Build vs Run Time
The env_file: directive is evaluated at different times depending on the command:
# Evaluated immediately (will fail if missing)
docker-compose build
docker-compose up
docker-compose config
# Not evaluated
docker-compose images
docker-compose versionThis is why docker-compose build fails even though env_file values are typically only needed at runtime. It's a known behavior that has been discussed in GitHub issues.
### CI/CD Best Practices
For CI/CD pipelines where .env files shouldn't be committed:
# .github/workflows/deploy.yml
steps:
- name: Create .env file
run: |
cat > .env << EOF
DATABASE_URL=${{ secrets.DATABASE_URL }}
API_KEY=${{ secrets.API_KEY }}
EOF
- name: Deploy
run: docker-compose up -dOr use environment variables directly:
# docker-compose.yml for CI
services:
app:
image: myapp
environment:
- DATABASE_URL # Will be read from the shell environment
- API_KEY### Security Note
Never commit .env files containing secrets to version control. Instead:
1. Add .env to .gitignore
2. Provide a .env.example with placeholder values
3. Document required variables in your README
4. Use secret management in production (Docker Secrets, Vault, etc.)
dockerfile parse error line 5: unknown instruction: RRUN
How to fix 'unknown instruction' Dockerfile parse error in Docker
Error response from daemon: manifest for nginx:nonexistent not found: manifest unknown: manifest unknown
How to fix 'manifest for image:tag not found' in Docker
Error response from daemon: invalid reference format: repository name must be lowercase
How to fix 'repository name must be lowercase' in Docker
Error response from daemon: No such image
How to fix 'No such image' in Docker
Error response from daemon: Container is not running
How to fix 'Container is not running' when using docker exec