This content originally appeared on DEV Community and was authored by Darshan Vasani
Why Secure User Management in Docker Matters?
By default, Docker containers run processes as root, which is:
- A huge security risk
- Can lead to host exploitation
- Bad for CI/CD and prod environments
NEVER ship containers that run as root in production!
Real-World Analogy
Giving root access is like giving a guest
the master key to your house, including bank vaults, server room, and more.
Instead, give them only what they need β just one room!
How to Add a Secure User in Docker
Example (Linux-based):
# Create a group & user with no login shell
RUN addgroup --system --gid 1001 appgroup \
&& adduser --system --uid 1001 --ingroup appgroup --disabled-password appuser
# Switch to non-root user
USER appuser
![]() |
Purpose |
---|---|
--system |
Marks as a system-level user/group |
--disabled-password |
Prevents password login |
USER appuser |
Runs all next steps as a non-root user |
Typical Secure Dockerfile Flow
FROM node:20-alpine
WORKDIR /app
# Copy and build with root privileges
COPY . .
RUN npm install && npm run build
# 🔒 Create a secure user
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
# ✅ Drop privileges
USER appuser
CMD ["node", "dist/index.js"]
Best Practices for Secure User Management
![]() |
![]() |
---|---|
![]() |
Reduces attack surface |
![]() USER instruction |
Ensures all commands run as non-root |
![]() chown ) |
Ensure new user can access copied files |
![]() docker scan or trivy
|
Catch misconfigurations |
![]() |
Less packages = fewer CVEs |
![]() .dockerignore
|
Prevent leaking .env , keys , .git
|
Preventing Permission Issues with Files
COPY --chown=appuser:appgroup . .
# OR fix it manually
RUN chown -R appuser:appgroup /app
Ensures the
appuser
has access to source files
Otherwise you might get
EACCES
or permission denied errors.
Dockerfile Security Summary Table
Feature | Good Practice | Why? |
---|---|---|
USER |
Use non-root user | ![]() |
COPY |
Use --chown flag |
![]() |
RUN |
Avoid sudo , limit shell access |
![]() |
ENTRYPOINT /CMD
|
Should not run as root | ![]() |
Check Current User in Container
You can debug by checking UID:
docker run -it your-image whoami
docker run -it your-image id
Bonus Tip: Use Docker Compose Securely
services:
api:
image: dpvasani56/secure-api
user: "1001:1001"
You can enforce user ID even if Dockerfile doesnβt specify it.
Final Checklist for Secure User Management
![]() |
Status |
---|---|
Create system user & group | ![]() |
Assign proper UID:GID | ![]() |
Switch user with USER
|
![]() |
Set file ownership (--chown ) |
![]() |
Remove unnecessary packages | ![]() |
Test permissions inside container | ![]() |
This content originally appeared on DEV Community and was authored by Darshan Vasani