
Copying and installing application source code and dependencies
The final step is to copy the application source code and dependencies that were previously built in the test stage, install the dependencies into the release image, and then remove any temporary files used during this process. We also need to set the working directory to /app, and configure the container to run as the app user we created in the previous section:
# Test stage
...
...
# Release stage
FROM alpine
LABEL application=todobackend
# Install operating system dependencies
RUN apk add --no-cache python3 mariadb-client bash
# Create app user
RUN addgroup -g 1000 app && \
adduser -u 1000 -G app -D app
# Copy and install application source and pre-built dependencies
COPY --from=test --chown=app:app /build /build
COPY --from=test --chown=app:app /app /app
RUN pip3 install -r /build/requirements.txt -f /build --no-index --no-cache-dir
RUN rm -rf /build
# Set working directory and application user
WORKDIR /app
USER app
You first use the COPY directive with the --from flag, which tells Docker to look in the stage specified in the --from flag for the files to copy. Here we copy the /build and /app folders from the test stage image to folders with the same names in the release stage, and also configure the --chown flag to change the ownership of these copied folders to the application user. We then use the pip3 command to install only the core requirements specified in the requirements.txt file (you don't need the dependencies specified in requirements_test.txt for running the application), using the --no-index flag to disable the PIP connecting to the internet to download packages, and instead use the /build folder, as referenced by the -f flag, to find the dependencies previously built during the test stage and copied to this folder. We also specify the --no-cache-dir flag to avoid unnecessarily caching packages in the local filesystem, and remove the /build folder once everything is installed.
Finally, you set the working directory as /app, and configure the container to run as the app user by specifying the USER directive.