

Update the web service within the file to build with Dockerfile.prod: If you're root in the container, you'll be root on the host. This is a bad practice since attackers can gain root access to the Docker host if they manage to break out of the container. Think of the pros and cons of using this approach over two different files.ĭid you notice that we created a non-root user? By default, Docker runs container processes as root inside of a container. You could take the multi-stage build approach a step further and use a single Dockerfile instead of creating two Dockerfiles. The wheels are then copied over to the final production image and the builder image is discarded. Essentially, builder is a temporary image that's used for building the Python wheels. Here, we used a Docker multi-stage build to reduce the final image size. $APP_HOME # chown all the files to the app user RUN chown -R app:app $APP_HOME # change to the app user USER app # run ENTRYPOINT
Postgres copy install#
RUN mkdir $APP_HOME WORKDIR $APP_HOME # install dependencies RUN apt-get update & apt-get install -y -no-install-recommends netcatĬOPY -from =builder /usr/src/app/wheels /wheelsĬOPY -from =builder /usr/src/app/requirements.txt. # create the appropriate directories ENV HOME =/home/app # create the app user RUN addgroup -system app & adduser -system -group app # FINAL # pull official base image FROM python:3.11.4-slim-buster # create directory for the app user RUN mkdir -p /home/app RUN pip wheel -no-cache-dir -no-deps -wheel-dir /usr/src/app/wheels -r requirements.txt # BUILDER # pull official base image FROM python:3.11.4-slim-buster as builder # set work directory WORKDIR /usr/src/app # set environment variables ENV PYTHONDONTWRITEBYTECODE 1 ENV PYTHONUNBUFFERED 1 # install system dependencies RUN apt-get update & \Īpt-get install -y -no-install-recommends gcc You can check that the volume was created as well by running: Public | django_session | table | hello_django Public | django_migrations | table | hello_django Public | django_content_type | table | hello_django Public | django_admin_log | table | hello_django

Public | auth_user_user_permissions | table | hello_django

Public | auth_user_groups | table | hello_django Public | auth_user | table | hello_django Public | auth_permission | table | hello_django Public | auth_group_permissions | table | hello_django Public | auth_group | table | hello_django You are now connected to database "hello_django_dev" as user "hello_django". ( 4 rows ) hello_django_dev = # \c hello_django_dev Template1 | hello_django | UTF8 | en_US.utf8 | en_US.utf8 | =c/hello_django + Template0 | hello_django | UTF8 | en_US.utf8 | en_US.utf8 | =c/hello_django + Postgres | hello_django | UTF8 | en_US.utf8 | en_US.utf8 | Hello_django_dev | hello_django | UTF8 | en_US.utf8 | en_US.utf8 | Name | Owner | Encoding | Collate | Ctype | Access privileges $ docker-compose exec db psql -username =hello_django -dbname =hello_django_dev Next, add a docker-compose.yml file to the project root: Review Docker Best Practices for Python Developers for more on structuring Dockerfiles as well as some best practices for configuring Docker for Python-based development.

We then set a working directory along with two environment variables: So, we started with a slim-buster-based Docker image for Python 3.11.4. # pull official base image FROM python:3.11.4-slim-buster # set work directory WORKDIR /usr/src/app # set environment variables ENV PYTHONDONTWRITEBYTECODE 1 ENV PYTHONUNBUFFERED 1 # install dependencies RUN pip install -upgrade pip
