Compare commits

..

4 Commits

Author SHA1 Message Date
11efb6f09c feat: Update readme
All checks were successful
Build Docker / BuildImage (push) Successful in 35s
Check Code Quality / RuffCheck (push) Successful in 44s
2025-11-20 17:48:36 +11:00
ba04fb7c53 fix: Revert docker CI/CD to use correct repo
All checks were successful
Build Docker / BuildImage (push) Successful in 34s
Check Code Quality / RuffCheck (push) Successful in 45s
2025-11-20 15:53:02 +11:00
eb08788f7a feat: Update Dockerfile to use UV and pyproject
All checks were successful
Check Code Quality / RuffCheck (push) Successful in 50s
Build Docker / BuildImage (push) Successful in 1m3s
2025-11-20 15:49:57 +11:00
c7d5b98507 fix: Cleanup code to comply with ruff
Some checks failed
Check Code Quality / RuffCheck (push) Successful in 43s
Build Docker / BuildImage (push) Failing after 1m10s
2025-11-20 15:44:56 +11:00
5 changed files with 67 additions and 45 deletions

View File

@@ -33,9 +33,13 @@ jobs:
tag_num="${tag}-${tag_num}"
fi
docker build -t nathanwoodburn:$tag_num .
docker tag nathanwoodburn:$tag_num git.woodburn.au/nathanwoodburn/nathanwoodburn:$tag_num
docker push git.woodburn.au/nathanwoodburn/nathanwoodburn:$tag_num
docker tag nathanwoodburn:$tag_num git.woodburn.au/nathanwoodburn/nathanwoodburn:$tag
docker push git.woodburn.au/nathanwoodburn/nathanwoodburn:$tag
repo=$GITHUB_REPOSITORY
repo=${repo#*/}
repo=$(echo $repo | tr '[:upper:]' '[:lower:]')
echo "container=$repo"
docker build -t $repo:$tag_num .
docker tag $repo:$tag_num git.woodburn.au/nathanwoodburn/$repo:$tag_num
docker push git.woodburn.au/nathanwoodburn/$repo:$tag_num
docker tag $repo:$tag_num git.woodburn.au/nathanwoodburn/$repo:$tag
docker push git.woodburn.au/nathanwoodburn/$repo:$tag

View File

@@ -1,17 +1,31 @@
FROM --platform=$BUILDPLATFORM python:3.10-alpine AS builder
FROM --platform=$BUILDPLATFORM python:3.13-alpine
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
# Install curl for healthcheck
RUN apk add --no-cache curl
# Set working directory
WORKDIR /app
COPY requirements.txt /app
RUN --mount=type=cache,target=/root/.cache/pip \
python3 -m pip install -r requirements.txt
# Install dependencies
RUN --mount=type=cache,target=/root/.cache/uv \
--mount=type=bind,source=uv.lock,target=uv.lock \
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
uv sync --locked --no-install-project
COPY . /app
# Copy the project into the image
ADD . /app
# Optionally mount /data to store the data
# VOLUME /data
# Sync the project
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --locked
ENTRYPOINT ["python3"]
CMD ["main.py"]
# Add mount point for data volume
ENV BASE_DIR=/data
VOLUME /data
FROM builder as dev-envs
EXPOSE 5000
ENTRYPOINT ["uv", "run"]
CMD ["main.py"]

View File

@@ -2,18 +2,32 @@
Python3 website template including git actions
# Development
1. Install requirements
## Requirements
- UV
## Development
1. Install project requirements
```bash
python3 -m pip install -r requirements.txt
uv sync
```
2. Run the dev server
```bash
python3 server.py
uv run python3 server.py
```
3. Alternatively use the virtual environment
```bash
source .venv/bin/activate
```
You can exit the environment with `deactivate`
For best development setup, you should install the git hook for pre-commit
```bash
uv run pre-commit install
```
# Production
## Production
Run using the main.py file
```bash
python3 main.py
```
```

20
main.py
View File

@@ -1,5 +1,3 @@
from flask import Flask
from server import app
import server
from gunicorn.app.base import BaseApplication
import os
@@ -20,23 +18,21 @@ class GunicornApp(BaseApplication):
def load(self):
return self.application
if __name__ == '__main__':
if __name__ == "__main__":
dotenv.load_dotenv()
workers = os.getenv('WORKERS', 1)
threads = os.getenv('THREADS', 2)
workers = os.getenv("WORKERS", 1)
threads = os.getenv("THREADS", 2)
workers = int(workers)
threads = int(threads)
options = {
'bind': '0.0.0.0:5000',
'workers': workers,
'threads': threads,
"bind": "0.0.0.0:5000",
"workers": workers,
"threads": threads,
}
gunicorn_app = GunicornApp(server.app, options)
print(f'Starting server with {workers} workers and {threads} threads', flush=True)
print(f"Starting server with {workers} workers and {threads} threads", flush=True)
gunicorn_app.run()

View File

@@ -1,9 +1,6 @@
from functools import cache
import json
from flask import (
Flask,
make_response,
redirect,
request,
jsonify,
render_template,
@@ -11,7 +8,6 @@ from flask import (
send_file,
)
import os
import json
import requests
from datetime import datetime
import dotenv
@@ -26,6 +22,7 @@ def find(name, path):
if name in files:
return os.path.join(root, name)
# Assets routes
@app.route("/assets/<path:path>")
def send_assets(path):
@@ -74,17 +71,13 @@ def wellknown(path):
# region Main routes
@app.route("/")
def index():
# Get current time in the format "dd MMM YYYY hh:mm AM/PM"
# current_datetime = datetime.now().strftime("%d %b %Y %I:%M %p")
# return render_template("index.html", datetime=current_datetime)
# Print the IP address of the requester
print(f"Request from IP: {request.remote_addr}")
# And the headers
print(f"Request headers: {request.headers}")
# return redirect("https://ya.c.woodburn.au")
# Get current time in the format "dd MMM YYYY hh:mm AM/PM"
current_datetime = datetime.now().strftime("%d %b %Y %I:%M %p")
return render_template("index.html", datetime=current_datetime)
@app.route("/<path:path>")
@@ -116,6 +109,7 @@ def catch_all(path: str):
api_requests = 0
@app.route("/api/v1/data", methods=["GET"])
def api_data():
"""