- Product Information
- UX / UI Design
- Agile
- Features
- Technologies Used
- Remote & Local Deployment
- Data Models
- Testing
- Credits
The app is designed to help cultivate a habit of daily introspection and self-reflection. By using the app, the user can establish a routine of engaging with their thoughts, goals and achievements every current day and evening.
The primary goal of the Mindful Minutes App is to encourage users to build a habit of checking in daily and reflecting on their experiences. To reinforce this habit, the app allows users to create, edit, delete and access their current day's journal entries while keeping the previous days' entries in a read-only mode. This approach ensures that users focus on the present, fostering a send of mindfulness and self-awareness.
For further details of the design process, please see:
Agile User Story Master on Google Sheets was created from a template supplied by our Cohort October 2022 Tutor, Rebecca Tracey-Timoney.
Personalise experience:
- How to use ChatGPT as a Personalized Mantra Generation for Meditation
- Utilise Generative AI To create a plan, break down the task to smaller tasks and give a clear timeline
- Integrate Google Calendar
- Add social account login option
Role | Mobile | Desktop |
---|---|---|
Logged out | ||
Logged in |
Mobile | Desktop |
---|---|
Position | Mobile | Desktop |
---|---|---|
Image (right) Text (left) |
||
Text (right) Image (left) |
sign-in_video.mov
Mobile | Desktop |
---|---|
login_video.mov
Mobile | Desktop |
---|---|
Mobile | Desktop |
---|---|
- HTML5
- CSS3
- JavaScript
- Python
- Django
- CKEditor
- Used this editor, rather than Summernote, due to conflict with Django version. I previously worked with CKEditor when I worked with ConcreteCMS
- Django
- Black
- DJ-Database-URL
- Generates the proper database configuration dictionary for the Django settings based on the
DATABASE_URL
environment variable
- Generates the proper database configuration dictionary for the Django settings based on the
- Gunicorn
- A production-grade WSGI server
- Django All Auth
- pytest-xdist
- Typetura
- I chose a lightweight tool rather than Bootstrap and the integrated RFS. Typetura is a service and tool enabling developers to implement responsive typography. I chose Typetura as I enjoy having fine-grained control over the typography.
# install packages
pip install <package_name>
# uninstall packages
pip uninstall <package_name>
# update requirements.txt file
pip freeze --local > requirements.txt
Ensure you have Docker installed.
All instruction are on the terminal command line.
- Build the image and start the container up in detached mode
docker compose up -d --build
- Check errors
docker compose logs -f
- Bring down the development containers
docker compose down --volumes
local-deploy_fork.webm
- Docker Registry
- Set up a Docker registry on Docker Hub
- Docker Registry Image
- Name and tag Docker image for project, with the following format:
registry-url/username/repo-name:tag
(e.g.docker.io/username/project:latest
)
- Name and tag Docker image for project, with the following format:
- GitHub Repository
- Set up repo secrets
- Go to "Settings" and under "Secrets and variables", click on "Actions"
- Create a secret for
DOCKER_REGISTRY_IMAGE
. Set this to the Docker Registry Image name and tag set in Step 2
- Create a new
YAML
file in the located in the.github/workflows
directory located in the root of the repo
- Set up repo secrets
- Create a new app
heroku create <app_name> --region eu
- check app details
heroku info --app <app_name>
- Login to the Heroku Container Registry
heroku container:login
- If not using ElephantSQL instance, and setting DATABASE_URL in the CONFIG_VARS, provision a new Postgres database
heroku addons:create heroku-postgresql:mini --app <app_name>
- Build the production Docker image and tag
cd app
docker build -f Dockerfile.prod -t registry.heroku.com/<app_name>/web .
- Test the database locally
heroku config:get DATABASE_URL --app <app_name>
export DATABASE_URL=<database_url>
or addDATABASE_URL
in the.env
file
- Set the SECRET_KEY
- heroku config:set SECRET_KEY="<app_name>" --app mindfulminutes
- Spin up the container
docker run --name <container_name> -e "PORT=8765" -p 8008:8765 registry.heroku.com/<app_name>/web:latest
- Bring down the container
docker stop <container_name>
docker rm <container_name>
- Check the
Dockerfile.prod
has setENV DJANGO_ALLOWED_HOSTS .herokuapp.com
- Build the image again
docker build -f Dockerfile.prod -t registry.heroku.com/<app_name>/web .
- Push the image to the registry
docker push registry.heroku.com/<app_nam>/web:latest
- Release the image. This should run the container
heroku container:release web --app <app_name>
- Apply migrations
heroku run python manage.py migrate --app <app_name>
- Ensure WhiteNoise has been installed
- Set
'whitenoise.middleware.WhiteNoiseMiddleware'
toMIDDLEWARE
insettings.py
- Set
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
insettings.py
- Add
RUN python manage.py collectstatic --noinput
toDockerfile.prod
after theCOPY . .
command
- Set
- Build the image again
- Push image to the registry
- Release the image
The step-by-step instructions is mainly for continuous integration (CI) and continuous deployment (CD). It is intended for remote deployment, specifically for deploying the Django application to Heroku.
The workflow assumes a Django project and code repository have been set up on GitHub, and Docker is being used for containerisation. It leverages GitHub Actions for CI/CD and final deployment target is Heroku.
1. Prerequisites
Before creating the YAML file, ensure the following has been set up:
- A Django project with version control hosted on GitHub
- Docker installed on your development machine
- Docker Hub Account or GitHub Container Registry (GHRC)
- A Heroku account and a Heroku app created via the GUI or CLI, for deployment
2. Creating the Workflow File
-
Create
.github/workflows
directory in the root of your project -
Inside the
workflows
directory create a new file.mkdir -p .github/workflows cd .github/workflows && touch django-ci-cd.yml
-
Open the file and add the following:
name: Django CI/CD # Name is arbitrary on: push: branches: - main env: IMAGE: ghrc.io/${{ github.repository }}/app:latest
- The
build
job responsible for building for Docker image and pushing it to a container registry (GHCR) - The
test
job performs tests and code linting on the codebase to ensure it meets quality standards- The idea is to ensure that the codebase is tested and built into a Docker image in a consistent and reliable manner.
3. Define the Build Job
Add the build
job to build and push the Docker image
jobs:
build:
name: Build and Push Docker Image
runs-on: ubuntu-latest
steps:
- name: Checkout codebase
uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version:3.11
- name: Login to GitHub Container Registry
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u "${{ github.actor }}" --password-stdin
- name: Pull Docker image
run: docker pull $IMAGE:latest || true
- name: Build Docker image
run: |
cd app
docker build
--cache-from $IMAGE:latest
--tag $IMAGE:latest
--file ./Dockerfile.prod
--build-arg SECRET_KEX=$SECRET_KEY
.
docker push $IMAGE:latest
ubuntu-latest
- provides an Ubuntu-based virtual machine
GITHUB_TOKEN
- a special token automatically provided by GitHub Actions to authenticate workflow when it runs
- available as a built-in environment variable within GitHub Actions workflow
docker login
- authenticates Heroku's container registry using the
HEROKU_AUTH_TOKEN
secret
- authenticates Heroku's container registry using the
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u "${{ github.actor }}" --password-stdin
- the
echo
command is used to print the value of the GitHub token to the standard output - the
|
(pipe symbol) is used to redirect the standard output of theecho
command as the input to thedocker login
command
- the
$IMAGE
- environment variable set to the image name that includes the GitHub Container Registry (GHCR) URL (
ghcr.io
)docker pull $IMAGE:latest || true
- attempts to pull the latest version of the Docker image, if the pull fails the|| true
ensures it doesn't cause the workflow to fail, allowing the workflow to proceed with the subsequent steps
- environment variable set to the image name that includes the GitHub Container Registry (GHCR) URL (
4. Define the Test Job
Add the test
job to run tests and code linting
test:
name: Test
needs: build
runs-on: ubuntu-latest
services:
- name: postgres-latest
alias: postgres
variables:
DATABASE_TEST_URL: ${{ env.DATABASE_TEST_URL }}
steps:
- name: Checkout codebase
uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: 3.11
- name: Install dependencies
run: pip install -r requirements.txt
- name: Lint with Flake8, Black and isort
run: |
cd app
pip install black==23.3.0 flake8==6.0.0 isort==5.12.0 pytest==7.2.2
pytest -p no:warnings
flake8 .
isort . --check-only --skip env
black . --check --exclude=migrations|venv
ubuntu-latest
- provides an Ubuntu-based virtual machine
needs
- specify the job that is required to have run successfully before it runs this job
services
- set up a Postgres container for the job
DATABASE_TEST_URL
- an environment variable, which connects the Django tests to the Postgres container
install -r requirements.txt
- installs the required Python dependencies for testing and deployment
- The
deploy
job deploys the Docker image to Heroku, effectively deploying your Django application to production- The workflow uses the Heroku container registry to push and deploy the Docker image to Heroku's infrastructure
5. Define the Deploy Job
Add the deploy
job to deploy to Heroku
deploy:
name: Deploy to production
needs: test
runs-on: ubuntu-latest
steps:
- name: Checkout codebase
uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: 3.11
- name: Deploy to Heroku
env:
HEROKU_APP_NAME: mindful-minutes
HEROKU_REGISTRY_IMAGE: registry.heroku.com/${HEROKU_APP_NAME}/web
run: |
cd app
docker build
--tag $HEROKU_REGISTRY_IMAGE
--file ./Dockerfile.prod
--build-arg SECRET_KEY=$SECRET_KEY
.
docker login -u _ -p ${{ secrets.HEROKU_AUTH_TOKEN }} registry.heroku.com
docker push $HEROKU_REGISTRY_IMAGE
chmod +x ./release.sh
./release.sh
ubuntu-latest
- provides an Ubuntu-based virtual machine
needs
- specify the job that is required to have run successfully before it runs this job
env
- specifies the Heroku app name and image registry URL for Heroku deployment
docker login
- authenticates Heroku's container registry using the
HEROKU_AUTH_TOKEN
secret
- authenticates Heroku's container registry using the
6. GitHub Secrets and Variables
- Go to the repository page
- Navigate to "Settings"
- Under "Settings and variables" listed on the left side menu, click "Actions"
- Click "New repository secret"
- Add the following secrets:
HEROKU_AUTH_TOKEN
- Copy the Heroku API Key from your "Account" page or use CLI to create one
heroku authorizations:create
7. Commit and Push
- Save the
YAML
file - Commit changes
- Push to GitHub repository
8. Enable GitHub Actions
9. Configuring Heroku
Before deploying to Heroku, make sure you have set up your Heroku app correctly and have obtained
the HEROKU_AUTH_TOKEN
secret
- Create a new app on Heroku for you Django project
- Obtain the Heroku API Token from your Heroku account settings and add it as a secrete in your GitHub repository
name
HEROKU_AUTH_TOKEN
2. Fork the Repository
3. Set Up GitHub Secrets
- Go to the repository page
- Navigate to "Settings"
- Under "Settings and variables" listed on the left side menu, click "Actions"
- Click "New repository secret"
- Add the following secrets:
HEROKU_AUTH_TOKEN
- Copy the Heroku API Key from your "Account" page or use CLI to create one
heroku authorizations:create
4. Configure Heroku
5. Modify the Workflow YAML File
- Open the
YAML
file located in.github/workflows
- Go the
deploy
job and replace theHEROKU_APP_NAME: mindful-minutes
with the Heroku app name you created.
6. Trigger the Workflow & Verify Deployment
- Commit changes
- Push changes to
main
branch of your forked repository, this will trigger the GitHub Actions workflow - Go to GitHub Repository page and click the "Actions" tab to see the workflow running,
- build the Docker image
- run tests
- deploy the Docker image to Heroku (if the tests are passed)
- After the workflow completes successfully, go to Heroku app's URL to verify the application has been deployed and running correctly
Install python-dotenv
package with pip install python-dotenv
Create a .env
file at the root of the project with the following keys
SECRET=<YOUR_SECRET_KEY>
DATABASE_URL=<ELEPHANTSQL_URL>
DEVELOPMENT=<SET TO 'True' if in development mode or remove or set to 'False' for production>
heroku._create_app.webm
- Login
- From the Dashboard, click the "New" button
- Choose "Create new app" from the drop-down menu
- Give the app a unique name, it must be unique otherwise Heroku complains
- Choose the region appropriate to you
- Click the "Create app" button
elephantsql_database_instance.webm
- Login
- Click the "Create New Instance" button
- Set up a plan
- Provide a name
- Select the Tiny Turtle (Free) plan
- Add tags if needed
- Click the "Select Region" button
- Choose the data centre closest to you
- Click the "Review" button
- Click the "Create instance" button
- From the list of instances on your dashboard, click the name of the new instance
- Copy the URL from the "Details" page and paste this link into your settings.py file in your Django project
heroku._config_vars.webm
- Login
- Go to the project and click on the Settings tab
- Go to the "Config Vars" section and add the following variables:
- DATABASE_URL
- SECRET_KEY
- PORT (if not using CI/CD as this is set in the workflow)
- CLOUDINARY_URL (if not using Whitenoise)
- DISABLE_COLLECT_STATIC 1 (IMPORTANT - This is to be removed after Cloudinary or Whitenoise is connected)
created with LucidChart.
For further details of the API, please see:
For further details on testing, click here.
Browserstack was used for testing. The devices were:
Get a warning in the Firefox console regarding Font Awesome due to "glyths extend outside the bounding box". Cited from StackOverflow
- Add 'go to top' button on Readme.md
- How to Create Reusable SVG Icon React Components
- Help with snapping nodes to guidelines
- Adobe Express - Convert your image to an SVG for free
- CodePen|The Hamburger Menu by Matthew Blode
- CodePen|🍔 <-> ❌ (version 1) by Tomino Martinius
- CodePen|Menu "Hamburger" Icon Animations by Jesse Couch
- Getting started with Variable fonts on the web - Kevin Powell **
- Figma Dev Mode is here! - Kevin Powell
- Responsive navbar tutorial using HTML CSS & JS - Kevin Powell
- Support CSS Nesting Module
- Can I Use CSS Nesting
- Adobe Color - Lab
- Strengthening Typography with Responsive Techniques and Typetura
- Cubic Bezier
- You need to fix your
line-height
- Stacking Icons | Font Awesome
- 10 CSS animation tips and tricks
- Getting started with CSS nesting
- Learn how to create a responsive CSS grid layout | 07:23 - Using aspect-ratio on the images
- A better image reset for your CSS
- How to make horizontal line with words in the middle using CSS?
- Create a horizontal media scroller with CSS
- Build a responsive, animate, accessible accordion that looks pretty good
- Components - Schedule Template | Cody House
- Custom select menu - CSS only
- Copper and Wild - green floral covered notebook
- Nick Morrison - Laptop and notepad
- JESHOOTS.COM - White work table with notes, smartphone and laptop
- Web Dyno
- a lightweight Linux container used to run a single process, sucha as a web server or a background worker. Dynos are the building blocks of a Heroku application's runtime environment. It refers to the dyno responsible for handling incoming HTTP requests for you web application. It runs the web server specified in the Dockerfile.
- Test-Driven Development with Django, Django REST Framework and Docker
- Full Stack for Front-End Engineers, v3 - Jem Young
- Complete Intro to SQL & PostgreSQL - Brian Holt
- Complete Intro to Containers - Brian Holt
- Agile User Story Template Spread Sheet, resource provided by Rebecca Tracey-Timoney
- Project Management on GitHub
- Acceptance Criteria for User Stories: Purposes, Formats, Examples, and Best Practices
- User stories with examples and a template
- Define features and epics, organize your product and portfolio backlogs in Azure Boards
- Chapter 15: Requirements and user stories
- Epics, User Stories, Themes, and Initiatives: The Key Difference and Examples
- How to Write a Good User Story: with Examples & Templates
- Epics vs. User Stories: what’s the difference?
- Heroku Dev Center - The Heroku CLI
- How to use Environment Variables in Django
- Django Deployment checklist
- Error saving credentials: error storing credentials - err: exit status 1, out: `error getting credentials - err: exit status 1
- How to make isort black compatible. Original Question: isort conflicts with black?
- Configuration via a file
- How can I stop black formatter from formatting migrations files of a Django project?
- Pushed docker image to registry.heroku.com via Github actions but it doesn't show up anywhere?
- H14 error in heroku - "no web processes running"
- Causes of Heroku H10-App Crashed Error And How To Solve Them
- GitHub Actions in action - Setting up Django and Postgres
- GitHub Actions - Create starter workflows
- Schedule Planner Repository
- Pushing container images to GitHub Container Actions
- Postgres - Docker Hub
- GitHub Actions - Automate your GitHub workflows
- GitHub Action: Ubuntu-latest workflows will use Ubuntu-22.04
- Heroku Dev Center - Container Registry & Runtime (Docker Deploy)
- Creating PostgreSQL service containers
- This is a good starting point getting Python, Django, Postgres running as a service, pytest, black and pip caching rolling with GitHub Actions
- Setup postgres in GitHub Actions for Django
- GitHub Actions - Variables
- How to connect to Postgres in GitHub Actions
- Deploy Django application to Heroku with GitHub Actions
- Django Documentation
- Test-Driven Development with Django, Django REST Framework and Docker
- Django Girls Tutorial
- Getting the Most Out of the Django's User Model
- Django - Extend User Model
- Adding Social Authentication to Django
- How To Add Social Authentication Using Django-Allauth To Your Django Project (Google OAuth Example)
- Provider Configuration | django-allauth
- How should I generate an API key that allows me to use Heroku Platform API?
- Getting Started with the Platform API
- Heroku CLI Authentication
- Heroku CLI Commands
- Creating a Custom User Model in Django
- Testing Models with Django using Faker and Factory Boy
- Pytest for Beginners
- Pytest
- Testing in Django with Selenium
- How to authorize user in Django testing REST framework APIClient post method
- Freezegun
- Pycharm|Pytest
- Effectively Using Django REST Framework Serializers
- Introduction to Django Channels
- Migrating a Custom User Model Mid-Project in Django
- Customize Django Admin
- A Guide to Performance Testing and Optimization with Python and Django
- Scaling Django Applications: Best Practices and Strategies
Thanks to Adam Gilroy for giving me permission to use his LinkedIn Post as inspiration for a Use Case.