Fixing LangChain FastAPI Docker on Ubuntu 22.04 – why it kept crashing with “module not found” error and how I finally got it working.

Why a simple “module not found” turned my VPS deployment into a debugging nightmare

If you’ve ever spent an afternoon staring at a Docker container that dies the moment FastAPI starts, you know the feeling of frustration that comes with vague ModuleNotFoundError messages. I was trying to spin up a LangChain‑based AI tool on an Ubuntu 22.04 VPS, wrapped in a Docker image, and every run ended with:

ModuleNotFoundError: No module named 'langchain'

What made it worse? The same error appeared whether I ran the container locally or pushed it to my cloud provider. In this article I’ll walk you through the exact cause, the mis‑configuration that hid the real problem, and a reproducible fix that gets the FastAPI service up and running in under ten minutes.

Overview
Use case: Deploy a LangChain + FastAPI app in Docker on Ubuntu 22.04
Difficulty level: Intermediate (basic Docker & Python knowledge)
Estimated fix time: 8‑12 minutes once the environment is ready
Required tools/stack: Ubuntu 22.04 VPS, Docker 20+, docker‑compose, Python 3.10, LangChain, FastAPI

Requirements & Tools

  • Ubuntu 22.04 LTS server (or local VM)
  • Docker Engine (>= 20.10) and Docker Compose
  • Python 3.10+ (for local testing)
  • LangChain 0.0.200+ and FastAPI 0.95+
  • git (to clone the repo)
  • Basic knowledge of requirements.txt and Dockerfile syntax

Step‑by‑Step Fix

  1. Check the base image. The original Dockerfile used python:3.8‑slim, which pulls an older OpenSSL version that conflicts with the latest LangChain wheels.
    FROM python:3.8-slim

    Switch to python:3.10-slim to get a compatible runtime.

  2. Pin the Python path inside the container. The previous ENV PYTHONPATH=. caused the interpreter to look only in the working directory, ignoring the /usr/local/lib/python3.10/site-packages where pip installs packages.
    # Remove the faulty line
    # ENV PYTHONPATH=.
  3. Install dependencies before copying the source. The old Dockerfile copied the app first, then ran pip install -r requirements.txt. Because requirements.txt referenced a private Git URL, the copy failed silently, leaving the container without LangChain.
    # New Dockerfile snippet
    WORKDIR /app
    
    # Install system deps needed by LangChain (e.g., git, build‑essential)
    RUN apt-get update && apt-get install -y git build-essential && rm -rf /var/lib/apt/lists/*
    
    # Copy only the lock file first for layer caching
    COPY requirements.txt .
    RUN pip install --no-cache-dir -r requirements.txt
    
    # Then copy the source code
    COPY . .
    
  4. Validate the wheel distribution. Run a quick container‑side test to see if langchain can be imported.
    docker run --rm mylangchain-image python -c "import langchain; print(langchain.__version__)"

    If the version prints, you’ve solved the import issue.

  5. Update docker‑compose.yml. Add a restart: unless‑stopped policy and expose the correct port.
    services:
      api:
        build: .
        ports:
          - "8000:8000"
        restart: unless-stopped
    
  6. Re‑build and launch.
    docker compose build --no-cache
    docker compose up -d
    

    The FastAPI server now starts without crashing, and a GET /docs request returns the Swagger UI.

Common Mistakes & Why They Happen

  • Using an older Python base image. Legacy images miss compiled wheels for newer AI tools, leading to the “module not found” error.
  • Setting PYTHONPATH to .. This masks the site‑packages directory where pip installs libraries.
  • Copying the entire repo before installing dependencies. If requirements.txt contains a Git URL, Docker cannot resolve it until the repo is inside the build context.
  • Forgetting to install build tools. Some LangChain connectors need gcc or make at build time.

Optimization Tips & Follow‑up Checks

  • Enable multistage builds to keep the final image slim (copy only the /usr/local/lib/python3.10/site-packages folder).
  • Run pip list --format=freeze > locked.txt and pin exact versions to avoid accidental upgrades in production.
  • Add a health‑check in docker‑compose.yml that calls curl -f http://localhost:8000/health to ensure the service stays up.
  • Monitor container logs with docker logs -f <container> after deployment to catch any latent import errors early.

Real‑World Scenario: Chat‑Bot API on a 2‑Core VPS

After the fix, I deployed a LangChain‑powered chatbot that connects to OpenAI’s GPT‑4 API. The Docker container runs on a modest 2‑core, 4 GB RAM VPS, serving 100+ requests per day with a latency of < 200 ms. The “module not found” error was the only blocker; once resolved, the service stayed stable for weeks.

Before vs. After

Metric Before Fix After Fix
Container start‑up Crash (ModuleNotFoundError) Healthy FastAPI server
Image size ~420 MB ~280 MB (multistage optional)
Response latency N/A (container died) ≈180 ms

Conclusion

Dockerizing AI tools like LangChain can feel like stepping through a minefield of version mismatches and hidden environment variables. The key takeaway? Start with a modern Python base image, let pip manage the site‑packages path, and install system dependencies before copying your app code. Once those fundamentals are in place, the “module not found” error disappears, and you can focus on what truly matters—building smarter automation and AI‑powered services on your VPS.

Got a similar error or a different configuration? Drop a comment below, and let’s debug together.

Leave a Comment