在GitHub Actions中用Docker运行pytest遇内存不足问题求助
方案合理性分析
用docker-compose搭建一致的测试环境是完全合理的——这种方式能确保本地和CI环境的依赖、配置完全对齐,避免“本地跑通CI挂”的问题。但GitHub Actions的默认托管Runner内存资源有限(Ubuntu默认是7GB左右),同时运行Django容器、PostGIS容器再加上pytest进程,很容易触发内存耗尽(exit code 137就是OOM kill的典型表现),哪怕单个测试文件也可能因为PostGIS本身的内存开销触发问题。
内存问题解决办法
1. 调低PostGIS容器的内存参数
PostGIS默认的数据库配置是面向生产环境的,测试环境不需要这么高的内存分配。在docker-compose.yml的PostGIS服务中添加内存相关的启动参数:
services: db: image: postgis/postgis:latest command: ["postgres", "-c", "shared_buffers=128MB", "-c", "work_mem=4MB", "-c", "maintenance_work_mem=64MB"] # 其他配置...
这些参数会大幅降低PostgreSQL/PostGIS的内存占用,适合测试场景。
2. 升级GitHub Actions Runner规格
GitHub提供了大内存的托管Runner选项,在workflow文件中指定即可:
jobs: test: runs-on: ubuntu-latest-16core # 16GB内存,2倍于默认规格 # 其他步骤...
如果是私有仓库,也可以用自托管Runner,配置更大的内存资源。
3. 优化Django测试的内存开销
- 用
pytest-django的--reuse-db参数,避免每次测试都重建数据库,减少磁盘IO和内存消耗:pytest --reuse-db - 在测试用的settings中关闭不必要的功能:设置
DEBUG=False,禁用非必需的中间件(比如缓存、静态文件处理中间件),关闭django-debug-toolbar等调试工具。 - 避免在测试中加载大量测试数据,尽量用最小化的测试数据集。
4. 拆分测试任务
把测试用例拆分成多个独立的GitHub Actions Job,每个Job只跑一部分测试文件,分散内存压力:
jobs: test-auth: runs-on: ubuntu-latest steps: # 拉代码、配置环境... - run: pytest tests/auth/ test-geospatial: runs-on: ubuntu-latest steps: # 拉代码、配置环境... - run: pytest tests/geospatial/
替代方案
1. 直接在Runner中安装PostGIS
跳过docker-compose,直接在GitHub Actions的Ubuntu Runner上安装PostGIS依赖,然后跑测试:
jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Install PostGIS run: | sudo apt-get update sudo apt-get install -y postgresql-15-postgis-3 postgresql-client-15 sudo -u postgres createdb test_db sudo -u postgres psql -d test_db -c "CREATE EXTENSION postgis;" - name: Setup Python uses: actions/setup-python@v5 with: python-version: "3.11" - name: Install dependencies run: | python -m pip install --upgrade pip pip install -r requirements.txt pip install pytest-django - name: Run tests run: pytest env: DATABASE_URL: postgis://postgres:@localhost/test_db
这种方式省去了容器的额外内存开销,内存占用会低很多。
2. 使用GitHub Actions服务容器
把PostGIS作为服务容器启动,Django直接在Runner中运行,兼顾环境一致性和内存效率:
jobs: test: runs-on: ubuntu-latest services: db: image: postgis/postgis:latest env: POSTGRES_USER: postgres POSTGRES_PASSWORD: "" POSTGRES_DB: test_db options: >- --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 ports: - 5432:5432 steps: - uses: actions/checkout@v4 - name: Setup Python uses: actions/setup-python@v5 with: python-version: "3.11" - name: Install dependencies run: | python -m pip install --upgrade pip pip install -r requirements.txt pip install pytest-django - name: Run tests run: pytest env: DATABASE_URL: postgis://postgres:@localhost/test_db
服务容器是GitHub Actions原生支持的,比docker-compose更轻量,内存占用更低。
内容的提问来源于stack exchange,提问作者shivam singh

