如何通过CircleCI获取Heroku部署所用的Docker镜像
Django应用镜像化与多环境部署方案
需求说明
- 本地运行Django应用,已配置CircleCI使用Python+Postgres镜像完成测试,测试通过后通过
heroku/deploy-via-git部署到Heroku - 希望获取Heroku运行的应用镜像,推送到Docker Hub后,本地可直接通过
docker compose up启动站点 - 曾考虑本地用Docker Compose构建镜像后在CircleCI复用,但对嵌套构建操作存疑;尝试拉取Heroku镜像未果
可行性分析
直接拉取Heroku运行的镜像不可行:Heroku的应用容器是基于Buildpack自动构建的内部镜像,Heroku并未提供直接导出/拉取该镜像的官方能力,用户只能操作应用代码或数据库,无法获取完整镜像文件。
最优实现方案
放弃从Heroku拉取镜像的思路,改为在CircleCI流水线中统一完成测试、构建可复用Docker镜像、推送Docker Hub、部署Heroku的全流程,具体步骤如下:
- 编写Django应用的
Dockerfile和docker-compose.yml(本地先验证可用) - 修改CircleCI配置,在测试通过后添加Docker镜像构建、推送步骤
- 调整Heroku部署方式(可选:改用容器部署,保持镜像一致性)
- 本地直接从Docker Hub拉取镜像,用
docker compose up启动
1. 基础配置文件编写
Dockerfile示例
# 使用官方Python镜像作为基础 FROM python:3.10.2-slim # 设置工作目录 WORKDIR /app # 复制依赖文件并安装 COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # 复制应用代码 COPY . . # 设置环境变量 ENV PYTHONDONTWRITEBYTECODE 1 ENV PYTHONUNBUFFERED 1 # 暴露应用端口 EXPOSE 8000 # 启动命令(根据实际项目调整,例如用gunicorn) CMD ["gunicorn", "--bind", "0.0.0.0:8000", "your_project_name.wsgi:application"]
本地docker-compose.yml示例
version: '3.8' services: web: image: your-dockerhub-username/django-app:latest ports: - "8000:8000" environment: - DB_HOST=db - DB_NAME=postgres - DB_USER=theophile - DB_PASSWORD=postgres depends_on: - db db: image: postgres:14.1 environment: - POSTGRES_USER=theophile - POSTGRES_PASSWORD=postgres - POSTGRES_DB=postgres volumes: - postgres_data:/var/lib/postgresql/data/ volumes: postgres_data:
2. 修改后的CircleCI配置
version: 2.1 docker-auth: &docker-auth auth: username: $DOCKERHUB_USERNAME password: $DOCKERHUB_PASSWORD orbs: python: circleci/python@1.5.0 heroku: circleci/heroku@0.0.10 docker: circleci/docker@2.2.0 jobs: build-and-test: docker: - image: cimg/python:3.10.2 - image: cimg/postgres:14.1 environment: POSTGRES_USER: theophile POSTGRES_PASSWORD: postgres POSTGRES_DB: postgres steps: - checkout - run: command: pip install -r requirements.txt name: Install Deps - run: name: Run MIGRATE command: python manage.py migrate environment: DATABASE_URL: postgres://theophile:postgres@localhost:5432/postgres - run: name: Run loaddata from Json command: python manage.py loaddata datadump.json environment: DATABASE_URL: postgres://theophile:postgres@localhost:5432/postgres - run: name: Run tests command: pytest environment: DATABASE_URL: postgres://theophile:postgres@localhost:5432/postgres build-and-push-docker: docker: - image: cimg/base:stable steps: - checkout - docker/checkout - docker/login: <<: *docker-auth - docker/build: image: your-dockerhub-username/django-app tag: latest,${CIRCLE_SHA1} - docker/push: image: your-dockerhub-username/django-app tag: latest,${CIRCLE_SHA1} deploy-to-heroku: docker: - image: cimg/base:stable steps: - checkout - heroku/install - heroku/deploy-via-git: force: true # 强制推送,可选 workflows: deploy-and-publish: jobs: - build-and-test - build-and-push-docker: requires: - build-and-test - deploy-to-heroku: requires: - build-and-test
3. 关键说明
- 测试环节:补充
DATABASE_URL环境变量,确保测试时能正确连接Postgres服务 - 镜像构建:使用CircleCI的Docker orb简化镜像构建、登录、推送流程,同时打
latest和提交哈希两个标签,便于版本追溯 - Heroku部署:可继续使用原有的
deploy-via-git,也可以改为Heroku容器部署(用heroku container:push),确保运行环境与Docker镜像一致 - 本地运行:配置好
docker-compose.yml后,直接执行docker compose pull && docker compose up即可启动站点
内容的提问来源于stack exchange,提问作者Théophile Sers
相关产品推荐
相关产品推荐

