Skip to content

Commit 630d61f

Browse files
committed
overhaul current project to prepare for any updates
switch to `uv` switch to pyproject.toml for project metadata make project non-flat modernize with ruff rules modernize with strict pylance format cleanup around database needs cleanup around containerization use dynamic file paths where possible
1 parent d8b4375 commit 630d61f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+1263
-209
lines changed

.dockerignore

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,18 @@
1+
# generated or tooling
12
.git/
23
.github/
3-
types_/
4+
.ruff_cache/
5+
.venv/
6+
7+
# types arent needed at runtime
8+
src/types_/
9+
10+
# meta and template files
11+
.env
12+
.env.template
413
config.template.toml
14+
docker-compose.yaml
515
Dockerfile
616
LICENSE
717
migration.sql
8-
pyproject.toml
918
README.md

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,4 +161,5 @@ cython_debug/
161161

162162
# Config Files...
163163
config.toml
164-
.config.toml
164+
.config.toml
165+
compose.override.yaml

.python-version

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.13

Dockerfile

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,38 @@
1-
FROM python:3.12-slim
1+
ARG PYTHON_BASE=3.13-slim-bookworm
2+
ARG UV_BASE=python3.13-bookworm-slim
23

3-
LABEL org.opencontainers.image.source=https://github.com/pythonistaguild/mystbin
4-
LABEL org.opencontainers.image.description="Container for running MystB.in"
5-
LABEL org.opencontainers.image.licenses=GPLv3
6-
7-
RUN mkdir -p /etc/apt/keyrings \
8-
&& apt update -y \
9-
&& apt-get install --no-install-recommends -y \
10-
# deps for building python deps
11-
git \
12-
build-essential \
13-
libcurl4-gnutls-dev \
14-
gnutls-dev \
15-
libmagic-dev \
4+
FROM ghcr.io/astral-sh/uv:${UV_BASE} AS builder
5+
6+
ENV UV_PYTHON_DOWNLOADS=0
7+
8+
WORKDIR /project
9+
10+
# install latest git
11+
RUN apt-get update -y \
12+
&& apt-get upgrade -y \
13+
&& apt-get install --no-install-recommends --no-install-suggests -y git \
1614
&& rm -rf /var/lib/apt/lists/*
1715

18-
# copy project requirement files here to ensure they will be cached.
16+
RUN --mount=type=cache,target=/root/.cache/uv \
17+
--mount=type=bind,source=pyproject.toml,target=/project/pyproject.toml \
18+
--mount=type=bind,source=uv.lock,target=/project/uv.lock \
19+
uv sync --frozen --no-install-project --no-dev
20+
21+
ADD --chown=1000:1000 . /project
22+
23+
RUN --mount=type=cache,target=/root/.cache/uv \
24+
uv sync --frozen --no-install-project --no-dev
25+
26+
FROM python:${PYTHON_BASE}
27+
28+
LABEL org.opencontainers.image.source=https://github.com/pythonistaguild/mystbin
29+
LABEL org.opencontainers.image.description="A paste service built for simplicity and beauty"
30+
31+
USER 1000:1000
32+
1933
WORKDIR /app
20-
COPY requirements.txt ./
2134

22-
# install runtime deps
23-
RUN pip install -Ur requirements.txt
35+
COPY --from=builder --chown=1000:1000 /project /app
36+
ENV PATH="/app/.venv/bin:$PATH"
2437

25-
COPY . /app/
26-
ENTRYPOINT python -O launcher.py
38+
CMD ["python", "-O", "launcher.py"]

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,5 @@ Easily share code and text.
3636
- Run `docker compose up -d` to start the services.
3737
- If you want to use redis for session/limit handling, run with the redis profile: `docker compose --profile redis up -d`
3838
- The redis container doesn't expose connections outside of the network, but for added security edit `redis.conf` and change the password.
39+
40+
- Backing up the database to the host file system is **opt in**. You can use the `backup` profile with docker-compose to spin up the sidecar container for performing backups.

db-backup/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
backups/

db-backup/backup.sh

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#!/bin/bash
2+
3+
while true; do
4+
DATE=$(date +%F_%H-%M-%S);
5+
BACKUP_FILE=/backups/backups/db_backup_${DATE}.sql.zstd;
6+
echo "[INFO] Starting backup at ${DATE}";
7+
pg_dump -h database -U "${POSTGRES_USER}" -w -d "${POSTGRES_DB}" -Z zstd -f "${BACKUP_FILE}";
8+
echo "[INFO] Backup complete: ${BACKUP_FILE}";
9+
10+
# Keep only last 7 backups
11+
find /backups -type f -name 'db_backup_*.sql.zstd' -mtime +7 -delete;
12+
echo "[INFO] Cleanup complete. Sleeping for 24h...";
13+
sleep 86400;
14+
done

db-backup/backups/.keep

Whitespace-only changes.

docker-compose.yaml

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,17 @@ services:
22
mystbin:
33
image: ghcr.io/pythonistaguild/mystbin
44
container_name: mystbin
5+
environment:
6+
- CONFIG_PATH=/app-config
57
ports:
68
- 8181:8181
79
restart: unless-stopped
810
depends_on:
911
database:
1012
condition: service_healthy
1113
restart: true
12-
volumes:
13-
- ./config.toml:/app/config.toml:ro
14+
configs:
15+
- app-config
1416

1517
database:
1618
image: postgres:16
@@ -24,9 +26,30 @@ services:
2426
env_file: .env
2527
environment:
2628
- PG_DATA=/var/lib/postgresql/data
27-
- POSTGRES_DB=mystbin
2829
volumes:
2930
- mystbin_pg_data:/var/lib/postgresql/data
31+
user: "1000:1000"
32+
33+
db-backups:
34+
image: postgres:16
35+
container_name: db-backups
36+
depends_on:
37+
database:
38+
condition: service_healthy
39+
restart: true
40+
env_file:
41+
- .env
42+
environment:
43+
- PGPASSWORD=${POSTGRES_PASSWORD}
44+
volumes:
45+
- ./db-backup:/backups
46+
- ./db-backup/backup.sh:/backup.sh
47+
entrypoint: ["/bin/bash"]
48+
command: "/backup.sh"
49+
restart: unless-stopped
50+
user: "1000:1000"
51+
profiles:
52+
- backup
3053

3154
redis:
3255
image: redis:latest
@@ -38,5 +61,9 @@ services:
3861
- "./redis.conf:/config/redis.conf:ro"
3962
command: ["redis-server", "/config/redis.conf"]
4063

64+
configs:
65+
app-config:
66+
file: ./config.toml
67+
4168
volumes:
4269
mystbin_pg_data:

launcher.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,21 @@
2323
import starlette_plus
2424
import uvicorn
2525

26-
import core
27-
import core.config
28-
26+
from src import core
2927

3028
starlette_plus.setup_logging(level=logging.INFO)
31-
logger: logging.Logger = logging.getLogger(__name__)
29+
LOGGER = logging.getLogger(__name__)
30+
31+
__all__ = ()
3232

3333

3434
async def main() -> None:
35-
async with aiohttp.ClientSession() as session, core.Database(
36-
dsn=core.CONFIG["DATABASE"]["dsn"], session=session, github_config=core.CONFIG.get("GITHUB")
37-
) as database:
35+
async with (
36+
aiohttp.ClientSession() as session,
37+
core.Database(
38+
dsn=core.CONFIG["DATABASE"]["dsn"], session=session, github_config=core.CONFIG.get("GITHUB")
39+
) as database,
40+
):
3841
app: core.Application = core.Application(database=database)
3942

4043
host: str = core.CONFIG["SERVER"]["host"]
@@ -55,4 +58,4 @@ async def main() -> None:
5558
try:
5659
asyncio.run(main())
5760
except KeyboardInterrupt:
58-
logger.info("Closing the MystBin application due to KeyboardInterrupt.")
61+
LOGGER.info("Closing the MystBin application due to KeyboardInterrupt.")

0 commit comments

Comments
 (0)