"key cannot contain a space" error while running docker compose - docker

I am trying to deploy my django app to app engine using dockerfile and for that after following a few blogs such as these, I created a docker-compose.yml file but when I run the docker compose up command or docker-compose -f docker-compose-deploy.yml run --rm gcloud sh -c "gcloud app deploy" I get an error key cannot contain a space. See below:
For example:
$ docker compose up
key cannot contain a space
$ cat docker-compose.yml
version: '3.7'
services:
app:
build:
context: .
ports: ['8000:8000']
volumes: ['./app:/app']
Can someone please help me to fix this error? I have tried yamllint to validate the yaml file for any space/indentation type of error and it doesn't show any error to me.
EDIT:
Here is the content for file in the longer command:
version: '3.7'
services:
gcloud:
image: google/cloud-sdk:338.0.0
volumes:
- gcp-creds:/creds
- .:/app
working_dir: /app
environment:
- CLOUDSDK_CONFIG=/creds
volumes:
gcp-creds:

Ok this is resolved finally! After beating my head around, I was able to finally resolve this issue by doing the following things:
Unchecked the option to use "Docker Compose v2" from my docker desktop settings. Here is the setting in Docker Desktop
Closed the docker desktop app and restarted it.
Please try these steps in case you face the issue. Thanks!

Just adding another alt answer here that I confirmed worked for me when following the steps above did not. My case is slightly different, but as Google brought me here first I thought I'd leave a note.
Check your env var values for spaces!
This may only be applicable if you are using env_var files (appreciate that OP is not in the minimal example, hence saying this is different).
Unescaped spaces in variables will cause this cryptic error message.
So, given a compose file like this:
version: '3.7'
services:
gcloud:
image: google/cloud-sdk:338.0.0
volumes:
- gcp-creds:/creds
- .:/app
working_dir: /app
env_file:
- some_env_file.env
If some_env_file.env looks like this:
MY_VAR=some string with spaces
then we get the cryptic key cannot contain a space.
If instead we change some_env_file.env to be like this:
MY_VAR="some string with spaces"
then all is well.
The issue has been reported to docker-compose.
Google brought me here first, and when your suggestion sadly didn't work for me, it then took me to this reddit thread, where I found out the above.

Docker Compose (at least since v2) automatically parses .env files before processing the docker-compose.yml file, regardless of any env_file setting within the yaml file. If any of the variables inside your .env file contains spaces, then you will get the error key cannot contain a space.
Two workarounds exist at this time:
Rename your .env file to something else, or
Create an alternate/empty .env file, e.g. .env.docker and then explicitly set the --env-file parameter, i.e. docker compose --env-file .env.docker config.
Track the related issues here:
https://github.com/docker/compose/issues/6741
https://github.com/docker/compose/issues/8736
https://github.com/docker/compose/issues/6951
https://github.com/docker/compose/issues/4642
https://github.com/docker/compose/commit/ed18cefc040f66bb7f5f5c9f7b141cbd3afbbc89
https://docs.docker.com/compose/env-file/

One more thing to be care about - since Compose V2, this error may be raise in case you have inline comments in the env file used by Compose. For example
---
version: "3.7"
services:
backend:
build:
context: .
dockerfile: Dockerfile
env_file: .app.env
and that .app.env is like this
RABBIT_USER=user # RabbitMQ user
the same error may occur. To fix just move comment to its own line
# RabbitMQ user
RABBIT_USER=user

Related

persist %USERPROFILE% folder using docker compose volume

