ModuleNotFoundError: No module named 'app.models' on Railway but works locally (FastAPI + worker, same repo)
navitas28
PROOP

2 months ago

I am deploying a FastAPI API service + background worker from the same repository on Railway, using two services (web and worker) defined via a Procfile.

The application works perfectly locally and in Docker, but fails only on Railway with:

ModuleNotFoundError: No module named 'app.models'

Project Structure:

repo-root/

├── start.py

├── start_worker.py

├── Procfile

└── app/

├── init.py

├── main.py

├── core/

├── models/

│ ├── init.py

│ ├── profile.py

│ ├── post.py

│ └── ...

├── tasks/

│ ├── init.py

│ ├── profiler_tasks.py

│ └── post_tasks.py

└── services/

All directories have __init__.py.

----------------------------------------------------------------------------------

Imports That Fail

from app.models import profile

Error on Railway

✓ Successfully imported app module from /app/app/__init__.py
✗ Failed to import: No module named 'app.models'

Traceback (most recent call last):
  File "/app/start.py", line 33, in <module>
    from app.models import profile
ModuleNotFoundError: No module named 'app.models'

start.py

import sys
from pathlib import Path
import logging

PROJECT_ROOT = Path(__file__).resolve().parent
if str(PROJECT_ROOT) not in sys.path:
    sys.path.insert(0, str(PROJECT_ROOT))

logging.basicConfig(level=logging.INFO)

from app.main import app

if __name__ == "__main__":
    import uvicorn
    import os

    uvicorn.run(
        "app.main:app",
        host="0.0.0.0",
        port=int(os.getenv("PORT", 8000)),
    )

start_worker.py

import sys
from pathlib import Path
import logging
import time

PROJECT_ROOT = Path(__file__).resolve().parent
if str(PROJECT_ROOT) not in sys.path:
    sys.path.insert(0, str(PROJECT_ROOT))

logging.basicConfig(level=logging.INFO)

from app.tasks.profiler_tasks import run_profiler
from app.tasks.post_tasks import run_post_tasks

def main():
    while True:
        run_profiler()
        run_post_tasks()
        time.sleep(5)

if __name__ == "__main__":
    main()

Procfile

web: python start.py
worker: python start_worker.py

Environment Details

  • Python 3.12

  • FastAPI

  • Uvicorn

  • Railway (2 services from same repo)

What’s Confusing

  • import appworks

  • from app.models import profilefails

  • All packages have __init__.py

  • Works locally + Docker

  • Fails only on Railway

The log even confirms:

Successfully imported app module from /app/app/__init__.py

Which suggests Python resolves app, but cannot find its submodules.

Question

What causes app to be importable but app.models to fail only on Railway, and what is the correct way to structure or start the app so that both API and worker can run as separate Railway services from the same repository?

0 Replies

Loading...