• Stars
    star
    475
  • Rank 92,465 (Top 2 %)
  • Language
    Go
  • License
    MIT License
  • Created over 7 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Go binary to change Docker container user/group and file permissions at runtime

fixuid

Build Status

fixuid is a Go binary that changes a Docker container's user/group and file permissions that were set at build time to the UID/GID that the container was started with at runtime. Primary use case is in development Docker containers when working with host mounted volumes.

fixuid was born because there is currently no way to remap host volume UIDs/GIDs from the Docker Engine, see moby issue 7198 for more details.

Check out BoxBoat's blog post for a practical explanation of how fixuid benefits development teams consisting of multiple developers.

fixuid should only be used in development Docker containers. DO NOT INCLUDE in a production container image

Overview

  • build a Dockerfile with user/group dockeruser:dockergroup that has UID/GID 1000:1000
  • host is running as UID/GID 1001:1002, host mounted volume has permissions 1001:1002
  • run the docker container with argument -u 1001:1002 so that container is now running with same UID/GID as host
  • fixuid can run as an entrypoint or in a startup script and performs the following:
    • changes dockeruser UID to 1001
    • changes dockergroup GID to 1002
    • changes all file permissions for old dockeruser:dockergroup to 1001:1002
    • updates $HOME inside container to dockeruser $HOME
  • now container UID/GID matches host UID/GID and files created in the container on the host mount will be correct

Motivation

Common Docker development workflows involve mounting source code into a container via a host volume. Build tools such as gradle, yarn, webpack, etc. download dependencies and create files in the host mount.

Many times the UID/GID of the build tools running in the Docker container do not match the UID/GID of the mounted host volume, and files generated in the container do not match files in the host volume. This can lead to problems, such as an IDE running on the host not able to modify a file that was created by the container due to a file ownership mismatch.

In large development teams, it is possible to have many developers running as different UIDs/GIDs on their host systems. With fixuid, individual developers can run the same container using the appropriate UID/GID for their host environment.

Install fixuid in Dockerfile

  1. Create a non-root user and group inside of your docker container. Use any UID/GID, 1000:1000 is a good choice.

    Note: some images already create UID/GID 1000:1000 for you, e.g. nodejs creates user/group node:node as UID/GID 1000:1000. In this case you can skip this step and use the node:node user/group.

# sample command to create user/group on different base images
# creates user "docker" with UID 1000, home directory /home/docker, and shell /bin/sh
# creates group "docker" with GID 1000

# alpine
RUN addgroup -g 1000 docker && \
    adduser -u 1000 -G docker -h /home/docker -s /bin/sh -D docker
    
# debian / ubuntu
RUN addgroup --gid 1000 docker && \
    adduser --uid 1000 --ingroup docker --home /home/docker --shell /bin/sh --disabled-password --gecos "" docker

# centos / fedora
RUN groupadd -g 1000 docker && \
    useradd -u 1000 -g docker -d /home/docker -s /bin/sh docker
  1. Install fixuid in the container, ensure that root owns the file, make it execuatble, and enable the setuid bit. Create the file /etc/fixuid/config.yml with two lines, user: <user> and group: <group> using the user and group from step 1.

    Note: this command must be run as root and requires that curl is installed in the container

RUN USER=docker && \
    GROUP=docker && \
    curl -SsL https://github.com/boxboat/fixuid/releases/download/v0.5.1/fixuid-0.5.1-linux-amd64.tar.gz | tar -C /usr/local/bin -xzf - && \
    chown root:root /usr/local/bin/fixuid && \
    chmod 4755 /usr/local/bin/fixuid && \
    mkdir -p /etc/fixuid && \
    printf "user: $USER\ngroup: $GROUP\n" > /etc/fixuid/config.yml
  1. Set the default user/group to user:group and set the entrypoint to fixuid.
USER docker:docker
ENTRYPOINT ["fixuid"]
  1. Run the container using UID/GID of your host. Replace 1000:1000 with your host's UID/GID:
docker run --rm -it -u 1000:1000 <image name> sh

Set Default Values inside of Docker Compose

Set a default UID and GID for the container to run as inside of the docker-compose.yml file. Developers who are running as a different UID/GID on their host can override the defaults using environment variables or a .env file