I am searching on how to persist user profile folder in volume mounting
I have folder C:\Users\ABEL\source\repos which needs to be persisted for a windows container. The username should be from the host. It is unknown.
Below is my docker-compose file, The volume section is not correct.
Any comments will be helpful. Thanks in advance
version: '3.4'
services:
directoryservice:
image: abc-directoryservice:latest
build: .
ports:
- "44309:44309"
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=https://+:44309;
- ASPNETCORE_Kestrel__Certificates__Default__Password=welcome123#
- ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx
volumes:
- ./devops/https/abccert.pfx:/https/aspnetapp.pfx:ro
# - "$env:USERPROFILE/source:$env:USERPROFILE/source"
- ${Env:USERPROFILE}\source:${Env:USERPROFILE}\source
I get below error
invalid interpolation format for services.directoryservice.volumes.[]: "${Env:USERPROFILE}\\source:${Env:USERPROFILE}\\source". You may need to escape any $ with another $.
The $env:USERPROFILE/ ${env:USERPROFILE} syntax is specific to PowerShell.
Judging by the docs, docker-compose uses its own syntax: $USERPROFILE / ${USERPROFILE}
You report a follow-up problem, namely that the Windows-style path stored in $USERPROFILE (%USERPROFILE%) (e.g. C:\Users\jdoe\source) isn't converted to a Unix-style path (e.g. c/Users/jdoe/source)
This answer suggests that you must set environment variable COMPOSE_CONVERT_WINDOWS_PATHS to 1, before running your docker-compose command.
E.g., in a PowerShell session:
$env:COMPOSE_CONVERT_WINDOWS_PATHS=1
Consider adding this statement to your $PROFILE file so that it takes effect in future PowerShell sessions too.

Insufficient permissions for local file change in strapi docker

I tried to install strapi with PostgreSQL from its official doc, I changed the name for mounted volumes in YAML file and keep all the rest the same as the given one in the doc.
based on strapi PostgreSQL docker-compose.yaml file see original
version: '3'
services:
strapi:
image: strapi/strapi
# totally the same as doc
volumes:
- ./backend:/srv/app
# totally the same as doc
postgres:
image: postgres
# totally the same as doc
volumes:
- ./database:/var/lib/postgresql/data
Then I pulled the latest image, and run them all, and it worked.
The folder structure now has all needed files and all functionalities are working in GUI provided in http://localhost:1337/admin/ and I could make the first content type.
\backend
\\ all_strapi_files + node_modules
\database
docker-compose.yaml
But the problem is that I can't add additional changes to files inside my editor(vscode).
I face the following error on every try for saving file changes
Failed to save 'files': Insufficient permissions. Select 'Retry as Sudo' to retry as superuser.
Also, I can not set up the yarn workspace properly, cause it doesn't have an access to remove backend/node_modules.
Git commands are not permitted either
git clean -f -- something
> failed to remove something: Permission denied
I can save every file by sudo which vscode provides, but I guess I ruined something or there is some extra thing to setup. I'm not an expert in docker and strapi, so sorry for not mentioning all content that might be needed.
This docker-compose configuration isn't good when you have changed inside a container with mount bind. Scenarios like that it's better to use docker volume.
[...]
postgres:
image: postgres
volumes:
- db-data:/var/lib/postgresql/data
volumes:
db-data:
How are you change Strapi with VSCode? My question is because most container images are configured to run with the root user, if possible when you are development to change outside the container and copy it to inside.

How to set environment variable into docker container using docker-compose

I want to set credentials to use Google Translate Api Client so I have to set environment variable GOOGLE_APPLICATION_CREDENTIALS that value is path to credential file (from Google Cloud).
When I have been used docker build and docker run it was pretty easy.
I have been used docker run
--env GOOGLE_APPLICATION_CREDENTIALS=/usr/src/app/CryptoTraderBot-901d31d199ce.json and environment variable has been set.
More difficult things come when I tried to set it in docker-compose. I have to use docker-compose because I need few containers so it is only way to achieve this.
Based on Docker compose environment variables documentation I created my docker-compose.yml file that looks like this:
version: "3"
services:
redis:
image: redis:4-alpine
crypto-bot:
build: .
depends_on:
- redis
environment:
- GOOGLE_APPLICATION_CREDENTIALS = /usr/src/app/CryptoTraderBot-901d31d199ce.json
I also have been tried multiple combination of path to .json file but none of this has been worked properly.
Have you got any idea how can I set it properly ?
While creating this question I have been resolve this problem in a funny and easy way but I have been thought that I post answer to help someone in the future with similiar problem.
All you have to do is remove " " (space) next = sign so two last lines of docker-compose.yml should looks like this:
environment:
- GOOGLE_APPLICATION_CREDENTIALS=/usr/src/app/CryptoTraderBot-901d31d199ce.json
Docker Compose has a newer feature called secrets. You can bind the credentials like this:
services:
secret-service:
build:
context: secret-service
environment:
- GOOGLE_APPLICATION_CREDENTIALS=/run/secrets/gcp-credentials
secrets:
- gcp-credentials
secrets:
gcp-credentials:
file: ./gcp-credentials.json
Reference: https://docs.docker.com/compose/compose-file/#secrets

