Skip to content

halfpintutopia/mindful-minutes

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Mindful Minutes

Django CI/CD

amiresponsive

Table of Contents

Product Information

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.

UX / UI Design

For further details of the design process, please see:

Agile

Agile User Story Master on Google Sheets was created from a template supplied by our Cohort October 2022 Tutor, Rebecca Tracey-Timoney.

Future Implementations

Personalise experience:

Accessibility

Features

Header

Role Mobile Desktop
Header mobile
Logged out Header logged out menu mobile Header logged out menu desktop
Logged in Header logged in menu mobile Header logged in menu desktop

Footer

Mobile Desktop
Footer mobile Footer desktop

Calendar

Calender

Accordion

Accordion

Sections

Text and image

Position Mobile Desktop
Image (right)
Text (left)
Image (right) and text (left) section for mobile Image (right) and text (left) section for desktop
Text (right)
Image (left)
Text (right) and image (left) section for mobile Text (right) and image (left) section for desktop

Forms

Register

sign-in_video.mov
Mobile Desktop
Sign in Form Mobile Sign in Form Mobile

Login

login_video.mov
Mobile Desktop
Log in Form Mobile Log in Form Mobile

Account page

Mobile Desktop
header_mobile

Technologies Used

Stack

  • HTML5
  • CSS3
  • JavaScript
  • Python

Frameworks

  • Django

Packages

  • CKEditor
    • Used this editor, rather than Summernote, due to conflict with Django version. I previously worked with CKEditor when I worked with ConcreteCMS

Frameworks, Libraries & Additional Programs/Software/Tools used

  • Django

Libraries & Dependencies

Tools

  • 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

Remote & Local Deployment

Ensure you have Docker installed.

All instruction are on the terminal command line.

Local Deployment

  1. 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

Fork the Repository

local-deploy_fork.webm
Additional Information
Configuration steps
  1. Docker Registry
    • Set up a Docker registry on Docker Hub
  2. 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)
  3. 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

Remote Deployment

  1. Create a new app
    • heroku create <app_name> --region eu
    • check app details heroku info --app <app_name>
  2. Login to the Heroku Container Registry
    • heroku container:login
  3. 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>
  4. Build the production Docker image and tag
    1. cd app
    2. docker build -f Dockerfile.prod -t registry.heroku.com/<app_name>/web .
    3. Test the database locally
      • heroku config:get DATABASE_URL --app <app_name>
      • export DATABASE_URL=<database_url> or add DATABASE_URL in the .env file
    4. Set the SECRET_KEY
      • heroku config:set SECRET_KEY="<app_name>" --app mindfulminutes
    5. Spin up the container
      • docker run --name <container_name> -e "PORT=8765" -p 8008:8765 registry.heroku.com/<app_name>/web:latest
    6. Bring down the container
      • docker stop <container_name>
      • docker rm <container_name>
  5. Check the Dockerfile.prod has set ENV DJANGO_ALLOWED_HOSTS .herokuapp.com
  6. Build the image again
    • docker build -f Dockerfile.prod -t registry.heroku.com/<app_name>/web .
  7. Push the image to the registry
    • docker push registry.heroku.com/<app_nam>/web:latest
  8. Release the image. This should run the container
    • heroku container:release web --app <app_name>
  9. Apply migrations
    • heroku run python manage.py migrate --app <app_name>
  10. Ensure WhiteNoise has been installed
    1. Set'whitenoise.middleware.WhiteNoiseMiddleware' to MIDDLEWARE in settings.py
    2. Set STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') in settings.py
    3. Add RUN python manage.py collectstatic --noinput to Dockerfile.prod after the COPY . . command
  11. Build the image again
  12. Push image to the registry
  13. Release the image

Additional Information

Create the Initial GitHub Actions Workflow YAML For CI/CD

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:

  1. A Django project with version control hosted on GitHub
  2. Docker installed on your development machine
  3. Docker Hub Account or GitHub Container Registry (GHRC)
  4. A Heroku account and a Heroku app created via the GUI or CLI, for deployment
