How to Add Users to a Docker Container

Master Docker user management by learning how to create users, assign permissions, and implement security best practices in containers.

How to Add Users to a Docker Container

By default, Docker containers run as root. That’s fine for quick tests but bad for production. This guide shows you how to add users properly.

Three ways to handle this:

  1. Dockerfile - Create users at build time (recommended)
  2. Runtime - Add users to running containers (temporary)
  3. User mapping - Match host and container users (for permissions)

Let’s go through each one.

Why Bother?

Running as root in containers is risky:

  • Security: If the app gets compromised, the attacker has root
  • Permissions: Writing files as root messes up host permissions
  • Best practice: Least privilege principle applies here too

Bottom line: Production containers should not run as root.

Method 1: Create Users in Dockerfile

Best practice is to set up users when building the image.

Basic User Creation

FROM ubuntu:20.04

# Create a non-root user
RUN useradd -m -s /bin/bash appuser

# Switch to the new user
USER appuser

# Set working directory
WORKDIR /home/appuser

Advanced User Setup

FROM ubuntu:20.04

# Update package list
RUN apt-get update && apt-get install -y sudo

# Create user with specific UID/GID
RUN groupadd -r appgroup --gid=1001 && \
    useradd -r -g appgroup --uid=1001 --shell=/bin/bash --create-home appuser

# Add user to sudo group (if needed)
RUN usermod -aG sudo appuser

# Set password (for development only)
RUN echo 'appuser:password' | chpasswd

# Switch to non-root user
USER appuser

WORKDIR /home/appuser

Key Commands Explained

CommandPurposeExample
useradd -mCreate user with home directoryuseradd -m john
groupaddCreate user groupgroupadd developers
usermod -aGAdd user to groupusermod -aG sudo john
USERSet default user for containerUSER appuser

Some other docker articles that can help you in your docker journey:

Method 2: Add Users at Runtime

Sometimes you need to create users in an already running container. Not recommended for production, but useful for debugging.

Create User in Running Container

# Enter the container
docker exec -it container_name bash

# Create user inside container
useradd -m -s /bin/bash newuser

# Set password
passwd newuser

# Add to sudo group (if needed)
usermod -aG sudo newuser

# Switch to new user
su - newuser

Using Docker Exec with Specific User

# Run commands as specific user
docker exec -it --user newuser container_name bash

# Or run single commands
docker exec --user newuser container_name whoami

Method 3: Map Host Users to Container

When you mount volumes, file ownership can get messy. This method keeps host and container permissions in sync.

User ID/Group ID Mapping

FROM ubuntu:20.04

# Create user with specific UID/GID that matches host user
ARG USER_ID=1000
ARG GROUP_ID=1000

RUN groupadd -g $GROUP_ID appgroup && \
    useradd -u $USER_ID -g $GROUP_ID -m -s /bin/bash appuser

USER appuser

Build with host user IDs:

docker build --build-arg USER_ID=$(id -u) --build-arg GROUP_ID=$(id -g) -t myapp .

Docker Compose User Mapping

version: '3.8'
services:
  app:
    build: .
    user: "${UID}:${GID}"
    volumes:
      - .:/app
    environment:
      - USER_ID=${UID}
      - GROUP_ID=${GID}

Run with:

UID=$(id -u) GID=$(id -g) docker-compose up

Best Practices

1. Never Run as Root in Production

# Good
FROM ubuntu:20.04
RUN useradd -m appuser
USER appuser

# Bad - root by default
FROM ubuntu:20.04

2. Use Specific UID/GID

Avoid permission headaches with mounted volumes:

RUN groupadd -g 1001 appgroup && \
    useradd -u 1001 -g appgroup -m appuser
USER appuser

3. Use Multi-Stage Builds

Build as root, run as user:

# Build stage
FROM ubuntu:20.04 as builder
RUN apt-get update && apt-get install -y build-essential
COPY . /src
WORKDIR /src
RUN make build

# Runtime stage
FROM ubuntu:20.04
RUN useradd -m appuser
USER appuser
COPY --from=builder /src/app /home/appuser/app

4. Set File Ownership

Use COPY --chown to avoid permission issues:

COPY --chown=appuser:appuser app/ /home/appuser/app/
USER appuser

Quick Checklist

✅ Do❌ Don’t
Create dedicated usersRun as root in production
Set specific UID/GIDUse random UIDs
Set proper ownershipUse 777 permissions
Test before deployingAssume it just works

Quick Reference

Common User Creation Commands

# Create user with home directory
useradd -m -s /bin/bash username

# Create user with specific UID/GID
useradd -u 1001 -g 1001 -m username

# Add user to group
usermod -aG groupname username

# Change file ownership
chown -R username:groupname /path/to/files

Dockerfile User Examples

# Simple non-root user
FROM ubuntu:20.04
RUN useradd -m appuser
USER appuser

# User with sudo access
FROM ubuntu:20.04
RUN apt-get update && apt-get install -y sudo
RUN useradd -m -s /bin/bash appuser
RUN usermod -aG sudo appuser
USER appuser

# User with specific UID/GID
FROM ubuntu:20.04
RUN groupadd -g 1001 appgroup && \
    useradd -u 1001 -g appgroup -m appuser
USER appuser

TL;DR

  1. Always create non-root users for production containers
  2. Use specific UID/GID to avoid permission issues with volumes
  3. Set file ownership with COPY --chown
  4. Test before deploying - run whoami and check permissions

Start simple. Create a non-root user in your Dockerfile. Worry about namespaces and advanced security later.