A third option on Linux (or on MacOS Intel if you install bindfs) in addition to the two in @Daniel t.'s answer is something I found in moby/moby#7198: use a host-side bind mount to rewrite the UID and GID, and then mount the target of that mount into your container.
For example:
sudo bindfs -u UID -g GID app app_chowned
docker run -d \
-it \
--name devtest \
-v "$(pwd)"/app_chowned:/app \
nginx:latest
All credit to jjrv on GitHub, the author of that comment.