Dockerfiles not found when running docker-compose on windows (boot2docker)

I'm hoping that I've just missed something terribly obvious, but here's the situation I'm faced with.
Problem
Running docker-compose on windows after following docker-compose install steps from the website
docker-compose.yml file works fine on unix systems (have tested on Mac)
Currently fails immediately on Windows when it cannot locate any Dockerfiles for the services defined in the yml file. Here's the error:
NOTE: The image above might be a bit confusing. The environment variable below is called GOPATH, but the folder on my colleague's computer is also called GOPATH. This gives the impression that the env var isn't set correctly, but it is indeed.
version: '3'
services:
renopost:
depends_on:
- reno-cassandra
- reno-kafka
- reno-consul
build:
context: ${GOPATH}/src/renopost
dockerfile: ${GOPATH}/src/renopost/docker/dev/Dockerfile
container_name: renopost
image: renopost
ports:
- "4000:4000"
volumes:
- ${GOPATH}/src/renopost:/go/src/renopost
Above is a snippet of the docker-compose.yml file that is being run. The GOPATH env variable is indeed set and when following the directory path listed, I can confirm the file exists in that location.
Is there some interaction here with the OracleBoxVM that boot2docker uses where it isn't actually finding that file?

Passing environment variables to application in a Docker container through docker-compose

I want to pass environment variables to the applications containerized in Docker through docker-compose. This is a VS 2017 15.3 solution Tools for Docker.
In my docker.compose.yml file I have:
app.web:
image: app.web
env_file:
- ./path.to.project/config.env
build:
context: ./path.to.project
dockerfile: Dockerfile
In config.env I have:
TEST=Compose
But when I try to read the variables using Environment.GetEnvironmentVariable("TEST"); I always get null.
If I set a non-existent file in env_file it complains when I run it, so I give for granted that is locating the file.
If I set the variable this way:
app.web:
image: app.web
environment:
- TEST=ComposeLiteral
build:
context: ./path.to.project
dockerfile: Dockerfile
I get "ComposeLiteral" when evaluating "TEST".
Which is the correct way of passing a file with environment variables to the application?
The problem is that the config.env file I was using was starting with the UTF8 BOM, making text editors to show me the same content, but causing docker compose to read something else.
When you add a text file through Visual Studio, the BOM is added.
I created an example project with the problem.
Then in the log is possible to see how the wrong parsing is happening:
config.env:
environment:
NUGET_FALLBACK_PACKAGES: /root/.nuget/fallbackpackages
"\uFEFFTEST": Compose
config2.env
environment:
NUGET_FALLBACK_PACKAGES: /root/.nuget/fallbackpackages
TEST: Compose
https://github.com/docker/compose/issues/5220
I am not able to reproduce your problem. If I start with your Dockerfile:
version: "2"
services:
app.web:
image: app.web
env_file:
- ./path.to.project/config.env
build:
context: ./path.to.project
dockerfile: Dockerfile
And in path.to.project I use the following Dockerfile:
FROM alpine
RUN apk add --update python3
COPY dumpenv.py /dumpenv.py
CMD python3 /dumpenv.py
Which runs a simple web server that does nothing but dump environment variables:
import http.server
import os
class Handler(http.server.BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header('Content-type', 'text/plain')
self.end_headers()
content = []
for k, v in os.environ.items():
content.append('{:20} {}'.format(k, v))
self.wfile.write(bytes('\n'.join(content), 'utf-8'))
return
server = http.server.HTTPServer(('0.0.0.0', 8080), Handler)
server.serve_forever()
If I docker-compose up this environment and then connect to the service, I see:
PWD /
TEST ComposeLiteral
HOSTNAME 5388e6e2717a
SHLVL 1
HOME /root
PATH ...
You can find this complete example online here. If you see different behavior using this same example, could you update your question to include a complete reproducer?

Resources