On this page

Container Runtime

When Guara Cloud deploys your service, the container runs inside a secure, hardened environment. This page describes how the runtime works and what you need to know when writing your Dockerfile.

Non-root execution

All containers run as a non-root user with UID 1000 and GID 1000. This is enforced by the platform and cannot be changed.

This means:

  • Your application process will always run as user 1000, regardless of any USER directive in your Dockerfile.
  • Files inside your image must be readable by all users (permissions 644 for files, 755 for directories) — this is the default for most Docker images.
  • The platform drops every Linux capability except NET_BIND_SERVICE, so UID 1000 can bind a configured low port. Port 8080 remains the recommended default for image portability.

Dockerfile best practices

When writing a Dockerfile for Guara Cloud, keep these guidelines in mind:

# Use a non-root user in your image for consistency
FROM node:20-alpine

# Create a non-root user (optional but recommended)
RUN addgroup -g 1000 appgroup && adduser -u 1000 -G appgroup -D appuser

WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .

# Ensure files are world-readable (default for COPY)
# Avoid restrictive permissions like chmod 700

# Use an unprivileged port
EXPOSE 8080

# Set the user (Guara Cloud will override to UID 1000 regardless)
USER appuser

CMD ["node", "server.js"]

Filesystem

For your applications, the container root filesystem is writable — but every write happens as the non-root user (UID 1000). You can only write where UID 1000 has permission, so paths owned by root (such as the directories the stock nginx image ships) are off-limits even though the filesystem is not globally read-only.

Platform-managed catalog services (databases, caches, brokers) run with a stricter, fully read-only root filesystem. That hardening does not apply to your own app containers.

Writable paths

To make common workloads (nginx caches, PID files, logs, temp data) work out of the box, Guara Cloud mounts the following group-writable ephemeral volumes — writable by UID 1000 regardless of the base image’s ownership:

PathPurposeSize limit (all profiles)
/tmpTemporary files, caches, session data256 MiB
/var/runPID files, Unix sockets64 MiB
/var/cacheApplication caches (nginx, package, etc.)256 MiB
/var/logApplication log files128 MiB

Common scenarios

If your application tries to write to a root-owned path outside these mounts, you will see a Permission denied error. Here are common solutions:

Framework/ToolDefault write pathSolution
Next.js.next/cacheSet NEXT_CACHE_DIR=/tmp/next-cache environment variable
nginx/var/cache/nginxAlready writable via /var/cache
PHP/tmp for sessionsAlready writable
Python/pip~/.cache/pipSet PIP_CACHE_DIR=/tmp/pip-cache
Node.js/npm~/.npmSet npm_config_cache=/tmp/npm-cache
GeneralApplication-specificRedirect writes to /tmp via environment variables or flags

Security restrictions

Guara Cloud enforces a strict security policy on all containers:

RestrictionDescription
No privilege escalationContainers cannot gain additional privileges at runtime
Capabilities minimizedAll capabilities are dropped except NET_BIND_SERVICE; no mount or network-admin access
Seccomp profile enforcedOnly safe system calls are allowed (RuntimeDefault profile)
No root executionThe container process always runs as UID 1000
Non-root writes onlyRoot FS is writable, but only as UID 1000 — root-owned paths are read-only
No service account tokenContainers have no access to Kubernetes API credentials

These restrictions follow the Kubernetes Pod Security Standards (PSS) restricted profile, the highest level of container security available.

Port configuration

Your application must listen on the port configured in the service settings (default: 8080). Guara Cloud injects the PORT environment variable with the configured value.

// Example: read the PORT environment variable
const port = process.env.PORT || 8080;
app.listen(port);

Summary

PropertyValue
Runtime userUID 1000 / GID 1000
Root filesystemWritable, but only as UID 1000 (read-only for catalog services)
Writable paths/tmp, /var/run, /var/cache, /var/log (group-writable mounts)
Privilege escalationDisabled
Linux capabilitiesAll dropped except NET_BIND_SERVICE
Seccomp profileRuntimeDefault
Default port8080 (configurable)