Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions lib/compose.ts
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,18 @@ function normalizeService(
// Delete env_file, as compose-go adds env_file vars to service.environment
delete service.env_file;

// Coerce null/undefined env var values to empty string.
// `KEY: null` is valid in the Compose spec, but the API
// rejects null values for env vars, so we coerce to '' to match
// @balena/compose parser behavior prior to integrating compose-parser.
if (service.environment) {
for (const [key, value] of Object.entries(service.environment)) {
if (value == null) {
service.environment[key] = '';
}
}
}

// Delete label_file, as compose-go adds label_file labels to service.labels
delete service.label_file;

Expand Down
28 changes: 28 additions & 0 deletions test/compose.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,34 @@ describe('compose-go parsing & validation', () => {
});
});

it('should coerce null/undefined environment values to empty string', async () => {
const composition = await parse(
'test/fixtures/compose/services/null_env.yml',
);
expect(composition).to.deep.equal({
services: {
main: {
image: 'alpine:latest',
command: ['sh', '-c', 'sleep infinity'],
environment: {
EXPLICIT_VALUE: 'hello',
EXPLICIT_EMPTY: '',
NULL_DICT_FORM: '',
IMPLICIT_NULL_DICT_FORM: '',
},
networks: {
default: null,
},
},
},
networks: {
default: {
ipam: {},
},
},
});
});

it('should merge services from extends config', async () => {
const composition = await parse(
'test/fixtures/compose/services/extends.yml',
Expand Down
9 changes: 9 additions & 0 deletions test/fixtures/compose/services/null_env.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
services:
main:
image: alpine:latest
command: sh -c "sleep infinity"
environment:
EXPLICIT_VALUE: hello
EXPLICIT_EMPTY: ""
NULL_DICT_FORM: null
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should add an UNDEFINED_FORM: which is also accepted by compose. Weirdly docker-compose removes explicit fields defined with null but I saw that is not the same behavior of compose-go

IMPLICIT_NULL_DICT_FORM:
Loading