How to checkout branches if there are files create

2019-08-20 03:25发布

问题:

In my pet project I set up docker-compose for development. The issue is that I've create django migration inside dockerimage and created commit. After checkout to main branch I see an error. These files become untracked and I cannot merge sub branch into the main.

git checkout master

warning: unable to unlink 'apps/app_name/migrations/0001_initial.py': Permission denied
warning: unable to unlink 'apps/app_name/migrations/0002_auto_20190127_1815.py': Permission denied
warning: unable to unlink 'apps/app_name/migrations/__init__.py': Permission denied
Switched to branch 'master'

Also I tried to it with sudo. All new files will appear untracked in main branch but no new commits will be added(based on git log)

docker-compose.yml

version: '3'

services:
  db:
    image: postgres
  web:
    build:
      dockerfile: ./compose/Dockerfile.dev
      context: .
    command: /start
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    depends_on:
      - db
    links:
      - db:db

Dockerfile

FROM python:3.6.8-alpine

ENV PYTHONUNBUFFERED 1

RUN apk update \
  # psycopg2 dependencies
  && apk add --virtual build-deps gcc python3-dev musl-dev \
  && apk add postgresql-dev \
  # Pillow dependencies
  && apk add jpeg-dev zlib-dev freetype-dev lcms2-dev openjpeg-dev tiff-dev tk-dev tcl-dev \
  # CFFI dependencies
  && apk add libffi-dev py-cffi \
  # Translations dependencies
  && apk add gettext \
  # https://docs.djangoproject.com/en/dev/ref/django-admin/#dbshell
  && apk add postgresql-client

RUN mkdir /code

WORKDIR /code

COPY /requirements /code/requirements/

RUN pip install -r requirements/dev.txt

COPY . /code/

COPY ./compose/start /start
RUN sed -i 's/\r//' /start
RUN chmod +x /start

start.sh

#!/bin/sh

set -o errexit
set -o pipefail
set -o nounset


python manage.py migrate
python manage.py runserver_plus 0.0.0.0:8000

回答1:

Dockerfile

FROM python:3.6.8-alpine

ENV PYTHONUNBUFFERED 1

ARG CONTAINER_USER="python"
ARG CONTAINER_UID="1000"
ARG CONTAINER_GID="1000"
ARG WORKSPACE=/home/"${CONTAINER_USER}"/code

RUN apk update \
  # psycopg2 dependencies
  && apk add --virtual build-deps gcc python3-dev musl-dev \
  && apk add postgresql-dev \
  # Pillow dependencies
  && apk add jpeg-dev zlib-dev freetype-dev lcms2-dev openjpeg-dev tiff-dev tk-dev tcl-dev \
  # CFFI dependencies
  && apk add libffi-dev py-cffi \
  # Translations dependencies
  && apk add gettext \
  # https://docs.djangoproject.com/en/dev/ref/django-admin/#dbshell
  && apk add postgresql-client && \

  addgroup -g "${CONTAINER_GID}" -S "${CONTAINER_USER}" && \
  adduser -s /bin/ash -u "${CONTAINER_UID}" -G  "${CONTAINER_USER}" -h /home/"${CONTAINER_USER}" -D "${CONTAINER_USER}"

USER "${CONTAINER_USER}"

WORKDIR "${WORKSPACE}"

COPY  ./requirements/dev.txt "${WORKSPACE}"/requirements.txt

RUN pip install -r requirements.txt

Is bad practice to run whatsoever in a docker container as the root user, just like you wouldn't do it in your computer. I added a user python that will have the same uid of your computer, assuming your operating system user as the uid 1000 as it is normal in Linux machines. If you are in another OS than this may not work and you will need to find the solution for your specific OS.

docker-compose.yml

version: '3'

services:
  db:
    image: postgres
  web:
    build:
      dockerfile: ./compose/Dockerfile.dev
      context: .
      args:
        CONTAINER_UID: ${UID:-1000}
        CONTAINER_GID: ${GID:-1000}
    command: ./compose/start
    volumes:
      - .:/home/python/code
    ports:
      - "8000:8000"
    depends_on:
      - db

links is deprecated and was replaced by depends_on, thus not necessary to use both.

In order to build the container with the same permissions of your filesystem for your user I have added args to de dockerfile build section and I use the OS values for $UID and $GID, but if they are not set will default to 1000.

You can see what are the ones in your Linux OS with id -u for $UID and id -g for the $GID.

Shell Script

Make it executable in your repo and commit the change so that you don't need to do it each time you build the docker image.

chmod 700 ./compose/start

I don't use +x because that is a bad practice in terms of security, once you will allow everyone to execute the script.

Summary

Any files created now inside of the container will have the uid and gid of 1000, thus no more conflict should occur with permissions.