Other stacks
Last updated
If your stack isn't Python, Node.js or prebuilt .NET, the zip flow won't detect it — you need a Dockerfile. That's a small piece of work, and it gives you full control.
Once you have one, Git Push is the natural deploy path.
A Dockerfile that works here
Whatever the language, the same handful of rules apply:
FROM <runtime>:<version>-slim
WORKDIR /app
# dependencies first, so a code change reuses this layer
COPY <manifest> .
RUN <install dependencies>
COPY . .
# production server, binding all interfaces
CMD ["<your-command>"]
The constraints that matter:
- Named
Dockerfile, at the root of what you push. Not in a subfolder. - No build arguments are available. Every
ARGneeds a default, and nothing can depend on build-time environment variables. - Bind
0.0.0.0, not localhost. - One process. No supervisord, no process manager — the platform restarts your process when it exits.
- Log to stdout, unbuffered. Not to a file inside the container.
- Exit non-zero on unrecoverable errors, so failures are visible as exit codes.
- Keep the build modest — the builder has less memory than your app does.
Language notes
Go, Rust — multi-stage build into a minimal runtime image. Both produce small containers and suit the platform well. See Go.
Java, Kotlin — build with a JDK image, run with a JRE image. Set -XX:MaxRAMPercentage explicitly and leave headroom for non-heap memory, or the process gets killed. Gradle and Maven builds often exceed the builder's memory — use --no-daemon, or build in CI.
PHP — the traditional nginx + PHP-FPM pair is two processes, which fights the one-process model. FrankenPHP collapses both into a single binary and fits naturally; disable its automatic HTTPS since TLS terminates at the edge.
Ruby, Elixir, and others — ordinary release-based deployments. Watch for two things: frameworks that expect a web server in front (you have none, so your app serves its own static files), and anything that wants to cluster across nodes, which isn't available.
Getting a first draft
Ask your AI coding tool for the Dockerfile and give it the constraints above — the numbered list is the whole specification. Then check the result against them, because the common generated mistakes are exactly the ones that list covers: a dev-server command, an unset ARG, EXPOSE mistaken for a port binding, and a localhost bind.