Skip to content

Commit 4610d4c

Browse files
committed
Remove Django's dbbackup and add custom backup script
1 parent 4f3eb5a commit 4610d4c

File tree

3 files changed

+81
-18
lines changed

3 files changed

+81
-18
lines changed

app/backup.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
#!/usr/bin/env python3
2+
"""
3+
DB backup script
4+
Dumps PostgreSQL database and uploads it to S3.
5+
"""
6+
7+
import os
8+
import subprocess
9+
import sys
10+
from datetime import datetime, timezone
11+
12+
import boto3
13+
14+
# Settings
15+
DB_NAME = os.environ.get("UMAP_DB_NAME", "umap")
16+
DB_USER = os.environ.get("UMAP_DB_USER", "umap")
17+
DB_PASSWORD = os.environ.get("UMAP_DB_PASSWORD", "")
18+
DB_HOST = os.environ.get("UMAP_DB_HOST", "localhost")
19+
DB_PORT = os.environ.get("UMAP_DB_PORT", "5432")
20+
21+
S3_BUCKET = os.environ.get("S3_BUCKET_NAME")
22+
S3_REGION = os.environ.get("AWS_DEFAULT_REGION", "us-east-1")
23+
S3_PREFIX = "backups"
24+
25+
if not S3_BUCKET:
26+
print("ERROR: S3_BUCKET_NAME env var is not set.")
27+
sys.exit(1)
28+
29+
# Filename
30+
timestamp = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H-%M-%SZ")
31+
filename = f"{DB_NAME}_{timestamp}.dump.gz"
32+
s3_key = f"{S3_PREFIX}/{filename}"
33+
34+
print(f"Database : {DB_USER}@{DB_HOST}:{DB_PORT}/{DB_NAME}")
35+
print(f"S3 target: s3://{S3_BUCKET}/{s3_key}")
36+
print()
37+
38+
# DB dump
39+
print("Running pg_dump...")
40+
env = os.environ.copy()
41+
env["PGPASSWORD"] = DB_PASSWORD
42+
43+
pg_dump = subprocess.Popen(
44+
[
45+
"pg_dump",
46+
"-h", DB_HOST,
47+
"-p", DB_PORT,
48+
"-U", DB_USER,
49+
"-d", DB_NAME,
50+
"-F", "c",
51+
],
52+
stdout=subprocess.PIPE,
53+
stderr=subprocess.PIPE,
54+
env=env,
55+
)
56+
57+
dump_data, pg_err = pg_dump.communicate()
58+
59+
if pg_dump.returncode != 0:
60+
print(f"ERROR: pg_dump failed (exit {pg_dump.returncode}):")
61+
print(pg_err.decode())
62+
sys.exit(1)
63+
64+
size_mb = len(dump_data) / 1024 / 1024
65+
print(f"Dump size: {size_mb:.1f} MB")
66+
67+
# S3 upload
68+
print(f"Uploading to S3...")
69+
s3 = boto3.client("s3", region_name=S3_REGION)
70+
71+
try:
72+
s3.put_object(
73+
Bucket=S3_BUCKET,
74+
Key=s3_key,
75+
Body=dump_data,
76+
)
77+
except Exception as e:
78+
print(f"ERROR: S3 upload failed: {e}")
79+
sys.exit(1)
80+
81+
print(f"Done. Backup saved to s3://{S3_BUCKET}/{s3_key}")

app/pyproject.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ description = "A HOT instance for uMap"
55
readme = "README.md"
66
requires-python = ">=3.13"
77
dependencies = [
8-
"django-dbbackup>=5.0.0",
98
"djangorestframework>=3.16.1",
109
"gunicorn>=23.0.0",
1110
"psycopg2-binary>=2.9.10",

app/settings.py

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -48,26 +48,9 @@
4848

4949
if not "hotumap" in INSTALLED_APPS:
5050
INSTALLED_APPS.append("hotumap")
51-
if not "dbbackup" in INSTALLED_APPS:
52-
INSTALLED_APPS.append("dbbackup")
5351
if not "rest_framework" in INSTALLED_APPS:
5452
INSTALLED_APPS.append("rest_framework")
5553

56-
DBBACKUP_STORAGE = 'django.core.files.storage.FileSystemStorage'
57-
DBBACKUP_STORAGE_OPTIONS = {'location': './backups'}
58-
59-
if os.environ.get('ENABLE_S3_STORAGE', False) == 'True':
60-
DBBACKUP_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
61-
DBBACKUP_STORAGE_OPTIONS = {
62-
"access_key": os.environ.get('S3_ACCESS_KEY'),
63-
"secret_key": os.environ.get('S3_SECRET_KEY'),
64-
"security_token": os.environ.get('S3_SECURITY_TOKEN'),
65-
"bucket_name": os.environ.get('S3_BUCKET_NAME'),
66-
"endpoint_url": os.environ.get('S3_ENDPOINT_URL'),
67-
"location": "backups"
68-
}
69-
70-
7154
LANGUAGE_CODE = "en"
7255

7356
# Set to False if login into django account should not be possible. You can

0 commit comments

Comments
 (0)