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

Eg dc #6

Closed
wants to merge 16 commits into from
Closed
7 changes: 7 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
__pycache__
.dockerignore
Dockerfile
*.md
*.pyc
*.pyo
.git
66 changes: 66 additions & 0 deletions .github/workflows/ci-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
name: CI

on:
push:
branches:
- main

jobs:
test:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v2

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1

- name: Cache Docker layers
uses: actions/cache@v2
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-

- name: Build and start Docker containers
run: |
docker-compose up -d

- name: Wait for the server to be up
run: |
while ! curl -s http://localhost:5000/ > /dev/null; do
sleep 1
done

- name: Run tests
run: |
docker exec -t pokebackpackfinal_pokeapp_1 python3 -m unittest discover -s /app/poke_app/ -p '*test.py'

- name: Stop Docker containers
run: docker-compose down

build:
needs: test
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v2

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1

- name: Login to Docker Hub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

- name: Build and push Docker image
run: |
echo "DOCKER_TAG=${GITHUB_REF#refs/heads/}" >> $GITHUB_ENV
docker build -t evilgenius13/pokeapp:${DOCKER_TAG} .
docker push evilgenius13/pokeapp:${DOCKER_TAG}
41 changes: 41 additions & 0 deletions .github/workflows/ci-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: CI

on:
pull_request:
branches: [ main ]

jobs:
test:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v2

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1

- name: Cache Docker layers
uses: actions/cache@v2
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-

- name: Build and start Docker containers
run: |
docker-compose up -d

- name: Wait for the server to be up
run: |
while ! curl -s http://localhost:5000/ > /dev/null; do
sleep 1
done

- name: Run tests
run: |
docker exec -t pokebackpackfinal_pokeapp_1 python3 -m unittest discover -s /app/poke_app/ -p '*test.py'

- name: Stop Docker containers
run: docker-compose down
10 changes: 8 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
# Base image
FROM python:3.9
FROM python:3.8-slim-buster

# Set the working directory in the container
WORKDIR /app

