From the team behind aidrop.it — one workspace to build, host, and keep changing your code.
You committed a Dockerfile, pushed it, and the next deploy still picked the wrong Node version. The log mentions a buildpack. None of the commands in your file ran. The file is valid and in the repository; the host never chose it as the build instruction.
A repository can contain several ways to build, so the deploy must name one. The build mode answers whether a buildpack should infer an image or whether your Dockerfile is the authority. The Dockerfile path answers which file to read. Committing the file answers neither question.
A Dockerfile is input, not automatic intent
A host cannot treat every file named Dockerfile as an instruction. A monorepo may carry one for the API, another for a worker, and a third for local development. The repository root may also contain an old file while production uses build/Dockerfile.api.
Inference tools solve a different problem. They inspect manifests, choose a language, and generate their own Dockerfile. That path is useful when the repository has no container definition. If inference remains the recorded build mode, the builder has no reason to open the file you added.
This distinction explains a common bad fix: editing the committed Dockerfile again after a buildpack failure. The next build repeats the same inference, ignores the same file, and fails for the same reason. Read the recorded build mode before changing code, the same way you should read the runtime before choosing a stack.
The file path and the build context are separate
A Dockerfile under apps/api/Dockerfile does not make apps/api the build context. Many builders still hand the repository root to Docker, then point -f at the nested file. Its COPY paths must therefore be written from the repository root:
# apps/api/Dockerfile
COPY apps/api/package.json apps/api/package-lock.json ./
RUN npm ci
COPY apps/api/ ./
Writing COPY package.json ./ would look beside the build context root, not beside the Dockerfile. Moving the file changes its location, but it does not change the coordinate system of the files it copies.
That is why a deploy record needs both values: build_type: dockerfile and build_dockerfile_path: apps/api/Dockerfile. One chooses the mechanism; the other names its input. A repository that backs two services can then build each service from its own file without splitting the code.
Inference also chooses versions
A buildpack has to choose a runtime version when the repository does not declare one. Its default may be older than your laptop, newer than your lockfile expects, or different from the version your last host used. The resulting error looks like a dependency problem even though the missing input is a version.
Declare the version in the language's own file, such as engines.node, .nvmrc, .python-version, or the go directive in go.mod. Use a Dockerfile when you need the operating system packages, build stages, or exact base image under your control. Then name that Dockerfile in the deploy settings. A file nobody selects is documentation, not execution.
Keep the build contract beside the code
Save this as DEPLOY-BUILD.md. Fill it from the host's recorded settings rather than from the files you expect it to use. The two commands catch the most common path and context mistake before a remote build spends time on it.
# Build contract
Mode: buildpack | dockerfile
Dockerfile path: ____________________ # required for dockerfile mode
Build context: repository root | ____________________
Runtime version from: ____________________ # engines.node, .nvmrc, etc.
Service directory: ____________________
Start command: ____________________
Port / health path: ____________________ / ____________________
Last verified commit: ____________________
# Does every source of COPY exist from the repository root?
docker build -f apps/api/Dockerfile .
# Which version declarations will an inference tool find?
find . -maxdepth 3 -type f \( -name package.json -o -name .nvmrc -o -name .python-version -o -name go.mod \) -print
FAQ
Why is my host ignoring my Dockerfile? Check whether the recorded build mode is a buildpack or another inference tool. A committed Dockerfile does not switch that setting by itself. Select Dockerfile mode and name the file's path, then check whether the builder uses the repository root as its context.
Should every application have a Dockerfile? No. A buildpack is a sound default for a conventional application that declares its runtime version. Use a Dockerfile when you need exact system packages, multiple build stages, a nonstandard start path, or a base image you control.
How does aidrop.it choose between nixpacks and my Dockerfile? On aidrop.it, service_build defaults to build_type: nixpacks, which writes its own Dockerfile. To use yours, pass build_type: dockerfile and build_dockerfile_path with the file name relative to the repository root. The build context stays at that root even when the file lives deeper in a monorepo.
Does moving a Dockerfile change the build context? No, unless the build command also changes the context. The -f path chooses the Dockerfile while the final path in docker build -f path/to/Dockerfile . chooses the context. If the context is ., every COPY source is resolved from the repository root.
Get it running from the session you are already in
Connect your coding agent over MCP and ask it to deploy. aidrop builds the repository and runs it on a public address; when a build or the app fails, the log says why, and your agent fixes it and builds again.