Overview

This document outlines the configuration and usage of Docker within a development environment using Docker Compose and a multi-stage Dockerfile specifically designed for a JavaScript application with Python dependencies.

Docker Compose Configuration

The docker-compose.yml file orchestrates the application services and defines how the application should be built and run during development. Below is a sample configuration:

version: "3.7"

services:
  docs:
    build:
      context: .
      dockerfile: Dockerfile
      target: dev
    ports:
      - 8000:8000
    volumes:
      - ./:/app

Key Sections Explained

  • version: Specifies the version of the Docker Compose file format.

  • services: Defines the services that will be run. In this case, the docs service is defined for serving documentation.

  • build: Under this section:

    • context: Indicates the root directory to build the Docker image.
    • dockerfile: Specifies the path of the Dockerfile to be used for building this service.
    • target: Identifies which stage of the multi-stage Dockerfile to use for the build process, in this case targeting the dev stage.
  • ports: Maps port 8000 of the container to port 8000 on the host machine, allowing access to the service through this port.

  • volumes: Mounts the current directory (./) into the /app directory of the container, enabling real-time updates to the source files.

Dockerfile Configuration

A multi-stage Dockerfile allows for optimized builds and separation of concerns. Below is an example that details the stages of the Dockerfile:

# Install the base requirements for the app.
# This stage is to support development.
FROM --platform=$BUILDPLATFORM python:alpine AS base
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt

FROM --platform=$BUILDPLATFORM node:18-alpine AS app-base
WORKDIR /app
COPY app/package.json app/yarn.lock ./
COPY app/spec ./spec
COPY app/src ./src

# Run tests to validate app
FROM app-base AS test
RUN yarn install
RUN yarn test

# Clear out the node_modules and create the zip
FROM app-base AS app-zip-creator
COPY --from=test /app/package.json /app/yarn.lock ./
COPY app/spec ./spec
COPY app/src ./src
RUN apk add zip && \
    zip -r /app.zip /app

# Dev-ready container - actual files will be mounted in
FROM --platform=$BUILDPLATFORM base AS dev
CMD ["mkdocs", "serve", "-a", "0.0.0.0:8000"]

# Do the actual build of the mkdocs site
FROM --platform=$BUILDPLATFORM base AS build
COPY . .
RUN mkdocs build

# Extract the static content from the build
# and use a nginx image to serve the content
FROM --platform=$TARGETPLATFORM nginx:alpine
COPY --from=app-zip-creator /app.zip /usr/share/nginx/html/assets/app.zip
COPY --from=build /app/site /usr/share/nginx/html

Stage Breakdown

  1. Base Stage:

    • Uses python:alpine to install Python dependencies stated in requirements.txt.
    • Sets the working directory to /app.
  2. App Base Stage:

    • Uses node:18-alpine as the base for Node.js dependencies.
    • Copies necessary files into the working directory.
  3. Test Stage:

    • Installs Node.js packages and runs the tests to confirm validity.
  4. App Zip Creator Stage:

    • Zips the application files after tests pass, preparing for deployment.
  5. Dev Stage:

    • Creates a development-ready container.
    • Runs the command mkdocs serve -a 0.0.0.0:8000 to initiate the MkDocs server.
  6. Build Stage:

    • Completes the build of the MkDocs site.
  7. Final Stage:

    • Switches to an nginx:alpine base for serving static content.

Running the Development Environment

To start the development environment, execute the following command in the terminal:

docker-compose up --build

This command builds the images as defined in the Dockerfile and starts the services as specified in the docker-compose.yml.

After running the command, the Docker container for the documentation will be accessible via http://localhost:8000, depending on your local configuration.

Ensure that the necessary dependencies in requirements.txt and package.json are correctly defined to prevent build issues.

Conclusion

This configuration provides a robust setup for developing an application using Docker, allowing efficient management of dependencies, testing, and real-time updates during development.

The usage of multi-stage builds helps in maintaining a cleaner and smaller image for deployment scenarios, focusing on local development requirements.