Skip to content

Commit 3e8648a

Browse files
author
Shaun B
committed
Make Multistage Docker Build
1 parent 9332993 commit 3e8648a

File tree

6 files changed

+100
-34
lines changed

6 files changed

+100
-34
lines changed

.github/workflows/main.yml

+45-21
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,27 @@ jobs:
1717
run: echo ${GITHUB_TOKEN} | docker login -u ${GITHUB_ACTOR} --password-stdin docker.pkg.github.com
1818
env:
1919
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
20-
- name: Pull image
20+
- name: Pull images
2121
run: |
22-
docker pull ${{ env.IMAGE }}:latest || true
23-
- name: Build image
22+
docker pull ${{ env.IMAGE }}-builder:latest || true
23+
docker pull ${{ env.IMAGE }}-final:latest || true
24+
- name: Build images
2425
run: |
2526
docker build \
26-
--cache-from ${{ env.IMAGE }}:latest \
27-
--tag ${{ env.IMAGE }}:latest \
27+
--target builder \
28+
--cache-from ${{ env.IMAGE }}-builder:latest \
29+
--tag ${{ env.IMAGE }}-builder:latest \
30+
--file ./project/Dockerfile.prod \
31+
"./project"
32+
docker build \
33+
--cache-from ${{ env.IMAGE }}-final:latest \
34+
--tag ${{ env.IMAGE }}-final:latest \
2835
--file ./project/Dockerfile.prod \
2936
"./project"
30-
- name: Push image
37+
- name: Push images
3138
run: |
32-
docker push ${{ env.IMAGE }}:latest
39+
docker push ${{ env.IMAGE }}-builder:latest
40+
docker push ${{ env.IMAGE }}-final:latest
3341
3442
test:
3543
name: Test Docker Image
@@ -42,14 +50,21 @@ jobs:
4250
run: echo ${GITHUB_TOKEN} | docker login -u ${GITHUB_ACTOR} --password-stdin docker.pkg.github.com
4351
env:
4452
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
45-
- name: Pull image
53+
- name: Pull images
4654
run: |
47-
docker pull ${{ env.IMAGE }}:latest || true
48-
- name: Build image
55+
docker pull ${{ env.IMAGE }}-builder:latest || true
56+
docker pull ${{ env.IMAGE }}-final:latest || true
57+
- name: Build images
4958
run: |
5059
docker build \
51-
--cache-from ${{ env.IMAGE }}:latest \
52-
--tag ${{ env.IMAGE }}:latest \
60+
--target builder \
61+
--cache-from ${{ env.IMAGE }}-builder:latest \
62+
--tag ${{ env.IMAGE }}-builder:latest \
63+
--file ./project/Dockerfile.prod \
64+
"./project"
65+
docker build \
66+
--cache-from ${{ env.IMAGE }}-final:latest \
67+
--tag ${{ env.IMAGE }}-final:latest \
5368
--file ./project/Dockerfile.prod \
5469
"./project"
5570
- name: Run container
@@ -61,7 +76,9 @@ jobs:
6176
-e ENVIRONMENT=dev \
6277
-e DATABASE_TEST_URL=sqlite://sqlite.db \
6378
-p 5003:8765 \
64-
${{ env.IMAGE }}:latest
79+
${{ env.IMAGE }}-final:latest
80+
- name: Install requirements
81+
run: docker exec fastapi-tdd pip install black flake8 isort pytest
6582
- name: Pytest
6683
run: docker exec fastapi-tdd python -m pytest .
6784
- name: Flake8
@@ -76,7 +93,7 @@ jobs:
7693
runs-on: ubuntu-latest
7794
needs: [build, test]
7895
env:
79-
HEROKU_APP_NAME: immense-island-91665
96+
HEROKU_APP_NAME: <APP_NAME>
8097
HEROKU_REGISTRY_IMAGE: registry.heroku.com/${HEROKU_APP_NAME}/web
8198
steps:
8299
- name: Checkout master
@@ -85,13 +102,21 @@ jobs:
85102
run: echo ${GITHUB_TOKEN} | docker login -u ${GITHUB_ACTOR} --password-stdin docker.pkg.github.com
86103
env:
87104
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
88-
- name: Pull image
105+
- name: Pull images
89106
run: |
90-
docker pull ${{ env.IMAGE }}:latest || true
91-
- name: Build image
107+
docker pull ${{ env.IMAGE }}-builder:latest || true
108+
docker pull ${{ env.IMAGE }}-final:latest || true
109+
- name: Build images
92110
run: |
93111
docker build \
94-
--cache-from ${{ env.IMAGE }}:latest \
112+
--target builder \
113+
--cache-from ${{ env.IMAGE }}-builder:latest \
114+
--tag ${{ env.IMAGE }}-builder:latest \
115+
--file ./project/Dockerfile.prod \
116+
"./project"
117+
docker build \
118+
--cache-from ${{ env.IMAGE }}-final:latest \
119+
--tag ${{ env.IMAGE }}:latest \
95120
--tag ${{ env.HEROKU_REGISTRY_IMAGE }}:latest \
96121
--file ./project/Dockerfile.prod \
97122
"./project"
@@ -100,13 +125,12 @@ jobs:
100125
env:
101126
HEROKU_AUTH_TOKEN: ${{ secrets.HEROKU_AUTH_TOKEN }}
102127
- name: Push to the registry
103-
run: docker push ${{ env.HEROKU_REGISTRY_IMAGE }}
128+
run: docker push ${{ env.HEROKU_REGISTRY_IMAGE }}:latest
104129
- name: Set environment variables
105130
run: |
106131
echo ::set-env name=HEROKU_REGISTRY_IMAGE::${{ env.HEROKU_REGISTRY_IMAGE }}
107132
echo ::set-env name=HEROKU_AUTH_TOKEN::${{ secrets.HEROKU_AUTH_TOKEN }}
108133
- name: Release
109134
run: |
110135
chmod +x ./release.sh
111-
./release.sh
112-
136+
./release.sh

