Container image requirements
Understand the image rules required for safe managed container hosting on alawadi.cloud.
Runtime requirements
Your app runs as a managed container on Kubernetes, not as a VPS. The platform enforces restricted Pod Security, so your image has to follow a few rules. The good news: you do not configure these by hand. When you set up deployment, the portal generates a production-ready Dockerfile and a GitHub Actions workflow for your stack that already satisfy every rule below.
- Listen on port 8080. The platform always routes to
8080. Bind to0.0.0.0and read thePORTenvironment variable (it is set to8080). There is no port field when you create a container. The port is fixed. - Run as a non-root user. Restricted Pod Security rejects root containers.
Add a non-root user in your Dockerfile and
USERit, and write temporary files to/tmp. - Pin an immutable tag or digest.
:latestand untagged images are rejected with400 BAD_IMAGEand nothing is rolled out. Deploys use the commit SHA (...:${{ github.sha }}) or a@sha256:...digest so every rollout is reproducible and auditable. - Push to your registry on alawadi.cloud. Deployed images must come from
registry.alawadi.cloud/.... Arbitrary public images (for examplenginx:1.27from Docker Hub) are not accepted as a deploy target; the deploy is rejected with400 BAD_IMAGE. - Stay unprivileged. Do not require privileged mode, host networking,
hostPath, or Docker socket access. The platform enforces this at admission and re-checks it independently across every workload; see Security and isolation. - Expose a health endpoint so the platform can probe your app. The exact
path depends on your stack (for example
/healthzfor Node, Go, FastAPI, and Rust;/api/healthfor Next.js;/upfor Laravel;/actuator/healthfor Spring).
You do not write these from scratch
In the portal, open your registry under Dashboard → Registries. The CI workflow templates card lets you pick your runtime (Node/Express, Next.js, Python FastAPI/Django, Go, PHP Laravel, Java Spring, Rust, or static Vite) and gives you, with copy buttons:
- a Supporting Dockerfile for that stack, already non-root, already
EXPOSE 8080, with the base image pinned to a major version (no floatinglatest); and - a
.github/workflows/deploy.ymlthat builds, pushes over OIDC, and deploys, pre-filled with your registry address, audience, container ID, and deploy audience.
Use the generated files. The Dockerfile below is shown only so you know what a compliant image looks like; the portal produces an equivalent (multi-stage, production-grade) file for your chosen stack.
# syntax=docker/dockerfile:1
FROM node:22-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json* ./
RUN npm ci --omit=dev
FROM node:22-alpine AS runner
ENV NODE_ENV=production PORT=8080
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
# node:alpine ships a non-root "node" user.
USER node
EXPOSE 8080
# Bind 0.0.0.0 and read PORT:
# app.listen(process.env.PORT || 8080, "0.0.0.0")
CMD ["node", "server.js"]Where the image comes from
You build the image in GitHub Actions and push it to your registry on alawadi.cloud. No static registry password is ever used; login is OIDC-only. See Deploy with GitHub Actions for the full build → push → deploy flow.
Deploy your first app
Get a container live on a public HTTPS URL in five steps. The portal generates the deploy workflow for you, so there is nothing to upload and no passwords to paste.
App runtime model
How alawadi.cloud runs your container apps in isolated, fully managed environments, with no servers, SSH, or kubectl to manage.