Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mod8 #102

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
Open

Mod8 #102

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.env
.git
.venv
Dockerfile
.vscode
README.md
18 changes: 18 additions & 0 deletions .github/workflows/continousint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Continuous Integration
on:
push:
paths-ignore:
- 'README.md'

pull_request:
paths-ignore:
- 'README.md'

jobs:
build:
name: Build and test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: docker build --tag todo-app:test --target test .
- run: docker run todo-app:test
119 changes: 119 additions & 0 deletions Architecturediagrams/C4diagram.drawio
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
<mxfile host="app.diagrams.net" modified="2024-04-12T11:20:30.135Z" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36" etag="FORz_NWIwY1BAt8qg-8A" version="24.2.3" type="device" pages="3">
<diagram name="Page-1" id="ZNKD_h5mJuoZfkbOYL_d">
<mxGraphModel dx="1434" dy="746" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="nXZ37tVTMCc-88TCOidA-1" value="Todo App" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="350" y="320" width="230" height="130" as="geometry" />
</mxCell>
<mxCell id="nXZ37tVTMCc-88TCOidA-2" value="User" style="shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;html=1;outlineConnect=0;" vertex="1" parent="1">
<mxGeometry x="430" y="60" width="30" height="60" as="geometry" />
</mxCell>
<mxCell id="nXZ37tVTMCc-88TCOidA-3" value="" style="endArrow=classic;html=1;rounded=0;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="440" y="140" as="sourcePoint" />
<mxPoint x="440" y="320" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="nXZ37tVTMCc-88TCOidA-4" value="Access through browser" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="nXZ37tVTMCc-88TCOidA-3">
<mxGeometry x="-0.2667" y="-1" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
</root>
</mxGraphModel>
</diagram>
<diagram id="_8eElZynshBiuD9LQZMb" name="Page-2">
<mxGraphModel dx="1434" dy="746" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="VQg4Q9CJstqcQp871knV-3" value="Todo App (Docker Container)" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="100" y="460" width="450" height="380" as="geometry" />
</mxCell>
<mxCell id="VQg4Q9CJstqcQp871knV-4" value="Flask&amp;nbsp;" style="whiteSpace=wrap;html=1;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="150" y="500" width="80" height="80" as="geometry" />
</mxCell>
<mxCell id="VQg4Q9CJstqcQp871knV-5" value="Python code" style="whiteSpace=wrap;html=1;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="334" y="500" width="80" height="80" as="geometry" />
</mxCell>
<mxCell id="VQg4Q9CJstqcQp871knV-7" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.5;entryY=0.375;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="1" target="VQg4Q9CJstqcQp871knV-4">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="190" y="330" as="sourcePoint" />
<mxPoint x="250" y="220" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="VQg4Q9CJstqcQp871knV-9" value="Http requests" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="VQg4Q9CJstqcQp871knV-7">
<mxGeometry x="-0.34" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="VQg4Q9CJstqcQp871knV-8" value="" style="endArrow=classic;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="1" source="VQg4Q9CJstqcQp871knV-4" target="VQg4Q9CJstqcQp871knV-5">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="390" y="510" as="sourcePoint" />
<mxPoint x="440" y="460" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="VQg4Q9CJstqcQp871knV-10" value="Execute code" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="VQg4Q9CJstqcQp871knV-8">
<mxGeometry x="-0.1154" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
</root>
</mxGraphModel>
</diagram>
<diagram id="Rj3bOvYVxlC3pdh7jtiT" name="Page-3">
<mxGraphModel dx="1434" dy="746" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="viwvxLdPgYCNpIaG5Ijx-2" value="Python Code" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="120" y="200" width="580" height="370" as="geometry" />
</mxCell>
<mxCell id="viwvxLdPgYCNpIaG5Ijx-3" value="App.py (structure)" style="whiteSpace=wrap;html=1;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="360" y="230" width="80" height="80" as="geometry" />
</mxCell>
<mxCell id="viwvxLdPgYCNpIaG5Ijx-4" value="Data" style="whiteSpace=wrap;html=1;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="190" y="380" width="80" height="80" as="geometry" />
</mxCell>
<mxCell id="viwvxLdPgYCNpIaG5Ijx-5" value="HTML&amp;nbsp;&lt;div&gt;Templates&amp;nbsp;&lt;/div&gt;" style="whiteSpace=wrap;html=1;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="570" y="450" width="80" height="80" as="geometry" />
</mxCell>
<mxCell id="xpd4-uEIjkvCwGak7LLN-1" value="" style="endArrow=classic;html=1;rounded=0;" edge="1" parent="1" target="viwvxLdPgYCNpIaG5Ijx-3">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="400" y="30" as="sourcePoint" />
<mxPoint x="440" y="360" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="xpd4-uEIjkvCwGak7LLN-2" value="Requests arrival&amp;nbsp;" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="xpd4-uEIjkvCwGak7LLN-1">
<mxGeometry x="-0.37" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="xpd4-uEIjkvCwGak7LLN-3" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;entryX=1.025;entryY=0.65;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="1" source="viwvxLdPgYCNpIaG5Ijx-5" target="viwvxLdPgYCNpIaG5Ijx-3">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="390" y="210" as="sourcePoint" />
<mxPoint x="440" y="160" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="xpd4-uEIjkvCwGak7LLN-4" value="Providing Data to generate web page" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="xpd4-uEIjkvCwGak7LLN-3">
<mxGeometry x="0.0231" y="-1" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="xpd4-uEIjkvCwGak7LLN-5" value="" style="endArrow=classic;startArrow=classic;html=1;rounded=0;entryX=-0.012;entryY=0.625;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0.75;exitY=0;exitDx=0;exitDy=0;" edge="1" parent="1" source="viwvxLdPgYCNpIaG5Ijx-4" target="viwvxLdPgYCNpIaG5Ijx-3">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="270" y="350" as="sourcePoint" />
<mxPoint x="320" y="300" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="xpd4-uEIjkvCwGak7LLN-6" value="App request from data and data returns response&lt;div&gt;&amp;nbsp;&lt;/div&gt;" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="xpd4-uEIjkvCwGak7LLN-5">
<mxGeometry x="-0.1788" y="-2" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>
Binary file added Architecturediagrams/ComponentDiagram.drawio.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Architecturediagrams/Contextdiagram.drawio.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Architecturediagrams/codediagram.drawio.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 21 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
FROM python AS base
RUN pip install poetry
WORKDIR /app
COPY . .
RUN poetry install
ENTRYPOINT poetry run flask run --host=0.0.0.0