2. Creating the Workflow File
  1. Create .github/workflows directory in the root of your project

  2. Inside the workflows directory create a new file.

    mkdir -p .github/workflows 
    cd .github/workflows && touch django-ci-cd.yml
  3. 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

Continuous Integration (CI)
  • 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
  • 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 the echo command as the input to the docker login command
  • $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
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

Continuous Deployment (CD)
  • 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
6. GitHub Secrets and Variables
  1. Go to the repository page
  2. Navigate to "Settings"
  3. Under "Settings and variables" listed on the left side menu, click "Actions"
  4. Click "New repository secret"
  5. 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
  1. Save the YAML file
  2. Commit changes
  3. 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

  1. Create a new app on Heroku for you Django project
  2. Obtain the Heroku API Token from your Heroku account settings and add it as a secrete in your GitHub repository name HEROKU_AUTH_TOKEN

Set Up GitHub Actions Workflow YAML For CI/CD After Cloning

1. Prerequisites
  1. A GitHub account
  2. A Heroku account
2. Fork the Repository

See Fork the Repository

3. Set Up GitHub Secrets
  1. Go to the repository page
  2. Navigate to "Settings"
  3. Under "Settings and variables" listed on the left side menu, click "Actions"
  4. Click "New repository secret"
  5. 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
  1. Login to Heroku account
  2. Create a new Heroku app using the GUI or CLI
     heroku create <name>
  3. Take note of the Heroku app name as this will be used for the deployment setup
5. Modify the Workflow YAML File
  1. Open the YAML file located in .github/workflows
  2. Go the deploy job and replace the HEROKU_APP_NAME: mindful-minutes with the Heroku app name you created.
6. Trigger the Workflow & Verify Deployment
  1. Commit changes
  2. Push changes to main branch of your forked repository, this will trigger the GitHub Actions workflow
  3. 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)
  4. 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>

Create Heroku App (via the Dashboard)

heroku._create_app.webm
  1. Login
  2. From the Dashboard, click the "New" button
  3. Choose "Create new app" from the drop-down menu
  4. Give the app a unique name, it must be unique otherwise Heroku complains
  5. Choose the region appropriate to you
  6. Click the "Create app" button

Create a new PostgreSQL Database Instance

elephantsql_database_instance.webm
  1. Login
  2. Click the "Create New Instance" button
  3. Set up a plan
    • Provide a name
    • Select the Tiny Turtle (Free) plan
    • Add tags if needed
  4. Click the "Select Region" button
    • Choose the data centre closest to you
  5. Click the "Review" button
  6. Click the "Create instance" button
  7. From the list of instances on your dashboard, click the name of the new instance
  8. Copy the URL from the "Details" page and paste this link into your settings.py file in your Django project

Set up Heroku Config Vars

heroku._config_vars.webm
  1. Login
  2. Go to the project and click on the Settings tab
  3. 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)

Contributing

Data Models

Schematics

Mindful Minutes ERD - Database ER diagram (crow's foot) created with LucidChart.

API

For further details of the API, please see:

Testing

Django Test Driven Development using REST Framework

For further details on testing, click here.

User experience

Browserstack was used for testing. The devices were:

Bugs & Fixes

Known Bugs

Get a warning in the Firefox console regarding Font Awesome due to "glyths extend outside the bounding box". Cited from StackOverflow

Lighthouse

Validator Testing

Credits

References

Style

Images

Definitions

  • 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.

Code Used

References & Resources

Additional Courses

Agile

Deployment

Issues / Bugs

CI / CD

Django

Python Dependencies / Packages

Heroku

Testing

Automated testing

Django

Performance and Optimisation

Content

Media

Acknowledgements

Thanks to Adam Gilroy for giving me permission to use his LinkedIn Post as inspiration for a Use Case.

Back to the top