nginx:
  image: my-nginx
  user: ${FIXUID:-1000}:${FIXGID:-1000}
  volumes:
    - ./nginx:/etc/nginx
    - ./www:/var/www

Specify Paths and Behavior across Devices

The default behavior of fixuid is to start at the root path / and recursively scan each file and directory on the same devices as /. In the configuration file /etc/fixuid/config.yml, you can specify specify the directories that should be recursively scanned:

user: docker
group: docker
paths:
  - /home/docker
  - /tmp

fixuid will only recurse into a directory as long as it is on the same initial device specified in paths and will not recurse into directories mounted on other devices. This includes Docker volumes. If you want fixuid to run on the root Docker filesystem and a Docker volume at /home/docker/.cache, your configuration should include:

user: docker
group: docker
paths:
  - /
  - /home/docker/.cache

Run in Startup Script instead of Entrypoint

You can run fixuid as part of your container's startup script. fixuid will export HOME=/path/to/home if $HOME is the default value of /, so be sure to evaluate the output of fixuid when running as a script.

#!/bin/sh

# UID/GID map to unknown user/group, $HOME=/ (the default when no home directory is defined)

eval $( fixuid )

# UID/GID now match user/group, $HOME has been set to user's home directory

Command-Line Flags

fixuid has the following command-line flags:

Usage of ./fixuid:
  -q	quiet mode

More Repositories

1

aks-health-check

A client-side tool to perform automated checks against an AKS cluster to see if it follows best-practices.
JavaScript
73
star
2

traefik-tls

Traefik with multiple services and TLS termination
Shell
41
star
3

config-merge

Tool for merging JSON/TOML/YAML files and performing environment variable substitution
JavaScript
36
star
4

dockhand-jenkins

Upstream Jenkins Shared Library to Build, Promote, and Deploy Docker images
Groovy
36
star
5

okta-nginx

NGINX Docker image with Okta OIDC JWT Verification
Go
30
star
6

grypeadmissioncontroller

This repository hosts the admission controller build on top of grype.
Go
20
star
7

dockhand-secrets-operator

Simplify Kubernetes Secrets Management with Dockhand Secrets Operator
Go
17
star
8

dockcmd

CLI tool providing a collection of commands to facilitate DevOps and accelerate CI/CD
Go
17
star
9

custom-terraform-provider

Custom Terraform Provider implementation example for our blog post at https://boxboat.com/2020/02/04/writing-a-custom-terraform-provider/.
Go
17
star
10

dockhand-lru-registry

Docker Registry that cleans up Least Recently Used tags
Go
11
star
11

kube-ingress-lets-encrypt

Kubernetes Ingress automatic Let's Encrypt certifcates
Shell
10
star
12

kube-configmap-secret-update

Kubernetes Rolling Update on ConfigMap and Secret changes
Shell
9
star
13

auto-dockerfile

Automatically updated Docker images for common clients/utilities
Shell
8
star
14

terraform-azure-actions

GitHub Actions to deploy Terraform via pull-request workflow
5
star
15

dockhand-lite

Flexible CLI to Build, Promote, and Deploy Artifacts through CI systems
TypeScript
5
star
16

Validate-Merge

4
star
17

training-labs

Java
3
star
18

dockhand-charts

Smarty
3
star
19

intoto-spire-go-hello-world

Go
3
star
20

speedboat-terragrunt

HCL
2
star
21

bootcamp-labs

BoxBoat Boot Camp Lab Exercises
Dockerfile
2
star
22

tf-module-google

HCL
2
star
23

ado-agent-example

Self-hosted Azure DevOps Pipeline Agents in Kubernetes
Dockerfile
2
star
24

k8s-tpm-device

Go
2
star
25

vault-rancher-masterclass

Operationalizing Vault for the Normal Operator
Shell
2
star
26

bootcamp

Dockerfile
1
star
27

aks-wkshp-1

AKS Workshop Presented in January 2021
Shell
1
star
28

terraform-boxboat-aws-modules

HCL
1
star
29

jetstream-exporter

Prometheus exporter for NATS Jetstream
Go
1
star
30

iac-azure-workshop

Use Terraform to create a Windows virtual machine on Azure and then use Ansible to configure it.
Shell
1
star
31

bb-py

BoxBoat Python Cloud Library
Python
1
star