FROM base as production
ENV FLASK_DEBUG=false
ENTRYPOINT poetry run flask run --host=0.0.0.0
# Configure for production

FROM base as development
ENV FLASK_DEBUG=true
ENTRYPOINT poetry run flask run --host=0.0.0.0
# Configure for local development

FROM base as test

ENTRYPOINT poetry run pytest
41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,44 @@ You should see output similar to the following:
* Debugger PIN: 226-556-590
```
Now visit [`http://localhost:5000/`](http://localhost:5000/) in your web browser to view the app.

```git remote -v ```
tells us / lists our remotes


### See below for how to build the two docker images
```
docker build --target development --tag todo-app:dev .
docker build --target production --tag todo-app:prod .
```
### Command to run the production container
```
docker run --env-file .env -it -p 5001:5000 todo-app:prod
```
This command pases through the environment variables with the `--env-file` flag, and the `-it` flags make it easier to interact with the container (e.g. allowing us to shut it down with ctrl+c from our host terminal). With the `-p` flag, the app can be accessed at the address `http://localhost:5001`.

### Command to run dev container
```
docker run --env-file .env -it -p 5001:5000 --mount "type=bind,source=$(pwd)/todo_app,target=/app/todo_app" todo-app:dev
```
Bind mount is miroring a folder and the folder in this instance is the todo app folder allowing changes to the code without having to rebuild the container. Running dev changes without having to access the container

### Running Pytest
```bash
poetry run pytest
```


### Azure Hosting
The container image that is deployed on Azure is hosted on Docker Hub at https://hub.docker.com/repository/docker/nashussain76/todo-app/general

The website is hosted at https://nashusappservice.azurewebsites.net/

To update the website you will need to run the following commands to build and push the updated container image:
```Bash
docker build --target production --tag nashussain76/todo-app:prod .
docker push nashussain76/todo-app:prod
```
Next you will need to make a POST request to the webhook link provided on the App Service (under the Deployment Centre tab)> This will trigger Azure to pull the updated image from Docker Hub (link not provided as it includes credentials)


Loading