# Install netcat for our startup script - doesn't come with slim-buster (needed for the startup script)
RUN apt-get update && apt-get install -y netcat && rm -rf /var/lib/apt/lists/*

# Copy the requirements file
COPY requirements.txt .

# Install the required dependencies
RUN pip install -r requirements.txt

# Copy the application code into the container
# Copy the application code and the start-pokeapp.sh script into the container
COPY . .

# Ensure start-pokeapp.sh is executable
RUN chmod +x start-pokeapp.sh

# Expose the port your Flask app will be running on
EXPOSE 5000

Expand Down
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
- Find out their type, height, weight, and more!
- Find items and their descriptions
- Add Pokemon to your team, up to six.
- Built in caching to speed up the app

## Filling the Database
- To fill the database:
- Go to base.html
- Click the button that says "Fill Database"
- Please note it will take a bit to complete. When it's done you'll get a message saying data filled.

Expand All @@ -20,3 +20,7 @@
- `docker-compose build`
- `docker-compose up`

## And DevOps!
- If you have portainer or another docker management system that allows you to use github repos, you can point to this repo and use `dc-ops.yml` to deploy the app.
### Thank you
- Thank you to @digitsgaming for the continual support with server infrastructure and deployment.
45 changes: 45 additions & 0 deletions dc-ops.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
version: '3' # This is a deployment config for portainer. It pulls from the github repo.

volumes:
postgres_data:
driver: local

services:
postgres:
image: postgres:latest
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
POSTGRES_USER: Ash
POSTGRES_PASSWORD: Ketchum
POSTGRES_DB: pokeappdb
healthcheck:
test: ["CMD-SHELL", "pg_isready -U Ash"]
interval: 30s
timeout: 10s
retries: 3
start_period: 5s

redis:
image: redis:latest
ports:
- "6379:6379"
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 30s
timeout: 10s
retries: 3
start_period: 5s

pokeapp:
build: .
ports:
- "5000:5000"
environment:
SECRET_KEY: pokemon
DATABASE_URL: postgresql://Ash:Ketchum@postgres:5432/pokeappdb
REDIS_URL: redis://redis:6379/0
depends_on:
- postgres
- redis
command: /app/start-pokeapp.sh # Script command to watch for postgres and redis to be ready before starting the app
54 changes: 54 additions & 0 deletions dc-swarm.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
version: '3.8' # Newer Docker Compose version. This is a deployment config for portainer with docker swarm. It pulls from the github repo.

volumes:
postgres_data:
driver: local

services:
postgres:
image: postgres:latest
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
POSTGRES_USER: Ash
POSTGRES_PASSWORD: Ketchum
POSTGRES_DB: pokeappdb
healthcheck:
test: ["CMD-SHELL", "pg_isready -U Ash"]
interval: 30s
timeout: 10s
retries: 3
start_period: 5s

redis:
image: redis:latest
ports:
- target: 6379
published: 6379
protocol: tcp
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 30s
timeout: 10s
retries: 3
start_period: 5s

pokeapp:
image: evilgenius13/pokeapp:v2.3
ports:
- target: 5000
published: 5000
protocol: tcp
environment:
SECRET_KEY: pokemon
DATABASE_URL: postgresql://Ash:Ketchum@postgres:5432/pokeappdb
REDIS_URL: redis://redis:6379/0
depends_on:
- postgres
- redis
command: /app/start-pokeapp.sh
deploy:
replicas: 3
update_config:
parallelism: 1
delay: 10s
33 changes: 29 additions & 4 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,20 +1,45 @@
version: '3'

volumes:
postgres_data:
driver: local

services:
postgres:
image: postgres:latest
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
POSTGRES_USER: Ash
POSTGRES_PASSWORD: Ketchum
POSTGRES_DB: pokeappdb
healthcheck:
test: ["CMD-SHELL", "pg_isready -U Ash"]
interval: 30s
timeout: 10s
retries: 3
start_period: 5s

redis:
image: redis:latest
ports:
- "6379:6379"
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 30s
timeout: 10s
retries: 3
start_period: 5s

pokeapp:
image: evilgenius13/pokeapp:latest
image: evilgenius13/pokeapp:v2.3
ports:
- "5000:5000"
environment:
POSTGRES_USER: Ash
POSTGRES_PASSWORD: Ketchum
SECRET_KEY: pokemon
DATABASE_URL: postgresql://Ash:Ketchum@postgres:5432/pokeappdb
REDIS_URL: redis://redis:6379/0
depends_on:
- postgres
- postgres
- redis
command: /app/start-pokeapp.sh # Script command to watch for postgres and redis to be ready before starting the app
36 changes: 32 additions & 4 deletions poke_app/routes.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import os
import asyncio
import random
import redis
from flask_caching import Cache
from flask import Blueprint, request, render_template, redirect, url_for, flash
from flask_login import login_user, logout_user, login_required, current_user
from poke_app.models import Pokemon, Items, User
Expand All @@ -11,6 +14,13 @@

main = Blueprint("main", __name__)
auth = Blueprint("auth", __name__)
REDIS_URL = os.environ.get('REDIS_URL', 'redis://localhost:6379/0')
app.redis = redis.StrictRedis.from_url(REDIS_URL)
cache = Cache(config={
'CACHE_TYPE': 'redis',
'CACHE_REDIS_URL': REDIS_URL
})
cache.init_app(app)

colours = {
'Normal': '#A8A77A',
Expand Down Expand Up @@ -57,13 +67,24 @@ async def get_items_data(session):

return items_data

TIMEOUT = 300 # 300 seconds or 5 minutes

@cache.memoize(timeout=TIMEOUT)
def get_all_pokemon():
return Pokemon.query.all()

@cache.memoize(timeout=TIMEOUT)
def get_all_items():
return Items.query.all()


#! Routes Below this line
#------------------------------------------------------------#

@main.route('/')
def homepage():
pokemon = Pokemon.query.all()
items = Items.query.all()
pokemon = get_all_pokemon()
items = get_all_items()
# If there are no Pokémon in the database, set a default Pokémon of the day.
if not pokemon:
potd = Pokemon(
Expand Down Expand Up @@ -257,15 +278,22 @@ async def fill_data():
db.session.commit()

asyncio.run(fill_data())

# Clear the cache for the get_all_pokemon and get_all_items functions
cache.delete_memoized(get_all_pokemon)
cache.delete_memoized(get_all_items)

flash('Data has been filled!', 'success')
return redirect(url_for('main.homepage'))

@main.route('/profile/<username>')
def profile(username):
user = User.query.filter_by(username=username).first_or_404()
users = User.query.all()
pokemon = Pokemon.query.all()
items = Items.query.all()

pokemon = get_all_pokemon()
items = get_all_items()

num_users = len(users)
num_pokemon = len(pokemon)
num_items = len(items)
Expand Down
Loading