Skip to content
Open
Show file tree
Hide file tree
Changes from 3 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
6 changes: 6 additions & 0 deletions .changeset/true-hands-type.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@e2b/python-sdk': patch
'e2b': patch
---

fixes default workdir and user in fromDockerfile
12 changes: 10 additions & 2 deletions packages/js-sdk/src/template/dockerfileParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ export function parseDockerfile(
const fromInstruction = fromInstructions[0]
const argumentsData = fromInstruction.getArguments()
let baseImage = 'e2bdev/base' // default fallback
let userChanged = false
let workdirChanged = false
if (argumentsData && argumentsData.length > 0) {
baseImage = argumentsData[0].getValue()
}
Expand Down Expand Up @@ -113,10 +115,12 @@ export function parseDockerfile(
break

case 'WORKDIR':
workdirChanged = true
handleWorkdirInstruction(instruction, templateBuilder)
break

case 'USER':
userChanged = true
handleUserInstruction(instruction, templateBuilder)
break

Expand Down Expand Up @@ -145,8 +149,12 @@ export function parseDockerfile(
}

// Set the user and workdir to the E2B defaults
templateBuilder.setUser('user')
templateBuilder.setWorkdir('/home/user')
if (!userChanged) {
templateBuilder.setUser('user')
}
if (!workdirChanged) {
templateBuilder.setWorkdir('/home/user')
}

return {
baseImage,
Expand Down
55 changes: 54 additions & 1 deletion packages/js-sdk/tests/template/methods/fromMethods.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { buildTemplateTest } from '../../setup'
import { Template } from '../../../src'
import { InstructionType } from '../../../src/template/types'
import path from 'node:path'
import fs from 'node:fs'
import { afterAll, beforeAll } from 'vitest'
import { afterAll, beforeAll, assert } from 'vitest'

const fileContextPath = path.join(__dirname, 'dockerfile-context')

Expand Down Expand Up @@ -93,3 +94,55 @@ RUN npm install`
const template = Template({ fileContextPath }).fromDockerfile(dockerfile)
await buildTemplate(template, { skipCache: true })
})

buildTemplateTest('fromDockerfile with default user and workdir', () => {
const dockerfile = 'FROM node:24'
const template = Template({ fileContextPath }).fromDockerfile(dockerfile)

assert.equal(
// @ts-expect-error - instructions is not a property of TemplateBuilder
template.instructions[template.instructions.length - 2].type,
InstructionType.USER
)
assert.equal(
// @ts-expect-error - instructions is not a property of TemplateBuilder
template.instructions[template.instructions.length - 2].args[0],
'user'
)
assert.equal(
// @ts-expect-error - instructions is not a property of TemplateBuilder
template.instructions[template.instructions.length - 1].type,
InstructionType.WORKDIR
)
assert.equal(
// @ts-expect-error - instructions is not a property of TemplateBuilder
template.instructions[template.instructions.length - 1].args[0],
'/home/user'
)
})

buildTemplateTest('fromDockerfile with custom user and workdir', () => {
const dockerfile = 'FROM node:24\nUSER mish\nWORKDIR /home/mish'
const template = Template({ fileContextPath }).fromDockerfile(dockerfile)

assert.equal(
// @ts-expect-error - instructions is not a property of TemplateBuilder
template.instructions[template.instructions.length - 2].type,
InstructionType.USER
)
assert.equal(
// @ts-expect-error - instructions is not a property of TemplateBuilder
template.instructions[template.instructions.length - 2].args[0],
'mish'
)
assert.equal(
// @ts-expect-error - instructions is not a property of TemplateBuilder
template.instructions[template.instructions.length - 1].type,
InstructionType.WORKDIR
)
assert.equal(
// @ts-expect-error - instructions is not a property of TemplateBuilder
template.instructions[template.instructions.length - 1].args[0],
'/home/mish'
)
})
11 changes: 9 additions & 2 deletions packages/python-sdk/e2b/template/dockerfile_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ def parse_dockerfile(
if " as " in base_image.lower():
base_image = base_image.split(" as ")[0].strip()

user_changed = False
workdir_changed = False

# Set the user and workdir to the Docker defaults
template_builder.set_user("root")
template_builder.set_workdir("/")
Expand All @@ -118,8 +121,10 @@ def parse_dockerfile(
elif instruction in ["COPY", "ADD"]:
_handle_copy_instruction(value, template_builder)
elif instruction == "WORKDIR":
workdir_changed = True
_handle_workdir_instruction(value, template_builder)
elif instruction == "USER":
user_changed = True
_handle_user_instruction(value, template_builder)
elif instruction in ["ENV", "ARG"]:
_handle_env_instruction(value, instruction, template_builder)
Expand All @@ -130,8 +135,10 @@ def parse_dockerfile(
continue

# Set the user and workdir to the E2B defaults
template_builder.set_user("user")
template_builder.set_workdir("/home/user")
if not user_changed:
template_builder.set_user("user")
if not workdir_changed:
template_builder.set_workdir("/home/user")

return base_image

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import pytest

from e2b import AsyncTemplate
from e2b.template.types import InstructionType


@pytest.fixture(scope="module")
Expand Down Expand Up @@ -111,3 +112,31 @@ async def test_from_dockerfile(async_build, setup_dockerfile_context):
file_context_path=setup_dockerfile_context
).from_dockerfile(dockerfile)
await async_build(template, skip_cache=True)


@pytest.mark.skip_debug()
async def test_from_dockerfile_with_default_user_and_workdir(setup_dockerfile_context):
dockerfile = "FROM node:24"

template = AsyncTemplate(
file_context_path=setup_dockerfile_context
).from_dockerfile(dockerfile)

assert template._template._instructions[-2]["type"] == InstructionType.USER
assert template._template._instructions[-2]["args"][0] == "user"
assert template._template._instructions[-1]["type"] == InstructionType.WORKDIR
assert template._template._instructions[-1]["args"][0] == "/home/user"


@pytest.mark.skip_debug()
async def test_from_dockerfile_with_custom_user_and_workdir(setup_dockerfile_context):
dockerfile = "FROM node:24\nUSER mish\nWORKDIR /home/mish"

template = AsyncTemplate(
file_context_path=setup_dockerfile_context
).from_dockerfile(dockerfile)

assert template._template._instructions[-2]["type"] == InstructionType.USER
assert template._template._instructions[-2]["args"][0] == "mish"
assert template._template._instructions[-1]["type"] == InstructionType.WORKDIR
assert template._template._instructions[-1]["args"][0] == "/home/mish"
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import pytest

from e2b import Template
from e2b.template.types import InstructionType


@pytest.fixture(scope="module")
Expand Down Expand Up @@ -112,3 +113,31 @@ def test_from_dockerfile(build, setup_dockerfile_context):
dockerfile
)
build(template, skip_cache=True)


@pytest.mark.skip_debug()
def test_from_dockerfile_with_default_user_and_workdir(setup_dockerfile_context):
dockerfile = "FROM node:24"

template = Template(file_context_path=setup_dockerfile_context).from_dockerfile(
dockerfile
)

assert template._template._instructions[-2]["type"] == InstructionType.USER
assert template._template._instructions[-2]["args"][0] == "user"
assert template._template._instructions[-1]["type"] == InstructionType.WORKDIR
assert template._template._instructions[-1]["args"][0] == "/home/user"


@pytest.mark.skip_debug()
def test_from_dockerfile_with_custom_user_and_workdir(setup_dockerfile_context):
dockerfile = "FROM node:24\nUSER mish\nWORKDIR /home/mish"

template = Template(file_context_path=setup_dockerfile_context).from_dockerfile(
dockerfile
)

assert template._template._instructions[-2]["type"] == InstructionType.USER
assert template._template._instructions[-2]["args"][0] == "mish"
assert template._template._instructions[-1]["type"] == InstructionType.WORKDIR
assert template._template._instructions[-1]["args"][0] == "/home/mish"
Loading