Guides

Your own Dockerfile — Go, Rust, Java and anything else

For languages Meghly does not build by itself (Go, Rust, Java, Elixir …), or when you need a build of your own, run the app with your own Dockerfile.

For ASP.NET Core, Node.js, Python, PHP and static sites Meghly makes the build itself — no Dockerfile needed. For anything else (Go, Rust, Java/Spring, Elixir, Deno, Bun …), bring your own Dockerfile.

Telling the app to use the Dockerfile

A Dockerfile in the repository is not used by itself — the app's kind has to say so:

  1. Apps → New app → a Git repository or a zip.
  2. In What is it? choose Dockerfile.
  3. If the Dockerfile is not at the repository's root (and there is more than one), under Advanced:
    • Dockerfile path — from the repository's root, such as src/Shop.Api/Dockerfile.
    • Build context — the folder the build sees; empty means the repository's root.

To change them later, the app's General page has the same two fields.

Unless the kind is Dockerfile, Meghly tries to recognise the app its own way. When it recognises nothing but finds a Dockerfile, Detect tells you: set the app's kind to Dockerfile.

The rules

RuleWhy, and what to do
PortTaken from the final stage's EXPOSE. With no EXPOSE, or a port below 1024, the app must listen on PORT (8080).
Not rootThe app always runs as an ordinary (non-root) user, so it cannot listen on 80 or 443.
Read-onlyWhile running, it can write only to /tmp and the app's volumes.
Build context.git, node_modules, bin, obj and .env files never reach the build — install dependencies inside the Dockerfile and set secrets on the app. Your .dockerignore is honoured too.
TimeA build may take up to 15 minutes.

Health checks, release commands, workers, cron, volumes, domains and databases all work as for any other app.

Example: Go

Dockerfile
FROM golang:1.25-alpine AS build
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o /out/app ./cmd/server

FROM gcr.io/distroless/static-debian12:nonroot
COPY --from=build /out/app /app
EXPOSE 8080
ENTRYPOINT ["/app"]
main.go
port := os.Getenv("PORT")
if port == "" {
    port = "8080"
}
http.ListenAndServe(":"+port, mux)

Example: Java (Spring Boot)

Dockerfile
FROM eclipse-temurin:21-jdk AS build
WORKDIR /src
COPY . .
RUN ./mvnw -q -DskipTests package

FROM eclipse-temurin:21-jre
COPY --from=build /src/target/*.jar /app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app.jar"]

To make Spring Boot read PORT:

src/main/resources/application.properties
server.port=${PORT:8080}

Example: Rust

Dockerfile
FROM rust:1-slim AS build
WORKDIR /src
COPY . .
RUN cargo build --release

FROM debian:bookworm-slim
COPY --from=build /src/target/release/server /usr/local/bin/server
EXPOSE 8080
CMD ["server"]

Databases and variables

A linked database brings the same variables to a Dockerfile app: DATABASE_URL, DB_HOST, DB_PORT … (Databases). Read them at run time, not during the build.

When something goes wrong

What you seeCause and fix
Detect: "set the App's runtime to Dockerfile"Set the kind to Dockerfile in What is it? / General.
Detect: "EXPOSEs port 80, which only root may open"Make the app listen on PORT (8080) and EXPOSE 8080.
COPY failed: … not foundCheck the Build context, and that the file is not under .git / node_modules or an .env.
read-only file systemWrite to /tmp or a volume.

Stuck?

Talk to our engineers directly — by phone or email.

01782618248shohag.meghly@gmail.com