makefile

+3
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ postgres: ## Access db via psql
3737
rebuild: ## Rebuild docker images
3838
@docker-compose up -d --build
3939

40+
rebuild-db: ## Rebuild db in docker image
41+
@docker-compose exec web python app/db.py
42+
4043
test: ## Run the current test suite
4144
@docker-compose exec web python -m pytest --cov="."
4245

project/Dockerfile

+3-2
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,14 @@ ENV PYTHONUNBUFFERED 1
1010

1111
# install system dependencies
1212
RUN apt-get update \
13-
&& apt-get -y install netcat gcc \
13+
&& apt-get -y install netcat gcc postgresql \
1414
&& apt-get clean
1515

1616
# install python dependencies
1717
RUN pip install --upgrade pip
1818
COPY ./requirements.txt .
19-
RUN pip install -r requirements.txt
19+
COPY ./requirements-dev.txt .
20+
RUN pip install -r requirements-dev.txt
2021

2122
# add app
2223
COPY . .

project/Dockerfile.prod

+41-4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,39 @@
1+
###########
2+
# BUILDER #
3+
###########
4+
5+
# pull official base image
6+
FROM python:3.8.3-slim-buster as builder
7+
8+
# install system dependencies
9+
RUN apt-get update \
10+
&& apt-get -y install gcc postgresql \
11+
&& apt-get clean
12+
13+
# set work directory
14+
WORKDIR /usr/src/app
15+
16+
# set environment varibles
17+
ENV PYTHONDONTWRITEBYTECODE 1
18+
ENV PYTHONUNBUFFERED 1
19+
20+
# install dependencies
21+
RUN pip install --upgrade pip
22+
COPY ./requirements.txt .
23+
RUN pip wheel --no-cache-dir --no-deps --wheel-dir /usr/src/app/wheels -r requirements.txt
24+
25+
# lint
26+
COPY . /usr/src/app/
27+
RUN pip install black flake8 isort
28+
RUN flake8 .
29+
RUN black --exclude=migrations .
30+
RUN isort ./**/*.py
31+
32+
33+
#########
34+
# FINAL #
35+
#########
36+
137
# pull official base image
238
FROM python:3.8.3-slim-buster
339

@@ -13,7 +49,7 @@ ENV APP_HOME=/home/app/web
1349
RUN mkdir $APP_HOME
1450
WORKDIR $APP_HOME
1551

16-
# set environment varibles
52+
# set environment variables
1753
ENV PYTHONDONTWRITEBYTECODE 1
1854
ENV PYTHONUNBUFFERED 1
1955
ENV ENVIRONMENT prod
@@ -25,15 +61,16 @@ RUN apt-get update \
2561
&& apt-get clean
2662

2763
# install python dependencies
64+
COPY --from=builder /usr/src/app/wheels /wheels
65+
COPY --from=builder /usr/src/app/requirements.txt .
2866
RUN pip install --upgrade pip
29-
COPY ./requirements.txt .
30-
RUN pip install -r requirements.txt
67+
RUN pip install --no-cache /wheels/*
3168

3269
# add app
3370
COPY . .
3471

3572
# chown all the files to the app user
36-
RUN chown -R app:app $APP_HOME
73+
RUN chown -R app:app $HOME
3774

3875
# change to the app user
3976
USER app

project/requirements-dev.txt

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
black==19.10b0
2+
flake8===3.8.2
3+
isort==4.3.21
4+
pytest==5.4.2
5+
pytest-cov==2.9.0
6+
pytest-xdist==1.32.0
7+
8+
-r requirements.txt

project/requirements.txt

-7
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,7 @@
11
asyncpg==0.20.1
2-
black==19.10b0
32
fastapi==0.55.1
4-
flake8===3.8.2
53
gunicorn==20.0.4
6-
isort==4.3.21
74
newspaper3k==0.2.8
8-
nltk==3.5
9-
pytest==5.4.2
10-
pytest-cov==2.9.0
11-
pytest-xdist==1.32.0
125
requests==2.23.0
136
tortoise-orm==0.16.12
147
uvicorn==0.11.5

0 commit comments

Comments
 (0)