Skip to content

Commit dcf0b4f

Browse files
committed
hoftfix
1 parent 267c173 commit dcf0b4f

5 files changed

Lines changed: 48 additions & 10 deletions

File tree

.env.production.example

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,16 @@ DATABASE_URL=
1414
REDIS_URL=redis://redis:6379/1
1515
REDIS_MAXMEMORY=128mb
1616
REDIS_MAXMEMORY_POLICY=allkeys-lru
17+
REDIS_MEM_LIMIT=192m
1718

1819
# Optional runtime settings
1920
PYTHONUNBUFFERED=1
2021
CACHE_DEFAULT_TIMEOUT=300
22+
23+
# Gunicorn / container tuning for low-resource EC2 instances
24+
GUNICORN_WORKERS=2
25+
GUNICORN_THREADS=2
26+
GUNICORN_TIMEOUT=600
27+
GUNICORN_MAX_REQUESTS=1000
28+
GUNICORN_MAX_REQUESTS_JITTER=100
29+
WEB_MEM_LIMIT=768m

.github/workflows/cd-ec2.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ jobs:
1717
deploy:
1818
if: ${{ github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' }}
1919
runs-on: ubuntu-latest
20-
environment: production
20+
environment:
21+
name: production
2122

2223
steps:
2324
- name: Validate required secrets

DEPLOYMENT.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,27 @@ docker compose -f docker-compose.prod.yml ps
7575

7676
App listens on `127.0.0.1:8000` on host (intentionally not public).
7777

78+
### If EC2 is memory-constrained
79+
80+
For small instances, tune `.env` before `docker compose up`:
81+
82+
- `GUNICORN_WORKERS=2` (or `1` on very small instances)
83+
- `GUNICORN_THREADS=2`
84+
- `WEB_MEM_LIMIT=768m`
85+
- `REDIS_MAXMEMORY=128mb`
86+
- `REDIS_MEM_LIMIT=192m`
87+
88+
Optional but recommended: add swap (example: 2 GB):
89+
90+
```bash
91+
sudo fallocate -l 2G /swapfile || sudo dd if=/dev/zero of=/swapfile bs=1M count=2048
92+
sudo chmod 600 /swapfile
93+
sudo mkswap /swapfile
94+
sudo swapon /swapfile
95+
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
96+
free -h
97+
```
98+
7899
## 6. Configure Nginx Reverse Proxy
79100

80101
Create `/etc/nginx/sites-available/tigerpath`:

Dockerfile

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,21 @@ COPY frontend .
2525
EXPOSE 3000
2626
CMD ["bun", "run", "dev", "--host", "0.0.0.0"]
2727

28+
# ---------- frontend build assets ----------
29+
FROM oven/bun:1.3.8 AS frontend-build
30+
WORKDIR /opt/tigerpath/frontend
31+
COPY frontend/package.json frontend/bun.lock ./
32+
RUN bun install --frozen-lockfile --ignore-scripts
33+
COPY frontend .
34+
RUN bun run build
35+
2836
# ---------- production ----------
2937
FROM base AS production
3038

31-
# Build frontend assets (requires bun)
32-
RUN apt-get update && apt-get install -y --no-install-recommends curl unzip \
33-
&& curl -fsSL https://bun.sh/install | bash \
34-
&& export PATH="$HOME/.bun/bin:$PATH" \
35-
&& cd frontend && bun install --frozen-lockfile && bun run build \
36-
&& apt-get purge -y curl unzip && apt-get autoremove -y && rm -rf /var/lib/apt/lists/*
39+
# Copy prebuilt frontend assets from dedicated Bun stage
40+
COPY --from=frontend-build /opt/tigerpath/assets/dist /opt/tigerpath/assets/dist
3741

3842
RUN python manage.py collectstatic --noinput
3943

4044
EXPOSE 8000
41-
CMD ["gunicorn", "config.wsgi:application", "-w", "4", "--bind", "0.0.0.0:8000", "--timeout", "600"]
45+
CMD ["gunicorn", "config.wsgi:application", "-w", "2", "--bind", "0.0.0.0:8000", "--timeout", "600"]

docker-compose.prod.yml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ services:
22
redis:
33
image: redis:7-alpine
44
restart: unless-stopped
5+
mem_limit: ${REDIS_MEM_LIMIT:-192m}
56
command:
67
[
78
"redis-server",
89
"--maxmemory",
9-
"${REDIS_MAXMEMORY:-256mb}",
10+
"${REDIS_MAXMEMORY:-128mb}",
1011
"--maxmemory-policy",
1112
"${REDIS_MAXMEMORY_POLICY:-allkeys-lru}",
1213
]
@@ -24,7 +25,9 @@ services:
2425
dockerfile: Dockerfile
2526
target: production
2627
restart: unless-stopped
27-
command: gunicorn config.wsgi:application -w 4 --bind 0.0.0.0:8000 --timeout 600
28+
init: true
29+
mem_limit: ${WEB_MEM_LIMIT:-768m}
30+
command: gunicorn config.wsgi:application --worker-class gthread --workers ${GUNICORN_WORKERS:-2} --threads ${GUNICORN_THREADS:-2} --bind 0.0.0.0:8000 --timeout ${GUNICORN_TIMEOUT:-600} --max-requests ${GUNICORN_MAX_REQUESTS:-1000} --max-requests-jitter ${GUNICORN_MAX_REQUESTS_JITTER:-100}
2831
ports:
2932
- "127.0.0.1:8000:8000"
3033
env_file:

0 commit comments

Comments
 (0)